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