diff --git a/core/net/llsec/llsec802154.h b/core/net/llsec/llsec802154.h index 6ab6a9793..2ccd30515 100644 --- a/core/net/llsec/llsec802154.h +++ b/core/net/llsec/llsec802154.h @@ -85,6 +85,12 @@ #define LLSEC802154_USES_EXPLICIT_KEYS 0 #endif /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */ +#ifdef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_CONF_USES_FRAME_COUNTER +#else /* LLSEC802154_CONF_USES_FRAME_COUNTER */ +#define LLSEC802154_USES_FRAME_COUNTER (LLSEC802154_SECURITY_LEVEL != FRAME802154_SECURITY_LEVEL_NONE) +#endif /* LLSEC802154_CONF_USES_FRAME_COUNTER */ + #if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN #define LLSEC802154_HTONS(n) (n) #define LLSEC802154_HTONL(n) (n) diff --git a/core/net/mac/frame802154.c b/core/net/mac/frame802154.c index 3cd85d20b..c2982a014 100644 --- a/core/net/mac/frame802154.c +++ b/core/net/mac/frame802154.c @@ -44,11 +44,11 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * -*/ + */ /* * \brief This file is where the main functions that relate to frame * manipulation will reside. -*/ + */ /** * \file @@ -61,7 +61,7 @@ /** * \addtogroup frame802154 * @{ -*/ + */ #include "sys/cc.h" #include "net/mac/frame802154.h" @@ -69,11 +69,18 @@ #include "net/linkaddr.h" #include +/** \brief The 16-bit identifier of the PAN on which the device is + * operating. If this value is 0xffff, the device is not + * associated. + */ +static uint16_t mac_pan_id = IEEE802154_PANID; + /** * \brief Structure that contains the lengths of the various addressing and security fields * in the 802.15.4 header. This structure is used in \ref frame802154_create() */ typedef struct { + uint8_t seqno_len; /**< Length (in bytes) of sequence number field */ uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */ uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */ uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */ @@ -111,30 +118,199 @@ get_key_id_len(uint8_t key_id_mode) } } #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ +/*---------------------------------------------------------------------------*/ +/* Get current PAN ID */ +uint16_t +frame802154_get_pan_id(void) +{ + return mac_pan_id; +} +/*---------------------------------------------------------------------------*/ +/* Set current PAN ID */ +void +frame802154_set_pan_id(uint16_t pan_id) +{ + mac_pan_id = pan_id; +} +/*----------------------------------------------------------------------------*/ +/* Tells whether a given Frame Control Field indicates a frame with + * source PANID and/or destination PANID */ +void +frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest_pan_id) +{ + int src_pan_id = 0; + int dest_pan_id = 0; + + if(fcf == NULL) { + return; + } + + if(fcf->frame_version == FRAME802154_IEEE802154E_2012) { + if(!fcf->panid_compression) { + /* Compressed PAN ID == no PAN ID at all */ + if(fcf->dest_addr_mode == fcf->dest_addr_mode) { + /* No address or both addresses: include destination PAN ID */ + dest_pan_id = 1; + } else if(fcf->dest_addr_mode) { + /* Only dest address, include dest PAN ID */ + dest_pan_id = 1; + } else if(fcf->src_addr_mode) { + /* Only src address, include src PAN ID */ + src_pan_id = 1; + } + } + if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 1) { + /* No address included, include dest PAN ID conditionally */ + if(!fcf->panid_compression) { + dest_pan_id = 1; + } + } + /* Remove the following rule the day rows 2 and 3 from table 2a are fixed: */ + if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 0) { + /* Not meaningful, we include a PAN ID iff the compress flag is set, but + * this is what the standard currently stipulates */ + dest_pan_id = fcf->panid_compression; + } + } else { + /* No PAN ID in ACK */ + if(fcf->frame_type != FRAME802154_ACKFRAME) { + if(!fcf->panid_compression && fcf->src_addr_mode & 3) { + /* If compressed, don't inclue source PAN ID */ + src_pan_id = 1; + } + if(fcf->dest_addr_mode & 3) { + dest_pan_id = 1; + } + } + } + + if(has_src_pan_id != NULL) { + *has_src_pan_id = src_pan_id; + } + if(has_dest_pan_id != NULL) { + *has_dest_pan_id = dest_pan_id; + } +} +/*---------------------------------------------------------------------------*/ +/* Check if the destination PAN ID, if any, matches ours */ +int +frame802154_check_dest_panid(frame802154_t *frame) +{ + int has_dest_panid; + + if(frame == NULL) { + return 0; + } + frame802154_has_panid(&frame->fcf, NULL, &has_dest_panid); + if(has_dest_panid + && frame->dest_pid != frame802154_get_pan_id() + && frame->dest_pid != FRAME802154_BROADCASTPANDID) { + /* Packet to another PAN */ + return 0; + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Check is the address is a broadcast address, whatever its size */ +int +frame802154_is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +/* Check and extract source and destination linkaddr from frame */ +int +frame802154_extract_linkaddr(frame802154_t *frame, + linkaddr_t *source_address, linkaddr_t *dest_address) +{ + int src_addr_len; + int dest_addr_len; + + if(frame == NULL) { + return 0; + } + /* Check and extract source address */ + src_addr_len = frame->fcf.src_addr_mode ? + ((frame->fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0; + if(src_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.src_addr_mode, frame->src_addr)) { + /* Broadcast address */ + if(source_address != NULL) { + linkaddr_copy(source_address, &linkaddr_null); + } + } else { + /* Unicast address */ + if(src_addr_len != LINKADDR_SIZE) { + /* Destination address has a size we can not handle */ + return 0; + } + if(source_address != NULL) { + linkaddr_copy(source_address, (linkaddr_t *)frame->src_addr); + } + } + + /* Check and extract destination address */ + dest_addr_len = frame->fcf.dest_addr_mode ? + ((frame->fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0; + if(dest_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.dest_addr_mode, frame->dest_addr)) { + /* Broadcast address */ + if(dest_address != NULL) { + linkaddr_copy(dest_address, &linkaddr_null); + } + } else { + /* Unicast address */ + if(dest_addr_len != LINKADDR_SIZE) { + /* Destination address has a size we can not handle */ + return 0; + } + if(dest_address != NULL) { + linkaddr_copy(dest_address, (linkaddr_t *)frame->dest_addr); + } + } + + return 1; +} /*----------------------------------------------------------------------------*/ static void field_len(frame802154_t *p, field_length_t *flen) { + int has_src_panid; + int has_dest_panid; + /* init flen to zeros */ memset(flen, 0, sizeof(field_length_t)); /* Determine lengths of each field based on fcf and other args */ - if(p->fcf.dest_addr_mode & 3) { - flen->dest_pid_len = 2; + if((p->fcf.sequence_number_suppression & 1) == 0) { + flen->seqno_len = 1; } - if(p->fcf.src_addr_mode & 3) { + + /* IEEE802.15.4e changes the meaning of PAN ID Compression (see Table 2a). + * In this case, we leave the decision whether to compress PAN ID or not + * up to the caller. */ + if(p->fcf.frame_version < FRAME802154_IEEE802154E_2012) { + /* Set PAN ID compression bit if src pan id matches dest pan id. */ + if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 && + p->src_pid == p->dest_pid) { + p->fcf.panid_compression = 1; + } else { + p->fcf.panid_compression = 0; + } + } + + frame802154_has_panid(&p->fcf, &has_src_panid, &has_dest_panid); + + if(has_src_panid) { flen->src_pid_len = 2; } - /* Set PAN ID compression bit if src pan id matches dest pan id. */ - if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 && - p->src_pid == p->dest_pid) { - p->fcf.panid_compression = 1; - - /* compressed header, only do dest pid */ - flen->src_pid_len = 0; - } else { - p->fcf.panid_compression = 0; + if(has_dest_panid) { + flen->dest_pid_len = 2; } /* determine address lengths */ @@ -144,9 +320,16 @@ field_len(frame802154_t *p, field_length_t *flen) #if LLSEC802154_SECURITY_LEVEL /* Aux security header */ if(p->fcf.security_enabled & 1) { - flen->aux_sec_len = 5 + flen->aux_sec_len = 1; /* FCF + possibly frame counter and key ID */ + if(p->aux_hdr.security_control.frame_counter_suppression == 0) { + if(p->aux_hdr.security_control.frame_counter_size == 1) { + flen->aux_sec_len += 5; + } else { + flen->aux_sec_len += 4; + } + } #if LLSEC802154_USES_EXPLICIT_KEYS - + get_key_id_len(p->aux_hdr.security_control.key_id_mode); + flen->aux_sec_len += get_key_id_len(p->aux_hdr.security_control.key_id_mode); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ ; } @@ -161,14 +344,14 @@ field_len(frame802154_t *p, field_length_t *flen) * frame to send. * * \return The length of the frame header. -*/ + */ int frame802154_hdrlen(frame802154_t *p) { field_length_t flen; field_len(p, &flen); - return 3 + flen.dest_pid_len + flen.dest_addr_len + - flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len; + return 2 + flen.seqno_len + flen.dest_pid_len + flen.dest_addr_len + + flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len; } /*----------------------------------------------------------------------------*/ /** @@ -181,7 +364,7 @@ frame802154_hdrlen(frame802154_t *p) * \param buf Pointer to the buffer to use for the frame. * * \return The length of the frame header -*/ + */ int frame802154_create(frame802154_t *p, uint8_t *buf) { @@ -193,7 +376,7 @@ frame802154_create(frame802154_t *p, uint8_t *buf) #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ field_len(p, &flen); - + /* OK, now we have field lengths. Time to actually construct */ /* the outgoing frame, and store it in buf */ buf[0] = (p->fcf.frame_type & 7) | @@ -201,13 +384,18 @@ frame802154_create(frame802154_t *p, uint8_t *buf) ((p->fcf.frame_pending & 1) << 4) | ((p->fcf.ack_required & 1) << 5) | ((p->fcf.panid_compression & 1) << 6); - buf[1] = ((p->fcf.dest_addr_mode & 3) << 2) | + buf[1] = ((p->fcf.sequence_number_suppression & 1)) | + ((p->fcf.ie_list_present & 1)) << 1 | + ((p->fcf.dest_addr_mode & 3) << 2) | ((p->fcf.frame_version & 3) << 4) | ((p->fcf.src_addr_mode & 3) << 6); - /* sequence number */ - buf[2] = p->seq; - pos = 3; + pos = 2; + + /* Sequence number */ + if(flen.seqno_len == 1) { + buf[pos++] = p->seq; + } /* Destination PAN ID */ if(flen.dest_pid_len == 2) { @@ -230,17 +418,24 @@ frame802154_create(frame802154_t *p, uint8_t *buf) for(c = flen.src_addr_len; c > 0; c--) { buf[pos++] = p->src_addr[c - 1]; } - #if LLSEC802154_SECURITY_LEVEL /* Aux header */ if(flen.aux_sec_len) { buf[pos++] = p->aux_hdr.security_control.security_level #if LLSEC802154_USES_EXPLICIT_KEYS - | (p->aux_hdr.security_control.key_id_mode << 3) + | (p->aux_hdr.security_control.key_id_mode << 3) #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ + | (p->aux_hdr.security_control.frame_counter_suppression << 5) + | (p->aux_hdr.security_control.frame_counter_size << 6) ; - memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4); - pos += 4; + if(p->aux_hdr.security_control.frame_counter_suppression == 0) { + /* We support only 4-byte counters */ + memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4); + pos += 4; + if(p->aux_hdr.security_control.frame_counter_size == 1) { + pos++; + } + } #if LLSEC802154_USES_EXPLICIT_KEYS key_id_mode = p->aux_hdr.security_control.key_id_mode; @@ -272,11 +467,13 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) uint8_t *p; frame802154_fcf_t fcf; int c; + int has_src_panid; + int has_dest_panid; #if LLSEC802154_USES_EXPLICIT_KEYS uint8_t key_id_mode; #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ - if(len < 3) { + if(len < 2) { return 0; } @@ -289,20 +486,32 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) fcf.ack_required = (p[0] >> 5) & 1; fcf.panid_compression = (p[0] >> 6) & 1; + fcf.sequence_number_suppression = p[1] & 1; + fcf.ie_list_present = (p[1] >> 1) & 1; fcf.dest_addr_mode = (p[1] >> 2) & 3; fcf.frame_version = (p[1] >> 4) & 3; fcf.src_addr_mode = (p[1] >> 6) & 3; /* copy fcf and seqNum */ memcpy(&pf->fcf, &fcf, sizeof(frame802154_fcf_t)); - pf->seq = p[2]; - p += 3; /* Skip first three bytes */ + p += 2; /* Skip first two bytes */ + + if(fcf.sequence_number_suppression == 0) { + pf->seq = p[0]; + p++; + } + + frame802154_has_panid(&fcf, &has_src_panid, &has_dest_panid); /* Destination address, if any */ if(fcf.dest_addr_mode) { - /* Destination PAN */ - pf->dest_pid = p[0] + (p[1] << 8); - p += 2; + if(has_dest_panid) { + /* Destination PAN */ + pf->dest_pid = p[0] + (p[1] << 8); + p += 2; + } else { + pf->dest_pid = 0; + } /* Destination address */ /* l = addr_len(fcf.dest_addr_mode); */ @@ -329,9 +538,12 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) /* Source address, if any */ if(fcf.src_addr_mode) { /* Source PAN */ - if(!fcf.panid_compression) { + if(has_src_panid) { pf->src_pid = p[0] + (p[1] << 8); p += 2; + if(!has_dest_panid) { + pf->dest_pid = pf->src_pid; + } } else { pf->src_pid = pf->dest_pid; } @@ -357,18 +569,25 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf) linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null); pf->src_pid = 0; } - + #if LLSEC802154_SECURITY_LEVEL if(fcf.security_enabled) { pf->aux_hdr.security_control.security_level = p[0] & 7; #if LLSEC802154_USES_EXPLICIT_KEYS pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3; #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ + pf->aux_hdr.security_control.frame_counter_suppression = p[0] >> 5; + pf->aux_hdr.security_control.frame_counter_size = p[0] >> 6; p += 1; - - memcpy(pf->aux_hdr.frame_counter.u8, p, 4); - p += 4; - + + if(pf->aux_hdr.security_control.frame_counter_suppression == 0) { + memcpy(pf->aux_hdr.frame_counter.u8, p, 4); + p += 4; + if(pf->aux_hdr.security_control.frame_counter_size == 1) { + p ++; + } + } + #if LLSEC802154_USES_EXPLICIT_KEYS key_id_mode = pf->aux_hdr.security_control.key_id_mode; if(key_id_mode) { diff --git a/core/net/mac/frame802154.h b/core/net/mac/frame802154.h index 64a367120..defb64b53 100644 --- a/core/net/mac/frame802154.h +++ b/core/net/mac/frame802154.h @@ -41,7 +41,7 @@ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. -*/ + */ /** * \addtogroup net @@ -59,14 +59,14 @@ * This file converts to and from a structure to a packed 802.15.4 * frame. * -*/ - + */ /* Includes */ #ifndef FRAME_802154_H #define FRAME_802154_H #include "contiki-conf.h" +#include "net/linkaddr.h" #ifdef IEEE802154_CONF_PANID #define IEEE802154_PANID IEEE802154_CONF_PANID @@ -74,6 +74,18 @@ #define IEEE802154_PANID 0xABCD #endif /* IEEE802154_CONF_PANID */ +#ifdef FRAME802154_CONF_VERSION +#define FRAME802154_VERSION FRAME802154_CONF_VERSION +#else /* FRAME802154_CONF_VERSION */ +#define FRAME802154_VERSION FRAME802154_IEEE802154_2006 +#endif /* FRAME802154_CONF_VERSION */ + +#ifdef FRAME802154_CONF_SUPPR_SEQNO +#define FRAME802154_SUPPR_SEQNO FRAME802154_CONF_SUPPR_SEQNO +#else /* FRAME802154_CONF_SUPPR_SEQNO */ +#define FRAME802154_SUPPR_SEQNO 0 +#endif /* FRAME802154_CONF_SUPPR_SEQNO */ + /* Macros & Defines */ /** \brief These are some definitions of values used in the FCF. See the 802.15.4 spec for details. @@ -97,8 +109,9 @@ #define FRAME802154_BROADCASTADDR (0xFFFF) #define FRAME802154_BROADCASTPANDID (0xFFFF) -#define FRAME802154_IEEE802154_2003 (0x00) -#define FRAME802154_IEEE802154_2006 (0x01) +#define FRAME802154_IEEE802154_2003 (0x00) +#define FRAME802154_IEEE802154_2006 (0x01) +#define FRAME802154_IEEE802154E_2012 (0x02) #define FRAME802154_SECURITY_LEVEL_NONE (0) #define FRAME802154_SECURITY_LEVEL_MIC_32 (1) @@ -125,7 +138,7 @@ * 3. Addressing fields - 4 - 20 bytes - Variable * 4. Aux security header - 0 - 14 bytes - Variable * 5. CRC - 2 bytes - Fixed -*/ + */ /** * \brief Defines the bitfields of the frame control field (FCF). @@ -136,7 +149,9 @@ typedef struct { uint8_t frame_pending; /**< 1 bit. True if sender has more data to send */ uint8_t ack_required; /**< 1 bit. Is an ack frame required? */ uint8_t panid_compression; /**< 1 bit. Is this a compressed header? */ - /* uint8_t reserved; */ /**< 3 bit. Unused bits */ + /* uint8_t reserved; */ /**< 1 bit. Unused bit */ + uint8_t sequence_number_suppression; /**< 1 bit. Does the header omit sequence number?, see 802.15.4e */ + uint8_t ie_list_present; /**< 1 bit. Does the header contain Information Elements?, see 802.15.4e */ uint8_t dest_addr_mode; /**< 2 bit. Destination address mode, see 802.15.4 */ uint8_t frame_version; /**< 2 bit. 802.15.4 frame version */ uint8_t src_addr_mode; /**< 2 bit. Source address mode, see 802.15.4 */ @@ -146,6 +161,8 @@ typedef struct { typedef struct { uint8_t security_level; /**< 3 bit. security level */ uint8_t key_id_mode; /**< 2 bit. Key identifier mode */ + uint8_t frame_counter_suppression; /**< 1 bit. Frame counter suppression */ + uint8_t frame_counter_size; /**< 1 bit. Frame counter size (0: 4 bytes, 1: 5 bytes) */ uint8_t reserved; /**< 3 bit. Reserved bits */ } frame802154_scf_t; @@ -193,6 +210,20 @@ int frame802154_hdrlen(frame802154_t *p); int frame802154_create(frame802154_t *p, uint8_t *buf); int frame802154_parse(uint8_t *data, int length, frame802154_t *pf); +/* Get current PAN ID */ +uint16_t frame802154_get_pan_id(void); +/* Set current PAN ID */ +void frame802154_set_pan_id(uint16_t pan_id); +/* Tells whether a given Frame Control Field indicates a frame with + * source PANID and/or destination PANID */ +void frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest_pan_id); +/* Check if the destination PAN ID, if any, matches ours */ +int frame802154_check_dest_panid(frame802154_t *frame); +/* Check is the address is a broadcast address, whatever its size */ +int frame802154_is_broadcast_addr(uint8_t mode, uint8_t *addr); +/* Check and extract source and destination linkaddr from frame */ +int frame802154_extract_linkaddr(frame802154_t *frame, linkaddr_t *source_address, linkaddr_t *dest_address); + /** @} */ #endif /* FRAME_802154_H */ /** @} */ diff --git a/core/net/mac/framer-802154.c b/core/net/mac/framer-802154.c index ce96f6239..14ccc5aa3 100644 --- a/core/net/mac/framer-802154.c +++ b/core/net/mac/framer-802154.c @@ -62,30 +62,6 @@ static uint8_t mac_dsn; static uint8_t initialized = 0; -/** \brief The 16-bit identifier of the PAN on which the device is - * sending to. If this value is 0xffff, the device is not - * associated. - */ -static const uint16_t mac_dst_pan_id = IEEE802154_PANID; - -/** \brief The 16-bit identifier of the PAN on which the device is - * operating. If this value is 0xffff, the device is not - * associated. - */ -static const uint16_t mac_src_pan_id = IEEE802154_PANID; - -/*---------------------------------------------------------------------------*/ -static int -is_broadcast_addr(uint8_t mode, uint8_t *addr) -{ - int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; - while(i-- > 0) { - if(addr[i] != 0xff) { - return 0; - } - } - return 1; -} /*---------------------------------------------------------------------------*/ static int create_frame(int type, int do_create) @@ -93,6 +69,10 @@ create_frame(int type, int do_create) frame802154_t params; int hdr_len; + if(frame802154_get_pan_id() == 0xffff) { + return -1; + } + /* init to zeros */ memset(¶ms, 0, sizeof(params)); @@ -109,10 +89,14 @@ create_frame(int type, int do_create) } else { params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK); } + /* We do not compress PAN ID in outgoing frames, i.e. include one PAN ID (dest by default) + * There is one exception, seemingly a typo in Table 2a: rows 2 and 3: when there is no + * source nor destination address, we have dest PAN ID iff compression is *set*. */ params.fcf.panid_compression = 0; + params.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO; - /* Insert IEEE 802.15.4 (2006) version bits. */ - params.fcf.frame_version = FRAME802154_IEEE802154_2006; + /* Insert IEEE 802.15.4 version bits. */ + params.fcf.frame_version = FRAME802154_VERSION; #if LLSEC802154_SECURITY_LEVEL if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) { @@ -120,8 +104,13 @@ create_frame(int type, int do_create) } /* Setting security-related attributes */ params.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); +#if LLSEC802154_USES_FRAME_COUNTER params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1); params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3); +#else /* LLSEC802154_USES_FRAME_COUNTER */ + params.aux_hdr.security_control.frame_counter_suppression = 1; + params.aux_hdr.security_control.frame_counter_size = 1; +#endif /* LLSEC802154_USES_FRAME_COUNTER */ #if LLSEC802154_USES_EXPLICIT_KEYS params.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE); params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX); @@ -150,21 +139,20 @@ create_frame(int type, int do_create) /** \todo For phase 1 the addresses are all long. We'll need a mechanism in the rime attributes to tell the mac to use long or short for phase 2. - */ + */ if(LINKADDR_SIZE == 2) { /* Use short address mode if linkaddr size is short. */ params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; } else { params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE; } - params.dest_pid = mac_dst_pan_id; + params.dest_pid = frame802154_get_pan_id(); if(packetbuf_holds_broadcast()) { /* Broadcast requires short address mode. */ params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; params.dest_addr[0] = 0xFF; params.dest_addr[1] = 0xFF; - } else { linkaddr_copy((linkaddr_t *)¶ms.dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); @@ -177,7 +165,7 @@ create_frame(int type, int do_create) } /* Set the source PAN ID to the global variable. */ - params.src_pid = mac_src_pan_id; + params.src_pid = frame802154_get_pan_id(); /* * Set up the source address using only the long address mode for @@ -191,7 +179,6 @@ create_frame(int type, int do_create) if(!do_create) { /* Only calculate header length */ return hdr_len; - } else if(packetbuf_hdralloc(hdr_len)) { frame802154_create(¶ms, packetbuf_hdrptr()); @@ -223,35 +210,41 @@ parse(void) { frame802154_t frame; int hdr_len; - + hdr_len = frame802154_parse(packetbuf_dataptr(), packetbuf_datalen(), &frame); - + if(hdr_len && packetbuf_hdrreduce(hdr_len)) { packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type); - + if(frame.fcf.dest_addr_mode) { - if(frame.dest_pid != mac_src_pan_id && - frame.dest_pid != FRAME802154_BROADCASTPANDID) { + if(frame.dest_pid != frame802154_get_pan_id() && + frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return FRAMER_FAILED; } - if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { + if(!frame802154_is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); - packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); + if(frame.fcf.sequence_number_suppression == 0) { + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); + } else { + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, 0xffff); + } #if NETSTACK_CONF_WITH_RIME packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); #endif - + #if LLSEC802154_SECURITY_LEVEL if(frame.fcf.security_enabled) { packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); +#if LLSEC802154_USES_FRAME_COUNTER packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]); +#endif /* LLSEC802154_USES_FRAME_COUNTER */ #if LLSEC802154_USES_EXPLICIT_KEYS packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode); packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index); @@ -264,7 +257,7 @@ parse(void) PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen()); - + return hdr_len; } return FRAMER_FAILED;