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 */
76static 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 */
82typedef 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/*----------------------------------------------------------------------------*/
92CC_INLINE static uint8_t
93addr_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
106static uint8_t
107get_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 */
123uint16_t
124frame802154_get_pan_id(void)
125{
126 return mac_pan_id;
127}
128/*---------------------------------------------------------------------------*/
129/* Set current PAN ID */
130void
131frame802154_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 */
138void
139frame802154_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 */
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 */
205int
206frame802154_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 */
224bool
225frame802154_is_broadcast_addr(uint8_t mode, const uint8_t *addr)
226{
227 int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8;
228 while(i-- > 0) {
229 if(addr[i] != 0xff) {
230 return false;
231 }
232 }
233 return true;
234}
235/*---------------------------------------------------------------------------*/
236/* Check and extract source and destination linkaddr from frame */
237int
238frame802154_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/*----------------------------------------------------------------------------*/
288static void
289field_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 */
357int
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}
365void
366frame802154_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 */
391int
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) {
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
468void
469frame802154_parse_fcf(const uint8_t *data, frame802154_fcf_t *pfcf)
470{
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 */
499int
500frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
501{
502 uint8_t *p;
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) {
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/** \} */
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.
Definition: frame802154.c:500
#define FRAME802154_NOADDR
Only valid for ACK or Beacon frames.
Definition: frame802154.h:110
int frame802154_create(frame802154_t *p, uint8_t *buf)
Creates a frame for transmission over the air.
Definition: frame802154.c:392
int frame802154_hdrlen(frame802154_t *p)
Calculates the length of the frame header.
Definition: frame802154.c:358
static uint16_t mac_pan_id
The 16-bit identifier of the PAN on which the device is operating.
Definition: frame802154.c:76
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
Definition: linkaddr.c:63
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.
Definition: frame802154.h:189
frame802154_frame_counter_t frame_counter
Frame counter, used for security.
Definition: frame802154.h:190
uint8_t key_index
Key Index subfield.
Definition: frame802154.h:192
frame802154_key_source_t key_source
Key Source subfield.
Definition: frame802154.h:191
The IEEE 802.15.4 frame has a number of constant/fixed fields that can be counted to make frame const...
Definition: frame802154.h:153
uint8_t frame_type
3 bit.
Definition: frame802154.h:154
uint8_t frame_version
2 bit.
Definition: frame802154.h:163
uint8_t ie_list_present
1 bit.
Definition: frame802154.h:161
uint8_t security_enabled
1 bit.
Definition: frame802154.h:155
uint8_t sequence_number_suppression
< 1 bit.
Definition: frame802154.h:160
uint8_t src_addr_mode
2 bit.
Definition: frame802154.h:164
uint8_t panid_compression
1 bit.
Definition: frame802154.h:158
uint8_t ack_required
1 bit.
Definition: frame802154.h:157
uint8_t dest_addr_mode
2 bit.
Definition: frame802154.h:162
uint8_t frame_pending
1 bit.
Definition: frame802154.h:156
uint8_t key_id_mode
2 bit.
Definition: frame802154.h:170
uint8_t frame_counter_size
1 bit.
Definition: frame802154.h:172
uint8_t frame_counter_suppression
1 bit.
Definition: frame802154.h:171
uint8_t security_level
3 bit.
Definition: frame802154.h:169
Parameters used by the frame802154_create() function.
Definition: frame802154.h:199
uint8_t seq
Sequence number.
Definition: frame802154.h:206
uint8_t dest_addr[8]
Destination address.
Definition: frame802154.h:203
frame802154_aux_hdr_t aux_hdr
Aux security header.
Definition: frame802154.h:209
uint8_t * payload
Pointer to 802.15.4 payload.
Definition: frame802154.h:210
uint8_t src_addr[8]
Source address.
Definition: frame802154.h:204
uint16_t src_pid
Source PAN ID.
Definition: frame802154.h:208
frame802154_fcf_t fcf
Frame control field
Definition: frame802154.h:205
uint16_t dest_pid
Destination PAN ID.
Definition: frame802154.h:207
int payload_len
Length of payload field.
Definition: frame802154.h:211
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:107