Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2010, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 */ 00032 00033 /** 00034 * \file 00035 * Implementation of the ContikiMAC power-saving radio duty cycling protocol 00036 * \author 00037 * Adam Dunkels <adam@sics.se> 00038 * Niclas Finne <nfi@sics.se> 00039 * Joakim Eriksson <joakime@sics.se> 00040 */ 00041 00042 #include "contiki-conf.h" 00043 #include "dev/leds.h" 00044 #include "dev/radio.h" 00045 #include "dev/watchdog.h" 00046 #include "lib/random.h" 00047 #include "net/mac/contikimac.h" 00048 #include "net/netstack.h" 00049 #include "net/rime.h" 00050 #include "sys/compower.h" 00051 #include "sys/pt.h" 00052 #include "sys/rtimer.h" 00053 00054 00055 #include <string.h> 00056 00057 /* TX/RX cycles are synchronized with neighbor wake periods */ 00058 #ifndef WITH_PHASE_OPTIMIZATION 00059 #define WITH_PHASE_OPTIMIZATION 1 00060 #endif 00061 /* Two byte header added to allow recovery of padded short packets */ 00062 /* Wireshark will not understand such packets at present */ 00063 #ifdef CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 00064 #define WITH_CONTIKIMAC_HEADER CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 00065 #else 00066 #define WITH_CONTIKIMAC_HEADER 1 00067 #endif 00068 /* More aggressive radio sleeping when channel is busy with other traffic */ 00069 #ifndef WITH_FAST_SLEEP 00070 #define WITH_FAST_SLEEP 1 00071 #endif 00072 /* Radio does CSMA and autobackoff */ 00073 #ifndef RDC_CONF_HARDWARE_CSMA 00074 #define RDC_CONF_HARDWARE_CSMA 0 00075 #endif 00076 /* Radio returns TX_OK/TX_NOACK after autoack wait */ 00077 #ifndef RDC_CONF_HARDWARE_ACK 00078 #define RDC_CONF_HARDWARE_ACK 0 00079 #endif 00080 /* MCU can sleep during radio off */ 00081 #ifndef RDC_CONF_MCU_SLEEP 00082 #define RDC_CONF_MCU_SLEEP 0 00083 #endif 00084 00085 #if NETSTACK_RDC_CHANNEL_CHECK_RATE >= 64 00086 #undef WITH_PHASE_OPTIMIZATION 00087 #define WITH_PHASE_OPTIMIZATION 0 00088 #endif 00089 00090 #if WITH_CONTIKIMAC_HEADER 00091 #define CONTIKIMAC_ID 0x00 00092 00093 struct hdr { 00094 uint8_t id; 00095 uint8_t len; 00096 }; 00097 #endif /* WITH_CONTIKIMAC_HEADER */ 00098 00099 /* CYCLE_TIME for channel cca checks, in rtimer ticks. */ 00100 #ifdef CONTIKIMAC_CONF_CYCLE_TIME 00101 #define CYCLE_TIME (CONTIKIMAC_CONF_CYCLE_TIME) 00102 #else 00103 #define CYCLE_TIME (RTIMER_ARCH_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE) 00104 #endif 00105 00106 /* CHANNEL_CHECK_RATE is enforced to be a power of two. 00107 * If RTIMER_ARCH_SECOND is not also a power of two, there will be an inexact 00108 * number of channel checks per second due to the truncation of CYCLE_TIME. 00109 * This will degrade the effectiveness of phase optimization with neighbors that 00110 * do not have the same truncation error. 00111 * Define SYNC_CYCLE_STARTS to ensure an integral number of checks per second. 00112 */ 00113 #if RTIMER_ARCH_SECOND & (RTIMER_ARCH_SECOND - 1) 00114 #define SYNC_CYCLE_STARTS 1 00115 #endif 00116 00117 /* Are we currently receiving a burst? */ 00118 static int we_are_receiving_burst = 0; 00119 /* Has the receiver been awoken by a burst we're sending? */ 00120 static int is_receiver_awake = 0; 00121 00122 /* BURST_RECV_TIME is the maximum time a receiver waits for the 00123 next packet of a burst when FRAME_PENDING is set. */ 00124 #define INTER_PACKET_DEADLINE CLOCK_SECOND / 32 00125 00126 /* ContikiMAC performs periodic channel checks. Each channel check 00127 consists of two or more CCA checks. CCA_COUNT_MAX is the number of 00128 CCAs to be done for each periodic channel check. The default is 00129 two.*/ 00130 #define CCA_COUNT_MAX 2 00131 00132 /* Before starting a transmission, Contikimac checks the availability 00133 of the channel with CCA_COUNT_MAX_TX consecutive CCAs */ 00134 #define CCA_COUNT_MAX_TX 6 00135 00136 /* CCA_CHECK_TIME is the time it takes to perform a CCA check. */ 00137 /* Note this may be zero. AVRs have 7612 ticks/sec, but block until cca is done */ 00138 #define CCA_CHECK_TIME RTIMER_ARCH_SECOND / 8192 00139 00140 /* CCA_SLEEP_TIME is the time between two successive CCA checks. */ 00141 /* Add 1 when rtimer ticks are coarse */ 00142 #if RTIMER_ARCH_SECOND > 8000 00143 #define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000 00144 #else 00145 #define CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 2000) + 1 00146 #endif 00147 00148 /* CHECK_TIME is the total time it takes to perform CCA_COUNT_MAX 00149 CCAs. */ 00150 #define CHECK_TIME (CCA_COUNT_MAX * (CCA_CHECK_TIME + CCA_SLEEP_TIME)) 00151 00152 /* CHECK_TIME_TX is the total time it takes to perform CCA_COUNT_MAX_TX 00153 CCAs. */ 00154 #define CHECK_TIME_TX (CCA_COUNT_MAX_TX * (CCA_CHECK_TIME + CCA_SLEEP_TIME)) 00155 00156 /* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking 00157 for activity after a potential packet has been detected by a CCA 00158 check. */ 00159 #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80 00160 00161 /* MAX_SILENCE_PERIODS is the maximum amount of periods (a period is 00162 CCA_CHECK_TIME + CCA_SLEEP_TIME) that we allow to be silent before 00163 we turn of the radio. */ 00164 #define MAX_SILENCE_PERIODS 5 00165 00166 /* MAX_NONACTIVITY_PERIODS is the maximum number of periods we allow 00167 the radio to be turned on without any packet being received, when 00168 WITH_FAST_SLEEP is enabled. */ 00169 #define MAX_NONACTIVITY_PERIODS 10 00170 00171 00172 00173 /* STROBE_TIME is the maximum amount of time a transmitted packet 00174 should be repeatedly transmitted as part of a transmission. */ 00175 #define STROBE_TIME (CYCLE_TIME + 2 * CHECK_TIME) 00176 00177 /* GUARD_TIME is the time before the expected phase of a neighbor that 00178 a transmitted should begin transmitting packets. */ 00179 #define GUARD_TIME 10 * CHECK_TIME + CHECK_TIME_TX 00180 00181 /* INTER_PACKET_INTERVAL is the interval between two successive packet transmissions */ 00182 #define INTER_PACKET_INTERVAL RTIMER_ARCH_SECOND / 5000 00183 00184 /* AFTER_ACK_DETECTECT_WAIT_TIME is the time to wait after a potential 00185 ACK packet has been detected until we can read it out from the 00186 radio. */ 00187 #define AFTER_ACK_DETECTECT_WAIT_TIME RTIMER_ARCH_SECOND / 1500 00188 00189 /* MAX_PHASE_STROBE_TIME is the time that we transmit repeated packets 00190 to a neighbor for which we have a phase lock. */ 00191 #define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60 00192 00193 00194 /* SHORTEST_PACKET_SIZE is the shortest packet that ContikiMAC 00195 allows. Packets have to be a certain size to be able to be detected 00196 by two consecutive CCA checks, and here is where we define this 00197 shortest size. 00198 Padded packets will have the wrong ipv6 checksum unless CONTIKIMAC_HEADER 00199 is used (on both sides) and the receiver will ignore them. 00200 With no header, reduce to transmit a proper multicast RPL DIS. */ 00201 #ifdef CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE 00202 #define SHORTEST_PACKET_SIZE CONTIKIMAC_CONF_SHORTEST_PACKET_SIZE 00203 #else 00204 #define SHORTEST_PACKET_SIZE 43 00205 #endif 00206 00207 00208 #define ACK_LEN 3 00209 00210 #include <stdio.h> 00211 static struct rtimer rt; 00212 static struct pt pt; 00213 00214 static volatile uint8_t contikimac_is_on = 0; 00215 static volatile uint8_t contikimac_keep_radio_on = 0; 00216 00217 static volatile unsigned char we_are_sending = 0; 00218 static volatile unsigned char radio_is_on = 0; 00219 00220 #define DEBUG 0 00221 #if DEBUG 00222 #include <stdio.h> 00223 #define PRINTF(...) printf(__VA_ARGS__) 00224 #define PRINTDEBUG(...) printf(__VA_ARGS__) 00225 #else 00226 #define PRINTF(...) 00227 #define PRINTDEBUG(...) 00228 #endif 00229 00230 #if CONTIKIMAC_CONF_COMPOWER 00231 static struct compower_activity current_packet; 00232 #endif /* CONTIKIMAC_CONF_COMPOWER */ 00233 00234 #if WITH_PHASE_OPTIMIZATION 00235 00236 #include "net/mac/phase.h" 00237 00238 #ifdef CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS 00239 #define MAX_PHASE_NEIGHBORS CONTIKIMAC_CONF_MAX_PHASE_NEIGHBORS 00240 #endif 00241 00242 #ifndef MAX_PHASE_NEIGHBORS 00243 #define MAX_PHASE_NEIGHBORS 30 00244 #endif 00245 00246 PHASE_LIST(phase_list, MAX_PHASE_NEIGHBORS); 00247 00248 #endif /* WITH_PHASE_OPTIMIZATION */ 00249 00250 #define DEFAULT_STREAM_TIME (4 * CYCLE_TIME) 00251 00252 #ifndef MIN 00253 #define MIN(a, b) ((a) < (b)? (a) : (b)) 00254 #endif /* MIN */ 00255 00256 struct seqno { 00257 rimeaddr_t sender; 00258 uint8_t seqno; 00259 }; 00260 00261 #ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY 00262 #define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY 00263 #else /* NETSTACK_CONF_MAC_SEQNO_HISTORY */ 00264 #define MAX_SEQNOS 16 00265 #endif /* NETSTACK_CONF_MAC_SEQNO_HISTORY */ 00266 static struct seqno received_seqnos[MAX_SEQNOS]; 00267 00268 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 00269 static struct timer broadcast_rate_timer; 00270 static int broadcast_rate_counter; 00271 #endif /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */ 00272 00273 /*---------------------------------------------------------------------------*/ 00274 static void 00275 on(void) 00276 { 00277 if(contikimac_is_on && radio_is_on == 0) { 00278 radio_is_on = 1; 00279 NETSTACK_RADIO.on(); 00280 } 00281 } 00282 /*---------------------------------------------------------------------------*/ 00283 static void 00284 off(void) 00285 { 00286 if(contikimac_is_on && radio_is_on != 0 && 00287 contikimac_keep_radio_on == 0) { 00288 radio_is_on = 0; 00289 NETSTACK_RADIO.off(); 00290 } 00291 } 00292 /*---------------------------------------------------------------------------*/ 00293 static volatile rtimer_clock_t cycle_start; 00294 static char powercycle(struct rtimer *t, void *ptr); 00295 static void 00296 schedule_powercycle(struct rtimer *t, rtimer_clock_t time) 00297 { 00298 int r; 00299 00300 if(contikimac_is_on) { 00301 00302 if(RTIMER_CLOCK_LT(RTIMER_TIME(t) + time, RTIMER_NOW() + 2)) { 00303 time = RTIMER_NOW() - RTIMER_TIME(t) + 2; 00304 } 00305 00306 r = rtimer_set(t, RTIMER_TIME(t) + time, 1, 00307 (void (*)(struct rtimer *, void *))powercycle, NULL); 00308 if(r != RTIMER_OK) { 00309 printf("schedule_powercycle: could not set rtimer\n"); 00310 } 00311 } 00312 } 00313 /*---------------------------------------------------------------------------*/ 00314 static void 00315 schedule_powercycle_fixed(struct rtimer *t, rtimer_clock_t fixed_time) 00316 { 00317 int r; 00318 00319 if(contikimac_is_on) { 00320 00321 if(RTIMER_CLOCK_LT(fixed_time, RTIMER_NOW() + 1)) { 00322 fixed_time = RTIMER_NOW() + 1; 00323 } 00324 00325 r = rtimer_set(t, fixed_time, 1, 00326 (void (*)(struct rtimer *, void *))powercycle, NULL); 00327 if(r != RTIMER_OK) { 00328 printf("schedule_powercycle: could not set rtimer\n"); 00329 } 00330 } 00331 } 00332 /*---------------------------------------------------------------------------*/ 00333 static void 00334 powercycle_turn_radio_off(void) 00335 { 00336 #if CONTIKIMAC_CONF_COMPOWER 00337 uint8_t was_on = radio_is_on; 00338 #endif /* CONTIKIMAC_CONF_COMPOWER */ 00339 00340 if(we_are_sending == 0 && we_are_receiving_burst == 0) { 00341 off(); 00342 #if CONTIKIMAC_CONF_COMPOWER 00343 if(was_on && !radio_is_on) { 00344 compower_accumulate(&compower_idle_activity); 00345 } 00346 #endif /* CONTIKIMAC_CONF_COMPOWER */ 00347 } 00348 } 00349 /*---------------------------------------------------------------------------*/ 00350 static void 00351 powercycle_turn_radio_on(void) 00352 { 00353 if(we_are_sending == 0 && we_are_receiving_burst == 0) { 00354 on(); 00355 } 00356 } 00357 /*---------------------------------------------------------------------------*/ 00358 static char 00359 powercycle(struct rtimer *t, void *ptr) 00360 { 00361 #if SYNC_CYCLE_STARTS 00362 static volatile rtimer_clock_t sync_cycle_start; 00363 static volatile uint8_t sync_cycle_phase; 00364 #endif 00365 00366 PT_BEGIN(&pt); 00367 00368 #if SYNC_CYCLE_STARTS 00369 sync_cycle_start = RTIMER_NOW(); 00370 #else 00371 cycle_start = RTIMER_NOW(); 00372 #endif 00373 00374 while(1) { 00375 static uint8_t packet_seen; 00376 static rtimer_clock_t t0; 00377 static uint8_t count; 00378 00379 #if SYNC_CYCLE_STARTS 00380 /* Compute cycle start when RTIMER_ARCH_SECOND is not a multiple of CHANNEL_CHECK_RATE */ 00381 if (sync_cycle_phase++ == NETSTACK_RDC_CHANNEL_CHECK_RATE) { 00382 sync_cycle_phase = 0; 00383 sync_cycle_start += RTIMER_ARCH_SECOND; 00384 cycle_start = sync_cycle_start; 00385 } else { 00386 #if (RTIMER_ARCH_SECOND * NETSTACK_RDC_CHANNEL_CHECK_RATE) > 65535 00387 cycle_start = sync_cycle_start + ((unsigned long)(sync_cycle_phase*RTIMER_ARCH_SECOND))/NETSTACK_RDC_CHANNEL_CHECK_RATE; 00388 #else 00389 cycle_start = sync_cycle_start + (sync_cycle_phase*RTIMER_ARCH_SECOND)/NETSTACK_RDC_CHANNEL_CHECK_RATE; 00390 #endif 00391 } 00392 #else 00393 cycle_start += CYCLE_TIME; 00394 #endif 00395 00396 packet_seen = 0; 00397 00398 for(count = 0; count < CCA_COUNT_MAX; ++count) { 00399 t0 = RTIMER_NOW(); 00400 if(we_are_sending == 0 && we_are_receiving_burst == 0) { 00401 powercycle_turn_radio_on(); 00402 /* Check if a packet is seen in the air. If so, we keep the 00403 radio on for a while (LISTEN_TIME_AFTER_PACKET_DETECTED) to 00404 be able to receive the packet. We also continuously check 00405 the radio medium to make sure that we wasn't woken up by a 00406 false positive: a spurious radio interference that was not 00407 caused by an incoming packet. */ 00408 if(NETSTACK_RADIO.channel_clear() == 0) { 00409 packet_seen = 1; 00410 break; 00411 } 00412 powercycle_turn_radio_off(); 00413 } 00414 schedule_powercycle_fixed(t, RTIMER_NOW() + CCA_SLEEP_TIME); 00415 PT_YIELD(&pt); 00416 } 00417 00418 if(packet_seen) { 00419 static rtimer_clock_t start; 00420 static uint8_t silence_periods, periods; 00421 start = RTIMER_NOW(); 00422 00423 periods = silence_periods = 0; 00424 while(we_are_sending == 0 && radio_is_on && 00425 RTIMER_CLOCK_LT(RTIMER_NOW(), 00426 (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { 00427 00428 /* Check for a number of consecutive periods of 00429 non-activity. If we see two such periods, we turn the 00430 radio off. Also, if a packet has been successfully 00431 received (as indicated by the 00432 NETSTACK_RADIO.pending_packet() function), we stop 00433 snooping. */ 00434 #if !RDC_CONF_HARDWARE_CSMA 00435 /* A cca cycle will disrupt rx on some radios, e.g. mc1322x, rf230 */ 00436 /*TODO: Modify those drivers to just return the internal RSSI when already in rx mode */ 00437 if(NETSTACK_RADIO.channel_clear()) { 00438 ++silence_periods; 00439 } else { 00440 silence_periods = 0; 00441 } 00442 #endif 00443 00444 ++periods; 00445 00446 if(NETSTACK_RADIO.receiving_packet()) { 00447 silence_periods = 0; 00448 } 00449 if(silence_periods > MAX_SILENCE_PERIODS) { 00450 powercycle_turn_radio_off(); 00451 break; 00452 } 00453 if(WITH_FAST_SLEEP && 00454 periods > MAX_NONACTIVITY_PERIODS && 00455 !(NETSTACK_RADIO.receiving_packet() || 00456 NETSTACK_RADIO.pending_packet())) { 00457 powercycle_turn_radio_off(); 00458 break; 00459 } 00460 if(NETSTACK_RADIO.pending_packet()) { 00461 break; 00462 } 00463 00464 schedule_powercycle(t, CCA_CHECK_TIME + CCA_SLEEP_TIME); 00465 PT_YIELD(&pt); 00466 } 00467 if(radio_is_on) { 00468 if(!(NETSTACK_RADIO.receiving_packet() || 00469 NETSTACK_RADIO.pending_packet()) || 00470 !RTIMER_CLOCK_LT(RTIMER_NOW(), 00471 (start + LISTEN_TIME_AFTER_PACKET_DETECTED))) { 00472 powercycle_turn_radio_off(); 00473 } 00474 } 00475 } 00476 00477 if(RTIMER_CLOCK_LT(RTIMER_NOW() - cycle_start, CYCLE_TIME - CHECK_TIME * 4)) { 00478 /* Schedule the next powercycle interrupt, or sleep the mcu until then. 00479 Sleeping will not exit from this interrupt, so ensure an occasional wake cycle 00480 or foreground processing will be blocked until a packet is detected */ 00481 #if RDC_CONF_MCU_SLEEP 00482 static uint8_t sleepcycle; 00483 if ((sleepcycle++<16) && !we_are_sending && !radio_is_on) { 00484 rtimer_arch_sleep(CYCLE_TIME - (RTIMER_NOW() - cycle_start)); 00485 } else { 00486 sleepcycle = 0; 00487 schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); 00488 PT_YIELD(&pt); 00489 } 00490 #else 00491 schedule_powercycle_fixed(t, CYCLE_TIME + cycle_start); 00492 PT_YIELD(&pt); 00493 #endif 00494 } 00495 } 00496 00497 PT_END(&pt); 00498 } 00499 /*---------------------------------------------------------------------------*/ 00500 static int 00501 broadcast_rate_drop(void) 00502 { 00503 #if CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 00504 if(!timer_expired(&broadcast_rate_timer)) { 00505 broadcast_rate_counter++; 00506 if(broadcast_rate_counter < CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT) { 00507 return 0; 00508 } else { 00509 return 1; 00510 } 00511 } else { 00512 timer_set(&broadcast_rate_timer, CLOCK_SECOND); 00513 broadcast_rate_counter = 0; 00514 return 0; 00515 } 00516 #else /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */ 00517 return 0; 00518 #endif /* CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT */ 00519 } 00520 /*---------------------------------------------------------------------------*/ 00521 static int 00522 send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, struct rdc_buf_list *buf_list) 00523 { 00524 rtimer_clock_t t0; 00525 rtimer_clock_t encounter_time = 0; 00526 int strobes; 00527 uint8_t got_strobe_ack = 0; 00528 int hdrlen, len; 00529 uint8_t is_broadcast = 0; 00530 uint8_t is_reliable = 0; 00531 uint8_t is_known_receiver = 0; 00532 uint8_t collisions; 00533 int transmit_len; 00534 int ret; 00535 uint8_t contikimac_was_on; 00536 uint8_t seqno; 00537 #if WITH_CONTIKIMAC_HEADER 00538 struct hdr *chdr; 00539 #endif /* WITH_CONTIKIMAC_HEADER */ 00540 00541 /* Exit if RDC and radio were explicitly turned off */ 00542 if (!contikimac_is_on && !contikimac_keep_radio_on) { 00543 PRINTF("contikimac: radio is turned off\n"); 00544 return MAC_TX_ERR_FATAL; 00545 } 00546 00547 if(packetbuf_totlen() == 0) { 00548 PRINTF("contikimac: send_packet data len 0\n"); 00549 return MAC_TX_ERR_FATAL; 00550 } 00551 00552 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); 00553 if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) { 00554 is_broadcast = 1; 00555 PRINTDEBUG("contikimac: send broadcast\n"); 00556 00557 if(broadcast_rate_drop()) { 00558 return MAC_TX_COLLISION; 00559 } 00560 } else { 00561 #if UIP_CONF_IPV6 00562 PRINTDEBUG("contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", 00563 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], 00564 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1], 00565 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2], 00566 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3], 00567 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4], 00568 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5], 00569 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6], 00570 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]); 00571 #else /* UIP_CONF_IPV6 */ 00572 PRINTDEBUG("contikimac: send unicast to %u.%u\n", 00573 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], 00574 packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]); 00575 #endif /* UIP_CONF_IPV6 */ 00576 } 00577 is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) || 00578 packetbuf_attr(PACKETBUF_ATTR_ERELIABLE); 00579 00580 packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); 00581 00582 #if WITH_CONTIKIMAC_HEADER 00583 hdrlen = packetbuf_totlen(); 00584 if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) { 00585 /* Failed to allocate space for contikimac header */ 00586 PRINTF("contikimac: send failed, too large header\n"); 00587 return MAC_TX_ERR_FATAL; 00588 } 00589 chdr = packetbuf_hdrptr(); 00590 chdr->id = CONTIKIMAC_ID; 00591 chdr->len = hdrlen; 00592 00593 /* Create the MAC header for the data packet. */ 00594 hdrlen = NETSTACK_FRAMER.create(); 00595 if(hdrlen < 0) { 00596 /* Failed to send */ 00597 PRINTF("contikimac: send failed, too large header\n"); 00598 packetbuf_hdr_remove(sizeof(struct hdr)); 00599 return MAC_TX_ERR_FATAL; 00600 } 00601 hdrlen += sizeof(struct hdr); 00602 #else 00603 /* Create the MAC header for the data packet. */ 00604 hdrlen = NETSTACK_FRAMER.create(); 00605 if(hdrlen < 0) { 00606 /* Failed to send */ 00607 PRINTF("contikimac: send failed, too large header\n"); 00608 return MAC_TX_ERR_FATAL; 00609 } 00610 #endif 00611 00612 00613 /* Make sure that the packet is longer or equal to the shortest 00614 packet length. */ 00615 transmit_len = packetbuf_totlen(); 00616 if(transmit_len < SHORTEST_PACKET_SIZE) { 00617 /* Pad with zeroes */ 00618 uint8_t *ptr; 00619 ptr = packetbuf_dataptr(); 00620 memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen()); 00621 00622 PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen()); 00623 transmit_len = SHORTEST_PACKET_SIZE; 00624 } 00625 00626 00627 packetbuf_compact(); 00628 00629 NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len); 00630 00631 /* Remove the MAC-layer header since it will be recreated next time around. */ 00632 packetbuf_hdr_remove(hdrlen); 00633 00634 if(!is_broadcast && !is_receiver_awake) { 00635 #if WITH_PHASE_OPTIMIZATION 00636 ret = phase_wait(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), 00637 CYCLE_TIME, GUARD_TIME, 00638 mac_callback, mac_callback_ptr, buf_list); 00639 if(ret == PHASE_DEFERRED) { 00640 return MAC_TX_DEFERRED; 00641 } 00642 if(ret != PHASE_UNKNOWN) { 00643 is_known_receiver = 1; 00644 } 00645 #endif /* WITH_PHASE_OPTIMIZATION */ 00646 } 00647 00648 00649 00650 /* By setting we_are_sending to one, we ensure that the rtimer 00651 powercycle interrupt do not interfere with us sending the packet. */ 00652 we_are_sending = 1; 00653 00654 /* If we have a pending packet in the radio, we should not send now, 00655 because we will trash the received packet. Instead, we signal 00656 that we have a collision, which lets the packet be received. This 00657 packet will be retransmitted later by the MAC protocol 00658 instread. */ 00659 if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) { 00660 we_are_sending = 0; 00661 PRINTF("contikimac: collision receiving %d, pending %d\n", 00662 NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet()); 00663 return MAC_TX_COLLISION; 00664 } 00665 00666 /* Switch off the radio to ensure that we didn't start sending while 00667 the radio was doing a channel check. */ 00668 off(); 00669 00670 00671 strobes = 0; 00672 00673 /* Send a train of strobes until the receiver answers with an ACK. */ 00674 collisions = 0; 00675 00676 got_strobe_ack = 0; 00677 00678 /* Set contikimac_is_on to one to allow the on() and off() functions 00679 to control the radio. We restore the old value of 00680 contikimac_is_on when we are done. */ 00681 contikimac_was_on = contikimac_is_on; 00682 contikimac_is_on = 1; 00683 00684 #if !RDC_CONF_HARDWARE_CSMA 00685 /* Check if there are any transmissions by others. */ 00686 /* TODO: why does this give collisions before sending with the mc1322x? */ 00687 if(is_receiver_awake == 0) { 00688 int i; 00689 for(i = 0; i < CCA_COUNT_MAX_TX; ++i) { 00690 t0 = RTIMER_NOW(); 00691 on(); 00692 #if CCA_CHECK_TIME > 0 00693 while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { } 00694 #endif 00695 if(NETSTACK_RADIO.channel_clear() == 0) { 00696 collisions++; 00697 off(); 00698 break; 00699 } 00700 off(); 00701 t0 = RTIMER_NOW(); 00702 while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { } 00703 } 00704 } 00705 00706 if(collisions > 0) { 00707 we_are_sending = 0; 00708 off(); 00709 PRINTF("contikimac: collisions before sending\n"); 00710 contikimac_is_on = contikimac_was_on; 00711 return MAC_TX_COLLISION; 00712 } 00713 #endif /* RDC_CONF_HARDWARE_CSMA */ 00714 00715 #if !RDC_CONF_HARDWARE_ACK 00716 if(!is_broadcast) { 00717 /* Turn radio on to receive expected unicast ack. 00718 Not necessary with hardware ack detection, and may trigger an unnecessary cca or rx cycle */ 00719 on(); 00720 } 00721 #endif 00722 00723 watchdog_periodic(); 00724 t0 = RTIMER_NOW(); 00725 seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO); 00726 for(strobes = 0, collisions = 0; 00727 got_strobe_ack == 0 && collisions == 0 && 00728 RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) { 00729 00730 watchdog_periodic(); 00731 00732 if((is_receiver_awake || is_known_receiver) && !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) { 00733 PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]); 00734 break; 00735 } 00736 00737 len = 0; 00738 00739 00740 { 00741 rtimer_clock_t wt; 00742 rtimer_clock_t txtime; 00743 int ret; 00744 00745 txtime = RTIMER_NOW(); 00746 ret = NETSTACK_RADIO.transmit(transmit_len); 00747 00748 #if RDC_CONF_HARDWARE_ACK 00749 /* For radios that block in the transmit routine and detect the ACK in hardware */ 00750 if(ret == RADIO_TX_OK) { 00751 if(!is_broadcast) { 00752 got_strobe_ack = 1; 00753 encounter_time = txtime; 00754 break; 00755 } 00756 } else if (ret == RADIO_TX_NOACK) { 00757 } else if (ret == RADIO_TX_COLLISION) { 00758 PRINTF("contikimac: collisions while sending\n"); 00759 collisions++; 00760 } 00761 wt = RTIMER_NOW(); 00762 while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } 00763 #else 00764 /* Wait for the ACK packet */ 00765 wt = RTIMER_NOW(); 00766 while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { } 00767 00768 if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() || 00769 NETSTACK_RADIO.pending_packet() || 00770 NETSTACK_RADIO.channel_clear() == 0)) { 00771 uint8_t ackbuf[ACK_LEN]; 00772 wt = RTIMER_NOW(); 00773 while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { } 00774 00775 len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); 00776 if(len == ACK_LEN && seqno == ackbuf[ACK_LEN-1]) { 00777 got_strobe_ack = 1; 00778 encounter_time = txtime; 00779 break; 00780 } else { 00781 PRINTF("contikimac: collisions while sending\n"); 00782 collisions++; 00783 } 00784 } 00785 #endif /* RDC_CONF_HARDWARE_ACK */ 00786 } 00787 } 00788 00789 off(); 00790 00791 PRINTF("contikimac: send (strobes=%u, len=%u, %s, %s), done\n", strobes, 00792 packetbuf_totlen(), 00793 got_strobe_ack ? "ack" : "no ack", 00794 collisions ? "collision" : "no collision"); 00795 00796 #if CONTIKIMAC_CONF_COMPOWER 00797 /* Accumulate the power consumption for the packet transmission. */ 00798 compower_accumulate(¤t_packet); 00799 00800 /* Convert the accumulated power consumption for the transmitted 00801 packet to packet attributes so that the higher levels can keep 00802 track of the amount of energy spent on transmitting the 00803 packet. */ 00804 compower_attrconv(¤t_packet); 00805 00806 /* Clear the accumulated power consumption so that it is ready for 00807 the next packet. */ 00808 compower_clear(¤t_packet); 00809 #endif /* CONTIKIMAC_CONF_COMPOWER */ 00810 00811 contikimac_is_on = contikimac_was_on; 00812 we_are_sending = 0; 00813 00814 /* Determine the return value that we will return from the 00815 function. We must pass this value to the phase module before we 00816 return from the function. */ 00817 if(collisions > 0) { 00818 ret = MAC_TX_COLLISION; 00819 } else if(!is_broadcast && !got_strobe_ack) { 00820 ret = MAC_TX_NOACK; 00821 } else { 00822 ret = MAC_TX_OK; 00823 } 00824 00825 #if WITH_PHASE_OPTIMIZATION 00826 00827 if(is_known_receiver && got_strobe_ack) { 00828 PRINTF("no miss %d wake-ups %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0], 00829 strobes); 00830 } 00831 00832 if(!is_broadcast) { 00833 if(collisions == 0 && is_receiver_awake == 0) { 00834 phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER), encounter_time, 00835 ret); 00836 } 00837 } 00838 #endif /* WITH_PHASE_OPTIMIZATION */ 00839 00840 return ret; 00841 } 00842 /*---------------------------------------------------------------------------*/ 00843 static void 00844 qsend_packet(mac_callback_t sent, void *ptr) 00845 { 00846 int ret = send_packet(sent, ptr, NULL); 00847 if(ret != MAC_TX_DEFERRED) { 00848 mac_call_sent_callback(sent, ptr, ret, 1); 00849 } 00850 } 00851 /*---------------------------------------------------------------------------*/ 00852 static void 00853 qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) 00854 { 00855 struct rdc_buf_list *curr = buf_list; 00856 struct rdc_buf_list *next; 00857 int ret; 00858 if(curr == NULL) { 00859 return; 00860 } 00861 /* Do not send during reception of a burst */ 00862 if(we_are_receiving_burst) { 00863 /* Prepare the packetbuf for callback */ 00864 queuebuf_to_packetbuf(curr->buf); 00865 /* Return COLLISION so the MAC may try again later */ 00866 mac_call_sent_callback(sent, ptr, MAC_TX_COLLISION, 1); 00867 return; 00868 } 00869 /* The receiver needs to be awoken before we send */ 00870 is_receiver_awake = 0; 00871 do { /* A loop sending a burst of packets from buf_list */ 00872 next = list_item_next(curr); 00873 00874 /* Prepare the packetbuf */ 00875 queuebuf_to_packetbuf(curr->buf); 00876 if(next != NULL) { 00877 packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1); 00878 } 00879 00880 /* Send the current packet */ 00881 ret = send_packet(sent, ptr, curr); 00882 if(ret != MAC_TX_DEFERRED) { 00883 mac_call_sent_callback(sent, ptr, ret, 1); 00884 } 00885 00886 if(ret == MAC_TX_OK) { 00887 if(next != NULL) { 00888 /* We're in a burst, no need to wake the receiver up again */ 00889 is_receiver_awake = 1; 00890 curr = next; 00891 } 00892 } else { 00893 /* The transmission failed, we stop the burst */ 00894 next = NULL; 00895 } 00896 } while(next != NULL); 00897 is_receiver_awake = 0; 00898 } 00899 /*---------------------------------------------------------------------------*/ 00900 /* Timer callback triggered when receiving a burst, after having waited for a next 00901 packet for a too long time. Turns the radio off and leaves burst reception mode */ 00902 static void 00903 recv_burst_off(void *ptr) 00904 { 00905 off(); 00906 we_are_receiving_burst = 0; 00907 } 00908 /*---------------------------------------------------------------------------*/ 00909 static void 00910 input_packet(void) 00911 { 00912 static struct ctimer ct; 00913 if(!we_are_receiving_burst) { 00914 off(); 00915 } 00916 00917 /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ 00918 00919 if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) { 00920 00921 #if WITH_CONTIKIMAC_HEADER 00922 struct hdr *chdr; 00923 chdr = packetbuf_dataptr(); 00924 if(chdr->id != CONTIKIMAC_ID) { 00925 PRINTF("contikimac: failed to parse hdr (%u)\n", packetbuf_totlen()); 00926 return; 00927 } 00928 packetbuf_hdrreduce(sizeof(struct hdr)); 00929 packetbuf_set_datalen(chdr->len); 00930 #endif /* WITH_CONTIKIMAC_HEADER */ 00931 00932 if(packetbuf_datalen() > 0 && 00933 packetbuf_totlen() > 0 && 00934 (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), 00935 &rimeaddr_node_addr) || 00936 rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), 00937 &rimeaddr_null))) { 00938 /* This is a regular packet that is destined to us or to the 00939 broadcast address. */ 00940 00941 /* If FRAME_PENDING is set, we are receiving a packets in a burst */ 00942 we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING); 00943 if(we_are_receiving_burst) { 00944 on(); 00945 /* Set a timer to turn the radio off in case we do not receive a next packet */ 00946 ctimer_set(&ct, INTER_PACKET_DEADLINE, recv_burst_off, NULL); 00947 } else { 00948 off(); 00949 ctimer_stop(&ct); 00950 } 00951 00952 /* Check for duplicate packet by comparing the sequence number 00953 of the incoming packet with the last few ones we saw. */ 00954 { 00955 int i; 00956 for(i = 0; i < MAX_SEQNOS; ++i) { 00957 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno && 00958 rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), 00959 &received_seqnos[i].sender)) { 00960 /* Drop the packet. */ 00961 /* printf("Drop duplicate ContikiMAC layer packet\n");*/ 00962 return; 00963 } 00964 } 00965 for(i = MAX_SEQNOS - 1; i > 0; --i) { 00966 memcpy(&received_seqnos[i], &received_seqnos[i - 1], 00967 sizeof(struct seqno)); 00968 } 00969 received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); 00970 rimeaddr_copy(&received_seqnos[0].sender, 00971 packetbuf_addr(PACKETBUF_ADDR_SENDER)); 00972 } 00973 00974 #if CONTIKIMAC_CONF_COMPOWER 00975 /* Accumulate the power consumption for the packet reception. */ 00976 compower_accumulate(¤t_packet); 00977 /* Convert the accumulated power consumption for the received 00978 packet to packet attributes so that the higher levels can 00979 keep track of the amount of energy spent on receiving the 00980 packet. */ 00981 compower_attrconv(¤t_packet); 00982 00983 /* Clear the accumulated power consumption so that it is ready 00984 for the next packet. */ 00985 compower_clear(¤t_packet); 00986 #endif /* CONTIKIMAC_CONF_COMPOWER */ 00987 00988 PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen()); 00989 NETSTACK_MAC.input(); 00990 return; 00991 } else { 00992 PRINTDEBUG("contikimac: data not for us\n"); 00993 } 00994 } else { 00995 PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen()); 00996 } 00997 } 00998 /*---------------------------------------------------------------------------*/ 00999 static void 01000 init(void) 01001 { 01002 radio_is_on = 0; 01003 PT_INIT(&pt); 01004 01005 rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, 01006 (void (*)(struct rtimer *, void *))powercycle, NULL); 01007 01008 contikimac_is_on = 1; 01009 01010 #if WITH_PHASE_OPTIMIZATION 01011 phase_init(&phase_list); 01012 #endif /* WITH_PHASE_OPTIMIZATION */ 01013 01014 } 01015 /*---------------------------------------------------------------------------*/ 01016 static int 01017 turn_on(void) 01018 { 01019 if(contikimac_is_on == 0) { 01020 contikimac_is_on = 1; 01021 contikimac_keep_radio_on = 0; 01022 rtimer_set(&rt, RTIMER_NOW() + CYCLE_TIME, 1, 01023 (void (*)(struct rtimer *, void *))powercycle, NULL); 01024 } 01025 return 1; 01026 } 01027 /*---------------------------------------------------------------------------*/ 01028 static int 01029 turn_off(int keep_radio_on) 01030 { 01031 contikimac_is_on = 0; 01032 contikimac_keep_radio_on = keep_radio_on; 01033 if(keep_radio_on) { 01034 radio_is_on = 1; 01035 return NETSTACK_RADIO.on(); 01036 } else { 01037 radio_is_on = 0; 01038 return NETSTACK_RADIO.off(); 01039 } 01040 } 01041 /*---------------------------------------------------------------------------*/ 01042 static unsigned short 01043 duty_cycle(void) 01044 { 01045 return (1ul * CLOCK_SECOND * CYCLE_TIME) / RTIMER_ARCH_SECOND; 01046 } 01047 /*---------------------------------------------------------------------------*/ 01048 const struct rdc_driver contikimac_driver = { 01049 "ContikiMAC", 01050 init, 01051 qsend_packet, 01052 qsend_list, 01053 input_packet, 01054 turn_on, 01055 turn_off, 01056 duty_cycle, 01057 }; 01058 /*---------------------------------------------------------------------------*/ 01059 uint16_t 01060 contikimac_debug_print(void) 01061 { 01062 return 0; 01063 } 01064 /*---------------------------------------------------------------------------*/