Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creation and Parsing of 802.15.4 Beacon and Command frames. #1904

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
135 changes: 131 additions & 4 deletions core/net/mac/frame802154.c
Expand Up @@ -86,6 +86,8 @@ typedef struct {
uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */
uint8_t src_addr_len; /**< Length (in bytes) of source address field */
uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */
uint8_t gts_fields_len;
uint8_t pendingAddr_fields_len;
} field_length_t;

/*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -322,6 +324,16 @@ field_len(frame802154_t *p, field_length_t *flen)
;
}
#endif /* LLSEC802154_USES_AUX_HEADER */
if(p->fcf.frame_type == FRAME802154_BEACONFRAME){
flen->gts_fields_len = 1;
flen->pendingAddr_fields_len=1+p->pendingAddr_fields.spec.numberOfShort*2+p->pendingAddr_fields.spec.numberOfExt*8;
}
else
{
flen->gts_fields_len = 0;
flen->pendingAddr_fields_len = 0;
}

}
/*----------------------------------------------------------------------------*/
/**
Expand All @@ -337,9 +349,20 @@ int
frame802154_hdrlen(frame802154_t *p)
{
field_length_t flen;
int len=0;

field_len(p, &flen);
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;
if(p->fcf.frame_type == FRAME802154_CMDFRAME){
len+=1;
if(p->commandIdentifier == 0x01)
len+=1;
if(p->commandIdentifier == 0x02)
len+=3;
}
if(p->fcf.frame_type == FRAME802154_BEACONFRAME)
len+=2; /*Superframe specification*/
return len + 2 + flen.seqno_len + flen.dest_pid_len + flen.dest_addr_len +
flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len + flen.gts_fields_len + flen.pendingAddr_fields_len;
}
/*----------------------------------------------------------------------------*/
/**
Expand All @@ -356,7 +379,7 @@ frame802154_hdrlen(frame802154_t *p)
int
frame802154_create(frame802154_t *p, uint8_t *buf)
{
int c;
int c,i=0,j=0;
field_length_t flen;
uint8_t pos;
#if LLSEC802154_USES_EXPLICIT_KEYS
Expand Down Expand Up @@ -436,7 +459,48 @@ frame802154_create(frame802154_t *p, uint8_t *buf)
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_USES_AUX_HEADER */

if(p->fcf.frame_type == FRAME802154_BEACONFRAME)
{
buf[pos++] = (p->superframe_spec.beaconOrder & 0xff) | ((p->superframe_spec.superframeOrder << 4) & 0xff);
buf[pos++] = (p->superframe_spec.finalCapSlot & 0xff) | (p->superframe_spec.ble << 4) | (p->superframe_spec.reserved << 5) | \
(p->superframe_spec.panCoord << 6) | (p->superframe_spec.assocPermit << 7);
buf[pos++] = 0x00; /*GTS fields to be implemented.*/
buf[pos++] = (p->pendingAddr_fields.spec.numberOfShort & 0xff) | ((p->pendingAddr_fields.spec.numberOfExt << 4) & 0xff);
//int i;
for(i=0; i < p->pendingAddr_fields.spec.numberOfShort; i++)
{
buf[pos++] = p->pendingAddr_fields.list.shortAddr[i].assignAddr[0];
buf[pos++] = p->pendingAddr_fields.list.shortAddr[i].assignAddr[1];
}
for(i=0; i < p->pendingAddr_fields.spec.numberOfExt; i++)
{
//int j;
for(j=7;j>=0;j--)
{
buf[pos++] = p->pendingAddr_fields.list.extAddr[i].assignAddr[j];
}
}
}
if(p->fcf.frame_type == FRAME802154_CMDFRAME)
{
buf[pos++] = p->commandIdentifier & 0xff;
if(p->commandIdentifier == 0x02)
{
buf[pos++]=p->assignedAddr.assignAddr[1];
buf[pos++]=p->assignedAddr.assignAddr[0];
buf[pos++]=p->assocStatus;
}
else if(p->commandIdentifier == 0x01) /*Association request*/
{
buf[pos++] = ((p->capability_info.deviceType & 0xff) << 1) | ((p->capability_info.powerSource & 0xff) << 2) | \
((p->capability_info.recOnIdle & 0xff) << 3) |((p->capability_info.security & 0xff) << 6) | \
((p->capability_info.allocate & 0xff) << 7);
}
else if(p->commandIdentifier == 0x04) /*Data request*/
{
buf[pos++] = (p->commandIdentifier & 0xff);
}
}
return (int)pos;
}
/*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -588,7 +652,70 @@ frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_USES_AUX_HEADER */
if(pf->fcf.frame_type == FRAME802154_BEACONFRAME)
{
pf->superframe_spec.beaconOrder = p[0] & 0x0f;
pf->superframe_spec.superframeOrder = (p[0] & 0xf0) >> 4;
pf->superframe_spec.finalCapSlot = p[1] & 0x0f;
pf->superframe_spec.ble = ((p[1] & 0xf0) >> 4) & 1;
pf->superframe_spec.reserved = (((p[1] & 0xf0) >> 4) & 2) >> 1;
pf->superframe_spec.panCoord = (((p[1] & 0xf0) >> 4) & 4) >> 2;
pf->superframe_spec.assocPermit = (((p[1] & 0xf0) >> 4) & 8)>>3;
p += 2;
p += 1; /*Skip GTS for now */
pf->pendingAddr_fields.spec.numberOfShort = p[0] & 0x0f;
pf->pendingAddr_fields.spec.numberOfExt = (p[0] & 0xf0) >> 4;
p+=1;
if(pf->pendingAddr_fields.spec.numberOfShort > 0)
{
int i;
for(i=0;i<pf->pendingAddr_fields.spec.numberOfShort;i++)
{
pf->pendingAddr_fields.list.shortAddr[i].assignAddr[1] = p[0];
pf->pendingAddr_fields.list.shortAddr[i].assignAddr[0] = p[1];
p+=2;
}
}
if(pf->pendingAddr_fields.spec.numberOfExt > 0)
{
int i;
for(i=0;i<pf->pendingAddr_fields.spec.numberOfExt;i++)
{
int j;
int k=7;
//atLog(VIRTUAL802154, LOG_INFO, __FILE__,__LINE__,__func__, "\n ext address: ");
for(j=0;j<8;j++){
//atLog(VIRTUAL802154, LOG_INFO, __FILE__,__LINE__,__func__, "%02x", p[j]);
pf->pendingAddr_fields.list.extAddr[i].assignAddr[k] = p[j];
k--;
}
p+=8;
}
}

}
else if(pf->fcf.frame_type == FRAME802154_CMDFRAME)
{
pf->commandIdentifier = p[0];
p+=1;
if(pf->commandIdentifier == 0x01)/*association request*/
{
pf->capability_info.deviceType = ((p[1] & 0x02) >> 1) & 0xff;
pf->capability_info.powerSource = ((p[1] & 0x04) >> 2) & 0xff;
pf->capability_info.recOnIdle = ((p[1] & 0x08) >> 3) & 0xff;
pf->capability_info.security = ((p[1] & 0x40) >> 6) & 0xff;
pf->capability_info.allocate = ((p[1] & 0x80) >> 7) & 0xff;
p+=1;
}
if(pf->commandIdentifier == 0x02)/*association response*/
{
pf->allocAddress.assignAddr[0] = p[1];
pf->allocAddress.assignAddr[1] = p[0];
p+=2;
pf->assocStatus = p[0];
p+=1;
}
}
/* header length */
c = p - data;
/* payload length */
Expand Down
76 changes: 76 additions & 0 deletions core/net/mac/frame802154.h
Expand Up @@ -140,6 +140,18 @@
* 5. CRC - 2 bytes - Fixed
*/


