Contiki-NG
Loading...
Searching...
No Matches
csma-output.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 */
32
33/**
34 * \file
35 * The 802.15.4 standard CSMA protocol (nonbeacon-enabled).
36 * Output functions.
37 * \author
38 * Adam Dunkels <adam@sics.se>
39 * Simon Duquennoy <simon.duquennoy@inria.fr>
40 */
41
42#include "net/mac/csma/csma.h"
46#include "net/packetbuf.h"
47#include "net/queuebuf.h"
48#include "dev/watchdog.h"
49#include "sys/ctimer.h"
50#include "sys/clock.h"
51#include "lib/random.h"
52#include "net/netstack.h"
53#include "lib/list.h"
54#include "lib/memb.h"
55#include "lib/assert.h"
56
57/* Log configuration */
58#include "sys/log.h"
59#define LOG_MODULE "CSMA"
60#define LOG_LEVEL LOG_LEVEL_MAC
61
62/* Constants of the IEEE 802.15.4 standard */
63
64/* macMinBE: Initial backoff exponent. Range 0--CSMA_MAX_BE */
65#ifdef CSMA_CONF_MIN_BE
66#define CSMA_MIN_BE CSMA_CONF_MIN_BE
67#else
68#define CSMA_MIN_BE 3
69#endif
70
71/* macMaxBE: Maximum backoff exponent. Range 3--8 */
72#ifdef CSMA_CONF_MAX_BE
73#define CSMA_MAX_BE CSMA_CONF_MAX_BE
74#else
75#define CSMA_MAX_BE 5
76#endif
77
78/* macMaxCSMABackoffs: Maximum number of backoffs in case of channel busy/collision. Range 0--5 */
79#ifdef CSMA_CONF_MAX_BACKOFF
80#define CSMA_MAX_BACKOFF CSMA_CONF_MAX_BACKOFF
81#else
82#define CSMA_MAX_BACKOFF 5
83#endif
84
85/* macMaxFrameRetries: Maximum number of re-transmissions attampts. Range 0--7 */
86#ifdef CSMA_CONF_MAX_FRAME_RETRIES
87#define CSMA_MAX_FRAME_RETRIES CSMA_CONF_MAX_FRAME_RETRIES
88#else
89#define CSMA_MAX_FRAME_RETRIES 7
90#endif
91
92/* Packet metadata */
93struct qbuf_metadata {
94 mac_callback_t sent;
95 void *cptr;
96 uint8_t max_transmissions;
97};
98
99/* Every neighbor has its own packet queue */
100struct neighbor_queue {
101 struct neighbor_queue *next;
102 linkaddr_t addr;
103 struct ctimer transmit_timer;
104 uint8_t transmissions;
105 uint8_t collisions;
106 LIST_STRUCT(packet_queue);
107};
108
109/* The maximum number of co-existing neighbor queues */
110#ifdef CSMA_CONF_MAX_NEIGHBOR_QUEUES
111#define CSMA_MAX_NEIGHBOR_QUEUES CSMA_CONF_MAX_NEIGHBOR_QUEUES
112#else
113#define CSMA_MAX_NEIGHBOR_QUEUES 2
114#endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */
115
116/* The maximum number of pending packet per neighbor */
117#ifdef CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
118#define CSMA_MAX_PACKET_PER_NEIGHBOR CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
119#else
120#define CSMA_MAX_PACKET_PER_NEIGHBOR MAX_QUEUED_PACKETS
121#endif /* CSMA_CONF_MAX_PACKET_PER_NEIGHBOR */
122
123#define MAX_QUEUED_PACKETS QUEUEBUF_NUM
124
125/* Neighbor packet queue */
126struct packet_queue {
127 struct packet_queue *next;
128 struct queuebuf *buf;
129 void *ptr;
130};
131
132MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES);
133MEMB(packet_memb, struct packet_queue, MAX_QUEUED_PACKETS);
134MEMB(metadata_memb, struct qbuf_metadata, MAX_QUEUED_PACKETS);
135LIST(neighbor_list);
136
137static void packet_sent(struct neighbor_queue *n,
138 struct packet_queue *q,
139 int status,
140 int num_transmissions);
141static void transmit_from_queue(void *ptr);
142/*---------------------------------------------------------------------------*/
143static struct neighbor_queue *
144neighbor_queue_from_addr(const linkaddr_t *addr)
145{
146 struct neighbor_queue *n = list_head(neighbor_list);
147 while(n != NULL) {
148 if(linkaddr_cmp(&n->addr, addr)) {
149 return n;
150 }
151 n = list_item_next(n);
152 }
153 return NULL;
154}
155/*---------------------------------------------------------------------------*/
156static clock_time_t
157backoff_period(void)
158{
159#if CONTIKI_TARGET_COOJA
160 /* Increase normal value by 20 to compensate for the coarse-grained
161 radio medium with Cooja motes */
162 return MAX(20 * CLOCK_SECOND / 3125, 1);
163#else /* CONTIKI_TARGET_COOJA */
164 /* Use the default in IEEE 802.15.4: aUnitBackoffPeriod which is
165 * 20 symbols i.e. 320 usec. That is, 1/3125 second. */
166 return MAX(CLOCK_SECOND / 3125, 1);
167#endif /* CONTIKI_TARGET_COOJA */
168}
169/*---------------------------------------------------------------------------*/
170static int
171send_one_packet(struct neighbor_queue *n, struct packet_queue *q)
172{
173 int ret;
174 int last_sent_ok = 0;
175
176 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
177 packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
178
179#if LLSEC802154_ENABLED
180#if LLSEC802154_USES_EXPLICIT_KEYS
181 /* This should possibly be taken from upper layers in the future */
182 packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, CSMA_LLSEC_KEY_ID_MODE);
183#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
184#endif /* LLSEC802154_ENABLED */
185
186 if(CSMA_FRAMER.create() < 0) {
187 /* Failed to allocate space for headers */
188 LOG_ERR("failed to create packet, seqno: %d\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
189 ret = MAC_TX_ERR_FATAL;
190 } else {
191 int is_broadcast;
192 uint8_t dsn;
193 dsn = ((uint8_t *)packetbuf_hdrptr())[2] & 0xff;
194
195 NETSTACK_RADIO.prepare(packetbuf_hdrptr(), packetbuf_totlen());
196
197 is_broadcast = packetbuf_holds_broadcast();
198
199 if(NETSTACK_RADIO.receiving_packet() ||
200 (!is_broadcast && NETSTACK_RADIO.pending_packet())) {
201
202 /* Currently receiving a packet over air or the radio has
203 already received a packet that needs to be read before
204 sending with auto ack. */
205 ret = MAC_TX_COLLISION;
206 } else {
207
208 switch(NETSTACK_RADIO.transmit(packetbuf_totlen())) {
209 case RADIO_TX_OK:
210 if(is_broadcast) {
211 ret = MAC_TX_OK;
212 } else if(CSMA_USE_RADIO_ACK) {
213 ret = MAC_TX_OK;
214 } else {
215 /* Check for ack */
216
217 /* Wait for max CSMA_ACK_WAIT_TIME */
218 RTIMER_BUSYWAIT_UNTIL(NETSTACK_RADIO.pending_packet(), CSMA_ACK_WAIT_TIME);
219
220 ret = MAC_TX_NOACK;
221 if(NETSTACK_RADIO.receiving_packet() ||
222 NETSTACK_RADIO.pending_packet() ||
223 NETSTACK_RADIO.channel_clear() == 0) {
224 int len;
225 uint8_t ackbuf[CSMA_ACK_LEN];
226
227 /* Wait an additional CSMA_AFTER_ACK_DETECTED_WAIT_TIME to complete reception */
228 RTIMER_BUSYWAIT_UNTIL(NETSTACK_RADIO.pending_packet(), CSMA_AFTER_ACK_DETECTED_WAIT_TIME);
229
230 if(NETSTACK_RADIO.pending_packet()) {
231 len = NETSTACK_RADIO.read(ackbuf, CSMA_ACK_LEN);
232 if(len == CSMA_ACK_LEN && ackbuf[2] == dsn) {
233 /* Ack received */
234 ret = MAC_TX_OK;
235 } else {
236 /* Not an ack or ack not for us: collision */
237 ret = MAC_TX_COLLISION;
238 }
239 }
240 }
241 }
242 break;
243 case RADIO_TX_NOACK:
244 ret = MAC_TX_NOACK;
245 break;
247 ret = MAC_TX_COLLISION;
248 break;
249 default:
250 ret = MAC_TX_ERR;
251 break;
252 }
253 }
254 }
255 if(ret == MAC_TX_OK) {
256 last_sent_ok = 1;
257 }
258
259 packet_sent(n, q, ret, 1);
260 return last_sent_ok;
261}
262/*---------------------------------------------------------------------------*/
263static void
264transmit_from_queue(void *ptr)
265{
266 struct neighbor_queue *n = ptr;
267 if(n) {
268 struct packet_queue *q = list_head(n->packet_queue);
269 if(q != NULL) {
270 LOG_INFO("preparing packet for ");
271 LOG_INFO_LLADDR(&n->addr);
272 LOG_INFO_(", seqno %u, tx %u, queue %d\n",
273 queuebuf_attr(q->buf, PACKETBUF_ATTR_MAC_SEQNO),
274 n->transmissions, list_length(n->packet_queue));
275 /* Send first packet in the neighbor queue */
276 queuebuf_to_packetbuf(q->buf);
277 send_one_packet(n, q);
278 }
279 }
280}
281/*---------------------------------------------------------------------------*/
282static void
283schedule_transmission(struct neighbor_queue *n)
284{
285 clock_time_t delay;
286 int backoff_exponent; /* BE in IEEE 802.15.4 */
287
288 backoff_exponent = MIN(n->collisions + CSMA_MIN_BE, CSMA_MAX_BE);
289
290 /* Compute max delay as per IEEE 802.15.4: 2^BE-1 backoff periods */
291 delay = ((1 << backoff_exponent) - 1) * backoff_period();
292 if(delay > 0) {
293 /* Pick a time for next transmission */
294 delay = random_rand() % delay;
295 }
296
297 LOG_DBG("scheduling transmission in %u ticks, NB=%u, BE=%u\n",
298 (unsigned)delay, n->collisions, backoff_exponent);
299 ctimer_set(&n->transmit_timer, delay, transmit_from_queue, n);
300}
301/*---------------------------------------------------------------------------*/
302static void
303free_packet(struct neighbor_queue *n, struct packet_queue *p, int status)
304{
305 if(p != NULL) {
306 /* Remove packet from queue and deallocate */
307 list_remove(n->packet_queue, p);
308
309 queuebuf_free(p->buf);
310 memb_free(&metadata_memb, p->ptr);
311 memb_free(&packet_memb, p);
312 LOG_DBG("free_queued_packet, queue length %d, free packets %zu\n",
313 list_length(n->packet_queue), memb_numfree(&packet_memb));
314 if(list_head(n->packet_queue) != NULL) {
315 /* There is a next packet. We reset current tx information */
316 n->transmissions = 0;
317 n->collisions = 0;
318 /* Schedule next transmissions */
319 schedule_transmission(n);
320 } else {
321 /* This was the last packet in the queue, we free the neighbor */
322 ctimer_stop(&n->transmit_timer);
323 list_remove(neighbor_list, n);
324 memb_free(&neighbor_memb, n);
325 }
326 }
327}
328/*---------------------------------------------------------------------------*/
329static void
330tx_done(int status, struct packet_queue *q, struct neighbor_queue *n)
331{
332 mac_callback_t sent;
333 struct qbuf_metadata *metadata;
334 void *cptr;
335 uint8_t ntx;
336
337 metadata = (struct qbuf_metadata *)q->ptr;
338 sent = metadata->sent;
339 cptr = metadata->cptr;
340 ntx = n->transmissions;
341
342 LOG_INFO("packet sent to ");
343 LOG_INFO_LLADDR(&n->addr);
344 LOG_INFO_(", seqno %u, status %u, tx %u, coll %u\n",
345 packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO),
346 status, n->transmissions, n->collisions);
347
348 free_packet(n, q, status);
349 mac_call_sent_callback(sent, cptr, status, ntx);
350}
351/*---------------------------------------------------------------------------*/
352static void
353rexmit(struct packet_queue *q, struct neighbor_queue *n)
354{
355 schedule_transmission(n);
356 /* This is needed to correctly attribute energy that we spent
357 transmitting this packet. */
358 queuebuf_update_attr_from_packetbuf(q->buf);
359}
360/*---------------------------------------------------------------------------*/
361static void
362collision(struct packet_queue *q, struct neighbor_queue *n,
363 int num_transmissions)
364{
365 struct qbuf_metadata *metadata;
366
367 metadata = (struct qbuf_metadata *)q->ptr;
368
369 n->collisions += num_transmissions;
370
371 if(n->collisions > CSMA_MAX_BACKOFF) {
372 n->collisions = 0;
373 /* Increment to indicate a next retry */
374 n->transmissions++;
375 }
376
377 if(n->transmissions >= metadata->max_transmissions) {
378 tx_done(MAC_TX_COLLISION, q, n);
379 } else {
380 rexmit(q, n);
381 }
382}
383/*---------------------------------------------------------------------------*/
384static void
385noack(struct packet_queue *q, struct neighbor_queue *n, int num_transmissions)
386{
387 struct qbuf_metadata *metadata;
388
389 metadata = (struct qbuf_metadata *)q->ptr;
390
391 n->collisions = 0;
392 n->transmissions += num_transmissions;
393
394 if(n->transmissions >= metadata->max_transmissions) {
395 tx_done(MAC_TX_NOACK, q, n);
396 } else {
397 rexmit(q, n);
398 }
399}
400/*---------------------------------------------------------------------------*/
401static void
402tx_ok(struct packet_queue *q, struct neighbor_queue *n, int num_transmissions)
403{
404 n->collisions = 0;
405 n->transmissions += num_transmissions;
406 tx_done(MAC_TX_OK, q, n);
407}
408/*---------------------------------------------------------------------------*/
409static void
410packet_sent(struct neighbor_queue *n,
411 struct packet_queue *q,
412 int status,
413 int num_transmissions)
414{
415 assert(n != NULL);
416 assert(q != NULL);
417
418 if(q->ptr == NULL) {
419 LOG_WARN("packet sent: no metadata\n");
420 return;
421 }
422
423 LOG_INFO("tx to ");
424 LOG_INFO_LLADDR(&n->addr);
425 LOG_INFO_(", seqno %u, status %u, tx %u, coll %u\n",
426 packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO),
427 status, n->transmissions, n->collisions);
428
429 switch(status) {
430 case MAC_TX_OK:
431 tx_ok(q, n, num_transmissions);
432 break;
433 case MAC_TX_NOACK:
434 noack(q, n, num_transmissions);
435 break;
436 case MAC_TX_COLLISION:
437 collision(q, n, num_transmissions);
438 break;
439 case MAC_TX_DEFERRED:
440 break;
441 default:
442 tx_done(status, q, n);
443 break;
444 }
445}
446/*---------------------------------------------------------------------------*/
447void
448csma_output_packet(mac_callback_t sent, void *ptr)
449{
450 struct packet_queue *q;
451 struct neighbor_queue *n;
452 const linkaddr_t *addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
453
455 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
456
457 /* Look for the neighbor entry */
458 n = neighbor_queue_from_addr(addr);
459 if(n == NULL) {
460 /* Allocate a new neighbor entry */
461 n = memb_alloc(&neighbor_memb);
462 if(n != NULL) {
463 /* Init neighbor entry */
464 linkaddr_copy(&n->addr, addr);
465 n->transmissions = 0;
466 n->collisions = 0;
467 /* Init packet queue for this neighbor */
468 LIST_STRUCT_INIT(n, packet_queue);
469 /* Add neighbor to the neighbor list */
470 list_add(neighbor_list, n);
471 }
472 }
473
474 if(n != NULL) {
475 /* Add packet to the neighbor's queue */
476 if(list_length(n->packet_queue) < CSMA_MAX_PACKET_PER_NEIGHBOR) {
477 q = memb_alloc(&packet_memb);
478 if(q != NULL) {
479 q->ptr = memb_alloc(&metadata_memb);
480 if(q->ptr != NULL) {
481 q->buf = queuebuf_new_from_packetbuf();
482 if(q->buf != NULL) {
483 struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
484 /* Neighbor and packet successfully allocated */
485 metadata->max_transmissions = packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
486 if(metadata->max_transmissions == 0) {
487 /* If not set by the application, use the default CSMA value */
488 metadata->max_transmissions = CSMA_MAX_FRAME_RETRIES + 1;
489 }
490 metadata->sent = sent;
491 metadata->cptr = ptr;
492 list_add(n->packet_queue, q);
493
494 LOG_INFO("sending to ");
495 LOG_INFO_LLADDR(addr);
496 LOG_INFO_(", len %u, seqno %u, queue length %d, free packets %zu\n",
498 packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO),
499 list_length(n->packet_queue), memb_numfree(&packet_memb));
500 /* If q is the first packet in the neighbor's queue, send asap */
501 if(list_head(n->packet_queue) == q) {
502 schedule_transmission(n);
503 }
504 return;
505 }
506 memb_free(&metadata_memb, q->ptr);
507 LOG_WARN("could not allocate queuebuf, dropping packet\n");
508 }
509 memb_free(&packet_memb, q);
510 LOG_WARN("could not allocate queuebuf, dropping packet\n");
511 }
512 /* The packet allocation failed. Remove and free neighbor entry if empty. */
513 if(list_length(n->packet_queue) == 0) {
514 list_remove(neighbor_list, n);
515 memb_free(&neighbor_memb, n);
516 }
517 } else {
518 LOG_WARN("Neighbor queue full\n");
519 }
520 LOG_WARN("could not allocate packet, dropping packet\n");
521 } else {
522 LOG_WARN("could not allocate neighbor, dropping packet\n");
523 }
524 mac_call_sent_callback(sent, ptr, MAC_TX_QUEUE_FULL, 1);
525}
526/*---------------------------------------------------------------------------*/
527void
528csma_output_init(void)
529{
530 memb_init(&packet_memb);
531 memb_init(&metadata_memb);
532 memb_init(&neighbor_memb);
533}
LLSEC802154 Security related configuration.
The 802.15.4 standard CSMA protocol (nonbeacon-enabled)
Header file for the callback timer.
802.15.4 frame creation and parsing functions
#define CLOCK_SECOND
A second, measured in system clock time.
Definition clock.h:105
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition ctimer.c:150
static void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition ctimer.h:150
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition linkaddr.c:48
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
Definition linkaddr.c:63
bool linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
Definition linkaddr.c:69
#define LIST(name)
Declare a linked list.
Definition list.h:90
static void * list_item_next(const void *item)
Get the next item following this item.
Definition list.h:294
int list_length(const_list_t list)
Get the length of a list.
Definition list.c:160
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition list.c:71
void list_remove(list_t list, const void *item)
Remove a specific element from a list.
Definition list.c:134
#define LIST_STRUCT(name)
Declare a linked list inside a structure declaraction.
Definition list.h:112
#define LIST_STRUCT_INIT(struct_ptr, name)
Initialize a linked list that is part of a structure.
Definition list.h:126
static void * list_head(const_list_t list)
Get a pointer to the first element of a list.
Definition list.h:169
int memb_free(struct memb *m, void *ptr)
Deallocate a memory block from a memory block previously declared with MEMB().
Definition memb.c:78
size_t memb_numfree(struct memb *m)
Count free memory blocks.
Definition memb.c:108
void * memb_alloc(struct memb *m)
Allocate a memory block from a block of memory declared with MEMB().
Definition memb.c:59
void memb_init(struct memb *m)
Initialize a memory block that was declared with MEMB().
Definition memb.c:52
#define MEMB(name, structure, num)
Declare a memory block.
Definition memb.h:91
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Definition packetbuf.c:167
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition packetbuf.c:155
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Definition packetbuf.c:149
bool packetbuf_holds_broadcast(void)
Checks whether the current packet is a broadcast.
Definition packetbuf.c:229
@ RADIO_TX_NOACK
A unicast frame was sent OK but an ACK was not received.
Definition radio.h:516
@ RADIO_TX_COLLISION
TX failed due to a collision.
Definition radio.h:511
@ RADIO_TX_OK
TX was successful and where an ACK was requested one was received.
Definition radio.h:498
#define RTIMER_BUSYWAIT_UNTIL(cond, max_time)
Busy-wait until a condition for at most max_time.
Definition rtimer.h:217
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
Linked list manipulation routines.
Header file for the logging system.
void mac_sequence_set_dsn(void)
Sets and increments the destination sequence number.
Header file for MAC sequence numbers management.
@ MAC_TX_COLLISION
The MAC layer did not get an acknowledgement for the packet.
Definition mac.h:97
@ MAC_TX_DEFERRED
The MAC layer transmission could not be performed because of an error.
Definition mac.h:103
@ MAC_TX_OK
The MAC layer transmission was OK.
Definition mac.h:93
@ MAC_TX_NOACK
The MAC layer deferred the transmission for a later time.
Definition mac.h:100
@ MAC_TX_ERR_FATAL
The MAC layer transmission could not be performed because of insufficient queue space,...
Definition mac.h:112
@ MAC_TX_ERR
The MAC layer transmission could not be performed because of a fatal error.
Definition mac.h:107
Memory block allocation routines.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
Header file for the Packet queue buffer management.
Header file for generating non-cryptographic random numbers.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition uip-nd6.c:107