Added support for IEEE 802.15.4 frame version 2

This commit is contained in:
Simon Duquennoy 2015-09-21 18:39:30 +02:00
parent f86494c6aa
commit 5cf9871d5b
4 changed files with 338 additions and 89 deletions

View file

@ -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)

View file

@ -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 <string.h>
/** \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) {

View file

@ -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 */
/** @} */

View file

@ -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(&params, 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 *)&params.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(&params, 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;