Contiki-NG
frame802154.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2008, Swedish Institute of Computer Science
4  * All rights reserved.
5  *
6  * Additional fixes for AVR contributed by:
7  *
8  * Colin O'Flynn coflynn@newae.com
9  * Eric Gnoske egnoske@gmail.com
10  * Blake Leverett bleverett@gmail.com
11  * Mike Vidales mavida404@gmail.com
12  * Kevin Brown kbrown3@uccs.edu
13  * Nate Bohlmann nate@elfwerks.com
14  *
15  * Additional fixes for MSP430 contributed by:
16  * Joakim Eriksson
17  * Niclas Finne
18  * Nicolas Tsiftes
19  *
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions are met:
24  *
25  * * Redistributions of source code must retain the above copyright
26  * notice, this list of conditions and the following disclaimer.
27  * * Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in
29  * the documentation and/or other materials provided with the
30  * distribution.
31  * * Neither the name of the copyright holders nor the names of
32  * contributors may be used to endorse or promote products derived
33  * from this software without specific prior written permission.
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
39  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
43  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45  * POSSIBILITY OF SUCH DAMAGE.
46  *
47  */
48 /*
49  * \brief This file is where the main functions that relate to frame
50  * manipulation will reside.
51  */
52 
53 /**
54  * \file
55  * \brief 802.15.4 frame creation and parsing functions
56  *
57  * This file converts to and from a structure to a packed 802.15.4
58  * frame.
59  */
60 
61 /**
62  * \addtogroup frame802154
63  * @{
64  */
65 
66 #include "sys/cc.h"
68 #include "net/mac/llsec802154.h"
69 #include "net/linkaddr.h"
70 #include <string.h>
71 
72 /** \brief The 16-bit identifier of the PAN on which the device is
73  * operating. If this value is 0xffff, the device is not
74  * associated.
75  */
76 static uint16_t mac_pan_id = IEEE802154_PANID;
77 
78 /**
79  * \brief Structure that contains the lengths of the various addressing and security fields
80  * in the 802.15.4 header. This structure is used in \ref frame802154_create()
81  */
82 typedef struct {
83  uint8_t seqno_len; /**< Length (in bytes) of sequence number field */
84  uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */
85  uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */
86  uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */
87  uint8_t src_addr_len; /**< Length (in bytes) of source address field */
88  uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */
89 } field_length_t;
90 
91 /*----------------------------------------------------------------------------*/
92 CC_INLINE static uint8_t
93 addr_len(uint8_t mode)
94 {
95  switch(mode) {
96  case FRAME802154_SHORTADDRMODE: /* 16-bit address */
97  return 2;
98  case FRAME802154_LONGADDRMODE: /* 64-bit address */
99  return 8;
100  default:
101  return 0;
102  }
103 }
104 /*----------------------------------------------------------------------------*/
105 #if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS
106 static uint8_t
107 get_key_id_len(uint8_t key_id_mode)
108 {
109  switch(key_id_mode) {
110  case FRAME802154_1_BYTE_KEY_ID_MODE:
111  return 1;
112  case FRAME802154_5_BYTE_KEY_ID_MODE:
113  return 5;
114  case FRAME802154_9_BYTE_KEY_ID_MODE:
115  return 9;
116  default:
117  return 0;
118  }
119 }
120 #endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_EXPLICIT_KEYS */
121 /*---------------------------------------------------------------------------*/
122 /* Get current PAN ID */
123 uint16_t
124 frame802154_get_pan_id(void)
125 {
126  return mac_pan_id;
127 }
128 /*---------------------------------------------------------------------------*/
129 /* Set current PAN ID */
130 void
131 frame802154_set_pan_id(uint16_t pan_id)
132 {
133  mac_pan_id = pan_id;
134 }
135 /*----------------------------------------------------------------------------*/
136 /* Tells whether a given Frame Control Field indicates a frame with
137  * source PANID and/or destination PANID */
138 void
139 frame802154_has_panid(frame802154_fcf_t *fcf, int *has_src_pan_id, int *has_dest_pan_id)
140 {
141  int src_pan_id = 0;
142  int dest_pan_id = 0;
143 
144  if(fcf == NULL) {
145  return;
146  }
147 
148  if(fcf->frame_version == FRAME802154_IEEE802154_2015) {
149  /*
150  * IEEE 802.15.4-2015
151  * Table 7-2, PAN ID Compression value for frame version 0b10
152  */
153  if((fcf->dest_addr_mode == FRAME802154_NOADDR &&
155  fcf->panid_compression == 1) ||
158  fcf->panid_compression == 0) ||
159  (fcf->dest_addr_mode == FRAME802154_LONGADDRMODE &&
160  fcf->src_addr_mode == FRAME802154_LONGADDRMODE &&
161  fcf->panid_compression == 0) ||
162  ((fcf->dest_addr_mode == FRAME802154_SHORTADDRMODE &&
165  fcf->src_addr_mode == FRAME802154_SHORTADDRMODE)) ){
166  dest_pan_id = 1;
167  }
168 
169  if(fcf->panid_compression == 0 &&
171  fcf->src_addr_mode == FRAME802154_LONGADDRMODE) ||
173  fcf->src_addr_mode == FRAME802154_SHORTADDRMODE) ||
174  (fcf->dest_addr_mode == FRAME802154_SHORTADDRMODE &&
175  fcf->src_addr_mode == FRAME802154_SHORTADDRMODE) ||
176  (fcf->dest_addr_mode == FRAME802154_SHORTADDRMODE &&
177  fcf->src_addr_mode == FRAME802154_LONGADDRMODE) ||
178  (fcf->dest_addr_mode == FRAME802154_LONGADDRMODE &&
179  fcf->src_addr_mode == FRAME802154_SHORTADDRMODE))) {
180  src_pan_id = 1;
181  }
182 
183  } else {
184  /* No PAN ID in ACK */
185  if(fcf->frame_type != FRAME802154_ACKFRAME) {
186  if(!fcf->panid_compression && (fcf->src_addr_mode & 3)) {
187  /* If compressed, don't include source PAN ID */
188  src_pan_id = 1;
189  }
190  if(fcf->dest_addr_mode & 3) {
191  dest_pan_id = 1;
192  }
193  }
194  }
195 
196  if(has_src_pan_id != NULL) {
197  *has_src_pan_id = src_pan_id;
198  }
199  if(has_dest_pan_id != NULL) {
200  *has_dest_pan_id = dest_pan_id;
201  }
202 }
203 /*---------------------------------------------------------------------------*/
204 /* Check if the destination PAN ID, if any, matches ours */
205 int
206 frame802154_check_dest_panid(frame802154_t *frame)
207 {
208  int has_dest_panid = 0;
209 
210  if(frame == NULL) {
211  return 0;
212  }
213  frame802154_has_panid(&frame->fcf, NULL, &has_dest_panid);
214  if(!has_dest_panid ||
215  (frame->dest_pid != frame802154_get_pan_id()
216  && frame->dest_pid != FRAME802154_BROADCASTPANDID)) {
217  /* Packet to another PAN */
218  return 0;
219  }
220  return 1;
221 }
222 /*---------------------------------------------------------------------------*/
223 /* Check is the address is a broadcast address, whatever its size */
224 int
225 frame802154_is_broadcast_addr(uint8_t mode, uint8_t *addr)
226 {
227  int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8;
228  while(i-- > 0) {
229  if(addr[i] != 0xff) {
230  return 0;
231  }
232  }
233  return 1;
234 }
235 /*---------------------------------------------------------------------------*/
236 /* Check and extract source and destination linkaddr from frame */
237 int
238 frame802154_extract_linkaddr(frame802154_t *frame,
239  linkaddr_t *source_address, linkaddr_t *dest_address)
240 {
241  int src_addr_len;
242  int dest_addr_len;
243 
244  if(frame == NULL) {
245  return 0;
246  }
247  /* Check and extract source address */
248  src_addr_len = frame->fcf.src_addr_mode ?
249  ((frame->fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0;
250  if(src_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.src_addr_mode, frame->src_addr)) {
251  /* Broadcast address */
252  if(source_address != NULL) {
253  linkaddr_copy(source_address, &linkaddr_null);
254  }
255  } else {
256  /* Unicast address */
257  if(src_addr_len != LINKADDR_SIZE) {
258  /* Destination address has a size we can not handle */
259  return 0;
260  }
261  if(source_address != NULL) {
262  linkaddr_copy(source_address, (linkaddr_t *)frame->src_addr);
263  }
264  }
265 
266  /* Check and extract destination address */
267  dest_addr_len = frame->fcf.dest_addr_mode ?
268  ((frame->fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0;
269  if(dest_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.dest_addr_mode, frame->dest_addr)) {
270  /* Broadcast address */
271  if(dest_address != NULL) {
272  linkaddr_copy(dest_address, &linkaddr_null);
273  }
274  } else {
275  /* Unicast address */
276  if(dest_addr_len != LINKADDR_SIZE) {
277  /* Destination address has a size we can not handle */
278  return 0;
279  }
280  if(dest_address != NULL) {
281  linkaddr_copy(dest_address, (linkaddr_t *)frame->dest_addr);
282  }
283  }
284 
285  return 1;
286 }
287 /*----------------------------------------------------------------------------*/
288 static void
289 field_len(frame802154_t *p, field_length_t *flen)
290 {
291  int has_src_panid;
292  int has_dest_panid;
293 
294  /* init flen to zeros */
295  memset(flen, 0, sizeof(field_length_t));
296 
297  /* Determine lengths of each field based on fcf and other args */
298  if((p->fcf.sequence_number_suppression & 1) == 0) {
299  flen->seqno_len = 1;
300  }
301 
302  /* IEEE802.15.4e changes the meaning of PAN ID Compression (see Table 2a).
303  * In this case, we leave the decision whether to compress PAN ID or not
304  * up to the caller. */
305  if(p->fcf.frame_version < FRAME802154_IEEE802154_2015) {
306  /* Set PAN ID compression bit if src pan id matches dest pan id. */
307  if((p->fcf.dest_addr_mode & 3) && (p->fcf.src_addr_mode & 3) &&
308  p->src_pid == p->dest_pid) {
309  p->fcf.panid_compression = 1;
310  } else {
311  p->fcf.panid_compression = 0;
312  }
313  }
314 
315  frame802154_has_panid(&p->fcf, &has_src_panid, &has_dest_panid);
316 
317  if(has_src_panid) {
318  flen->src_pid_len = 2;
319  }
320 
321  if(has_dest_panid) {
322  flen->dest_pid_len = 2;
323  }
324 
325  /* determine address lengths */
326  flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3);
327  flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3);
328 
329 #if LLSEC802154_USES_AUX_HEADER
330  /* Aux security header */
331  if(p->fcf.security_enabled & 1) {
332  flen->aux_sec_len = 1; /* FCF + possibly frame counter and key ID */
335  flen->aux_sec_len += 5;
336  } else {
337  flen->aux_sec_len += 4;
338  }
339  }
340 #if LLSEC802154_USES_EXPLICIT_KEYS
341  flen->aux_sec_len += get_key_id_len(p->aux_hdr.security_control.key_id_mode);
342 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
343  ;
344  }
345 #endif /* LLSEC802154_USES_AUX_HEADER */
346 }
347 /*----------------------------------------------------------------------------*/
348 /**
349  * \brief Calculates the length of the frame header. This function is
350  * meant to be called by a higher level function, that interfaces to a MAC.
351  *
352  * \param p Pointer to frame802154_t_t struct, which specifies the
353  * frame to send.
354  *
355  * \return The length of the frame header.
356  */
357 int
359 {
360  field_length_t flen;
361  field_len(p, &flen);
362  return 2 + flen.seqno_len + flen.dest_pid_len + flen.dest_addr_len +
363  flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len;
364 }
365 void
366 frame802154_create_fcf(frame802154_fcf_t *fcf, uint8_t *buf)
367 {
368  buf[0] = (fcf->frame_type & 7) |
369  ((fcf->security_enabled & 1) << 3) |
370  ((fcf->frame_pending & 1) << 4) |
371  ((fcf->ack_required & 1) << 5) |
372  ((fcf->panid_compression & 1) << 6);
373  buf[1] = ((fcf->sequence_number_suppression & 1)) |
374  ((fcf->ie_list_present & 1)) << 1 |
375  ((fcf->dest_addr_mode & 3) << 2) |
376  ((fcf->frame_version & 3) << 4) |
377  ((fcf->src_addr_mode & 3) << 6);
378 }
379 /*----------------------------------------------------------------------------*/
380 /**
381  * \brief Creates a frame for transmission over the air. This function is
382  * meant to be called by a higher level function, that interfaces to a MAC.
383  *
384  * \param p Pointer to frame802154_t struct, which specifies the
385  * frame to send.
386  *
387  * \param buf Pointer to the buffer to use for the frame.
388  *
389  * \return The length of the frame header
390  */
391 int
393 {
394  int c;
395  field_length_t flen;
396  uint8_t pos;
397 #if LLSEC802154_USES_EXPLICIT_KEYS
398  uint8_t key_id_mode;
399 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
400 
401  field_len(p, &flen);
402 
403  /* OK, now we have field lengths. Time to actually construct */
404  /* the outgoing frame, and store it in buf */
405  frame802154_create_fcf(&p->fcf, buf);
406  pos = 2;
407 
408  /* Sequence number */
409  if(flen.seqno_len == 1) {
410  buf[pos++] = p->seq;
411  }
412 
413  /* Destination PAN ID */
414  if(flen.dest_pid_len == 2) {
415  buf[pos++] = p->dest_pid & 0xff;
416  buf[pos++] = (p->dest_pid >> 8) & 0xff;
417  }
418 
419  /* Destination address */
420  for(c = flen.dest_addr_len; c > 0; c--) {
421  buf[pos++] = p->dest_addr[c - 1];
422  }
423 
424  /* Source PAN ID */
425  if(flen.src_pid_len == 2) {
426  buf[pos++] = p->src_pid & 0xff;
427  buf[pos++] = (p->src_pid >> 8) & 0xff;
428  }
429 
430  /* Source address */
431  for(c = flen.src_addr_len; c > 0; c--) {
432  buf[pos++] = p->src_addr[c - 1];
433  }
434 #if LLSEC802154_USES_AUX_HEADER
435  /* Aux header */
436  if(flen.aux_sec_len) {
437  buf[pos++] = p->aux_hdr.security_control.security_level
438 #if LLSEC802154_USES_EXPLICIT_KEYS
440 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
443  ;
445  /* We support only 4-byte counters */
446  memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4);
447  pos += 4;
449  pos++;
450  }
451  }
452 
453 #if LLSEC802154_USES_EXPLICIT_KEYS
454  key_id_mode = p->aux_hdr.security_control.key_id_mode;
455  if(key_id_mode) {
456  c = (key_id_mode - 1) * 4;
457  memcpy(buf + pos, p->aux_hdr.key_source.u8, c);
458  pos += c;
459  buf[pos++] = p->aux_hdr.key_index;
460  }
461 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
462  }
463 #endif /* LLSEC802154_USES_AUX_HEADER */
464 
465  return (int)pos;
466 }
467 
468 void
469 frame802154_parse_fcf(uint8_t *data, frame802154_fcf_t *pfcf)
470 {
471  frame802154_fcf_t fcf;
472 
473  /* decode the FCF */
474  fcf.frame_type = data[0] & 7;
475  fcf.security_enabled = (data[0] >> 3) & 1;
476  fcf.frame_pending = (data[0] >> 4) & 1;
477  fcf.ack_required = (data[0] >> 5) & 1;
478  fcf.panid_compression = (data[0] >> 6) & 1;
479 
480  fcf.sequence_number_suppression = data[1] & 1;
481  fcf.ie_list_present = (data[1] >> 1) & 1;
482  fcf.dest_addr_mode = (data[1] >> 2) & 3;
483  fcf.frame_version = (data[1] >> 4) & 3;
484  fcf.src_addr_mode = (data[1] >> 6) & 3;
485 
486  /* copy fcf */
487  memcpy(pfcf, &fcf, sizeof(frame802154_fcf_t));
488 }
489 /*----------------------------------------------------------------------------*/
490 /**
491  * \brief Parses an input frame. Scans the input frame to find each
492  * section, and stores the information of each section in a
493  * frame802154_t structure.
494  *
495  * \param data The input data from the radio chip.
496  * \param len The size of the input data
497  * \param pf The frame802154_t struct to store the parsed frame information.
498  */
499 int
500 frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
501 {
502  uint8_t *p;
503  frame802154_fcf_t fcf;
504  int c;
505  int has_src_panid;
506  int has_dest_panid;
507 #if LLSEC802154_USES_EXPLICIT_KEYS
508  uint8_t key_id_mode;
509 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
510 
511  if(len < 2) {
512  return 0;
513  }
514 
515  p = data;
516 
517  /* decode the FCF */
518  frame802154_parse_fcf(p, &fcf);
519  memcpy(&pf->fcf, &fcf, sizeof(frame802154_fcf_t));
520  p += 2; /* Skip first two bytes */
521 
522  if(fcf.sequence_number_suppression == 0) {
523  pf->seq = p[0];
524  p++;
525  }
526 
527  frame802154_has_panid(&fcf, &has_src_panid, &has_dest_panid);
528 
529  /* Destination address, if any */
530  if(fcf.dest_addr_mode) {
531  if(has_dest_panid) {
532  /* Destination PAN */
533  pf->dest_pid = p[0] + (p[1] << 8);
534  p += 2;
535  } else {
536  pf->dest_pid = 0;
537  }
538 
539  /* Destination address */
540 /* l = addr_len(fcf.dest_addr_mode); */
541 /* for(c = 0; c < l; c++) { */
542 /* pf->dest_addr.u8[c] = p[l - c - 1]; */
543 /* } */
544 /* p += l; */
545  if(fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) {
546  linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null);
547  pf->dest_addr[0] = p[1];
548  pf->dest_addr[1] = p[0];
549  p += 2;
550  } else if(fcf.dest_addr_mode == FRAME802154_LONGADDRMODE) {
551  for(c = 0; c < 8; c++) {
552  pf->dest_addr[c] = p[7 - c];
553  }
554  p += 8;
555  }
556  } else {
557  linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null);
558  pf->dest_pid = 0;
559  }
560 
561  /* Source address, if any */
562  if(fcf.src_addr_mode) {
563  /* Source PAN */
564  if(has_src_panid) {
565  pf->src_pid = p[0] + (p[1] << 8);
566  p += 2;
567  if(!has_dest_panid) {
568  pf->dest_pid = pf->src_pid;
569  }
570  } else {
571  pf->src_pid = pf->dest_pid;
572  }
573 
574  /* Source address */
575 /* l = addr_len(fcf.src_addr_mode); */
576 /* for(c = 0; c < l; c++) { */
577 /* pf->src_addr.u8[c] = p[l - c - 1]; */
578 /* } */
579 /* p += l; */
580  if(fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) {
581  linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null);
582  pf->src_addr[0] = p[1];
583  pf->src_addr[1] = p[0];
584  p += 2;
585  } else if(fcf.src_addr_mode == FRAME802154_LONGADDRMODE) {
586  for(c = 0; c < 8; c++) {
587  pf->src_addr[c] = p[7 - c];
588  }
589  p += 8;
590  }
591  } else {
592  linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null);
593  pf->src_pid = 0;
594  }
595 
596 #if LLSEC802154_USES_AUX_HEADER
597  if(fcf.security_enabled) {
598  pf->aux_hdr.security_control.security_level = p[0] & 7;
599 #if LLSEC802154_USES_EXPLICIT_KEYS
600  pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3;
601 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
604  p += 1;
605 
607  memcpy(pf->aux_hdr.frame_counter.u8, p, 4);
608  p += 4;
610  p ++;
611  }
612  }
613 
614 #if LLSEC802154_USES_EXPLICIT_KEYS
615  key_id_mode = pf->aux_hdr.security_control.key_id_mode;
616  if(key_id_mode) {
617  c = (key_id_mode - 1) * 4;
618  memcpy(pf->aux_hdr.key_source.u8, p, c);
619  p += c;
620  pf->aux_hdr.key_index = p[0];
621  p += 1;
622  }
623 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
624  }
625 #endif /* LLSEC802154_USES_AUX_HEADER */
626 
627  /* header length */
628  c = p - data;
629  /* payload length */
630  pf->payload_len = (len - c);
631  /* payload */
632  pf->payload = p;
633 
634  /* return header length if successful */
635  return c > len ? 0 : c;
636 }
637 /** \} */
frame802154_frame_counter_t frame_counter
Frame counter, used for security.
Definition: frame802154.h:189
uint16_t src_pid
Source PAN ID.
Definition: frame802154.h:207
frame802154_scf_t security_control
Security control bitfield.
Definition: frame802154.h:188
uint8_t dest_addr_mode
2 bit.
Definition: frame802154.h:161
uint8_t sequence_number_suppression
< 1 bit.
Definition: frame802154.h:159
frame802154_fcf_t fcf
Frame control field.
Definition: frame802154.h:204
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107
#define FRAME802154_NOADDR
Only valid for ACK or Beacon frames.
Definition: frame802154.h:109
uint8_t security_level
3 bit.
Definition: frame802154.h:168
uint8_t security_enabled
1 bit.
Definition: frame802154.h:154
Header file for the link-layer address representation
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
Definition: frame802154.c:500
int payload_len
Length of payload field.
Definition: frame802154.h:210
Common functionality of 802.15.4-compliant llsec_drivers.
uint8_t frame_pending
1 bit.
Definition: frame802154.h:155
uint8_t src_addr[8]
Source address.
Definition: frame802154.h:203
int frame802154_hdrlen(frame802154_t *p)
Calculates the length of the frame header.
Definition: frame802154.c:358
const linkaddr_t linkaddr_null
The null link-layer address.
frame802154_key_source_t key_source
Key Source subfield.
Definition: frame802154.h:190
uint8_t key_id_mode
2 bit.
Definition: frame802154.h:169
uint8_t key_index
Key Index subfield.
Definition: frame802154.h:191
uint8_t frame_counter_suppression
1 bit.
Definition: frame802154.h:170
uint8_t frame_version
2 bit.
Definition: frame802154.h:162
The IEEE 802.15.4 frame has a number of constant/fixed fields that can be counted to make frame const...
Definition: frame802154.h:152
uint8_t src_addr_mode
2 bit.
Definition: frame802154.h:163
802.15.4 frame creation and parsing functions
uint8_t frame_type
3 bit.
Definition: frame802154.h:153
uint16_t dest_pid
Destination PAN ID.
Definition: frame802154.h:206
Parameters used by the frame802154_create() function.
Definition: frame802154.h:198
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
Definition: linkaddr.c:63
uint8_t ie_list_present
1 bit.
Definition: frame802154.h:160
uint8_t seq
Sequence number.
Definition: frame802154.h:205
uint8_t panid_compression
1 bit.
Definition: frame802154.h:157
Default definitions of C compiler quirk work-arounds.
uint8_t * payload
Pointer to 802.15.4 payload.
Definition: frame802154.h:209
uint8_t dest_addr[8]
Destination address.
Definition: frame802154.h:202
uint8_t ack_required
1 bit.
Definition: frame802154.h:156
uint8_t frame_counter_size
1 bit.
Definition: frame802154.h:171
static uint16_t mac_pan_id
The 16-bit identifier of the PAN on which the device is operating.
Definition: frame802154.c:76
frame802154_aux_hdr_t aux_hdr
Aux security header.
Definition: frame802154.h:208
int frame802154_create(frame802154_t *p, uint8_t *buf)
Creates a frame for transmission over the air.
Definition: frame802154.c:392