42 #include "contiki-conf.h"
45 #include "dev/watchdog.h"
46 #include "lib/random.h"
59 #ifdef CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION
60 #define WITH_PHASE_OPTIMIZATION CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION
62 #define WITH_PHASE_OPTIMIZATION 1
66 #ifdef CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
67 #define WITH_CONTIKIMAC_HEADER CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER
69 #define WITH_CONTIKIMAC_HEADER 1
72 #ifndef WITH_FAST_SLEEP
73 #define WITH_FAST_SLEEP 1
76 #ifndef RDC_CONF_HARDWARE_CSMA
77 #define RDC_CONF_HARDWARE_CSMA 0
80 #ifndef RDC_CONF_HARDWARE_ACK
81 #define RDC_CONF_HARDWARE_ACK 0
84 #ifndef RDC_CONF_MCU_SLEEP
85 #define RDC_CONF_MCU_SLEEP 0
88 #if NETSTACK_RDC_CHANNEL_CHECK_RATE >= 64
89 #undef WITH_PHASE_OPTIMIZATION
90 #define WITH_PHASE_OPTIMIZATION 0
93 #if WITH_CONTIKIMAC_HEADER
94 #define CONTIKIMAC_ID 0x00
103 #ifdef CONTIKIMAC_CONF_CYCLE_TIME
104 #define CYCLE_TIME (CONTIKIMAC_CONF_CYCLE_TIME)
106 #define CYCLE_TIME (RTIMER_ARCH_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE)
116 #if RTIMER_ARCH_SECOND & (RTIMER_ARCH_SECOND - 1)
117 #define SYNC_CYCLE_STARTS 1
121 static int we_are_receiving_burst = 0;
125 #define INTER_PACKET_DEADLINE CLOCK_SECOND / 32
131 #ifdef CONTIKIMAC_CONF_CCA_COUNT_MAX
132 #define CCA_COUNT_MAX (CONTIKIMAC_CONF_CCA_COUNT_MAX)
134 #define CCA_COUNT_MAX 2
139 #ifdef CONTIKIMAC_CONF_CCA_COUNT_MAX_TX
140 #define CCA_COUNT_MAX_TX (CONTIKIMAC_CONF_CCA_COUNT_MAX_TX)
142 #define CCA_COUNT_MAX_TX 6
147 #ifdef CONTIKIMAC_CONF_CCA_CHECK_TIME
148 #define CCA_CHECK_TIME (CONTIKIMAC_CONF_CCA_CHECK_TIME)
150 #define CCA_CHECK_TIME RTIMER_ARCH_SECOND / 8192
155 #if RTIMER_ARCH_SECOND > 8000
156 #define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000
158 #define CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 2000) + 1
163 #define CHECK_TIME (CCA_COUNT_MAX * (CCA_CHECK_TIME + CCA_SLEEP_TIME))
167 #define CHECK_TIME_TX (CCA_COUNT_MAX_TX * (CCA_CHECK_TIME + CCA_SLEEP_TIME))
172 #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80
177 #define MAX_SILENCE_PERIODS 5
182 #define MAX_NONACTIVITY_PERIODS 10
188 #define STROBE_TIME (CYCLE_TIME + 2 * CHECK_TIME)
192 #define GUARD_TIME 10 * CHECK_TIME + CHECK_TIME_TX
195 #ifdef CONTIKIMAC_CONF_INTER_PACKET_INTERVAL
196 #define INTER_PACKET_INTERVAL CONTIKIMAC_CONF_INTER_PACKET_INTERVAL
198 #define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 2500
204 #ifdef CONTIKIMAC_CONF_AFTER_ACK_DETECTECT_WAIT_TIME
205 #define AFTER_ACK_DETECTECT_WAIT_TIME CONTIKIMAC_CONF_AFTER_ACK_DETECTECT_WAIT_TIME
207 #define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1500
212 #define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60
222 #ifdef CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE
223 #define SHORTEST_PACKET_SIZE CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE
225 #define SHORTEST_PACKET_SIZE 43
235 static volatile uint8_t contikimac_is_on = 0;
236 static volatile uint8_t contikimac_keep_radio_on = 0;
238 static volatile unsigned char we_are_sending = 0;
239 static volatile unsigned char radio_is_on = 0;
244 #define PRINTF(...) printf(__VA_ARGS__)
245 #define PRINTDEBUG(...) printf(__VA_ARGS__)
248 #define PRINTDEBUG(...)
251 #if CONTIKIMAC_CONF_COMPOWER
255 #if WITH_PHASE_OPTIMIZATION
261 #define DEFAULT_STREAM_TIME (4 * CYCLE_TIME)
264 #define MIN(a, b) ((a) < (b)? (a) : (b))
267 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
268 static struct timer broadcast_rate_timer;
269 static int broadcast_rate_counter;
276 if(contikimac_is_on && radio_is_on == 0) {
285 if(contikimac_is_on && radio_is_on != 0 &&
286 contikimac_keep_radio_on == 0) {
288 NETSTACK_RADIO.off();
292 static volatile rtimer_clock_t cycle_start;
293 static char powercycle(
struct rtimer *t,
void *ptr);
295 schedule_powercycle(
struct rtimer *t, rtimer_clock_t time)
299 if(contikimac_is_on) {
306 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
308 PRINTF(
"schedule_powercycle: could not set rtimer\n");
314 schedule_powercycle_fixed(
struct rtimer *t, rtimer_clock_t fixed_time)
318 if(contikimac_is_on) {
320 if(RTIMER_CLOCK_LT(fixed_time,
RTIMER_NOW() + 1)) {
325 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
327 PRINTF(
"schedule_powercycle: could not set rtimer\n");
333 powercycle_turn_radio_off(
void)
335 #if CONTIKIMAC_CONF_COMPOWER
336 uint8_t was_on = radio_is_on;
339 if(we_are_sending == 0 && we_are_receiving_burst == 0) {
341 #if CONTIKIMAC_CONF_COMPOWER
342 if(was_on && !radio_is_on) {
350 powercycle_turn_radio_on(
void)
352 if(we_are_sending == 0 && we_are_receiving_burst == 0) {
358 powercycle(
struct rtimer *t,
void *ptr)
360 #if SYNC_CYCLE_STARTS
361 static volatile rtimer_clock_t sync_cycle_start;
362 static volatile uint8_t sync_cycle_phase;
367 #if SYNC_CYCLE_STARTS
374 static uint8_t packet_seen;
375 static rtimer_clock_t t0;
376 static uint8_t count;
378 #if SYNC_CYCLE_STARTS
381 if(sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) {
382 sync_cycle_phase = 0;
383 sync_cycle_start += RTIMER_ARCH_SECOND;
384 cycle_start = sync_cycle_start;
386 #if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535
387 cycle_start = sync_cycle_start + ((
unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE;
389 cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE;
393 cycle_start += CYCLE_TIME;
398 for(count = 0; count < CCA_COUNT_MAX; ++count) {
400 if(we_are_sending == 0 && we_are_receiving_burst == 0) {
401 powercycle_turn_radio_on();
408 if(NETSTACK_RADIO.channel_clear() == 0) {
412 powercycle_turn_radio_off();
414 schedule_powercycle_fixed(t,
RTIMER_NOW() + CCA_SLEEP_TIME);
419 static rtimer_clock_t start;
420 static uint8_t silence_periods, periods;
423 periods = silence_periods = 0;
424 while(we_are_sending == 0 && radio_is_on &&
426 (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
434 #if !RDC_CONF_HARDWARE_CSMA
437 if(NETSTACK_RADIO.channel_clear()) {
446 if(NETSTACK_RADIO.receiving_packet()) {
449 if(silence_periods > MAX_SILENCE_PERIODS) {
450 powercycle_turn_radio_off();
453 if(WITH_FAST_SLEEP &&
454 periods > MAX_NONACTIVITY_PERIODS &&
455 !(NETSTACK_RADIO.receiving_packet() ||
456 NETSTACK_RADIO.pending_packet())) {
457 powercycle_turn_radio_off();
460 if(NETSTACK_RADIO.pending_packet()) {
464 schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME);
468 if(!(NETSTACK_RADIO.receiving_packet() ||
469 NETSTACK_RADIO.pending_packet()) ||
471 (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) {
472 powercycle_turn_radio_off();
477 if(RTIMER_CLOCK_LT(
RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) {
482 #if RDC_CONF_MCU_SLEEP
483 static uint8_t sleepcycle;
484 if((sleepcycle++ < 16) && !we_are_sending && !radio_is_on) {
485 rtimer_arch_sleep(CYCLE_TIME - (
RTIMER_NOW() - cycle_start));
488 schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
492 schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start);
502 broadcast_rate_drop(
void)
504 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT
506 broadcast_rate_counter++;
507 if(broadcast_rate_counter < CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT) {
514 broadcast_rate_counter = 0;
523 send_packet(mac_callback_t mac_callback,
void *mac_callback_ptr,
524 struct rdc_buf_list *buf_list,
525 int is_receiver_awake)
528 rtimer_clock_t encounter_time = 0;
530 uint8_t got_strobe_ack = 0;
532 uint8_t is_broadcast = 0;
533 uint8_t is_reliable = 0;
534 uint8_t is_known_receiver = 0;
538 uint8_t contikimac_was_on;
540 #if WITH_CONTIKIMAC_HEADER
545 if(!contikimac_is_on && !contikimac_keep_radio_on) {
546 PRINTF(
"contikimac: radio is turned off\n");
547 return MAC_TX_ERR_FATAL;
551 PRINTF(
"contikimac: send_packet data len 0\n");
552 return MAC_TX_ERR_FATAL;
555 #if !NETSTACK_CONF_BRIDGE_MODE
561 PRINTDEBUG(
"contikimac: send broadcast\n");
563 if(broadcast_rate_drop()) {
568 PRINTDEBUG(
"contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
569 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
570 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1],
571 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2],
572 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3],
573 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4],
574 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5],
575 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6],
576 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]);
578 PRINTDEBUG(
"contikimac: send unicast to %u.%u\n",
579 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
580 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]);
583 is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) ||
584 packetbuf_attr(PACKETBUF_ATTR_ERELIABLE);
586 packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
588 #if WITH_CONTIKIMAC_HEADER
592 PRINTF(
"contikimac: send failed, too large header\n");
593 return MAC_TX_ERR_FATAL;
596 chdr->id = CONTIKIMAC_ID;
600 hdrlen = NETSTACK_FRAMER.create();
603 PRINTF(
"contikimac: send failed, too large header\n");
604 packetbuf_hdr_remove(
sizeof(
struct hdr));
605 return MAC_TX_ERR_FATAL;
607 hdrlen +=
sizeof(
struct hdr);
610 hdrlen = NETSTACK_FRAMER.create();
613 PRINTF(
"contikimac: send failed, too large header\n");
614 return MAC_TX_ERR_FATAL;
621 if(transmit_len < SHORTEST_PACKET_SIZE) {
634 #ifdef NETSTACK_ENCRYPT
643 packetbuf_hdr_remove(hdrlen);
645 if(!is_broadcast && !is_receiver_awake) {
646 #if WITH_PHASE_OPTIMIZATION
647 ret = phase_wait(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
648 CYCLE_TIME, GUARD_TIME,
649 mac_callback, mac_callback_ptr, buf_list);
650 if(ret == PHASE_DEFERRED) {
653 if(ret != PHASE_UNKNOWN) {
654 is_known_receiver = 1;
670 if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) {
672 PRINTF(
"contikimac: collision receiving %d, pending %d\n",
673 NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet());
692 contikimac_was_on = contikimac_is_on;
693 contikimac_is_on = 1;
695 #if !RDC_CONF_HARDWARE_CSMA
698 if(is_receiver_awake == 0) {
700 for(i = 0; i < CCA_COUNT_MAX_TX; ++i) {
703 #if CCA_CHECK_TIME > 0
704 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { }
706 if(NETSTACK_RADIO.channel_clear() == 0) {
713 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { }
720 PRINTF(
"contikimac: collisions before sending\n");
721 contikimac_is_on = contikimac_was_on;
726 #if !RDC_CONF_HARDWARE_ACK
737 seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
738 for(strobes = 0, collisions = 0;
739 got_strobe_ack == 0 && collisions == 0 &&
740 RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + STROBE_TIME); strobes++) {
744 if(!is_broadcast && (is_receiver_awake || is_known_receiver) &&
745 !RTIMER_CLOCK_LT(
RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) {
746 PRINTF(
"miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]);
754 rtimer_clock_t txtime;
758 ret = NETSTACK_RADIO.transmit(transmit_len);
760 #if RDC_CONF_HARDWARE_ACK
763 if(ret == RADIO_TX_OK) {
766 encounter_time = txtime;
769 }
else if (ret == RADIO_TX_NOACK) {
770 }
else if (ret == RADIO_TX_COLLISION) {
771 PRINTF(
"contikimac: collisions while sending\n");
775 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }
779 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }
781 if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() ||
782 NETSTACK_RADIO.pending_packet() ||
783 NETSTACK_RADIO.channel_clear() == 0)) {
784 uint8_t ackbuf[ACK_LEN];
786 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { }
788 len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
789 if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) {
791 encounter_time = txtime;
794 PRINTF(
"contikimac: collisions while sending\n");
804 PRINTF(
"contikimac: send (strobes=%u, len=%u, %s, %s), done\n", strobes,
806 got_strobe_ack ?
"ack" :
"no ack",
807 collisions ?
"collision" :
"no collision");
809 #if CONTIKIMAC_CONF_COMPOWER
824 contikimac_is_on = contikimac_was_on;
832 }
else if(!is_broadcast && !got_strobe_ack) {
838 #if WITH_PHASE_OPTIMIZATION
839 if(is_known_receiver && got_strobe_ack) {
840 PRINTF(
"no miss %d wake-ups %d\n",
841 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
846 if(collisions == 0 && is_receiver_awake == 0) {
847 phase_update(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
848 encounter_time, ret);
857 qsend_packet(mac_callback_t sent,
void *ptr)
859 int ret = send_packet(sent, ptr,
NULL, 0);
861 mac_call_sent_callback(sent, ptr, ret, 1);
866 qsend_list(mac_callback_t sent,
void *ptr,
struct rdc_buf_list *buf_list)
868 struct rdc_buf_list *curr = buf_list;
869 struct rdc_buf_list *next;
871 int is_receiver_awake;
877 if(we_are_receiving_burst) {
879 queuebuf_to_packetbuf(curr->buf);
885 is_receiver_awake = 0;
890 queuebuf_to_packetbuf(curr->buf);
892 packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1);
896 ret = send_packet(sent, ptr, curr, is_receiver_awake);
898 mac_call_sent_callback(sent, ptr, ret, 1);
904 is_receiver_awake = 1;
911 }
while(next !=
NULL);
918 recv_burst_off(
void *ptr)
921 we_are_receiving_burst = 0;
927 static struct ctimer ct;
928 if(!we_are_receiving_burst) {
934 #ifdef NETSTACK_DECRYPT
940 #if WITH_CONTIKIMAC_HEADER
943 if(chdr->id != CONTIKIMAC_ID) {
961 we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING);
962 if(we_are_receiving_burst) {
980 #if CONTIKIMAC_CONF_COMPOWER
995 NETSTACK_MAC.input();
998 PRINTDEBUG(
"contikimac: data not for us\n");
1012 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
1014 contikimac_is_on = 1;
1016 #if WITH_PHASE_OPTIMIZATION
1025 if(contikimac_is_on == 0) {
1026 contikimac_is_on = 1;
1027 contikimac_keep_radio_on = 0;
1029 (
void (*)(
struct rtimer *,
void *))powercycle,
NULL);
1035 turn_off(
int keep_radio_on)
1037 contikimac_is_on = 0;
1038 contikimac_keep_radio_on = keep_radio_on;
1041 return NETSTACK_RADIO.on();
1044 return NETSTACK_RADIO.off();
1048 static unsigned short
1051 return (1ul *
CLOCK_SECOND * CYCLE_TIME) / RTIMER_ARCH_SECOND;
1054 const struct rdc_driver contikimac_driver = {
1066 contikimac_debug_print(
void)