summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorOlivier Dufour2012-10-09 13:23:46 +0200
committerOlivier Dufour2012-10-17 16:35:17 +0200
commit98e9f02c3f41f481853d9f2786683a6226789e76 (patch)
treef7c243e192be56a2aec79a080738ab68547d6379 /cleopatre
parentdb9797721a45f102129d1e1d8c42529720557505 (diff)
cleo/app/libmme: split mme_send function, refs #3436
Add mme_header_prepare and mme_prepare functions that fill respectively the MME Header and the MME Entry block. It helps unit testing and readability of the mme_send function.
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/application/libmme/inc/libmme.h2
-rw-r--r--cleopatre/application/libmme/src/mme.c143
2 files changed, 104 insertions, 41 deletions
diff --git a/cleopatre/application/libmme/inc/libmme.h b/cleopatre/application/libmme/inc/libmme.h
index 30adbc4fe2..64d58187cd 100644
--- a/cleopatre/application/libmme/inc/libmme.h
+++ b/cleopatre/application/libmme/inc/libmme.h
@@ -131,6 +131,8 @@ mme_error_t mme_push (mme_ctx_t *ctx, const void *data, unsigned int length, uns
mme_error_t mme_put (mme_ctx_t *ctx, const void *data, unsigned int length, unsigned int *result_length);
mme_error_t mme_pull (mme_ctx_t *ctx, void *data, unsigned int length, unsigned int *result_length);
mme_error_t mme_pop (mme_ctx_t *ctx, void *data, unsigned int length, unsigned int *result_length);
+int mme_header_prepare (MME_t *mh, mme_ctx_t *ctx, unsigned char *src_mac, unsigned char *dest);
+int mme_prepare (MME_t *mh, mme_ctx_t *ctx, int *fo, int index, unsigned char *pkt);
mme_error_t mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest, mme_ctx_t *confirm_ctx);
mme_error_t mme_listen (mme_ctx_t *ctx, char *iface, unsigned char *source, mme_listen_cb_t listen_cb, unsigned int tout);
diff --git a/cleopatre/application/libmme/src/mme.c b/cleopatre/application/libmme/src/mme.c
index a4f0fcca5c..97268988d3 100644
--- a/cleopatre/application/libmme/src/mme.c
+++ b/cleopatre/application/libmme/src/mme.c
@@ -361,6 +361,102 @@ _get_iface_mac_addr (int sock, char *iface, unsigned char *mac_addr)
}
/**
+* Build the MME header. It calculates the number of packet and returns it.
+* \param mh MME header, filled by this function
+* \param ctx MME context to send
+* \param src_mac MAC Address of the source
+* \param dest MAC Address of the destination
+* \return int The number of packets required to send the MME
+*/
+
+int
+mme_header_prepare (MME_t *mh, mme_ctx_t *ctx, unsigned char *src_mac,
+ unsigned char *dest)
+{
+ int nbpkt;
+ uint fmi_nf_mi = 0; /* Number of fragments */
+ uint fmi_fmsn = 0; /* SSN of the fragmented mme */
+ /*
+ * --- Create MME header ---
+ */
+
+ /* copy the Src mac addr */
+ memcpy (mh->mme_src, (void *)src_mac, 6);
+ /* copy the Dst mac addr */
+ memcpy (mh->mme_dest, (void *)dest, 6);
+ /* copy the protocol */
+ mh->mtype = htons (MME_TYPE);
+ /* set default mme version */
+ mh->mmv = MME_VERSION;
+ mh->mmtype = ctx->mmtype;
+
+ /* calculate number of mme packets needed */
+ nbpkt = (ctx->tail - ctx->head) / MME_MAX_SIZE;
+ if (nbpkt == 0 || (ctx->tail - ctx->head) % MME_MAX_SIZE)
+ {
+ nbpkt++;
+ }
+
+ fmi_nf_mi = nbpkt - 1;
+ /* Set the sequence number to 1 if the message is fragmented. This number
+ * correspond to a session number, all fragmented MME of this session must
+ * have the same fmsn number. */
+ fmi_fmsn = fmi_nf_mi ? 1 : 0;
+ mh->fmi = mme_fmi_set (fmi_nf_mi, 0, fmi_fmsn);
+
+ return nbpkt;
+}
+
+/**
+* Build a packet from the context. This function will be called by mme_send
+* before sending each fragment of the packet. The function will update the
+* fragment offset.
+* This function is for internal use, and should not be used outside the
+* library.
+* \param mh MME header, will be updated with the correct fragment number
+* \param ctx MME context to send
+* \param fo Fragment offset, from which data must be sent
+* \param index Fragment number
+* \param pkt Pointer to the head of the data buffer
+* \return int Size of the packet (including header)
+*/
+
+int
+mme_prepare (MME_t *mh, mme_ctx_t *ctx, int *fo, int index, unsigned char *pkt)
+{
+ int fs = 0;
+ uint fmi_nf_mi = 0; /* Number of fragments */
+ uint fmi_fn_mi = 0; /* Fragment number */
+ uint fmi_fmsn = 0; /* SSN of the fragmented mme */
+
+ /*
+ * --- Set per-message fragmentation info, current fragment number ---
+ */
+ mme_fmi_get (mh->fmi, &fmi_nf_mi, &fmi_fn_mi, &fmi_fmsn);
+ mh->fmi = mme_fmi_set (fmi_nf_mi, index, fmi_fmsn);
+
+ /*
+ * --- Append payload ---
+ */
+
+ /* calculate the size of the current fragment */
+ fs = ((ctx->tail - *fo) < MME_MAX_SIZE) ? (ctx->tail - *fo) : MME_MAX_SIZE;
+ /* copy the content into packet buffer */
+ memcpy (pkt, ctx->buffer + *fo, fs);
+ /* update fo */
+ *fo += fs;
+
+ /* zero-pad the rest if last packet fs < MME_MIN_SIZE, which is minimum size for mme packet */
+ if (fs < MME_MIN_SIZE)
+ {
+ memset (pkt + fs, 0x0, MME_MIN_SIZE - fs);
+ fs = MME_MIN_SIZE;
+ }
+
+ return (fs + sizeof (MME_t));
+}
+
+/**
* Send MME to network interface and wait for confirm MME; this is a synchronous transmit and receive transaction
* (function waits for answer MME before returning). If no answer packet is received before MME_CONFIRM_TIMEOUT,
* error is returned.<br>
@@ -399,7 +495,6 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
unsigned short nbpkt = 0;
fd_set fds;
int fo; /* current fragment offset */
- int fs; /* current fragment size */
struct sockaddr_ll pkt_info;
int last_pkt = 0;
uint fmi_nf_mi = 0; /* Number of fragments */
@@ -486,29 +581,11 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
return MME_ERROR_GEN;
}
- /*
- * --- Create MME header ---
- */
-
mh = (MME_t *)pkt_holder;
- /* copy the Src mac addr */
- memcpy (mh->mme_src, (void *)src_mac, 6);
- /* copy the Dst mac addr */
- memcpy (mh->mme_dest, (void *)dest, 6);
- /* copy the protocol */
- mh->mtype = htons (MME_TYPE);
- /* set default mme version */
- mh->mmv = MME_VERSION;
- mh->mmtype = ctx->mmtype;
- mh->fmi = 0;
- /* calculate number of mme packets needed */
- fmi_nf_mi = (ctx->tail - ctx->head) / (MME_MAX_SIZE);
- /* Set the sequence number to 1 if the message is fragmented. This number
- * correspond to a session number, all fragmented MME of this session must
- * have the same fmsn number. */
- fmi_fmsn = fmi_nf_mi ? 1 : 0;
- nbpkt = fmi_nf_mi + 1;
+ nbpkt = mme_header_prepare (mh, ctx, src_mac, dest);
+ mme_fmi_get (mh->fmi, &fmi_nf_mi, &fmi_fn_mi, &fmi_fmsn);
+
/* Security check, if nbpkt is more than 15 don't send anything and inform
* the user. */
if (fmi_nf_mi > 0xf)
@@ -524,27 +601,13 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
for (i=0; i<nbpkt; i++)
{
/*
- * --- Set per-message fragmentation info, current fragment number ---
- */
- mh->fmi = mme_fmi_set (fmi_nf_mi, i, fmi_fmsn);
-
- /*
* --- Append payload ---
*/
/* skip the MME header */
pkt = pkt_holder + sizeof (MME_t);
- /* calculate the size of the current fragment */
- fs = (ctx->tail - fo < (MME_MAX_SIZE)) ? ctx->tail - fo : (MME_MAX_SIZE);
- /* copy the content into packet buffer */
- memcpy (pkt, ctx->buffer + fo, fs);
- /* update fo */
- fo += fs;
- /* zero-pad the rest if last packet fs < MME_MIN_SIZE, which is minimum size for mme packet */
- if (fs < MME_MIN_SIZE)
- {
- memset (ctx->buffer + fo, 0x0, MME_MIN_SIZE - fs);
- fs = MME_MIN_SIZE;
- }
+
+ /* determine the size of whole packet (header + data) */
+ pkt_len = mme_prepare (mh, ctx, &fo, i, pkt);
/*
* --- Send raw packet ---
@@ -552,8 +615,6 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
/* initialize pkt pointer to the start of the send buffer */
pkt = pkt_holder;
- /* determine the size of whole packet (header + data) */
- pkt_len = sizeof (MME_t) + fs;
if ((sent = write (raw, pkt, pkt_len)) != pkt_len)
{
perror ("string error\n");