typedef union {
uint8_t assignAddr[2];
uint16_t readAddr;
}short_addr_t;

typedef union {
uint8_t assignAddr[8];
uint16_t readAddr[4];
}ext_addr_t;


/**
* \brief Defines the bitfields of the frame control field (FCF).
*/
Expand Down Expand Up @@ -185,6 +197,62 @@ typedef struct {
uint8_t key_index; /**< Key Index subfield */
} frame802154_aux_hdr_t;

typedef struct {
uint8_t beaconOrder;
uint8_t superframeOrder;
uint8_t finalCapSlot;
uint8_t ble;
uint8_t reserved;
uint8_t panCoord;
uint8_t assocPermit;
} frame_superframe_spec_t;

typedef struct {
uint8_t descCount;
uint8_t reserved;
uint8_t permit;
}frame_gts_spec_t;

typedef struct {
uint8_t directionMask;
uint8_t reserved;
}frame_gts_dir_t;

typedef struct {
uint16_t shortAddr;
uint8_t startSlot;
uint8_t gtsLength;
}frame_gts_list_t;

typedef struct {
frame_gts_spec_t gts_spec;
frame_gts_dir_t gts_dir;
frame_gts_list_t gts_list[7];
}frame_gts_t;

typedef struct {
ext_addr_t extAddr[7];
short_addr_t shortAddr[7];
}frame_addr_list_t;

typedef struct {
uint8_t numberOfShort;
uint8_t numberOfExt;
}frame_pending_spec_t;

typedef struct {
frame_pending_spec_t spec;
frame_addr_list_t list;
}frame_pendingAddr_t;

typedef struct {
uint8_t deviceType;
uint8_t powerSource;
uint8_t recOnIdle;
uint8_t security;
uint8_t allocate;
}capability_info_t;

/** \brief Parameters used by the frame802154_create() function. These
* parameters are used in the 802.15.4 frame header. See the 802.15.4
* specification for details.
Expand All @@ -202,6 +270,14 @@ typedef struct {
frame802154_aux_hdr_t aux_hdr; /**< Aux security header */
uint8_t *payload; /**< Pointer to 802.15.4 payload */
int payload_len; /**< Length of payload field */
frame_superframe_spec_t superframe_spec;
frame_gts_t gts_fields;
frame_pendingAddr_t pendingAddr_fields;
uint8_t commandIdentifier;
capability_info_t capability_info;
short_addr_t assignedAddr;
uint8_t assocStatus;
short_addr_t allocAddress;
} frame802154_t;

/* Prototypes */
Expand Down