summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorNélio Laranjeiro2012-09-04 09:58:52 +0200
committerNélio Laranjeiro2012-10-10 17:05:39 +0200
commit84104b65809a653426c832046d23c85889c3e5fd (patch)
tree914d251c585dd41f91d4ebc680c13a51b35224a8 /cleopatre
parent9a32593a494b8193c8837fa06c97552542652375 (diff)
cleo/application/libmme: handle correctly the MME FMI field, closes #3326
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/application/libmme/src/mme.c85
-rw-r--r--cleopatre/devkit/tests/libmme/utests/src/mme_utests.c40
2 files changed, 75 insertions, 50 deletions
diff --git a/cleopatre/application/libmme/src/mme.c b/cleopatre/application/libmme/src/mme.c
index 3735c47f36..156368e01d 100644
--- a/cleopatre/application/libmme/src/mme.c
+++ b/cleopatre/application/libmme/src/mme.c
@@ -33,6 +33,35 @@
#include "libmme.h"
/**
+ * Construct the FMI field of the MME header.
+ * \param nf_mi number of fragments
+ * \param fn_mi fragment number
+ * \param fmsn fragmentation message sequence number
+ * \return the FMI field.
+ */
+static inline unsigned short
+mme_fmi_set (uint nf_mi, uint fn_mi, uint fmsn)
+{
+ return (fmsn << 8) | (nf_mi << 4) | fn_mi;
+}
+
+/**
+ * Get the FMI field uncompressed from the MME header.
+ * \param fmi the compressed FMI
+ * \param nf_mi number of fragments
+ * \param fn_mi fragment number
+ * \param fmsn fragmentation message sequence number
+ */
+static inline void
+mme_fmi_get (const unsigned short fmi, uint *nf_mi,
+ uint *fn_mi, uint *fmsn)
+{
+ *fn_mi = fmi & 0xF;
+ *nf_mi = (fmi >> 4) & 0xF;
+ *fmsn = (fmi >> 8) & 0xFF;
+}
+
+/**
* Create a MME message context. This context is used to build the MME message step by step.<br>
* The provided buffer must be enough large to contain all the final payload.<br>
* The MME payload can be bigger than an ethernet payload, as the fragmentation is managed by the 'send' function.
@@ -373,7 +402,9 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
int fs; /* current fragment size */
struct sockaddr_ll pkt_info;
int last_pkt = 0;
- unsigned short hfmi; /* fmi in host byte order */
+ uint fmi_nf_mi = 0; /* Number of fragments */
+ uint fmi_fn_mi = 0; /* Fragment number */
+ uint fmi_fmsn = 0; /* SSN of the fragmented mme */
struct timeval timeout; /* When we should time out */
struct timeval now;
struct timeval waittime;
@@ -383,7 +414,7 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
int i;
int pkt_nfo_sz = sizeof (pkt_info);
mme_error_t ret;
- int pkt_cnt = 0;
+ uint pkt_cnt = 0;
char *iface_real;
/* protect from null pointers */
@@ -472,13 +503,19 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
mh->fmi = 0;
/* calculate number of mme packets needed */
- nbpkt = (ctx->tail - ctx->head) / (PKTSIZE - sizeof (MME_t));
- if (nbpkt == 0 || (ctx->tail - ctx->head) % (PKTSIZE - sizeof (MME_t)) > 0)
+ fmi_nf_mi = (ctx->tail - ctx->head) / (PKTSIZE - sizeof (MME_t));
+ /* 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;
+ /* Security check, if nbpkt is more than 15 don't send anything and inform
+ * the user. */
+ if (fmi_nf_mi > 0xf)
{
- nbpkt++;
+ printf("The MME to send is too long and cannot be fragmented\n");
+ return MME_ERROR_SPACE;
}
- /* set fragmentation info, nb of fragments */
- hfmi = nbpkt - 1;
/* initialize fragment offset to the begining of the payload*/
fo = ctx->head;
@@ -489,13 +526,7 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
/*
* --- Set per-message fragmentation info, current fragment number ---
*/
- /* clear out higher bits, keep only bits 0-3 */
- hfmi &= 0x0f;
- /* set bits 4-7 to a new value */
- hfmi |= i << 4 ;
-
- /* We now have correct hfmi, so we can set our pkg field (in network byteorder) */
- mh->fmi = hfmi;
+ mh->fmi = mme_fmi_set (fmi_nf_mi, i, fmi_fmsn);
/*
* --- Append payload ---
@@ -601,15 +632,15 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
}
mh = (MME_t *)pkt;
- hfmi = mh->fmi;
+ mme_fmi_get (mh->fmi, &fmi_nf_mi, &fmi_fn_mi, &fmi_fmsn);
/* check if response came from the our proper server, and if it is,
* check if correspondent response was sent (REQ/CNF or IND/RSP);
* by HP AV standard difference is in LSB, i.e. if REQ LSBs are ...00,
* CNF will be ...01, IND ...10 and RSP ...11 */
- if (memcmp (pkt_info.sll_addr, dest, 6) == 0 && /* we received packet from correct source */
- (mh->mmtype == confirm_ctx->mmtype) && /* we received type that we expect */
- hfmi >> 4 == pkt_cnt ) /* packets are coming in the right order */
+ if (memcmp (pkt_info.sll_addr, dest, 6) == 0 /* we received packet from correct source */
+ && mh->mmtype == confirm_ctx->mmtype /* we received type that we expect */
+ && fmi_fn_mi == pkt_cnt ) /* packets are coming in the right order */
{
break; /* good answer - go out and process the package */
@@ -617,7 +648,7 @@ mme_send (mme_ctx_t *ctx, mme_send_type_t type, char *iface, unsigned char *dest
} /* for */
/* check if the packet we received is the last one */
- if (hfmi >> 4 == (hfmi & 0x0f))
+ if (fmi_fn_mi == fmi_nf_mi)
last_pkt = 1;
/* skip the MME header */
@@ -668,7 +699,9 @@ mme_listen (mme_ctx_t *ctx, char *iface, unsigned char *source, mme_listen_cb_t
fd_set fds;
struct sockaddr_ll pkt_info;
int last_pkt = 0;
- unsigned short hfmi; /* fmi in host byte order */
+ uint fmi_nf_mi = 0; /* Number of fragments */
+ uint fmi_fn_mi = 0; /* Fragment number */
+ uint fmi_fmsn = 0; /* SSN of the fragmented mme */
struct timeval timeout; /* When we should time out */
struct timeval now;
struct timeval waittime;
@@ -677,7 +710,7 @@ mme_listen (mme_ctx_t *ctx, char *iface, unsigned char *source, mme_listen_cb_t
unsigned int result_len;
int pkt_nfo_sz = sizeof (pkt_info);
mme_error_t ret;
- int pkt_cnt = 0; /* to indicate if we recive packets in
+ uint pkt_cnt = 0; /* to indicate if we recive packets in
* correct order */
/* protect from null pointers */
@@ -837,23 +870,23 @@ mme_listen (mme_ctx_t *ctx, char *iface, unsigned char *source, mme_listen_cb_t
}
mh = (MME_t *)pkt;
- hfmi = mh->fmi;
+ mme_fmi_get (mh->fmi, &fmi_nf_mi, &fmi_fn_mi, &fmi_fmsn);
/* check if indication came from the good source, and if it is,
* check if cooresponds to our prepared response (REQ/CNF or IND/RSP);
* by HP AV standard difference is in LSB, i.e. if REQ LSBs are ...00,
* CNF will be ...01, IND ...10 and RSP ...11
* REQ is always CNF - 1, IND is RSP - 1 */
- if (memcmp (pkt_info.sll_addr, source, ETH_ALEN) == 0 && /* we received packet from correct source */
- (mh->mmtype == ctx->mmtype) && /* waited MME type */
- hfmi >> 4 == pkt_cnt) /* packets are coming in the right order */
+ if (memcmp (pkt_info.sll_addr, source, ETH_ALEN) == 0 /* we received packet from correct source */
+ && (mh->mmtype == ctx->mmtype) /* waited MME type */
+ && fmi_fn_mi == pkt_cnt) /* packets are coming in the right order */
{
break; /* good answer - go out and process the package */
}
} /* for */
/* check if the packet we received is the last one */
- if (hfmi >> 4 == (hfmi & 0x0f))
+ if (fmi_fn_mi == fmi_nf_mi)
last_pkt = 1;
/* skip the MME header */
diff --git a/cleopatre/devkit/tests/libmme/utests/src/mme_utests.c b/cleopatre/devkit/tests/libmme/utests/src/mme_utests.c
index bcdad42abb..02260e3a21 100644
--- a/cleopatre/devkit/tests/libmme/utests/src/mme_utests.c
+++ b/cleopatre/devkit/tests/libmme/utests/src/mme_utests.c
@@ -181,7 +181,7 @@ static int send_message()
{
MME_t *mh = &hdr;
int nbpkt;
- unsigned short hfmi;
+ uint fmi_nf_mi, fmi_fmsn;
unsigned int fo; /* current fragment offset */
unsigned int fs; /* current fragment size */
int i;
@@ -196,10 +196,11 @@ static int send_message()
mh = (MME_t *)frame_tx;
/* we will be sending the same num of packets as we received */
- nbpkt = ( mh->fmi & 0x0f ) + 1; /* clear out higher bits, keep only bits 0-3 */
+ fmi_nf_mi = (mh->fmi >> 4) & 0xf;
+ nbpkt = fmi_nf_mi + 1; /* clear out higher bits, keep only bits 0-3 */
/* set fragmentation info, nb of fragments */
- hfmi = nbpkt - 1;
+ fmi_fmsn = fmi_nf_mi ? 1 : 0;
/* initialize fragment offset to the begining of the payload*/
fo = thr_ctx->head;
@@ -209,13 +210,8 @@ static int send_message()
/*
* --- Set per-message fragmentation info, current fragment number ---
*/
- /* clear out higher bits, keep only bits 0-3 */
- hfmi &= 0x0f;
- /* set bits 4-7 to a new value */
- hfmi |= i << 4 ;
-
- /* We now have correct hfmi, so we can set our pkg field (in network byteorder) */
- mh->fmi = hfmi;
+ /* We now have correct fmi, so we can set our pkg field (in network byte order) */
+ mh->fmi = (fmi_fmsn << 8) | (fmi_nf_mi << 4) | i;
/*
* --- Append payload ---
@@ -332,7 +328,6 @@ static void* thread_receiver(void *unused)
uint32_t *check_frame;
int i;
#endif
- unsigned short hfmi; /* fmi in host byte order */
int rcv_len = 0;
unsigned char *pkt;
int nbpkt;
@@ -343,6 +338,7 @@ static void* thread_receiver(void *unused)
struct timeval waittime;
fd_set fds;
int res;
+ uint fmi_fn_mi, fmi_nf_mi, fmi_fmsn;
TRACE("Thread 'receiver' starting...\n");
@@ -430,8 +426,10 @@ static void* thread_receiver(void *unused)
} /* for */
/* check if the packet we received is the last one */
- hfmi = mh->fmi;
- if ( hfmi >> 4 == (hfmi & 0x0f) )
+ fmi_fmsn = mh->fmi >> 8;
+ fmi_nf_mi = (mh->fmi & 0xf0) >> 4;
+ fmi_fn_mi = mh->fmi & 0xf;
+ if (fmi_nf_mi == fmi_fn_mi)
last_pkt = 1;
/* skip the MME header */
@@ -472,18 +470,12 @@ static void* thread_receiver(void *unused)
memset(thr_buff + HEAD, 0xa, MSG_LEN/2);
memset(thr_buff + HEAD + MSG_LEN/2, 0xb, MSG_LEN/2);
- /* set the fragmentation information */
- hfmi &= 0;
-
/* calculate number of mme packets needed */
- nbpkt = (thr_ctx->tail - thr_ctx->head) / ( PKTSIZE - sizeof(MME_t) );
- if ( (thr_ctx->tail - thr_ctx->head) % ( PKTSIZE - sizeof(MME_t) ) > 0 )
- {
- nbpkt++;
- }
- /* set fragmentation info, nb of fragments */
- hfmi = nbpkt - 1;
- mh->fmi = hfmi;
+ fmi_nf_mi = (thr_ctx->tail - thr_ctx->head) / ( PKTSIZE - sizeof(MME_t));
+ fmi_fn_mi = 0;
+ fmi_fmsn = fmi_nf_mi ? 1 : 0;
+ nbpkt = fmi_nf_mi + 1;
+ mh->fmi = (fmi_fmsn << 8) | (fmi_nf_mi << 4) | fmi_fn_mi;
/* inverse the addresses */
memcpy(tmp_addr, mh->mme_dest, 6);