Contiki 2.5
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  * $Id: contikimac.c,v 1.48 2011/01/25 14:29:46 adamdunkels Exp $
32  */
33 
34 /**
35  * \file
36  * Implementation of the ContikiMAC power-saving radio duty cycling protocol
37  * \author
38  * Adam Dunkels <adam@sics.se>
39  * Niclas Finne <nfi@sics.se>
40  * Joakim Eriksson <joakime@sics.se>
41  */
42 
43 #include "contiki-conf.h"
44 #include "dev/leds.h"
45 #include "dev/radio.h"
46 #include "dev/watchdog.h"
47 #include "lib/random.h"
48 #include "net/mac/contikimac.h"
49 #include "net/netstack.h"
50 #include "net/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 #ifndef WITH_PHASE_OPTIMIZATION
59 #define WITH_PHASE_OPTIMIZATION 1
60 #endif
61 #ifndef WITH_STREAMING
62 #define WITH_STREAMING 0
63 #endif
64 #ifdef CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
65 #define WITH_CONTIKIMAC_HEADER CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
66 #else
67 #define WITH_CONTIKIMAC_HEADER 1
68 #endif
69 #ifndef WITH_FAST_SLEEP
70 #define WITH_FAST_SLEEP 1
71 #endif
72 
73 #if NETSTACK_RDC_CHANNEL_CHECK_RATE >= 64
74 #undef WITH_PHASE_OPTIMIZATION
75 #define WITH_PHASE_OPTIMIZATION 0
76 #endif
77 
78 #if WITH_CONTIKIMAC_HEADER
79 #define CONTIKIMAC_ID 0x00
80 
81 struct hdr {
82  uint8_t id;
83  uint8_t len;
84 };
85 #endif /* WITH_CONTIKIMAC_HEADER */
86 
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 
94 /* ContikiMAC performs periodic channel checks. Each channel check
95  consists of two or more CCA checks. CCA_COUNT_MAX is the number of
96  CCAs to be done for each periodic channel check. The default is
97  two.*/
98 #define CCA_COUNT_MAX 2
99 
100 /* CCA_CHECK_TIME is the time it takes to perform a CCA check. */
101 #define CCA_CHECK_TIME RTIMER_ARCH_SECOND / 8192
102 
103 /* CCA_SLEEP_TIME is the time between two successive CCA checks. */
104 #define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000
105 
106 /* CHECK_TIME is the total time it takes to perform CCA_COUNT_MAX
107  CCAs. */
108 #define CHECK_TIME (CCA_COUNT_MAX * (CCA_CHECK_TIME + CCA_SLEEP_TIME))
109 
110 /* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking
111  for activity after a potential packet has been detected by a CCA
112  check. */
113 #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80
114 
115 /* MAX_SILENCE_PERIODS is the maximum amount of periods (a period is
116  CCA_CHECK_TIME + CCA_SLEEP_TIME) that we allow to be silent before
117  we turn of the radio. */
118 #define MAX_SILENCE_PERIODS 5
119 
120 /* MAX_NONACTIVITY_PERIODS is the maximum number of periods we allow
121  the radio to be turned on without any packet being received, when
122  WITH_FAST_SLEEP is enabled. */
123 #define MAX_NONACTIVITY_PERIODS 10
124 
125 
126 
127 /* STROBE_TIME is the maximum amount of time a transmitted packet
128  should be repeatedly transmitted as part of a transmission. */
129 #define STROBE_TIME (CYCLE_TIME + 2 * CHECK_TIME)
130 
131 /* GUARD_TIME is the time before the expected phase of a neighbor that
132  a transmitted should begin transmitting packets. */
133 #define GUARD_TIME 11 * CHECK_TIME
134 
135 /* INTER_PACKET_INTERVAL is the interval between two successive packet transmissions */
136 #define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000
137 
138 /* AFTER_ACK_DETECTECT_WAIT_TIME is the time to wait after a potential
139  ACK packet has been detected until we can read it out from the
140  radio. */
141 #define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1500
142 
143 /* MAX_PHASE_STROBE_TIME is the time that we transmit repeated packets
144  to a neighbor for which we have a phase lock. */
145 #define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60
146 
147 
148 /* SHORTEST_PACKET_SIZE is the shortest packet that ContikiMAC
149  allows. Packets have to be a certain size to be able to be detected
150  by two consecutive CCA checks, and here is where we define this
151  shortest size. */
152 #define SHORTEST_PACKET_SIZE 43
153 
154 
155 #define ACK_LEN 3
156 
157 #include <stdio.h>
158 static struct rtimer rt;
159 static struct pt pt;
160 
161 static volatile uint8_t contikimac_is_on = 0;
162 static volatile uint8_t contikimac_keep_radio_on = 0;
163 
164 static volatile unsigned char we_are_sending = 0;
165 static volatile unsigned char radio_is_on = 0;
166 
167 #define DEBUG 1
168 #if DEBUG
169 #include <stdio.h>
170 #define PRINTF(...) printf(__VA_ARGS__)
171 #define PRINTDEBUG(...) printf(__VA_ARGS__)
172 #else
173 #define PRINTF(...)
174 #define PRINTDEBUG(...)
175 #endif
176 
177 /* Flag that is used to keep track of whether or not we are snooping
178  for announcements from neighbors. */
179 static volatile uint8_t is_snooping;
180 
181 #if CONTIKIMAC_CONF_COMPOWER
182 static struct compower_activity current_packet;
183 #endif /* CONTIKIMAC_CONF_COMPOWER */
184 
185 #if WITH_PHASE_OPTIMIZATION
186 
187 #include "net/mac/phase.h"
188 
189 #ifdef CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
190 #define MAX_PHASE_NEIGHBORS CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
191 #endif
192 
193 #ifndef MAX_PHASE_NEIGHBORS
194 #define MAX_PHASE_NEIGHBORS 30
195 #endif
196 
197 PHASE_LIST(phase_list, MAX_PHASE_NEIGHBORS);
198 
199 #endif /* WITH_PHASE_OPTIMIZATION */
200 
201 static volatile uint8_t is_streaming;
202 static rimeaddr_t is_streaming_to, is_streaming_to_too;
203 static volatile rtimer_clock_t stream_until;
204 
205 #define DEFAULT_STREAM_TIME (4 * CYCLE_TIME)
206 
207 #ifndef MIN
208 #define MIN(a, b) ((a) < (b)? (a) : (b))
209 #endif /* MIN */
210 
211 struct seqno {
212  rimeaddr_t sender;
213  uint8_t seqno;
214 };
215 
216 #ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY
217 #define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY
218 #else /* NETSTACK_CONF_MAC_SEQNO_HISTORY */
219 #define MAX_SEQNOS 16
220 #endif /* NETSTACK_CONF_MAC_SEQNO_HISTORY */
221 static struct seqno received_seqnos[MAX_SEQNOS];
222 
223 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
224 static struct timer broadcast_rate_timer;
225 static int broadcast_rate_counter;
226 #endif /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */
227 
228 /*---------------------------------------------------------------------------*/
229 static void
230 on(void)
231 {
232  if(contikimac_is_on && radio_is_on == 0) {
233  radio_is_on = 1;
234  NETSTACK_RADIO.on();
235  }
236 }
237 /*---------------------------------------------------------------------------*/
238 static void
239 off(void)
240 {
241  if(contikimac_is_on && radio_is_on != 0 && /*is_streaming == 0 &&*/
242  contikimac_keep_radio_on == 0) {
243  radio_is_on = 0;
244  NETSTACK_RADIO.off();
245  }
246 }
247 /*---------------------------------------------------------------------------*/
248 static volatile rtimer_clock_t cycle_start;
249 static char powercycle(struct rtimer *t, void *ptr);
250 static void
251 schedule_powercycle(struct rtimer *t, rtimer_clock_t time)
252 {
253  int r;
254 
255  if(contikimac_is_on) {
256 
257  if(RTIMER_CLOCK_LT(RTIMER_TIME(t) + time, RTIMER_NOW() + 2)) {
258  time = RTIMER_NOW() - RTIMER_TIME(t) + 2;
259  }
260 
261  r = rtimer_set(t, RTIMER_TIME(t) + time, 1,
262  (void (*)(struct rtimer *, void *))powercycle, NULL);
263  if(r != RTIMER_OK) {
264  printf("schedule_powercycle: could not set rtimer\n");
265  }
266  }
267 }
268 /*---------------------------------------------------------------------------*/
269 static void
270 schedule_powercycle_fixed(struct rtimer *t, rtimer_clock_t fixed_time)
271 {
272  int r;
273 
274  if(contikimac_is_on) {
275 
276  if(RTIMER_CLOCK_LT(fixed_time, RTIMER_NOW() + 1)) {
277  fixed_time = RTIMER_NOW() + 1;
278  }
279 
280  r = rtimer_set(t, fixed_time, 1,
281  (void (*)(struct rtimer *, void *))powercycle, NULL);
282  if(r != RTIMER_OK) {
283  printf("schedule_powercycle: could not set rtimer\n");
284  }
285  }
286 }
287 /*---------------------------------------------------------------------------*/
288 static void
289 powercycle_turn_radio_off(void)
290 {
291 #if CONTIKIMAC_CONF_COMPOWER
292  uint8_t was_on = radio_is_on;
293 #endif /* CONTIKIMAC_CONF_COMPOWER */
294 
295  if(we_are_sending == 0) {
296  off();
297 #if CONTIKIMAC_CONF_COMPOWER
298  if(was_on && !radio_is_on) {
300  }
301 #endif /* CONTIKIMAC_CONF_COMPOWER */
302  }
303 }
304 /*---------------------------------------------------------------------------*/
305 static void
306 powercycle_turn_radio_on(void)
307 {
308  if(we_are_sending == 0) {
309  on();
310  }
311 }
312 /*---------------------------------------------------------------------------*/
313 static char
314 powercycle(struct rtimer *t, void *ptr)
315 {
316  PT_BEGIN(&pt);
317 
318  cycle_start = RTIMER_NOW();
319 
320  while(1) {
321  static uint8_t packet_seen;
322  static rtimer_clock_t t0;
323  static uint8_t count;
324 
325  cycle_start += CYCLE_TIME;
326 
327  if(WITH_STREAMING && is_streaming) {
328  if(!RTIMER_CLOCK_LT(RTIMER_NOW(), stream_until)) {
329  is_streaming = 0;
330  rimeaddr_copy(&is_streaming_to, &rimeaddr_null);
331  rimeaddr_copy(&is_streaming_to_too, &rimeaddr_null);
332  }
333  }
334 
335  packet_seen = 0;
336 
337  do {
338  for(count = 0; count < CCA_COUNT_MAX; ++count) {
339  t0 = RTIMER_NOW();
340  if(we_are_sending == 0) {
341  powercycle_turn_radio_on();
342  /* Check if a packet is seen in the air. If so, we keep the
343  radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to
344  be able to receive the packet. We also continuously check
345  the radio medium to make sure that we wasn't woken up by a
346  false positive: a spurious radio interference that was not
347  caused by an incoming packet. */
348  if(NETSTACK_RADIO.channel_clear() == 0) {
349  packet_seen = 1;
350  break;
351  }
352  powercycle_turn_radio_off();
353  }
354  schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME);
355  PT_YIELD(&pt);
356  }
357 
358  if(packet_seen) {
359  static rtimer_clock_t start;
360  static uint8_t silence_periods, periods;
361  start = RTIMER_NOW();
362 
363  periods = silence_periods = 0;
364  while(we_are_sending == 0 && radio_is_on &&
365  RTIMER_CLOCK_LT(RTIMER_NOW(),
366  (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
367 
368  /* Check for a number of consecutive periods of
369  non-activity. If we see two such periods, we turn the
370  radio off. Also, if a packet has been successfully
371  received (as indicated by the
372  NETSTACK_RADIO.pending_packet() function), we stop
373  snooping. */
374  if(NETSTACK_RADIO.channel_clear()) {
375  ++silence_periods;
376  } else {
377  silence_periods = 0;
378  }
379 
380  ++periods;
381 
382  if(NETSTACK_RADIO.receiving_packet()) {
383  silence_periods = 0;
384  }
385  if(silence_periods > MAX_SILENCE_PERIODS) {
386  powercycle_turn_radio_off();
387  break;
388  }
389  if(WITH_FAST_SLEEP &&
390  periods > MAX_NONACTIVITY_PERIODS &&
391  !(NETSTACK_RADIO.receiving_packet() ||
392  NETSTACK_RADIO.pending_packet())) {
393  powercycle_turn_radio_off();
394  break;
395  }
396  if(NETSTACK_RADIO.pending_packet()) {
397  break;
398  }
399 
400  schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME);
401  PT_YIELD(&pt);
402  }
403  if(radio_is_on) {
404  if(!(NETSTACK_RADIO.receiving_packet() ||
405  NETSTACK_RADIO.pending_packet()) ||
406  !RTIMER_CLOCK_LT(RTIMER_NOW(),
407  (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
408  powercycle_turn_radio_off();
409  }
410  }
411  }
412  } while((is_snooping || is_streaming) &&
413  RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 8));
414 
415  if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) {
416  schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
417  PT_YIELD(&pt);
418  }
419  }
420 
421  PT_END(&pt);
422 }
423 /*---------------------------------------------------------------------------*/
424 static int
425 broadcast_rate_drop(void)
426 {
427 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
428  if(!timer_expired(&broadcast_rate_timer)) {
429  broadcast_rate_counter++;
430  if(broadcast_rate_counter < CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT) {
431  return 0;
432  } else {
433  return 1;
434  }
435  } else {
436  timer_set(&broadcast_rate_timer, CLOCK_SECOND);
437  broadcast_rate_counter = 0;
438  return 0;
439  }
440 #else /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */
441  return 0;
442 #endif /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */
443 }
444 /*---------------------------------------------------------------------------*/
445 static int
446 send_packet(mac_callback_t mac_callback, void *mac_callback_ptr)
447 {
448  rtimer_clock_t t0;
449  rtimer_clock_t encounter_time = 0, previous_txtime = 0;
450  int strobes;
451  uint8_t got_strobe_ack = 0;
452  int hdrlen, len;
453  uint8_t is_broadcast = 0;
454  uint8_t is_reliable = 0;
455  uint8_t is_known_receiver = 0;
456  uint8_t collisions;
457  int transmit_len;
458  int i;
459  int ret;
460  uint8_t contikimac_was_on;
461 #if WITH_CONTIKIMAC_HEADER
462  struct hdr *chdr;
463 #endif /* WITH_CONTIKIMAC_HEADER */
464 
465  if(packetbuf_totlen() == 0) {
466  PRINTF("contikimac: send_packet data len 0\n");
467  return MAC_TX_ERR_FATAL;
468  }
469 
470  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr);
471  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
472  is_broadcast = 1;
473  PRINTDEBUG("contikimac: send broadcast\n");
474 
475  if(broadcast_rate_drop()) {
476  return MAC_TX_COLLISION;
477  }
478  } else {
479 #if UIP_CONF_IPV6
480  PRINTDEBUG("contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
481  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
482  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1],
483  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2],
484  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3],
485  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4],
486  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5],
487  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6],
488  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]);
489 #else /* UIP_CONF_IPV6 */
490  PRINTDEBUG("contikimac: send unicast to %u.%u\n",
491  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
492  packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]);
493 #endif /* UIP_CONF_IPV6 */
494  }
495  is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) ||
496  packetbuf_attr(PACKETBUF_ATTR_ERELIABLE);
497 
498  if(WITH_STREAMING) {
499  if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
500  PACKETBUF_ATTR_PACKET_TYPE_STREAM) {
501  if(rimeaddr_cmp(&is_streaming_to, &rimeaddr_null)) {
502  rimeaddr_copy(&is_streaming_to,
503  packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
504  } else if(!rimeaddr_cmp
505  (&is_streaming_to, packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
506  rimeaddr_copy(&is_streaming_to_too,
507  packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
508  }
509  stream_until = RTIMER_NOW() + DEFAULT_STREAM_TIME;
510  is_streaming = 1;
511  }
512  }
513 
514  if(is_streaming) {
515  packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1);
516  }
517  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
518 
519 #if WITH_CONTIKIMAC_HEADER
520  hdrlen = packetbuf_totlen();
521  if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) {
522  /* Failed to allocate space for contikimac header */
523  PRINTF("contikimac: send failed, too large header\n");
524  return MAC_TX_ERR_FATAL;
525  }
526  chdr = packetbuf_hdrptr();
527  chdr->id = CONTIKIMAC_ID;
528  chdr->len = hdrlen;
529 
530  /* Create the MAC header for the data packet. */
531  hdrlen = NETSTACK_FRAMER.create();
532  if(hdrlen == 0) {
533  /* Failed to send */
534  PRINTF("contikimac: send failed, too large header\n");
535  packetbuf_hdr_remove(sizeof(struct hdr));
536  return MAC_TX_ERR_FATAL;
537  }
538  hdrlen += sizeof(struct hdr);
539 #else
540  /* Create the MAC header for the data packet. */
541  hdrlen = NETSTACK_FRAMER.create();
542  if(hdrlen == 0) {
543  /* Failed to send */
544  PRINTF("contikimac: send failed, too large header\n");
545  return MAC_TX_ERR_FATAL;
546  }
547 #endif
548 
549 
550  /* Make sure that the packet is longer or equal to the shortest
551  packet length. */
552  transmit_len = packetbuf_totlen();
553  if(transmit_len < SHORTEST_PACKET_SIZE) {
554  /* Pad with zeroes */
555  uint8_t *ptr;
556  ptr = packetbuf_dataptr();
557  memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen());
558 
559  PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen());
560  transmit_len = SHORTEST_PACKET_SIZE;
561  }
562 
563 
565 
566  NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len);
567 
568  /* Remove the MAC-layer header since it will be recreated next time around. */
569  packetbuf_hdr_remove(hdrlen);
570 
571  if(!is_broadcast && !is_streaming) {
572 #if WITH_PHASE_OPTIMIZATION
573  ret = phase_wait(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
574  CYCLE_TIME, GUARD_TIME,
575  mac_callback, mac_callback_ptr);
576  if(ret == PHASE_DEFERRED) {
577  return MAC_TX_DEFERRED;
578  }
579  if(ret != PHASE_UNKNOWN) {
580  is_known_receiver = 1;
581  }
582 #endif /* WITH_PHASE_OPTIMIZATION */
583  }
584 
585 
586 
587  /* By setting we_are_sending to one, we ensure that the rtimer
588  powercycle interrupt do not interfere with us sending the packet. */
589  we_are_sending = 1;
590 
591  /* If we have a pending packet in the radio, we should not send now,
592  because we will trash the received packet. Instead, we signal
593  that we have a collision, which lets the packet be received. This
594  packet will be retransmitted later by the MAC protocol
595  instread. */
596  if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) {
597  we_are_sending = 0;
598  PRINTF("contikimac: collision receiving %d, pending %d\n",
599  NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet());
600  return MAC_TX_COLLISION;
601  }
602 
603  /* Switch off the radio to ensure that we didn't start sending while
604  the radio was doing a channel check. */
605  off();
606 
607 
608  strobes = 0;
609 
610  /* Send a train of strobes until the receiver answers with an ACK. */
611  collisions = 0;
612 
613  got_strobe_ack = 0;
614 
615  /* Set contikimac_is_on to one to allow the on() and off() functions
616  to control the radio. We restore the old value of
617  contikimac_is_on when we are done. */
618  contikimac_was_on = contikimac_is_on;
619  contikimac_is_on = 1;
620 
621  if(is_streaming == 0) {
622  /* Check if there are any transmissions by others. */
623  for(i = 0; i < CCA_COUNT_MAX; ++i) {
624  t0 = RTIMER_NOW();
625  on();
626  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { }
627  if(NETSTACK_RADIO.channel_clear() == 0) {
628  collisions++;
629  off();
630  break;
631  }
632  off();
633  t0 = RTIMER_NOW();
634  while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { }
635  }
636  }
637 
638  if(collisions > 0) {
639  we_are_sending = 0;
640  off();
641  PRINTF("contikimac: collisions before sending\n");
642  contikimac_is_on = contikimac_was_on;
643  return MAC_TX_COLLISION;
644  }
645 
646  if(!is_broadcast) {
647  on();
648  }
649 
650  watchdog_periodic();
651  t0 = RTIMER_NOW();
652 
653  for(strobes = 0, collisions = 0;
654  got_strobe_ack == 0 && collisions == 0 &&
655  RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) {
656 
657  watchdog_periodic();
658 
659  if(is_known_receiver && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) {
660  PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]);
661  break;
662  }
663 
664  len = 0;
665 
666  previous_txtime = RTIMER_NOW();
667  {
668  rtimer_clock_t wt;
669  rtimer_clock_t txtime;
670  int ret;
671 
672  txtime = RTIMER_NOW();
673  ret = NETSTACK_RADIO.transmit(transmit_len);
674 
675  wt = RTIMER_NOW();
676  while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }
677 
678  if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() ||
679  NETSTACK_RADIO.pending_packet() ||
680  NETSTACK_RADIO.channel_clear() == 0)) {
681  uint8_t ackbuf[ACK_LEN];
682  wt = RTIMER_NOW();
683  while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { }
684 
685  len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
686  if(len == ACK_LEN) {
687  got_strobe_ack = 1;
688  encounter_time = previous_txtime;
689  break;
690  } else {
691  PRINTF("contikimac: collisions while sending\n");
692  collisions++;
693  }
694  }
695  previous_txtime = txtime;
696  }
697  }
698 
699  off();
700 
701  PRINTF("contikimac: send (strobes=%u, len=%u, %s, %s), done\n", strobes,
703  got_strobe_ack ? "ack" : "no ack",
704  collisions ? "collision" : "no collision");
705 
706 #if CONTIKIMAC_CONF_COMPOWER
707  /* Accumulate the power consumption for the packet transmission. */
708  compower_accumulate(&current_packet);
709 
710  /* Convert the accumulated power consumption for the transmitted
711  packet to packet attributes so that the higher levels can keep
712  track of the amount of energy spent on transmitting the
713  packet. */
714  compower_attrconv(&current_packet);
715 
716  /* Clear the accumulated power consumption so that it is ready for
717  the next packet. */
718  compower_clear(&current_packet);
719 #endif /* CONTIKIMAC_CONF_COMPOWER */
720 
721  contikimac_is_on = contikimac_was_on;
722  we_are_sending = 0;
723 
724  /* Determine the return value that we will return from the
725  function. We must pass this value to the phase module before we
726  return from the function. */
727  if(collisions > 0) {
728  ret = MAC_TX_COLLISION;
729  } else if(!is_broadcast && !got_strobe_ack) {
730  ret = MAC_TX_NOACK;
731  } else {
732  ret = MAC_TX_OK;
733  }
734 
735 #if WITH_PHASE_OPTIMIZATION
736 
737  if(is_known_receiver && got_strobe_ack) {
738  PRINTF("no miss %d wake-ups %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
739  strobes);
740  }
741 
742  if(!is_broadcast) {
743  if(collisions == 0 && is_streaming == 0) {
744  phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time,
745  ret);
746  }
747  }
748 #endif /* WITH_PHASE_OPTIMIZATION */
749 
750  if(WITH_STREAMING) {
751  if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
752  PACKETBUF_ATTR_PACKET_TYPE_STREAM_END) {
753  is_streaming = 0;
754  }
755  }
756 
757  return ret;
758 }
759 /*---------------------------------------------------------------------------*/
760 static void
761 qsend_packet(mac_callback_t sent, void *ptr)
762 {
763  int ret = send_packet(sent, ptr);
764  if(ret != MAC_TX_DEFERRED) {
765  mac_call_sent_callback(sent, ptr, ret, 1);
766  }
767 }
768 /*---------------------------------------------------------------------------*/
769 static void
770 input_packet(void)
771 {
772  /* We have received the packet, so we can go back to being
773  asleep. */
774  off();
775  PRINTF("contikimac: got packet\n");
776 
777  /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/
778 
779 
780  if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse()) {
781 
782 #if WITH_CONTIKIMAC_HEADER
783  struct hdr *chdr;
784  chdr = packetbuf_dataptr();
785  if(chdr->id != CONTIKIMAC_ID) {
786  PRINTF("contikimac: failed to parse hdr (%u)\n", packetbuf_totlen());
787  return;
788  }
789  packetbuf_hdrreduce(sizeof(struct hdr));
790  packetbuf_set_datalen(chdr->len);
791 #endif /* WITH_CONTIKIMAC_HEADER */
792 
793  if(packetbuf_datalen() > 0 &&
794  packetbuf_totlen() > 0 &&
795  (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
796  &rimeaddr_node_addr) ||
797  rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
798  &rimeaddr_null))) {
799  /* This is a regular packet that is destined to us or to the
800  broadcast address. */
801 
802 #if WITH_PHASE_OPTIMIZATION
803  /* If the sender has set its pending flag, it has its radio
804  turned on and we should drop the phase estimation that we
805  have from before. */
806  if(packetbuf_attr(PACKETBUF_ATTR_PENDING)) {
807  phase_remove(&phase_list, packetbuf_addr(PACKETBUF_ADDR_SENDER));
808  }
809 #endif /* WITH_PHASE_OPTIMIZATION */
810 
811  /* Check for duplicate packet by comparing the sequence number
812  of the incoming packet with the last few ones we saw. */
813  {
814  int i;
815  for(i = 0; i < MAX_SEQNOS; ++i) {
816  if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno &&
817  rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
818  &received_seqnos[i].sender)) {
819  PRINTF("contikimac: Drop duplicate ContikiMAC layer packet\n");
820  /* Drop the packet. */
821  /* printf("Drop duplicate ContikiMAC layer packet\n");*/
822  return;
823  }
824  }
825  for(i = MAX_SEQNOS - 1; i > 0; --i) {
826  memcpy(&received_seqnos[i], &received_seqnos[i - 1],
827  sizeof(struct seqno));
828  }
829  received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
830  rimeaddr_copy(&received_seqnos[0].sender,
831  packetbuf_addr(PACKETBUF_ADDR_SENDER));
832  }
833 
834 #if CONTIKIMAC_CONF_COMPOWER
835  /* Accumulate the power consumption for the packet reception. */
836  compower_accumulate(&current_packet);
837  /* Convert the accumulated power consumption for the received
838  packet to packet attributes so that the higher levels can
839  keep track of the amount of energy spent on receiving the
840  packet. */
841  compower_attrconv(&current_packet);
842 
843  /* Clear the accumulated power consumption so that it is ready
844  for the next packet. */
845  compower_clear(&current_packet);
846 #endif /* CONTIKIMAC_CONF_COMPOWER */
847 
848  PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen());
849  NETSTACK_MAC.input();
850  return;
851  } else {
852  PRINTDEBUG("contikimac: data not for us\n");
853  }
854  } else {
855  PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen());
856  }
857 }
858 /*---------------------------------------------------------------------------*/
859 static void
860 init(void)
861 {
862  radio_is_on = 0;
863  PT_INIT(&pt);
864  rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1,
865  (void (*)(struct rtimer *, void *))powercycle, NULL);
866 
867  contikimac_is_on = 1;
868 
869 #if WITH_PHASE_OPTIMIZATION
870  phase_init(&phase_list);
871 #endif /* WITH_PHASE_OPTIMIZATION */
872 
873 }
874 /*---------------------------------------------------------------------------*/
875 static int
876 turn_on(void)
877 {
878  if(contikimac_is_on == 0) {
879  contikimac_is_on = 1;
880  contikimac_keep_radio_on = 0;
881  rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1,
882  (void (*)(struct rtimer *, void *))powercycle, NULL);
883  }
884  return 1;
885 }
886 /*---------------------------------------------------------------------------*/
887 static int
888 turn_off(int keep_radio_on)
889 {
890  contikimac_is_on = 0;
891  contikimac_keep_radio_on = keep_radio_on;
892  if(keep_radio_on) {
893  radio_is_on = 1;
894  return NETSTACK_RADIO.on();
895  } else {
896  radio_is_on = 0;
897  return NETSTACK_RADIO.off();
898  }
899 }
900 /*---------------------------------------------------------------------------*/
901 static unsigned short
902 duty_cycle(void)
903 {
904  return (1ul * CLOCK_SECOND * CYCLE_TIME) / RTIMER_ARCH_SECOND;
905 }
906 /*---------------------------------------------------------------------------*/
907 const struct rdc_driver contikimac_driver = {
908  "ContikiMAC",
909  init,
910  qsend_packet,
911  input_packet,
912  turn_on,
913  turn_off,
914  duty_cycle,
915 };
916 /*---------------------------------------------------------------------------*/
917 uint16_t
918 contikimac_debug_print(void)
919 {
920  return 0;
921 }
922 /*---------------------------------------------------------------------------*/