Contiki 3.x
contikimac.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  * Implementation of the ContikiMAC power-saving radio duty cycling protocol
36  * \author
37  * Adam Dunkels <adam@sics.se>
38  * Niclas Finne <nfi@sics.se>
39  * Joakim Eriksson <joakime@sics.se>
40  */
41 
42 #include "contiki-conf.h"
43 #include "dev/leds.h"
44 #include "dev/radio.h"
45 #include "dev/watchdog.h"
46 #include "lib/random.h"
47 #include "net/mac/mac-sequence.h"
49 #include "net/netstack.h"
50 #include "net/rime/rime.h"
51 #include "sys/compower.h"
52 #include "sys/pt.h"
53 #include "sys/rtimer.h"
54 
55 
56 #include <string.h>
57 
58 /* TX/RX cycles are synchronized with neighbor wake periods */
59 #ifdef CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION
60 #define WITH_PHASE_OPTIMIZATION CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION
61 #else /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */
62 #define WITH_PHASE_OPTIMIZATION 1
63 #endif /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */
64 /* More aggressive radio sleeping when channel is busy with other traffic */
65 #ifndef WITH_FAST_SLEEP
66 #define WITH_FAST_SLEEP 1
67 #endif
68 /* Radio does CSMA and autobackoff */
69 #ifndef RDC_CONF_HARDWARE_CSMA
70 #define RDC_CONF_HARDWARE_CSMA 0
71 #endif
72 /* Radio returns TX_OK/TX_NOACK after autoack wait */
73 #ifndef RDC_CONF_HARDWARE_ACK
74 #define RDC_CONF_HARDWARE_ACK 0
75 #endif
76 /* MCU can sleep during radio off */
77 #ifndef RDC_CONF_MCU_SLEEP
78 #define RDC_CONF_MCU_SLEEP 0
79 #endif
80 
81 #if NETSTACK_RDC_CHANNEL_CHECK_RATE >= 64
82 #undef WITH_PHASE_OPTIMIZATION
83 #define WITH_PHASE_OPTIMIZATION 0
84 #endif
85 
86 /* CYCLE_TIME for channel cca checks, in rtimer ticks. */
87 #ifdef CONTIKIMAC_CONF_CYCLE_TIME
88 #define CYCLE_TIME (CONTIKIMAC_CONF_CYCLE_TIME)
89 #else
90 #define CYCLE_TIME (RTIMER_ARCH_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE)
91 #endif
92 
93 /* CHANNEL_CHECK_RATE is enforced to be a power of two.
94  * If RTIMER_ARCH_SECOND is not also a power of two, there will be an inexact
95  * number of channel checks per second due to the truncation of CYCLE_TIME.
96  * This will degrade the effectiveness of phase optimization with neighbors that
97  * do not have the same truncation error.
98  * Define SYNC_CYCLE_STARTS to ensure an integral number of checks per second.
99  */
100 #if RTIMER_ARCH_SECOND & (RTIMER_ARCH_SECOND - 1)
101 #define SYNC_CYCLE_STARTS 1
102 #endif
103 
104 /* Are we currently receiving a burst? */
105 static int we_are_receiving_burst = 0;
106 
107 /* INTER_PACKET_DEADLINE is the maximum time a receiver waits for the
108  next packet of a burst when FRAME_PENDING is set. */
109 #ifdef CONTIKIMAC_CONF_INTER_PACKET_DEADLINE
110 #define INTER_PACKET_DEADLINE CONTIKIMAC_CONF_INTER_PACKET_DEADLINE
111 #else
112 #define INTER_PACKET_DEADLINE CLOCK_SECOND / 32
113 #endif
114 
115 /* ContikiMAC performs periodic channel checks. Each channel check
116  consists of two or more CCA checks. CCA_COUNT_MAX is the number of
117  CCAs to be done for each periodic channel check. The default is
118  two.*/
119 #ifdef CONTIKIMAC_CONF_CCA_COUNT_MAX
120 #define CCA_COUNT_MAX (CONTIKIMAC_CONF_CCA_COUNT_MAX)
121 #else
122 #define CCA_COUNT_MAX 2
123 #endif
124 
125 /* Before starting a transmission, Contikimac checks the availability
126  of the channel with CCA_COUNT_MAX_TX consecutive CCAs */
127 #ifdef CONTIKIMAC_CONF_CCA_COUNT_MAX_TX
128 #define CCA_COUNT_MAX_TX (CONTIKIMAC_CONF_CCA_COUNT_MAX_TX)
129 #else
130 #define CCA_COUNT_MAX_TX 6
131 #endif
132 
133 /* CCA_CHECK_TIME is the time it takes to perform a CCA check. */
134 /* Note this may be zero. AVRs have 7612 ticks/sec, but block until cca is done */
135 #ifdef CONTIKIMAC_CONF_CCA_CHECK_TIME
136 #define CCA_CHECK_TIME (CONTIKIMAC_CONF_CCA_CHECK_TIME)
137 #else
138 #define CCA_CHECK_TIME RTIMER_ARCH_SECOND / 8192
139 #endif
140 
141 /* CCA_SLEEP_TIME is the time between two successive CCA checks. */
142 /* Add 1 when rtimer ticks are coarse */
143 #ifdef CONTIKIMAC_CONF_CCA_SLEEP_TIME
144 #define CCA_SLEEP_TIME CONTIKIMAC_CONF_CCA_SLEEP_TIME
145 #else
146 #if RTIMER_ARCH_SECOND > 8000
147 #define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000
148 #else
149 #define CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 2000) + 1
150 #endif /* RTIMER_ARCH_SECOND > 8000 */
151 #endif /* CONTIKIMAC_CONF_CCA_SLEEP_TIME */
152 
153 /* CHECK_TIME is the total time it takes to perform CCA_COUNT_MAX
154  CCAs. */
155 #define CHECK_TIME (CCA_COUNT_MAX * (CCA_CHECK_TIME + CCA_SLEEP_TIME))
156 
157 /* CHECK_TIME_TX is the total time it takes to perform CCA_COUNT_MAX_TX
158  CCAs. */
159 #define CHECK_TIME_TX (CCA_COUNT_MAX_TX * (CCA_CHECK_TIME + CCA_SLEEP_TIME))
160 
161 /* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking
162  for activity after a potential packet has been detected by a CCA
163  check. */
164 #ifdef CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED
165 #define LISTEN_TIME_AFTER_PACKET_DETECTED CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED
166 #else
167 #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80
168 #endif
169 
170 /* MAX_SILENCE_PERIODS is the maximum amount of periods (a period is
171  CCA_CHECK_TIME + CCA_SLEEP_TIME) that we allow to be silent before
172  we turn of the radio. */
173 #ifdef CONTIKIMAC_CONF_MAX_SILENCE_PERIODS
174 #define MAX_SILENCE_PERIODS CONTIKIMAC_CONF_MAX_SILENCE_PERIODS
175 #else
176 #define MAX_SILENCE_PERIODS 5
177 #endif
178 
179 /* MAX_NONACTIVITY_PERIODS is the maximum number of periods we allow
180  the radio to be turned on without any packet being received, when
181  WITH_FAST_SLEEP is enabled. */
182 #ifdef CONTIKIMAC_CONF_MAX_NONACTIVITY_PERIODS
183 #define MAX_NONACTIVITY_PERIODS CONTIKIMAC_CONF_MAX_NONACTIVITY_PERIODS
184 #else
185 #define MAX_NONACTIVITY_PERIODS 10
186 #endif
187 
188 
189 
190 
191 /* STROBE_TIME is the maximum amount of time a transmitted packet
192  should be repeatedly transmitted as part of a transmission. */
193 #define STROBE_TIME (CYCLE_TIME + 2 * CHECK_TIME)
194 
195 /* GUARD_TIME is the time before the expected phase of a neighbor that
196  a transmitted should begin transmitting packets. */
197 #ifdef CONTIKIMAC_CONF_GUARD_TIME
198 #define GUARD_TIME CONTIKIMAC_CONF_GUARD_TIME
199 #else
200 #define GUARD_TIME 10 * CHECK_TIME + CHECK_TIME_TX
201 #endif
202 
203 /* INTER_PACKET_INTERVAL is the interval between two successive packet transmissions */
204 #ifdef CONTIKIMAC_CONF_INTER_PACKET_INTERVAL
205 #define INTER_PACKET_INTERVAL CONTIKIMAC_CONF_INTER_PACKET_INTERVAL
206 #else
207 #define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 2500
208 #endif
209 
210 /* AFTER_ACK_DETECTECT_WAIT_TIME is the time to wait after a potential
211  ACK packet has been detected until we can read it out from the
212  radio. */
213 #ifdef CONTIKIMAC_CONF_AFTER_ACK_DETECTECT_WAIT_TIME
214 #define AFTER_ACK_DETECTECT_WAIT_TIME CONTIKIMAC_CONF_AFTER_ACK_DETECTECT_WAIT_TIME
215 #else
216 #define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1500
217 #endif
218 
219 /* MAX_PHASE_STROBE_TIME is the time that we transmit repeated packets
220  to a neighbor for which we have a phase lock. */
221 #ifdef CONTIKIMAC_CONF_MAX_PHASE_STROBE_TIME
222 #define MAX_PHASE_STROBE_TIME CONTIKIMAC_CONF_MAX_PHASE_STROBE_TIME
223 #else
224 #define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60
225 #endif
226 
227 #ifdef CONTIKIMAC_CONF_SEND_SW_ACK
228 #define CONTIKIMAC_SEND_SW_ACK CONTIKIMAC_CONF_SEND_SW_ACK
229 #else
230 #define CONTIKIMAC_SEND_SW_ACK 0
231 #endif
232 
233 #define ACK_LEN 3
234 
235 #include <stdio.h>
236 static struct rtimer rt;
237 static struct pt pt;
238 
239 static volatile uint8_t contikimac_is_on = 0;
240 static volatile uint8_t contikimac_keep_radio_on = 0;
241 
242 static volatile unsigned char we_are_sending = 0;
243 static volatile unsigned char radio_is_on = 0;
244 
245 #define DEBUG 0
246 #if DEBUG
247 #include <stdio.h>
248 #define PRINTF(...) printf(__VA_ARGS__)
249 #define PRINTDEBUG(...) printf(__VA_ARGS__)
250 #else
251 #define PRINTF(...)
252 #define PRINTDEBUG(...)
253 #endif
254 
255 #if CONTIKIMAC_CONF_COMPOWER
256 static struct compower_activity current_packet;
257 #endif /* CONTIKIMAC_CONF_COMPOWER */
258 
259 #if WITH_PHASE_OPTIMIZATION
260 
261 #include "net/mac/phase.h"
262 
263 #endif /* WITH_PHASE_OPTIMIZATION */
264 
265 #define DEFAULT_STREAM_TIME (4 * CYCLE_TIME)
266 
267 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
268 static struct timer broadcast_rate_timer;
269 static int broadcast_rate_counter;
270 #endif /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */
271 
272 /*---------------------------------------------------------------------------*/
273 static void
274 on(void)
275 {
276  if(contikimac_is_on && radio_is_on == 0) {
277  radio_is_on = 1;
278  NETSTACK_RADIO.on();
279  }
280 }
281 /*---------------------------------------------------------------------------*/
282 static void
283 off(void)
284 {
285  if(contikimac_is_on && radio_is_on != 0 &&
286  contikimac_keep_radio_on == 0) {
287  radio_is_on = 0;
288  NETSTACK_RADIO.off();
289  }
290 }
291 /*---------------------------------------------------------------------------*/
292 static volatile rtimer_clock_t cycle_start;
293 static void powercycle_wrapper(struct rtimer *t, void *ptr);
294 static char powercycle(struct rtimer *t, void *ptr);
295 static void
296 schedule_powercycle(struct rtimer *t, rtimer_clock_t time)
297 {
298  int r;
299  rtimer_clock_t now;
300 
301  if(contikimac_is_on) {
302 
303  time += RTIMER_TIME(t);
304  now = RTIMER_NOW();
305  if(RTIMER_CLOCK_LT(time, now + RTIMER_GUARD_TIME)) {
306  time = now + RTIMER_GUARD_TIME;
307  }
308 
309  r = rtimer_set(t, time, 1, powercycle_wrapper, NULL);
310 
311  if(r != RTIMER_OK) {
312  PRINTF("schedule_powercycle: could not set rtimer\n");
313  }
314  }
315 }
316 /*---------------------------------------------------------------------------*/
317 static void
318 schedule_powercycle_fixed(struct rtimer *t, rtimer_clock_t fixed_time)
319 {
320  int r;
321  rtimer_clock_t now;
322 
323  if(contikimac_is_on) {
324 
325  now = RTIMER_NOW();
326  if(RTIMER_CLOCK_LT(fixed_time, now + RTIMER_GUARD_TIME)) {
327  fixed_time = now + RTIMER_GUARD_TIME;
328  }
329 
330  r = rtimer_set(t, fixed_time, 1, powercycle_wrapper, NULL);
331  if(r != RTIMER_OK) {
332  PRINTF("schedule_powercycle: could not set rtimer\n");
333  }
334  }
335 }
336 /*---------------------------------------------------------------------------*/
337 static void
338 powercycle_turn_radio_off(void)
339 {
340 #if CONTIKIMAC_CONF_COMPOWER
341  uint8_t was_on = radio_is_on;
342 #endif /* CONTIKIMAC_CONF_COMPOWER */
343 
344  if(we_are_sending == 0 && we_are_receiving_burst == 0) {
345  off();
346 #if CONTIKIMAC_CONF_COMPOWER
347  if(was_on && !radio_is_on) {
349  }
350 #endif /* CONTIKIMAC_CONF_COMPOWER */
351  }
352 }
353 /*---------------------------------------------------------------------------*/
354 static void
355 powercycle_turn_radio_on(void)
356 {
357  if(we_are_sending == 0 && we_are_receiving_burst == 0) {
358  on();
359  }
360 }
361 /*---------------------------------------------------------------------------*/
362 static void
363 powercycle_wrapper(struct rtimer *t, void *ptr)
364 {
365  powercycle(t, ptr);
366 }
367 /*---------------------------------------------------------------------------*/
368 static char
369 powercycle(struct rtimer *t, void *ptr)
370 {
371 #if SYNC_CYCLE_STARTS
372  static volatile rtimer_clock_t sync_cycle_start;
373  static volatile uint8_t sync_cycle_phase;
374 #endif
375 
376  PT_BEGIN(&pt);
377 
378 #if SYNC_CYCLE_STARTS
379  sync_cycle_start = RTIMER_NOW();
380 #else
381  cycle_start = RTIMER_NOW();
382 #endif
383 
384  while(1) {
385  static uint8_t packet_seen;
386  static uint8_t count;
387 
388 #if SYNC_CYCLE_STARTS
389  /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple
390  of CHANNEL_CHECK_RATE */
391  if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) {
392  sync_cycle_phase = 0;
393  sync_cycle_start += RTIMER_ARCH_SECOND;
394  cycle_start = sync_cycle_start;
395  } else {
396 #if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535
397  cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE;
398 #else
399  cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE;
400 #endif
401  }
402 #else
403  cycle_start += CYCLE_TIME;
404 #endif
405 
406  packet_seen = 0;
407 
408  for(count = 0; count < CCA_COUNT_MAX; ++count) {
409  if(we_are_sending == 0 && we_are_receiving_burst == 0) {
410  powercycle_turn_radio_on();
411  /* Check if a packet is seen in the air. If so, we keep the
412  radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to
413  be able to receive the packet. We also continuously check
414  the radio medium to make sure that we wasn't woken up by a
415  false positive: a spurious radio interference that was not
416  caused by an incoming packet. */
417  if(NETSTACK_RADIO.channel_clear() == 0) {
418  packet_seen = 1;
419  break;
420  }
421  powercycle_turn_radio_off();
422  }
423 
424  // If this is the last CCA check, avoid yielding and go straight to scheduling
425  // our next cycle
426  if (count == CCA_COUNT_MAX - 1) {
427  break;
428  }
429 
430  schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME);
431  PT_YIELD(&pt);
432  }
433 
434  if(packet_seen) {
435  static rtimer_clock_t start;
436  static uint8_t silence_periods, periods;
437  start = RTIMER_NOW();
438 
439  periods = silence_periods = 0;
440  while(we_are_sending == 0 && radio_is_on &&
441  RTIMER_CLOCK_LT(RTIMER_NOW(),
442  (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
443 
444  /* Check for a number of consecutive periods of
445  non-activity. If we see two such periods, we turn the
446  radio off. Also, if a packet has been successfully
447  received (as indicated by the
448  NETSTACK_RADIO.pending_packet() function), we stop
449  snooping. */
450 //#if !RDC_CONF_HARDWARE_CSMA
451  /* A cca cycle will disrupt rx on some radios, e.g. mc1322x, rf230 */
452  /*TODO: Modify those drivers to just return the internal RSSI when already in rx mode */
453  if(NETSTACK_RADIO.channel_clear()) {
454  ++silence_periods;
455  } else {
456  silence_periods = 0;
457  }
458 //#endif
459 
460  ++periods;
461 
462  if(NETSTACK_RADIO.receiving_packet()) {
463  silence_periods = 0;
464  }
465  if(silence_periods > MAX_SILENCE_PERIODS) {
466  powercycle_turn_radio_off();
467  break;
468  }
469  if(WITH_FAST_SLEEP &&
470  periods > MAX_NONACTIVITY_PERIODS &&
471  !(NETSTACK_RADIO.receiving_packet() ||
472  NETSTACK_RADIO.pending_packet())) {
473  powercycle_turn_radio_off();
474  break;
475  }
476  if(NETSTACK_RADIO.pending_packet()) {
477  break;
478  }
479 
480  schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME);
481  PT_YIELD(&pt);
482  }
483  if(radio_is_on) {
484  if(!(NETSTACK_RADIO.receiving_packet() ||
485  NETSTACK_RADIO.pending_packet()) ||
486  !RTIMER_CLOCK_LT(RTIMER_NOW(),
487  (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
488  powercycle_turn_radio_off();
489  }
490  }
491  }
492 
493  if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) {
494  /* Schedule the next powercycle interrupt, or sleep the mcu
495  until then. Sleeping will not exit from this interrupt, so
496  ensure an occasional wake cycle or foreground processing will
497  be blocked until a packet is detected */
498 #if RDC_CONF_MCU_SLEEP
499  static uint8_t sleepcycle;
500  if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) {
501  rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start));
502  } else {
503  sleepcycle = 0;
504  schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
505  PT_YIELD(&pt);
506  }
507 #else
508  schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
509  PT_YIELD(&pt);
510 #endif
511  }
512  }
513 
514  PT_END(&pt);
515 }
516 /*---------------------------------------------------------------------------*/
517 static int
518 broadcast_rate_drop(void)
519 {
520 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
521  if(!timer_expired(&broadcast_rate_timer)) {
522  broadcast_rate_counter++;
523  if(broadcast_rate_counter < CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT) {
524  return 0;
525  } else {
526  return 1;
527  }
528  } else {
529  timer_set(&broadcast_rate_timer, CLOCK_SECOND);
530  broadcast_rate_counter = 0;
531  return 0;
532  }
533 #else /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */
534  return 0;
535 #endif /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */
536 }
537 /*---------------------------------------------------------------------------*/
538 static int
539 send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
540  struct rdc_buf_list *buf_list,
541  int is_receiver_awake)
542 {
543  rtimer_clock_t t0;
544 #if WITH_PHASE_OPTIMIZATION
545  rtimer_clock_t encounter_time = 0;
546 #endif
547  int strobes;
548  uint8_t got_strobe_ack = 0;
549  uint8_t is_broadcast = 0;
550  uint8_t is_known_receiver = 0;
551  uint8_t collisions;
552  int transmit_len;
553  int ret;
554  uint8_t contikimac_was_on;
555 #if !RDC_CONF_HARDWARE_ACK
556  int len;
557  uint8_t seqno;
558 #endif
559 
560  /* Exit if RDC and radio were explicitly turned off */
561  if(!contikimac_is_on && !contikimac_keep_radio_on) {
562  PRINTF("contikimac: radio is turned off\n");
563  return MAC_TX_ERR_FATAL;
564  }
565 
566  if(packetbuf_totlen() == 0) {
567  PRINTF("contikimac: send_packet data len 0\n");
568  return MAC_TX_ERR_FATAL;
569  }
570 
571 #if !NETSTACK_CONF_BRIDGE_MODE
572  /* If NETSTACK_CONF_BRIDGE_MODE is set, assume PACKETBUF_ADDR_SENDER is already set. */
573  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
574 #endif
576  is_broadcast = 1;
577  PRINTDEBUG("contikimac: send broadcast\n");
578 
579  if(broadcast_rate_drop()) {
580  return MAC_TX_COLLISION;
581  }
582  } else {
583 #if NETSTACK_CONF_WITH_IPV6
584  PRINTDEBUG("contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
585  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
586  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1],
587  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2],
588  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3],
589  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4],
590  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5],
591  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6],
592  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]);
593 #else /* NETSTACK_CONF_WITH_IPV6 */
594  PRINTDEBUG("contikimac: send unicast to %u.%u\n",
595  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
596  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]);
597 #endif /* NETSTACK_CONF_WITH_IPV6 */
598  }
599 
600  if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) {
601  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
602  if(NETSTACK_FRAMER.create() < 0) {
603  PRINTF("contikimac: framer failed\n");
604  return MAC_TX_ERR_FATAL;
605  }
606  }
607 
608  transmit_len = packetbuf_totlen();
609  NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len);
610 
611  if(!is_broadcast && !is_receiver_awake) {
612 #if WITH_PHASE_OPTIMIZATION
613  ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
614  CYCLE_TIME, GUARD_TIME,
615  mac_callback, mac_callback_ptr, buf_list);
616  if(ret == PHASE_DEFERRED) {
617  return MAC_TX_DEFERRED;
618  }
619  if(ret != PHASE_UNKNOWN) {
620  is_known_receiver = 1;
621  }
622 #endif /* WITH_PHASE_OPTIMIZATION */
623  }
624 
625 
626 
627  /* By setting we_are_sending to one, we ensure that the rtimer
628  powercycle interrupt do not interfere with us sending the packet. */
629  we_are_sending = 1;
630 
631  /* If we have a pending packet in the radio, we should not send now,
632  because we will trash the received packet. Instead, we signal
633  that we have a collision, which lets the packet be received. This
634  packet will be retransmitted later by the MAC protocol
635  instread. */
636  if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) {
637  we_are_sending = 0;
638  PRINTF("contikimac: collision receiving %d, pending %d\n",
639  NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet());
640  return MAC_TX_COLLISION;
641  }
642 
643  /* Switch off the radio to ensure that we didn't start sending while
644  the radio was doing a channel check. */
645  off();
646 
647 
648  strobes = 0;
649 
650  /* Send a train of strobes until the receiver answers with an ACK. */
651  collisions = 0;
652 
653  got_strobe_ack = 0;
654 
655  /* Set contikimac_is_on to one to allow the on() and off() functions
656  to control the radio. We restore the old value of
657  contikimac_is_on when we are done. */
658  contikimac_was_on = contikimac_is_on;
659  contikimac_is_on = 1;
660 
661 #if !RDC_CONF_HARDWARE_CSMA
662  /* Check if there are any transmissions by others. */
663  /* TODO: why does this give collisions before sending with the mc1322x? */
664  if(is_receiver_awake == 0) {
665  int i;
666  for(i = 0; i < CCA_COUNT_MAX_TX; ++i) {
667  t0 = RTIMER_NOW();
668  on();
669 #if CCA_CHECK_TIME > 0
670  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { }
671 #endif
672  if(NETSTACK_RADIO.channel_clear() == 0) {
673  collisions++;
674  off();
675  break;
676  }
677  off();
678  t0 = RTIMER_NOW();
679  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { }
680  }
681  }
682 
683  if(collisions > 0) {
684  we_are_sending = 0;
685  off();
686  PRINTF("contikimac: collisions before sending\n");
687  contikimac_is_on = contikimac_was_on;
688  return MAC_TX_COLLISION;
689  }
690 #endif /* RDC_CONF_HARDWARE_CSMA */
691 
692 #if !RDC_CONF_HARDWARE_ACK
693  if(!is_broadcast) {
694  /* Turn radio on to receive expected unicast ack. Not necessary
695  with hardware ack detection, and may trigger an unnecessary cca
696  or rx cycle */
697  on();
698  }
699  seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
700 #endif
701 
703  t0 = RTIMER_NOW();
704  for(strobes = 0, collisions = 0;
705  got_strobe_ack == 0 && collisions == 0 &&
706  RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) {
707 
709 
710  if(!is_broadcast && (is_receiver_awake || is_known_receiver) &&
711  !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) {
712  PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]);
713  break;
714  }
715 
716 #if !RDC_CONF_HARDWARE_ACK
717  len = 0;
718 #endif
719 
720  {
721  rtimer_clock_t wt;
722 #if WITH_PHASE_OPTIMIZATION
723  rtimer_clock_t txtime = RTIMER_NOW();
724 #endif
725 #if RDC_CONF_HARDWARE_ACK
726  int ret = NETSTACK_RADIO.transmit(transmit_len);
727 #else
728  NETSTACK_RADIO.transmit(transmit_len);
729 #endif
730 
731 #if RDC_CONF_HARDWARE_ACK
732  /* For radios that block in the transmit routine and detect the
733  ACK in hardware */
734  if(ret == RADIO_TX_OK) {
735  if(!is_broadcast) {
736  got_strobe_ack = 1;
737 #if WITH_PHASE_OPTIMIZATION
738  encounter_time = txtime;
739 #endif
740  break;
741  }
742  } else if (ret == RADIO_TX_NOACK) {
743  } else if (ret == RADIO_TX_COLLISION) {
744  PRINTF("contikimac: collisions while sending\n");
745  collisions++;
746  }
747  wt = RTIMER_NOW();
748  while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }
749 #else /* RDC_CONF_HARDWARE_ACK */
750  /* Wait for the ACK packet */
751  wt = RTIMER_NOW();
752  while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }
753 
754  if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() ||
755  NETSTACK_RADIO.pending_packet() ||
756  NETSTACK_RADIO.channel_clear() == 0)) {
757  uint8_t ackbuf[ACK_LEN];
758  wt = RTIMER_NOW();
759  while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { }
760 
761  len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
762  if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) {
763  got_strobe_ack = 1;
764 #if WITH_PHASE_OPTIMIZATION
765  encounter_time = txtime;
766 #endif
767  break;
768  } else {
769  PRINTF("contikimac: collisions while sending\n");
770  collisions++;
771  }
772  }
773 #endif /* RDC_CONF_HARDWARE_ACK */
774  }
775  }
776 
777  off();
778 
779  PRINTF("contikimac: send (strobes=%u, len=%u, %s, %s), done\n", strobes,
781  got_strobe_ack ? "ack" : "no ack",
782  collisions ? "collision" : "no collision");
783 
784 #if CONTIKIMAC_CONF_COMPOWER
785  /* Accumulate the power consumption for the packet transmission. */
786  compower_accumulate(&current_packet);
787 
788  /* Convert the accumulated power consumption for the transmitted
789  packet to packet attributes so that the higher levels can keep
790  track of the amount of energy spent on transmitting the
791  packet. */
792  compower_attrconv(&current_packet);
793 
794  /* Clear the accumulated power consumption so that it is ready for
795  the next packet. */
796  compower_clear(&current_packet);
797 #endif /* CONTIKIMAC_CONF_COMPOWER */
798 
799  contikimac_is_on = contikimac_was_on;
800  we_are_sending = 0;
801 
802  /* Determine the return value that we will return from the
803  function. We must pass this value to the phase module before we
804  return from the function. */
805  if(collisions > 0) {
806  ret = MAC_TX_COLLISION;
807  } else if(!is_broadcast && !got_strobe_ack) {
808  ret = MAC_TX_NOACK;
809  } else {
810  ret = MAC_TX_OK;
811  }
812 
813 #if WITH_PHASE_OPTIMIZATION
814  if(is_known_receiver && got_strobe_ack) {
815  PRINTF("no miss %d wake-ups %d\n",
816  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
817  strobes);
818  }
819 
820  if(!is_broadcast) {
821  if(collisions == 0 && is_receiver_awake == 0) {
822  phase_update(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
823  encounter_time, ret);
824  }
825  }
826 #endif /* WITH_PHASE_OPTIMIZATION */
827 
828  return ret;
829 }
830 /*---------------------------------------------------------------------------*/
831 static void
832 qsend_packet(mac_callback_t sent, void *ptr)
833 {
834  int ret = send_packet(sent, ptr, NULL, 0);
835  if(ret != MAC_TX_DEFERRED) {
836  mac_call_sent_callback(sent, ptr, ret, 1);
837  }
838 }
839 /*---------------------------------------------------------------------------*/
840 static void
841 qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list)
842 {
843  struct rdc_buf_list *curr;
844  struct rdc_buf_list *next;
845  int ret;
846  int is_receiver_awake;
847  int pending;
848 
849  if(buf_list == NULL) {
850  return;
851  }
852  /* Do not send during reception of a burst */
853  if(we_are_receiving_burst) {
854  /* Prepare the packetbuf for callback */
855  queuebuf_to_packetbuf(buf_list->buf);
856  /* Return COLLISION so the MAC may try again later */
857  mac_call_sent_callback(sent, ptr, MAC_TX_COLLISION, 1);
858  return;
859  }
860 
861  /* Create and secure frames in advance */
862  curr = buf_list;
863  do {
864  next = list_item_next(curr);
865  queuebuf_to_packetbuf(curr->buf);
866  if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) {
867  /* create and secure this frame */
868  if(next != NULL) {
869  packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1);
870  }
871  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
872  if(NETSTACK_FRAMER.create() < 0) {
873  PRINTF("contikimac: framer failed\n");
874  mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
875  return;
876  }
877 
878  packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1);
879  queuebuf_update_from_packetbuf(curr->buf);
880  }
881  curr = next;
882  } while(next != NULL);
883 
884  /* The receiver needs to be awoken before we send */
885  is_receiver_awake = 0;
886  curr = buf_list;
887  do { /* A loop sending a burst of packets from buf_list */
888  next = list_item_next(curr);
889 
890  /* Prepare the packetbuf */
891  queuebuf_to_packetbuf(curr->buf);
892 
893  pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
894 
895  /* Send the current packet */
896  ret = send_packet(sent, ptr, curr, is_receiver_awake);
897  if(ret != MAC_TX_DEFERRED) {
898  mac_call_sent_callback(sent, ptr, ret, 1);
899  }
900 
901  if(ret == MAC_TX_OK) {
902  if(next != NULL) {
903  /* We're in a burst, no need to wake the receiver up again */
904  is_receiver_awake = 1;
905  curr = next;
906  }
907  } else {
908  /* The transmission failed, we stop the burst */
909  next = NULL;
910  }
911  } while((next != NULL) && pending);
912 }
913 /*---------------------------------------------------------------------------*/
914 /* Timer callback triggered when receiving a burst, after having
915  waited for a next packet for a too long time. Turns the radio off
916  and leaves burst reception mode */
917 static void
918 recv_burst_off(void *ptr)
919 {
920  off();
921  we_are_receiving_burst = 0;
922 }
923 /*---------------------------------------------------------------------------*/
924 static void
925 input_packet(void)
926 {
927  static struct ctimer ct;
928  int duplicate = 0;
929 
930 #if CONTIKIMAC_SEND_SW_ACK
931  int original_datalen;
932  uint8_t *original_dataptr;
933 
934  original_datalen = packetbuf_datalen();
935  original_dataptr = packetbuf_dataptr();
936 #endif
937 
938  if(!we_are_receiving_burst) {
939  off();
940  }
941 
942  if(packetbuf_datalen() == ACK_LEN) {
943  /* Ignore ack packets */
944  PRINTF("ContikiMAC: ignored ack\n");
945  return;
946  }
947 
948  /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/
949 
950  if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) {
951  if(packetbuf_datalen() > 0 &&
952  packetbuf_totlen() > 0 &&
953  (linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
954  &linkaddr_node_addr) ||
956  /* This is a regular packet that is destined to us or to the
957  broadcast address. */
958 
959  /* If FRAME_PENDING is set, we are receiving a packets in a burst */
960  we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING);
961  if(we_are_receiving_burst) {
962  on();
963  /* Set a timer to turn the radio off in case we do not receive
964  a next packet */
965  ctimer_set(&ct, INTER_PACKET_DEADLINE, recv_burst_off, NULL);
966  } else {
967  off();
968  ctimer_stop(&ct);
969  }
970 
971 #if RDC_WITH_DUPLICATE_DETECTION
972  /* Check for duplicate packet. */
973  duplicate = mac_sequence_is_duplicate();
974  if(duplicate) {
975  /* Drop the packet. */
976  PRINTF("contikimac: Drop duplicate\n");
977  } else {
979  }
980 #endif /* RDC_WITH_DUPLICATE_DETECTION */
981 
982 #if CONTIKIMAC_CONF_COMPOWER
983  /* Accumulate the power consumption for the packet reception. */
984  compower_accumulate(&current_packet);
985  /* Convert the accumulated power consumption for the received
986  packet to packet attributes so that the higher levels can
987  keep track of the amount of energy spent on receiving the
988  packet. */
989  compower_attrconv(&current_packet);
990 
991  /* Clear the accumulated power consumption so that it is ready
992  for the next packet. */
993  compower_clear(&current_packet);
994 #endif /* CONTIKIMAC_CONF_COMPOWER */
995 
996  PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen());
997 
998 #if CONTIKIMAC_SEND_SW_ACK
999  {
1000  frame802154_t info154;
1001  frame802154_parse(original_dataptr, original_datalen, &info154);
1002  if(info154.fcf.frame_type == FRAME802154_DATAFRAME &&
1003  info154.fcf.ack_required != 0 &&
1004  linkaddr_cmp((linkaddr_t *)&info154.dest_addr,
1005  &linkaddr_node_addr)) {
1006  uint8_t ackdata[ACK_LEN] = {0, 0, 0};
1007 
1008  we_are_sending = 1;
1009  ackdata[0] = FRAME802154_ACKFRAME;
1010  ackdata[1] = 0;
1011  ackdata[2] = info154.seq;
1012  NETSTACK_RADIO.send(ackdata, ACK_LEN);
1013  we_are_sending = 0;
1014  }
1015  }
1016 #endif /* CONTIKIMAC_SEND_SW_ACK */
1017 
1018  if(!duplicate) {
1019  NETSTACK_MAC.input();
1020  }
1021  return;
1022  } else {
1023  PRINTDEBUG("contikimac: data not for us\n");
1024  }
1025  } else {
1026  PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen());
1027  }
1028 }
1029 /*---------------------------------------------------------------------------*/
1030 static void
1031 init(void)
1032 {
1033  radio_is_on = 0;
1034  PT_INIT(&pt);
1035 
1036  rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, powercycle_wrapper, NULL);
1037 
1038  contikimac_is_on = 1;
1039 
1040 #if WITH_PHASE_OPTIMIZATION
1041  phase_init();
1042 #endif /* WITH_PHASE_OPTIMIZATION */
1043 
1044 }
1045 /*---------------------------------------------------------------------------*/
1046 static int
1047 turn_on(void)
1048 {
1049  if(contikimac_is_on == 0) {
1050  contikimac_is_on = 1;
1051  contikimac_keep_radio_on = 0;
1052  rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, powercycle_wrapper, NULL);
1053  }
1054  return 1;
1055 }
1056 /*---------------------------------------------------------------------------*/
1057 static int
1058 turn_off(int keep_radio_on)
1059 {
1060  contikimac_is_on = 0;
1061  contikimac_keep_radio_on = keep_radio_on;
1062  if(keep_radio_on) {
1063  radio_is_on = 1;
1064  return NETSTACK_RADIO.on();
1065  } else {
1066  radio_is_on = 0;
1067  return NETSTACK_RADIO.off();
1068  }
1069 }
1070 /*---------------------------------------------------------------------------*/
1071 static unsigned short
1072 duty_cycle(void)
1073 {
1074  return (1ul * CLOCK_SECOND * CYCLE_TIME) / RTIMER_ARCH_SECOND;
1075 }
1076 /*---------------------------------------------------------------------------*/
1077 const struct rdc_driver contikimac_driver = {
1078  "ContikiMAC",
1079  init,
1080  qsend_packet,
1081  qsend_list,
1082  input_packet,
1083  turn_on,
1084  turn_off,
1085  duty_cycle,
1086 };
1087 /*---------------------------------------------------------------------------*/
1088 uint16_t
1089 contikimac_debug_print(void)
1090 {
1091  return 0;
1092 }
1093 /*---------------------------------------------------------------------------*/
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:158
Header file for the real-time timer module.
void mac_sequence_register_seqno(void)
Register the sequence number of the packetbuf.
Definition: mac-sequence.c:88
Protothreads implementation.
uint8_t dest_addr[8]
Destination address.
Definition: frame802154.h:196
#define PT_INIT(pt)
Initialize a protothread.
Definition: pt.h:79
The MAC layer deferred the transmission for a later time.
Definition: mac.h:86
static void start(void)
Start measurement.
The MAC layer did not get an acknowledgement for the packet.
Definition: mac.h:83
Header file for the radio API
frame802154_fcf_t fcf
Frame control field.
Definition: frame802154.h:198
void compower_attrconv(struct compower_activity *e)
Convert power contumption information to packet attributes.
Definition: compower.c:83
void compower_clear(struct compower_activity *e)
Clear power consumption information for a communication activity.
Definition: compower.c:77
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
Definition: timer.c:64
#define PT_YIELD(pt)
Yield from the current protothread.
Definition: pt.h:289
uint8_t seq
Sequence number.
Definition: frame802154.h:199
void * list_item_next(void *item)
Get the next item following this item.
Definition: list.c:325
An activity record that contains power consumption information for a specific communication activity...
Definition: compower.h:64
A timer.
Definition: timer.h:86
Header file for the communication power accounting module
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Definition: packetbuf.c:182
void compower_accumulate(struct compower_activity *e)
Accumulate power contumption for a communication activity.
Definition: compower.c:60
Header file for MAC sequence numbers management
int packetbuf_holds_broadcast(void)
Checks whether the current packet is a broadcast.
Definition: packetbuf.c:242
int mac_sequence_is_duplicate(void)
Tell whether the packetbuf is a duplicate packet.
Definition: mac-sequence.c:66
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Definition: packetbuf.c:164
struct compower_activity compower_idle_activity
The default idle communication activity.
Definition: compower.c:50
Header file for the ContikiMAC radio duty cycling protocol
The MAC layer transmission could not be performed because of an error.
Definition: mac.h:89
void(* init)(void)
Initialize the RDC driver.
Definition: rdc.h:72
Header file for the Rime stack
The MAC layer transmission was OK.
Definition: mac.h:79
#define NULL
The null pointer.
uint8_t frame_type
3 bit.
Definition: frame802154.h:147
int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr)
Post a real-time task.
Definition: rtimer.c:67
#define PT_BEGIN(pt)
Declare the start of a protothread inside the C function implementing the protothread.
Definition: pt.h:114
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:64
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
Definition: frame802154.c:465
static volatile clock_time_t count
These routines define the AVR-specific calls declared in /core/sys/clock.h CLOCK_SECOND is the number...
Definition: clock.c:80
The structure of a RDC (radio duty cycling) driver in Contiki.
Definition: rdc.h:68
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition: ctimer.c:99
uint8_t ack_required
1 bit.
Definition: frame802154.h:150
#define PT_END(pt)
Declare the end of a protothread.
Definition: pt.h:126
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition: packetbuf.c:170
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition: ctimer.c:149
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
Definition: linkaddr.c:66
linkaddr_t linkaddr_node_addr
The Rime address of the node.
Definition: linkaddr.c:48
Representation of a real-time task.
Definition: rtimer.h:86
Common functionality for phase optimization in duty cycling radio protocols
#define RTIMER_TIME(task)
Get the time that a task last was executed.
Definition: rtimer.h:148
Parameters used by the frame802154_create() function.
Definition: frame802154.h:192
Include file for the Contiki low-layer network stack (NETSTACK)
int timer_expired(struct timer *t)
Check if a timer has expired.
Definition: timer.c:122