Contiki 3.x
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"
67 #include "net/mac/frame802154.h"
68 #include "net/llsec/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_IEEE802154E_2012) {
149  if(!fcf->panid_compression) {
150  /* Compressed PAN ID == no PAN ID at all */
151  if(fcf->dest_addr_mode == fcf->dest_addr_mode) {
152  /* No address or both addresses: include destination PAN ID */
153  dest_pan_id = 1;
154  } else if(fcf->dest_addr_mode) {
155  /* Only dest address, include dest PAN ID */
156  dest_pan_id = 1;
157  } else if(fcf->src_addr_mode) {
158  /* Only src address, include src PAN ID */
159  src_pan_id = 1;
160  }
161  }
162  if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 1) {
163  /* No address included, include dest PAN ID conditionally */
164  if(!fcf->panid_compression) {
165  dest_pan_id = 1;
166  }
167  }
168  /* Remove the following rule the day rows 2 and 3 from table 2a are fixed: */
169  if(fcf->dest_addr_mode == 0 && fcf->dest_addr_mode == 0) {
170  /* Not meaningful, we include a PAN ID iff the compress flag is set, but
171  * this is what the standard currently stipulates */
172  dest_pan_id = fcf->panid_compression;
173  }
174  } else {
175  /* No PAN ID in ACK */
176  if(fcf->frame_type != FRAME802154_ACKFRAME) {
177  if(!fcf->panid_compression && fcf->src_addr_mode & 3) {
178  /* If compressed, don't inclue source PAN ID */
179  src_pan_id = 1;
180  }
181  if(fcf->dest_addr_mode & 3) {
182  dest_pan_id = 1;
183  }
184  }
185  }
186 
187  if(has_src_pan_id != NULL) {
188  *has_src_pan_id = src_pan_id;
189  }
190  if(has_dest_pan_id != NULL) {
191  *has_dest_pan_id = dest_pan_id;
192  }
193 }
194 /*---------------------------------------------------------------------------*/
195 /* Check if the destination PAN ID, if any, matches ours */
196 int
197 frame802154_check_dest_panid(frame802154_t *frame)
198 {
199  int has_dest_panid;
200 
201  if(frame == NULL) {
202  return 0;
203  }
204  frame802154_has_panid(&frame->fcf, NULL, &has_dest_panid);
205  if(has_dest_panid
206  && frame->dest_pid != frame802154_get_pan_id()
207  && frame->dest_pid != FRAME802154_BROADCASTPANDID) {
208  /* Packet to another PAN */
209  return 0;
210  }
211  return 1;
212 }
213 /*---------------------------------------------------------------------------*/
214 /* Check is the address is a broadcast address, whatever its size */
215 int
216 frame802154_is_broadcast_addr(uint8_t mode, uint8_t *addr)
217 {
218  int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8;
219  while(i-- > 0) {
220  if(addr[i] != 0xff) {
221  return 0;
222  }
223  }
224  return 1;
225 }
226 /*---------------------------------------------------------------------------*/
227 /* Check and extract source and destination linkaddr from frame */
228 int
229 frame802154_extract_linkaddr(frame802154_t *frame,
230  linkaddr_t *source_address, linkaddr_t *dest_address)
231 {
232  int src_addr_len;
233  int dest_addr_len;
234 
235  if(frame == NULL) {
236  return 0;
237  }
238  /* Check and extract source address */
239  src_addr_len = frame->fcf.src_addr_mode ?
240  ((frame->fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0;
241  if(src_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.src_addr_mode, frame->src_addr)) {
242  /* Broadcast address */
243  if(source_address != NULL) {
244  linkaddr_copy(source_address, &linkaddr_null);
245  }
246  } else {
247  /* Unicast address */
248  if(src_addr_len != LINKADDR_SIZE) {
249  /* Destination address has a size we can not handle */
250  return 0;
251  }
252  if(source_address != NULL) {
253  linkaddr_copy(source_address, (linkaddr_t *)frame->src_addr);
254  }
255  }
256 
257  /* Check and extract destination address */
258  dest_addr_len = frame->fcf.dest_addr_mode ?
259  ((frame->fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) ? 2 : 8) : 0;
260  if(dest_addr_len == 0 || frame802154_is_broadcast_addr(frame->fcf.dest_addr_mode, frame->dest_addr)) {
261  /* Broadcast address */
262  if(dest_address != NULL) {
263  linkaddr_copy(dest_address, &linkaddr_null);
264  }
265  } else {
266  /* Unicast address */
267  if(dest_addr_len != LINKADDR_SIZE) {
268  /* Destination address has a size we can not handle */
269  return 0;
270  }
271  if(dest_address != NULL) {
272  linkaddr_copy(dest_address, (linkaddr_t *)frame->dest_addr);
273  }
274  }
275 
276  return 1;
277 }
278 /*----------------------------------------------------------------------------*/
279 static void
280 field_len(frame802154_t *p, field_length_t *flen)
281 {
282  int has_src_panid;
283  int has_dest_panid;
284 
285  /* init flen to zeros */
286  memset(flen, 0, sizeof(field_length_t));
287 
288  /* Determine lengths of each field based on fcf and other args */
289  if((p->fcf.sequence_number_suppression & 1) == 0) {
290  flen->seqno_len = 1;
291  }
292 
293  /* IEEE802.15.4e changes the meaning of PAN ID Compression (see Table 2a).
294  * In this case, we leave the decision whether to compress PAN ID or not
295  * up to the caller. */
296  if(p->fcf.frame_version < FRAME802154_IEEE802154E_2012) {
297  /* Set PAN ID compression bit if src pan id matches dest pan id. */
298  if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 &&
299  p->src_pid == p->dest_pid) {
300  p->fcf.panid_compression = 1;
301  } else {
302  p->fcf.panid_compression = 0;
303  }
304  }
305 
306  frame802154_has_panid(&p->fcf, &has_src_panid, &has_dest_panid);
307 
308  if(has_src_panid) {
309  flen->src_pid_len = 2;
310  }
311 
312  if(has_dest_panid) {
313  flen->dest_pid_len = 2;
314  }
315 
316  /* determine address lengths */
317  flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3);
318  flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3);
319 
320 #if LLSEC802154_USES_AUX_HEADER
321  /* Aux security header */
322  if(p->fcf.security_enabled & 1) {
323  flen->aux_sec_len = 1; /* FCF + possibly frame counter and key ID */
326  flen->aux_sec_len += 5;
327  } else {
328  flen->aux_sec_len += 4;
329  }
330  }
331 #if LLSEC802154_USES_EXPLICIT_KEYS
332  flen->aux_sec_len += get_key_id_len(p->aux_hdr.security_control.key_id_mode);
333 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
334  ;
335  }
336 #endif /* LLSEC802154_USES_AUX_HEADER */
337 }
338 /*----------------------------------------------------------------------------*/
339 /**
340  * \brief Calculates the length of the frame header. This function is
341  * meant to be called by a higher level function, that interfaces to a MAC.
342  *
343  * \param p Pointer to frame802154_t_t struct, which specifies the
344  * frame to send.
345  *
346  * \return The length of the frame header.
347  */
348 int
350 {
351  field_length_t flen;
352  field_len(p, &flen);
353  return 2 + flen.seqno_len + flen.dest_pid_len + flen.dest_addr_len +
354  flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len;
355 }
356 /*----------------------------------------------------------------------------*/
357 /**
358  * \brief Creates a frame for transmission over the air. This function is
359  * meant to be called by a higher level function, that interfaces to a MAC.
360  *
361  * \param p Pointer to frame802154_t struct, which specifies the
362  * frame to send.
363  *
364  * \param buf Pointer to the buffer to use for the frame.
365  *
366  * \return The length of the frame header
367  */
368 int
370 {
371  int c;
372  field_length_t flen;
373  uint8_t pos;
374 #if LLSEC802154_USES_EXPLICIT_KEYS
375  uint8_t key_id_mode;
376 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
377 
378  field_len(p, &flen);
379 
380  /* OK, now we have field lengths. Time to actually construct */
381  /* the outgoing frame, and store it in buf */
382  buf[0] = (p->fcf.frame_type & 7) |
383  ((p->fcf.security_enabled & 1) << 3) |
384  ((p->fcf.frame_pending & 1) << 4) |
385  ((p->fcf.ack_required & 1) << 5) |
386  ((p->fcf.panid_compression & 1) << 6);
387  buf[1] = ((p->fcf.sequence_number_suppression & 1)) |
388  ((p->fcf.ie_list_present & 1)) << 1 |
389  ((p->fcf.dest_addr_mode & 3) << 2) |
390  ((p->fcf.frame_version & 3) << 4) |
391  ((p->fcf.src_addr_mode & 3) << 6);
392 
393  pos = 2;
394 
395  /* Sequence number */
396  if(flen.seqno_len == 1) {
397  buf[pos++] = p->seq;
398  }
399 
400  /* Destination PAN ID */
401  if(flen.dest_pid_len == 2) {
402  buf[pos++] = p->dest_pid & 0xff;
403  buf[pos++] = (p->dest_pid >> 8) & 0xff;
404  }
405 
406  /* Destination address */
407  for(c = flen.dest_addr_len; c > 0; c--) {
408  buf[pos++] = p->dest_addr[c - 1];
409  }
410 
411  /* Source PAN ID */
412  if(flen.src_pid_len == 2) {
413  buf[pos++] = p->src_pid & 0xff;
414  buf[pos++] = (p->src_pid >> 8) & 0xff;
415  }
416 
417  /* Source address */
418  for(c = flen.src_addr_len; c > 0; c--) {
419  buf[pos++] = p->src_addr[c - 1];
420  }
421 #if LLSEC802154_USES_AUX_HEADER
422  /* Aux header */
423  if(flen.aux_sec_len) {
424  buf[pos++] = p->aux_hdr.security_control.security_level
425 #if LLSEC802154_USES_EXPLICIT_KEYS
427 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
430  ;
432  /* We support only 4-byte counters */
433  memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4);
434  pos += 4;
436  pos++;
437  }
438  }
439 
440 #if LLSEC802154_USES_EXPLICIT_KEYS
441  key_id_mode = p->aux_hdr.security_control.key_id_mode;
442  if(key_id_mode) {
443  c = (key_id_mode - 1) * 4;
444  memcpy(buf + pos, p->aux_hdr.key_source.u8, c);
445  pos += c;
446  buf[pos++] = p->aux_hdr.key_index;
447  }
448 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
449  }
450 #endif /* LLSEC802154_USES_AUX_HEADER */
451 
452  return (int)pos;
453 }
454 /*----------------------------------------------------------------------------*/
455 /**
456  * \brief Parses an input frame. Scans the input frame to find each
457  * section, and stores the information of each section in a
458  * frame802154_t structure.
459  *
460  * \param data The input data from the radio chip.
461  * \param len The size of the input data
462  * \param pf The frame802154_t struct to store the parsed frame information.
463  */
464 int
465 frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
466 {
467  uint8_t *p;
468  frame802154_fcf_t fcf;
469  int c;
470  int has_src_panid;
471  int has_dest_panid;
472 #if LLSEC802154_USES_EXPLICIT_KEYS
473  uint8_t key_id_mode;
474 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
475 
476  if(len < 2) {
477  return 0;
478  }
479 
480  p = data;
481 
482  /* decode the FCF */
483  fcf.frame_type = p[0] & 7;
484  fcf.security_enabled = (p[0] >> 3) & 1;
485  fcf.frame_pending = (p[0] >> 4) & 1;
486  fcf.ack_required = (p[0] >> 5) & 1;
487  fcf.panid_compression = (p[0] >> 6) & 1;
488 
489  fcf.sequence_number_suppression = p[1] & 1;
490  fcf.ie_list_present = (p[1] >> 1) & 1;
491  fcf.dest_addr_mode = (p[1] >> 2) & 3;
492  fcf.frame_version = (p[1] >> 4) & 3;
493  fcf.src_addr_mode = (p[1] >> 6) & 3;
494 
495  /* copy fcf and seqNum */
496  memcpy(&pf->fcf, &fcf, sizeof(frame802154_fcf_t));
497  p += 2; /* Skip first two bytes */
498 
499  if(fcf.sequence_number_suppression == 0) {
500  pf->seq = p[0];
501  p++;
502  }
503 
504  frame802154_has_panid(&fcf, &has_src_panid, &has_dest_panid);
505 
506  /* Destination address, if any */
507  if(fcf.dest_addr_mode) {
508  if(has_dest_panid) {
509  /* Destination PAN */
510  pf->dest_pid = p[0] + (p[1] << 8);
511  p += 2;
512  } else {
513  pf->dest_pid = 0;
514  }
515 
516  /* Destination address */
517 /* l = addr_len(fcf.dest_addr_mode); */
518 /* for(c = 0; c < l; c++) { */
519 /* pf->dest_addr.u8[c] = p[l - c - 1]; */
520 /* } */
521 /* p += l; */
522  if(fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) {
523  linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null);
524  pf->dest_addr[0] = p[1];
525  pf->dest_addr[1] = p[0];
526  p += 2;
527  } else if(fcf.dest_addr_mode == FRAME802154_LONGADDRMODE) {
528  for(c = 0; c < 8; c++) {
529  pf->dest_addr[c] = p[7 - c];
530  }
531  p += 8;
532  }
533  } else {
534  linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null);
535  pf->dest_pid = 0;
536  }
537 
538  /* Source address, if any */
539  if(fcf.src_addr_mode) {
540  /* Source PAN */
541  if(has_src_panid) {
542  pf->src_pid = p[0] + (p[1] << 8);
543  p += 2;
544  if(!has_dest_panid) {
545  pf->dest_pid = pf->src_pid;
546  }
547  } else {
548  pf->src_pid = pf->dest_pid;
549  }
550 
551  /* Source address */
552 /* l = addr_len(fcf.src_addr_mode); */
553 /* for(c = 0; c < l; c++) { */
554 /* pf->src_addr.u8[c] = p[l - c - 1]; */
555 /* } */
556 /* p += l; */
557  if(fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) {
558  linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null);
559  pf->src_addr[0] = p[1];
560  pf->src_addr[1] = p[0];
561  p += 2;
562  } else if(fcf.src_addr_mode == FRAME802154_LONGADDRMODE) {
563  for(c = 0; c < 8; c++) {
564  pf->src_addr[c] = p[7 - c];
565  }
566  p += 8;
567  }
568  } else {
569  linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null);
570  pf->src_pid = 0;
571  }
572 
573 #if LLSEC802154_USES_AUX_HEADER
574  if(fcf.security_enabled) {
575  pf->aux_hdr.security_control.security_level = p[0] & 7;
576 #if LLSEC802154_USES_EXPLICIT_KEYS
577  pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3;
578 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
581  p += 1;
582 
584  memcpy(pf->aux_hdr.frame_counter.u8, p, 4);
585  p += 4;
587  p ++;
588  }
589  }
590 
591 #if LLSEC802154_USES_EXPLICIT_KEYS
592  key_id_mode = pf->aux_hdr.security_control.key_id_mode;
593  if(key_id_mode) {
594  c = (key_id_mode - 1) * 4;
595  memcpy(pf->aux_hdr.key_source.u8, p, c);
596  p += c;
597  pf->aux_hdr.key_index = p[0];
598  p += 1;
599  }
600 #endif /* LLSEC802154_USES_EXPLICIT_KEYS */
601  }
602 #endif /* LLSEC802154_USES_AUX_HEADER */
603 
604  /* header length */
605  c = p - data;
606  /* payload length */
607  pf->payload_len = (len - c);
608  /* payload */
609  pf->payload = p;
610 
611  /* return header length if successful */
612  return c > len ? 0 : c;
613 }
614 /** \} */
int frame802154_hdrlen(frame802154_t *p)
Calculates the length of the frame header.
Definition: frame802154.c:349
uint8_t security_enabled
1 bit.
Definition: frame802154.h:148
uint16_t src_pid
Source PAN ID.
Definition: frame802154.h:201
frame802154_scf_t security_control
Security control bitfield.
Definition: frame802154.h:182
uint8_t dest_addr[8]
Destination address.
Definition: frame802154.h:196
uint8_t key_id_mode
2 bit.
Definition: frame802154.h:163
uint16_t dest_pid
Destination PAN ID.
Definition: frame802154.h:200
uint8_t key_index
Key Index subfield.
Definition: frame802154.h:185
static uip_ds6_addr_t * addr
Pointer to a router list entry.
Definition: uip-nd6.c:124
frame802154_fcf_t fcf
Frame control field.
Definition: frame802154.h:198
uint8_t ie_list_present
1 bit.
Definition: frame802154.h:154
static uint16_t mac_pan_id
The 16-bit identifier of the PAN on which the device is operating.
Definition: frame802154.c:76
frame802154_frame_counter_t frame_counter
Frame counter, used for security.
Definition: frame802154.h:183
int payload_len
Length of payload field.
Definition: frame802154.h:204
Default definitions of C compiler quirk work-arounds.
uint8_t frame_pending
1 bit.
Definition: frame802154.h:149
uint8_t src_addr[8]
Source address.
Definition: frame802154.h:197
uint8_t seq
Sequence number.
Definition: frame802154.h:199
const linkaddr_t linkaddr_null
The null Rime address.
Definition: eth-conf.c:37
uint8_t * payload
Pointer to 802.15.4 payload.
Definition: frame802154.h:203
Common functionality of 802.15.4-compliant llsec_drivers.
int frame802154_create(frame802154_t *p, uint8_t *buf)
Creates a frame for transmission over the air.
Definition: frame802154.c:369
Header file for the Rime address representation
The IEEE 802.15.4 frame has a number of constant/fixed fields that can be counted to make frame const...
Definition: frame802154.h:146
frame802154_key_source_t key_source
Key Source subfield.
Definition: frame802154.h:184
#define NULL
The null pointer.
uint8_t frame_type
3 bit.
Definition: frame802154.h:147
802.15.4 frame creation and parsing functions
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
Definition: frame802154.c:465
uint8_t security_level
3 bit.
Definition: frame802154.h:162
uint8_t src_addr_mode
2 bit.
Definition: frame802154.h:157
uint8_t frame_counter_size
1 bit.
Definition: frame802154.h:165
frame802154_aux_hdr_t aux_hdr
Aux security header.
Definition: frame802154.h:202
uint8_t dest_addr_mode
2 bit.
Definition: frame802154.h:155
uint8_t panid_compression
1 bit.
Definition: frame802154.h:151
uint8_t ack_required
1 bit.
Definition: frame802154.h:150
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
Definition: linkaddr.c:60
uint8_t frame_version
2 bit.
Definition: frame802154.h:156
Parameters used by the frame802154_create() function.
Definition: frame802154.h:192
uint8_t frame_counter_suppression
1 bit.
Definition: frame802154.h:164
uint8_t sequence_number_suppression
< 1 bit.
Definition: frame802154.h:153