83 uint8_t frame_ctrl_len;
86 uint8_t dest_addr_len;
97 case FRAME802154_SHORTADDRMODE:
99 case FRAME802154_LONGADDRMODE:
106#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS
108get_key_id_len(uint8_t key_id_mode)
110 switch(key_id_mode) {
111 case FRAME802154_1_BYTE_KEY_ID_MODE:
113 case FRAME802154_5_BYTE_KEY_ID_MODE:
115 case FRAME802154_9_BYTE_KEY_ID_MODE:
125frame802154_get_pan_id(
void)
132frame802154_set_pan_id(uint16_t pan_id)
140frame802154_has_panid(
frame802154_fcf_t *fcf,
int *has_src_pan_id,
int *has_dest_pan_id)
203 if(has_src_pan_id != NULL) {
204 *has_src_pan_id = src_pan_id;
206 if(has_dest_pan_id != NULL) {
207 *has_dest_pan_id = dest_pan_id;
215 int has_dest_panid = 0;
220 frame802154_has_panid(&frame->
fcf, NULL, &has_dest_panid);
221 if(!has_dest_panid ||
222 (frame->
dest_pid != frame802154_get_pan_id()
223 && frame->
dest_pid != FRAME802154_BROADCASTPANDID)) {
232frame802154_is_broadcast_addr(uint8_t mode,
const uint8_t *
addr)
234 int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8;
236 if(
addr[i] != 0xff) {
246 linkaddr_t *source_address, linkaddr_t *dest_address)
259 if(source_address != NULL) {
264 if(src_addr_len != LINKADDR_SIZE) {
268 if(source_address != NULL) {
278 if(dest_address != NULL) {
283 if(dest_addr_len != LINKADDR_SIZE) {
287 if(dest_address != NULL) {
302 memset(flen, 0,
sizeof(field_length_t));
304 flen->frame_ctrl_len =
305 (p->fcf.frame_type == FRAME802154_MPFRAME) && !p->fcf.long_frame_control
310 if((p->fcf.sequence_number_suppression & 1) == 0) {
317 if(p->fcf.frame_version < FRAME802154_IEEE802154_2015) {
319 p->fcf.panid_compression = (p->fcf.dest_addr_mode & 3) &&
320 (p->fcf.src_addr_mode & 3) && p->src_pid == p->dest_pid;
323 frame802154_has_panid(&p->fcf, &has_src_panid, &has_dest_panid);
326 flen->src_pid_len = 2;
330 flen->dest_pid_len = 2;
334 flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3);
335 flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3);
337#if LLSEC802154_USES_AUX_HEADER
339 if(p->fcf.security_enabled & 1) {
340 flen->aux_sec_len = 1;
341 if(p->aux_hdr.security_control.frame_counter_suppression == 0) {
342 if(p->aux_hdr.security_control.frame_counter_size == 1) {
343 flen->aux_sec_len += 5;
345 flen->aux_sec_len += 4;
348#if LLSEC802154_USES_EXPLICIT_KEYS
349 flen->aux_sec_len += get_key_id_len(p->aux_hdr.security_control.key_id_mode);
369 return flen.frame_ctrl_len
381#if FRAME802154_VERSION == FRAME802154_IEEE802154_2015
384 buf[0] = FRAME802154_MPFRAME
430#if LLSEC802154_USES_EXPLICIT_KEYS
438 unsigned int pos = frame802154_create_fcf(&p->fcf, buf);
441 if(flen.seqno_len == 1) {
446 if(flen.dest_pid_len == 2) {
447 buf[pos++] = p->dest_pid & 0xff;
448 buf[pos++] = (p->dest_pid >> 8) & 0xff;
452 for(c = flen.dest_addr_len; c > 0; c--) {
453 buf[pos++] = p->dest_addr[c - 1];
457 if(flen.src_pid_len == 2) {
458 buf[pos++] = p->src_pid & 0xff;
459 buf[pos++] = (p->src_pid >> 8) & 0xff;
463 for(c = flen.src_addr_len; c > 0; c--) {
464 buf[pos++] = p->src_addr[c - 1];
466#if LLSEC802154_USES_AUX_HEADER
468 if(flen.aux_sec_len) {
469 buf[pos++] = p->aux_hdr.security_control.security_level
470#if LLSEC802154_USES_EXPLICIT_KEYS
471 | (p->aux_hdr.security_control.key_id_mode << 3)
473 | (p->aux_hdr.security_control.frame_counter_suppression << 5)
474 | (p->aux_hdr.security_control.frame_counter_size << 6)
476 if(p->aux_hdr.security_control.frame_counter_suppression == 0) {
478 memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4);
480 if(p->aux_hdr.security_control.frame_counter_size == 1) {
485#if LLSEC802154_USES_EXPLICIT_KEYS
486 key_id_mode = p->aux_hdr.security_control.key_id_mode;
488 c = (key_id_mode - 1) * 4;
489 memcpy(buf + pos, p->aux_hdr.key_source.u8, c);
491 buf[pos++] = p->aux_hdr.key_index;
507 case FRAME802154_MPFRAME:
547#define REQUIRE_BYTES(n) do { \
548 if((p - data) + (n) > len) { \
569#if LLSEC802154_USES_EXPLICIT_KEYS
580 p += frame802154_parse_fcf(p, &pf->
fcf);
588 frame802154_has_panid(&pf->
fcf, &has_src_panid, &has_dest_panid);
610 for(c = 0; c < 8; c++) {
625 pf->
src_pid = p[0] + (p[1] << 8);
627 if(!has_dest_panid) {
643 for(c = 0; c < 8; c++) {
653#if LLSEC802154_USES_AUX_HEADER
657#if LLSEC802154_USES_EXPLICIT_KEYS
674#if LLSEC802154_USES_EXPLICIT_KEYS
677 c = (key_id_mode - 1) * 4;
678 REQUIRE_BYTES(c + 1);
696 return c > len ? 0 : c;
Default definitions of C compiler quirk work-arounds.
802.15.4 frame creation and parsing functions
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
#define FRAME802154_NOADDR
Only valid for ACK or Beacon frames.
int frame802154_create(frame802154_t *p, uint8_t *buf)
Creates a frame for transmission over the air.
int frame802154_hdrlen(frame802154_t *p)
Calculates the length of the frame header.
static uint16_t mac_pan_id
The 16-bit identifier of the PAN on which the device is operating.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
const linkaddr_t linkaddr_null
The null link-layer address.
Header file for the link-layer address representation.
Common functionality of 802.15.4-compliant llsec_drivers.
frame802154_scf_t security_control
Security control bitfield.
frame802154_frame_counter_t frame_counter
Frame counter, used for security.
uint8_t key_index
Key Index subfield.
frame802154_key_source_t key_source
Key Source subfield.
The IEEE 802.15.4 frame has a number of constant/fixed fields that can be counted to make frame const...
uint8_t long_frame_control
1 bit.
uint8_t frame_version
2 bit.
uint8_t ie_list_present
1 bit.
uint8_t security_enabled
1 bit.
uint8_t sequence_number_suppression
< 1 bit.
uint8_t src_addr_mode
2 bit.
uint8_t panid_compression
1 bit.
uint8_t ack_required
1 bit.
uint8_t dest_addr_mode
2 bit.
uint8_t frame_pending
1 bit.
uint8_t key_id_mode
2 bit.
uint8_t frame_counter_size
1 bit.
uint8_t frame_counter_suppression
1 bit.
uint8_t security_level
3 bit.
Parameters used by the frame802154_create() function.
uint8_t seq
Sequence number.
uint8_t dest_addr[8]
Destination address.
frame802154_aux_hdr_t aux_hdr
Aux security header.
uint8_t * payload
Pointer to 802.15.4 payload.
uint8_t src_addr[8]
Source address.
uint16_t src_pid
Source PAN ID.
frame802154_fcf_t fcf
Frame control field.
uint16_t dest_pid
Destination PAN ID.
int payload_len
Length of payload field.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.