43 #include "contiki-conf.h"
46 #include "dev/watchdog.h"
47 #include "lib/random.h"
58 #ifndef WITH_PHASE_OPTIMIZATION
59 #define WITH_PHASE_OPTIMIZATION 1
61 #ifndef WITH_STREAMING
62 #define WITH_STREAMING 0
64 #ifdef CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
65 #define WITH_CONTIKIMAC_HEADER CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
67 #define WITH_CONTIKIMAC_HEADER 1
69 #ifndef WITH_FAST_SLEEP
70 #define WITH_FAST_SLEEP 1
73 #if NETSTACK_RDC_CHANNEL_CHECK_RATE >= 64
74 #undef WITH_PHASE_OPTIMIZATION
75 #define WITH_PHASE_OPTIMIZATION 0
78 #if WITH_CONTIKIMAC_HEADER
79 #define CONTIKIMAC_ID 0x00
87 #ifdef CONTIKIMAC_CONF_CYCLE_TIME
88 #define CYCLE_TIME (CONTIKIMAC_CONF_CYCLE_TIME)
90 #define CYCLE_TIME (RTIMER_ARCH_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE)
98 #define CCA_COUNT_MAX 2
101 #define CCA_CHECK_TIME RTIMER_ARCH_SECOND / 8192
104 #define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000
108 #define CHECK_TIME (CCA_COUNT_MAX * (CCA_CHECK_TIME + CCA_SLEEP_TIME))
113 #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80
118 #define MAX_SILENCE_PERIODS 5
123 #define MAX_NONACTIVITY_PERIODS 10
129 #define STROBE_TIME (CYCLE_TIME + 2 * CHECK_TIME)
133 #define GUARD_TIME 11 * CHECK_TIME
136 #define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000
141 #define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1500
145 #define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60
152 #define SHORTEST_PACKET_SIZE 43
161 static volatile uint8_t contikimac_is_on = 0;
162 static volatile uint8_t contikimac_keep_radio_on = 0;
164 static volatile unsigned char we_are_sending = 0;
165 static volatile unsigned char radio_is_on = 0;
170 #define PRINTF(...) printf(__VA_ARGS__)
171 #define PRINTDEBUG(...) printf(__VA_ARGS__)
174 #define PRINTDEBUG(...)
179 static volatile uint8_t is_snooping;
181 #if CONTIKIMAC_CONF_COMPOWER
185 #if WITH_PHASE_OPTIMIZATION
189 #ifdef CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
190 #define MAX_PHASE_NEIGHBORS CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS
193 #ifndef MAX_PHASE_NEIGHBORS
194 #define MAX_PHASE_NEIGHBORS 30
197 PHASE_LIST(phase_list, MAX_PHASE_NEIGHBORS);
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;
205 #define DEFAULT_STREAM_TIME (4 * CYCLE_TIME)
208 #define MIN(a, b) ((a) < (b)? (a) : (b))
216 #ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY
217 #define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY
219 #define MAX_SEQNOS 16
221 static struct seqno received_seqnos[MAX_SEQNOS];
223 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
224 static struct timer broadcast_rate_timer;
225 static int broadcast_rate_counter;
232 if(contikimac_is_on && radio_is_on == 0) {
241 if(contikimac_is_on && radio_is_on != 0 &&
242 contikimac_keep_radio_on == 0) {
244 NETSTACK_RADIO.off();
248 static volatile rtimer_clock_t cycle_start;
249 static char powercycle(
struct rtimer *t,
void *ptr);
251 schedule_powercycle(
struct rtimer *t, rtimer_clock_t time)
255 if(contikimac_is_on) {
262 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
264 printf(
"schedule_powercycle: could not set rtimer\n");
270 schedule_powercycle_fixed(
struct rtimer *t, rtimer_clock_t fixed_time)
274 if(contikimac_is_on) {
276 if(RTIMER_CLOCK_LT(fixed_time,
RTIMER_NOW() + 1)) {
281 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
283 printf(
"schedule_powercycle: could not set rtimer\n");
289 powercycle_turn_radio_off(
void)
291 #if CONTIKIMAC_CONF_COMPOWER
292 uint8_t was_on = radio_is_on;
295 if(we_are_sending == 0) {
297 #if CONTIKIMAC_CONF_COMPOWER
298 if(was_on && !radio_is_on) {
306 powercycle_turn_radio_on(
void)
308 if(we_are_sending == 0) {
314 powercycle(
struct rtimer *t,
void *ptr)
321 static uint8_t packet_seen;
322 static rtimer_clock_t t0;
323 static uint8_t count;
325 cycle_start += CYCLE_TIME;
327 if(WITH_STREAMING && is_streaming) {
328 if(!RTIMER_CLOCK_LT(
RTIMER_NOW(), stream_until)) {
338 for(count = 0; count < CCA_COUNT_MAX; ++count) {
340 if(we_are_sending == 0) {
341 powercycle_turn_radio_on();
348 if(NETSTACK_RADIO.channel_clear() == 0) {
352 powercycle_turn_radio_off();
354 schedule_powercycle_fixed(t,
RTIMER_NOW() + CCA_SLEEP_TIME);
359 static rtimer_clock_t start;
360 static uint8_t silence_periods, periods;
363 periods = silence_periods = 0;
364 while(we_are_sending == 0 && radio_is_on &&
366 (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
374 if(NETSTACK_RADIO.channel_clear()) {
382 if(NETSTACK_RADIO.receiving_packet()) {
385 if(silence_periods > MAX_SILENCE_PERIODS) {
386 powercycle_turn_radio_off();
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();
396 if(NETSTACK_RADIO.pending_packet()) {
400 schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME);
404 if(!(NETSTACK_RADIO.receiving_packet() ||
405 NETSTACK_RADIO.pending_packet()) ||
407 (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
408 powercycle_turn_radio_off();
412 }
while((is_snooping || is_streaming) &&
413 RTIMER_CLOCK_LT(
RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 8));
415 if(RTIMER_CLOCK_LT(
RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) {
416 schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
425 broadcast_rate_drop(
void)
427 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
429 broadcast_rate_counter++;
430 if(broadcast_rate_counter < CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT) {
437 broadcast_rate_counter = 0;
446 send_packet(mac_callback_t mac_callback,
void *mac_callback_ptr)
449 rtimer_clock_t encounter_time = 0, previous_txtime = 0;
451 uint8_t got_strobe_ack = 0;
453 uint8_t is_broadcast = 0;
454 uint8_t is_reliable = 0;
455 uint8_t is_known_receiver = 0;
460 uint8_t contikimac_was_on;
461 #if WITH_CONTIKIMAC_HEADER
466 PRINTF(
"contikimac: send_packet data len 0\n");
467 return MAC_TX_ERR_FATAL;
473 PRINTDEBUG(
"contikimac: send broadcast\n");
475 if(broadcast_rate_drop()) {
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]);
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]);
495 is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) ||
496 packetbuf_attr(PACKETBUF_ATTR_ERELIABLE);
499 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
500 PACKETBUF_ATTR_PACKET_TYPE_STREAM) {
503 packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
505 (&is_streaming_to, packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
507 packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
509 stream_until =
RTIMER_NOW() + DEFAULT_STREAM_TIME;
515 packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1);
517 packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
519 #if WITH_CONTIKIMAC_HEADER
523 PRINTF(
"contikimac: send failed, too large header\n");
524 return MAC_TX_ERR_FATAL;
527 chdr->id = CONTIKIMAC_ID;
531 hdrlen = NETSTACK_FRAMER.create();
534 PRINTF(
"contikimac: send failed, too large header\n");
535 packetbuf_hdr_remove(
sizeof(
struct hdr));
536 return MAC_TX_ERR_FATAL;
538 hdrlen +=
sizeof(
struct hdr);
541 hdrlen = NETSTACK_FRAMER.create();
544 PRINTF(
"contikimac: send failed, too large header\n");
545 return MAC_TX_ERR_FATAL;
553 if(transmit_len < SHORTEST_PACKET_SIZE) {
560 transmit_len = SHORTEST_PACKET_SIZE;
569 packetbuf_hdr_remove(hdrlen);
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) {
579 if(ret != PHASE_UNKNOWN) {
580 is_known_receiver = 1;
596 if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) {
598 PRINTF(
"contikimac: collision receiving %d, pending %d\n",
599 NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet());
618 contikimac_was_on = contikimac_is_on;
619 contikimac_is_on = 1;
621 if(is_streaming == 0) {
623 for(i = 0; i < CCA_COUNT_MAX; ++i) {
626 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { }
627 if(NETSTACK_RADIO.channel_clear() == 0) {
634 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { }
641 PRINTF(
"contikimac: collisions before sending\n");
642 contikimac_is_on = contikimac_was_on;
653 for(strobes = 0, collisions = 0;
654 got_strobe_ack == 0 && collisions == 0 &&
655 RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + STROBE_TIME); strobes++) {
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]);
669 rtimer_clock_t txtime;
673 ret = NETSTACK_RADIO.transmit(transmit_len);
676 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }
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];
683 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { }
685 len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
688 encounter_time = previous_txtime;
691 PRINTF(
"contikimac: collisions while sending\n");
695 previous_txtime = txtime;
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");
706 #if CONTIKIMAC_CONF_COMPOWER
721 contikimac_is_on = contikimac_was_on;
729 }
else if(!is_broadcast && !got_strobe_ack) {
735 #if WITH_PHASE_OPTIMIZATION
737 if(is_known_receiver && got_strobe_ack) {
738 PRINTF(
"no miss %d wake-ups %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
743 if(collisions == 0 && is_streaming == 0) {
744 phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time,
751 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
752 PACKETBUF_ATTR_PACKET_TYPE_STREAM_END) {
761 qsend_packet(mac_callback_t sent,
void *ptr)
763 int ret = send_packet(sent, ptr);
765 mac_call_sent_callback(sent, ptr, ret, 1);
775 PRINTF(
"contikimac: got packet\n");
782 #if WITH_CONTIKIMAC_HEADER
785 if(chdr->id != CONTIKIMAC_ID) {
802 #if WITH_PHASE_OPTIMIZATION
806 if(packetbuf_attr(PACKETBUF_ATTR_PENDING)) {
807 phase_remove(&phase_list, packetbuf_addr(PACKETBUF_ADDR_SENDER));
815 for(i = 0; i < MAX_SEQNOS; ++i) {
816 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno &&
818 &received_seqnos[i].sender)) {
819 PRINTF(
"contikimac: Drop duplicate ContikiMAC layer packet\n");
825 for(i = MAX_SEQNOS - 1; i > 0; --i) {
826 memcpy(&received_seqnos[i], &received_seqnos[i - 1],
827 sizeof(
struct seqno));
829 received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
831 packetbuf_addr(PACKETBUF_ADDR_SENDER));
834 #if CONTIKIMAC_CONF_COMPOWER
849 NETSTACK_MAC.input();
852 PRINTDEBUG(
"contikimac: data not for us\n");
865 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
867 contikimac_is_on = 1;
869 #if WITH_PHASE_OPTIMIZATION
870 phase_init(&phase_list);
878 if(contikimac_is_on == 0) {
879 contikimac_is_on = 1;
880 contikimac_keep_radio_on = 0;
882 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
888 turn_off(
int keep_radio_on)
890 contikimac_is_on = 0;
891 contikimac_keep_radio_on = keep_radio_on;
894 return NETSTACK_RADIO.on();
897 return NETSTACK_RADIO.off();
901 static unsigned short
904 return (1ul *
CLOCK_SECOND * CYCLE_TIME) / RTIMER_ARCH_SECOND;
918 contikimac_debug_print(
void)