Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2008, 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 * $Id: sicslowmac.c,v 1.9 2010/06/14 19:19:17 adamdunkels Exp $ 00032 */ 00033 00034 00035 /** 00036 * \file 00037 * Example glue code between the existing MAC code and the 00038 * Contiki mac interface 00039 * 00040 * \author 00041 * Adam Dunkels <adam@sics.se> 00042 * Eric Gnoske <egnoske@gmail.com> 00043 * Blake Leverett <bleverett@gmail.com> 00044 * 00045 * \addtogroup rf230mac 00046 */ 00047 00048 #include <stdlib.h> 00049 #include <stdbool.h> 00050 #include <string.h> 00051 #include <stdio.h> 00052 #include <avr/eeprom.h> 00053 #include <util/delay.h> 00054 #include "net/packetbuf.h" 00055 #include "zmac.h" 00056 #include "mac.h" 00057 #include "frame.h" 00058 #include "radio.h" 00059 #include "tcpip.h" 00060 #include "sicslowmac.h" 00061 #include "sicslowpan.h" 00062 #include "ieee-15-4-manager.h" 00063 00064 /* Macros */ 00065 #define DEBUG 0 00066 #define MAX_EVENTS 10 00067 00068 #if DEBUG 00069 #define PRINTF(...) printf(__VA_ARGS__) 00070 #define SICSLOW_CORRECTION_DELAY 70 00071 #else 00072 #define PRINTF(...) 00073 #define SICSLOW_CORRECTION_DELAY 7 00074 #endif 00075 00076 #ifdef JACKDAW 00077 #include "sicslow_ethernet.h" 00078 #define LOG_FRAME(x,y) mac_logTXtoEthernet(x,y) 00079 #else 00080 #define LOG_FRAME(x,y) 00081 #endif 00082 00083 /* Globals */ 00084 static struct mac_driver mac_driver_struct; 00085 static struct mac_driver *pmac_driver = &mac_driver_struct; 00086 extern ieee_15_4_manager_t ieee15_4ManagerAddress; 00087 static parsed_frame_t *parsed_frame; 00088 00089 /* The core mac layer has a pointer to the driver name in the first field. 00090 * It calls the radio driver with radio->send, which is the first field of the radio driver. 00091 * This glue directs radio->send to the custom mac layer. 00092 */ 00093 const struct mac_driver sicslowmac_driver = { 00094 (char *)sicslowmac_dataRequest, //Remove compiler warning. 00095 /* read_packet, */ 00096 /* set_receive_function, */ 00097 /* on, */ 00098 /* off, */ 00099 }; 00100 00101 static struct { 00102 uint8_t head; 00103 uint8_t tail; 00104 event_object_t event_object[MAX_EVENTS]; 00105 } event_queue; 00106 00107 /* Prototypes */ 00108 static void setinput(void (*r)(const struct mac_driver *d)); 00109 void (*pinput)(const struct mac_driver *r); 00110 void sicslowmac_unknownIndication(void); 00111 00112 00113 void (*sicslowmac_snifferhook)(const struct mac_driver *r) = NULL; 00114 00115 00116 /*---------------------------------------------------------------------------*/ 00117 /** 00118 * \brief Checks for any pending events in the queue. 00119 * 00120 * \return True if there is a pending event, else false. 00121 */ 00122 uint8_t 00123 mac_event_pending(void) 00124 { 00125 return (event_queue.head != event_queue.tail); 00126 } 00127 /*---------------------------------------------------------------------------*/ 00128 /** 00129 * \brief Puts an event into the queue of events. 00130 * 00131 * \param object is a pointer to the event to add to queue. 00132 */ 00133 void 00134 mac_put_event(event_object_t *object) 00135 { 00136 uint8_t newhead; 00137 00138 if ((event_queue.head + 1) % MAX_EVENTS == event_queue.tail){ 00139 /* queue full, get outta here */ 00140 return; 00141 } 00142 00143 newhead = event_queue.head; 00144 00145 /* store in queue */ 00146 event_queue.event_object[newhead] = *object; 00147 00148 /* calculate new head index */ 00149 newhead++; 00150 if (newhead >= MAX_EVENTS){ 00151 newhead = 0; 00152 } 00153 event_queue.head = newhead; 00154 } 00155 /*---------------------------------------------------------------------------*/ 00156 /** 00157 * \brief Pulls an event from the event queue. 00158 * Assumes that there is an event in the queue. See mac_event_pending(). 00159 * 00160 * \return Pointer to the event object, or NULL in the event of empty queue. 00161 */ 00162 event_object_t 00163 *mac_get_event(void) 00164 { 00165 event_object_t *object = NULL; 00166 volatile uint8_t newtail; 00167 00168 newtail = event_queue.tail; 00169 00170 object = &(event_queue.event_object[newtail]); 00171 00172 /* calculate new tail */ 00173 newtail++; 00174 if (newtail >= MAX_EVENTS){ 00175 newtail = 0; 00176 } 00177 00178 event_queue.tail = newtail; 00179 00180 return(object); 00181 } 00182 00183 void mac_pollhandler(void) 00184 { 00185 mac_task(0, NULL); 00186 } 00187 00188 /*---------------------------------------------------------------------------*/ 00189 /** 00190 * \brief This is the main loop task for the MAC. Called by the 00191 * main application loop. 00192 */ 00193 void 00194 mac_task(process_event_t ev, process_data_t data) 00195 { 00196 /* check for event in queue */ 00197 event_object_t *event; 00198 00199 if(mac_event_pending()){ 00200 00201 event = mac_get_event(); 00202 00203 /* Handle events from radio */ 00204 if (event){ 00205 00206 if (event->event == MAC_EVENT_RX){ 00207 /* got a frame, find out with kind of frame */ 00208 parsed_frame = (parsed_frame_t *)event->data; 00209 if (parsed_frame->fcf->frameType == DATAFRAME){ 00210 sicslowmac_dataIndication(); 00211 } else { 00212 00213 /* Hook to cath unknown frames */ 00214 sicslowmac_unknownIndication(); 00215 } 00216 00217 00218 /* Frame no longer in use */ 00219 parsed_frame->in_use = false; 00220 } 00221 00222 if (event->event == MAC_EVENT_DROPPED){ 00223 /* Frame was dropped */ 00224 PRINTF("sicslowmac: Frame Dropped!\n"); 00225 } 00226 } 00227 } 00228 } 00229 /*---------------------------------------------------------------------------*/ 00230 void 00231 setinput(void (*r)(const struct mac_driver *d)) 00232 { 00233 pinput = r; 00234 } 00235 /*---------------------------------------------------------------------------*/ 00236 static uint8_t dest_reversed[UIP_LLADDR_LEN]; 00237 static uint8_t src_reversed[UIP_LLADDR_LEN]; 00238 00239 # define MSB(u16) (((uint8_t* )&u16)[1]) 00240 # define LSB(u16) (((uint8_t* )&u16)[0]) 00241 00242 void 00243 sicslowmac_dataIndication(void) 00244 { 00245 packetbuf_clear(); 00246 00247 00248 #if UIP_LLADDR_LEN == 8 00249 /* Finally, get the stuff into the rime buffer.... */ 00250 packetbuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length); 00251 packetbuf_set_datalen(parsed_frame->payload_length); 00252 00253 memcpy(dest_reversed, (uint8_t *)parsed_frame->dest_addr, UIP_LLADDR_LEN); 00254 memcpy(src_reversed, (uint8_t *)parsed_frame->src_addr, UIP_LLADDR_LEN); 00255 00256 /* Change addresses to expected byte order */ 00257 byte_reverse((uint8_t *)dest_reversed, UIP_LLADDR_LEN); 00258 byte_reverse((uint8_t *)src_reversed, UIP_LLADDR_LEN); 00259 00260 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)dest_reversed); 00261 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)src_reversed); 00262 00263 #elif UIP_CONF_USE_RUM 00264 /* Finally, get the stuff into the rime buffer.... */ 00265 packetbuf_copyfrom(parsed_frame->payload + UIP_DATA_RUM_OFFSET, parsed_frame->payload_length - UIP_DATA_RUM_OFFSET); 00266 packetbuf_set_datalen(parsed_frame->payload_length + UIP_DATA_RUM_OFFSET); 00267 00268 dest_reversed[0] = MSB(parsed_frame->dest_pid); 00269 dest_reversed[1] = LSB(parsed_frame->dest_pid); 00270 dest_reversed[2] = 0; 00271 dest_reversed[3] = 0; 00272 dest_reversed[4] = MSB(parsed_frame->payload[0]); //FinalDestAddr 00273 dest_reversed[5] = LSB(parsed_frame->payload[1]); 00274 00275 src_reversed[0] = MSB(parsed_frame->src_pid); 00276 src_reversed[1] = LSB(parsed_frame->src_pid); 00277 src_reversed[2] = 0; 00278 src_reversed[3] = 0; 00279 src_reversed[4] = MSB(parsed_frame->payload[2]); //originAddr 00280 src_reversed[5] = LSB(parsed_frame->payload[3]); 00281 00282 #else 00283 /* Finally, get the stuff into the rime buffer.... */ 00284 packetbuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length); 00285 packetbuf_set_datalen(parsed_frame->payload_length); 00286 00287 dest_reversed[0] = MSB(parsed_frame->dest_pid); 00288 dest_reversed[1] = LSB(parsed_frame->dest_pid); 00289 dest_reversed[2] = 0; 00290 dest_reversed[3] = 0; 00291 dest_reversed[4] = MSB(parsed_frame->dest_addr->addr16); 00292 dest_reversed[5] = LSB(parsed_frame->dest_addr->addr16); 00293 00294 src_reversed[0] = MSB(parsed_frame->src_pid); 00295 src_reversed[1] = LSB(parsed_frame->src_pid); 00296 src_reversed[2] = 0; 00297 src_reversed[3] = 0; 00298 src_reversed[4] = MSB(parsed_frame->src_addr->addr16); 00299 src_reversed[5] = LSB(parsed_frame->src_addr->addr16); 00300 00301 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)dest_reversed); 00302 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)src_reversed); 00303 00304 #endif 00305 00306 PRINTF("sicslowmac: hand off frame to sicslowpan \n"); 00307 pinput(pmac_driver); 00308 } 00309 00310 void 00311 sicslowmac_unknownIndication(void) 00312 { 00313 if (sicslowmac_snifferhook) { 00314 00315 packetbuf_clear(); 00316 00317 /* Finally, get the stuff into the rime buffer.... */ 00318 packetbuf_copyfrom(parsed_frame->payload, parsed_frame->payload_length); 00319 packetbuf_set_datalen(parsed_frame->payload_length); 00320 00321 #if UIP_LLADDR_LEN == 8 00322 memcpy(dest_reversed, (uint8_t *)parsed_frame->dest_addr, UIP_LLADDR_LEN); 00323 memcpy(src_reversed, (uint8_t *)parsed_frame->src_addr, UIP_LLADDR_LEN); 00324 00325 /* Change addresses to expected byte order */ 00326 byte_reverse((uint8_t *)dest_reversed, UIP_LLADDR_LEN); 00327 byte_reverse((uint8_t *)src_reversed, UIP_LLADDR_LEN); 00328 00329 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)dest_reversed); 00330 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)src_reversed); 00331 00332 #elif UIP_CONF_USE_RUM 00333 00334 dest_reversed[0] = MSB(parsed_frame->dest_pid); 00335 dest_reversed[1] = LSB(parsed_frame->dest_pid); 00336 dest_reversed[2] = 0; 00337 dest_reversed[3] = 0; 00338 dest_reversed[4] = MSB(parsed_frame->payload[0]); //FinalDestAddr 00339 dest_reversed[5] = LSB(parsed_frame->payload[1]); 00340 00341 src_reversed[0] = MSB(parsed_frame->src_pid); 00342 src_reversed[1] = LSB(parsed_frame->src_pid); 00343 src_reversed[2] = 0; 00344 src_reversed[3] = 0; 00345 src_reversed[4] = MSB(parsed_frame->payload[2]); //originAddr 00346 src_reversed[5] = LSB(parsed_frame->payload[3]); 00347 00348 #else 00349 00350 dest_reversed[0] = MSB(parsed_frame->dest_pid); 00351 dest_reversed[1] = LSB(parsed_frame->dest_pid); 00352 dest_reversed[2] = 0; 00353 dest_reversed[3] = 0; 00354 dest_reversed[4] = MSB(parsed_frame->dest_addr->addr16); 00355 dest_reversed[5] = LSB(parsed_frame->dest_addr->addr16); 00356 00357 src_reversed[0] = MSB(parsed_frame->src_pid); 00358 src_reversed[1] = LSB(parsed_frame->src_pid); 00359 src_reversed[2] = 0; 00360 src_reversed[3] = 0; 00361 src_reversed[4] = MSB(parsed_frame->src_addr->addr16); 00362 src_reversed[5] = LSB(parsed_frame->src_addr->addr16); 00363 00364 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)dest_reversed); 00365 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)src_reversed); 00366 00367 #endif 00368 00369 PRINTF("sicslowmac: hand off frame to sniffer \n"); 00370 00371 sicslowmac_snifferhook(pmac_driver); 00372 } 00373 00374 } 00375 00376 /*---------------------------------------------------------------------------*/ 00377 /** 00378 * \brief This is the implementation of the 15.4 MAC Data Request 00379 * primitive. 00380 * 00381 * \return Integer denoting success or failure. 00382 * \retval 0 Failure. 00383 * \retval 1 Success. 00384 * 00385 * The data request primitive creates the frame header based 00386 * on static and dynamic data. The static data will be refined 00387 * in phase II of the project. The frame payload and length are 00388 * retrieved from the rime buffer and rime length respectively. 00389 * 00390 * When the header and payload are assembled into the 00391 * frame_create_params structure, the frame is created 00392 * by a call to frame_tx_create and then transmited via 00393 * radio_send_data. 00394 */ 00395 /*---------------------------------------------------------------------------*/ 00396 int 00397 sicslowmac_dataRequest(void) 00398 { 00399 00400 _delay_ms(SICSLOW_CORRECTION_DELAY); 00401 00402 /* create structure to store result. */ 00403 frame_create_params_t params; 00404 frame_result_t result; 00405 00406 /* Save the msduHandle in a global variable. */ 00407 msduHandle = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); 00408 00409 /* Build the FCF. */ 00410 params.fcf.frameType = DATAFRAME; 00411 params.fcf.securityEnabled = false; 00412 params.fcf.framePending = false; 00413 params.fcf.ackRequired = packetbuf_attr(PACKETBUF_ATTR_RELIABLE); 00414 params.fcf.panIdCompression = false; 00415 00416 /* Insert IEEE 802.15.4 (2003) version bit. */ 00417 params.fcf.frameVersion = IEEE802154_2003; 00418 00419 /* Increment and set the data sequence number. */ 00420 params.seq = macDSN++; 00421 00422 /* Complete the addressing fields. */ 00423 /** 00424 \todo For phase 1 the addresses are all long. We'll need a mechanism 00425 in the rime attributes to tell the mac to use long or short for phase 2. 00426 */ 00427 params.fcf.srcAddrMode = LONGADDRMODE; 00428 params.dest_pid = ieee15_4ManagerAddress.get_dst_panid(); 00429 00430 /* 00431 * If the output address is NULL in the Rime buf, then it is broadcast 00432 * on the 802.15.4 network. 00433 */ 00434 if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null) ) { 00435 /* Broadcast requires short address mode. */ 00436 params.fcf.destAddrMode = SHORTADDRMODE; 00437 params.dest_pid = BROADCASTPANDID; 00438 params.dest_addr.addr16 = BROADCASTADDR; 00439 00440 } else { 00441 00442 /* Phase 1.5 - end nodes send to anyone? */ 00443 memcpy(¶ms.dest_addr, (uint8_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER), LONG_ADDR_LEN); 00444 00445 /* Change from sicslowpan byte arrangement to sicslowmac */ 00446 byte_reverse((uint8_t*)¶ms.dest_addr.addr64, LONG_ADDR_LEN); 00447 00448 /* Phase 1 - end nodes only sends to pan coordinator node. */ 00449 /* params.dest_addr.addr64 = ieee15_4ManagerAddress.get_coord_long_addr(); */ 00450 params.fcf.destAddrMode = LONGADDRMODE; 00451 } 00452 00453 /* Set the source PAN ID to the global variable. */ 00454 params.src_pid = ieee15_4ManagerAddress.get_src_panid(); 00455 00456 /* 00457 * Set up the source address using only the long address mode for 00458 * phase 1. 00459 */ 00460 params.src_addr.addr64 = ieee15_4ManagerAddress.get_long_addr(); 00461 00462 /* Copy the payload data. */ 00463 params.payload_len = packetbuf_datalen(); 00464 params.payload = packetbuf_dataptr(); 00465 00466 /* Create transmission frame. */ 00467 frame_tx_create(¶ms, &result); 00468 00469 /* Log if needed */ 00470 LOG_FRAME(¶ms, &result); 00471 00472 /* Retry up to this many times to send the packet if radio is busy */ 00473 uint8_t retry_count = 3; 00474 00475 while(retry_count) { 00476 00477 PRINTF("sicslowmac: sending packet of length %d to radio, result:", result.length); 00478 00479 00480 00481 /* Send data to radio. */ 00482 radio_status_t rv = radio_send_data(result.length, result.frame); 00483 00484 if (rv == RADIO_SUCCESS) { 00485 PRINTF(" Success\n"); 00486 00487 return 1; /* True says that the packet could be sent */ 00488 } 00489 00490 00491 if (rv != RADIO_WRONG_STATE) { 00492 PRINTF(" Failed\n"); 00493 return 0; 00494 } 00495 00496 PRINTF(" Radio busy, retrying\n"); 00497 00498 /** \todo: Fix delay in sicslowmac so they do not block receiving */ 00499 00500 //We have blocking delay here, it is safest this way. BUT doesn't solve the 00501 //problem of TX when you are RXing.. as the RX code can't execute! 00502 if (retry_count == 3) { 00503 _delay_ms(10); 00504 } else if (retry_count == 2) { 00505 _delay_ms(50); 00506 } else if (retry_count == 1) { 00507 _delay_ms(200); 00508 } 00509 00510 retry_count--; 00511 } 00512 00513 PRINTF("sicslowmac: Unable to send packet, dropped\n"); 00514 return 0; 00515 00516 } 00517 /*---------------------------------------------------------------------------*/ 00518 /** 00519 * \brief Stub function that will be implemented in phase 2 to cause 00520 * end nodes to sleep. 00521 */ 00522 int 00523 mac_wake(void) 00524 { 00525 return 1; 00526 } 00527 /*---------------------------------------------------------------------------*/ 00528 /** 00529 * \brief Stub function that will be implemented in phase 2 to cause 00530 * end nodes to sleep. 00531 */ 00532 int 00533 mac_sleep(void) 00534 { 00535 return 1; 00536 } 00537 /*---------------------------------------------------------------------------*/ 00538 const struct mac_driver * 00539 sicslowmac_init(const struct radio_driver *d) 00540 { 00541 /* AD: commented out the radio_driver code for now.*/ 00542 /* radio = d; 00543 radio->set_receive_function(input_packet); 00544 radio->on();*/ 00545 00546 return &sicslowmac_driver; 00547 } 00548 /*---------------------------------------------------------------------------*/ 00549 /** 00550 * \brief This is the implementation of the 15.4 MAC Reset Request 00551 * primitive. 00552 * \param setDefaultPIB True if the default PIB values should be set. 00553 * \return Integer denoting success or failure. 00554 * \retval 0 Failure. 00555 * \retval 1 Success. 00556 * 00557 * Sets all PIB values to default. 00558 */ 00559 void 00560 sicslowmac_resetRequest (bool setDefaultPIB) 00561 { 00562 if(setDefaultPIB){ 00563 /* initialize all of the MAC PIB variables to their default values */ 00564 macCoordShortAddress = 0xffff; 00565 macDSN = rand() % 256; 00566 macSrcPANId = SOURCE_PAN_ID; 00567 macDstPANId = DEST_PAN_ID; 00568 macShortAddress = 0xffff; 00569 /* Setup the address of this device by reading a stored address from eeprom. */ 00570 /** \todo This might be read from the serial eeprom onboard Raven. */ 00571 AVR_ENTER_CRITICAL_REGION(); 00572 eeprom_read_block ((void *)&macLongAddr, EEPROMMACADDRESS, 8); 00573 00574 byte_reverse((uint8_t *) &macLongAddr, 8); 00575 00576 00577 AVR_LEAVE_CRITICAL_REGION(); 00578 } 00579 } 00580 00581 parsed_frame_t * sicslowmac_get_frame(void) 00582 { 00583 return parsed_frame; 00584 } 00585 00586 /*---------------------------------------------------------------------------*/ 00587 struct mac_driver * sicslowmac_get_driver(void) 00588 { 00589 return pmac_driver; 00590 } 00591 /*---------------------------------------------------------------------------*/ 00592 PROCESS(mac_process, "802.15.4 MAC process"); 00593 PROCESS_THREAD(mac_process, ev, data) 00594 { 00595 00596 PROCESS_POLLHANDLER(mac_pollhandler()); 00597 00598 00599 PROCESS_BEGIN(); 00600 00601 radio_status_t return_value; 00602 00603 /* init radio */ 00604 /** \todo: this screws up if calosc is set to TRUE, find out why? */ 00605 return_value = radio_init(false, NULL, NULL, NULL); 00606 00607 #if DEBUG 00608 if (return_value == RADIO_SUCCESS) { 00609 printf("Radio init successful.\n"); 00610 } else { 00611 printf("Radio init failed with return: %d\n", return_value); 00612 } 00613 #endif 00614 00615 uint8_t eeprom_channel; 00616 uint8_t eeprom_check; 00617 00618 eeprom_channel = eeprom_read_byte((uint8_t *)9); 00619 eeprom_check = eeprom_read_byte((uint8_t *)10); 00620 00621 if ((eeprom_channel < 11) || (eeprom_channel > 26) || ((uint8_t)eeprom_channel != (uint8_t)~eeprom_check)) { 00622 #if UIP_CONF_USE_RUM 00623 eeprom_channel = 19; //Default 00624 #else 00625 eeprom_channel = 24; //Default 00626 #endif 00627 } 00628 00629 radio_set_operating_channel(eeprom_channel); 00630 radio_use_auto_tx_crc(true); 00631 radio_set_trx_state(TRX_OFF); 00632 00633 mac_init(); 00634 00635 /* Set up MAC function pointers and sicslowpan callback. */ 00636 pmac_driver->set_receive_function = setinput; 00637 pmac_driver->send = sicslowmac_dataRequest; 00638 sicslowpan_init(pmac_driver); 00639 00640 ieee_15_4_init(&ieee15_4ManagerAddress); 00641 00642 radio_set_trx_state(RX_AACK_ON); 00643 00644 while(1) { 00645 PROCESS_YIELD(); 00646 mac_task(ev, data); 00647 00648 } 00649 00650 PROCESS_END(); 00651 } 00652 00653 void byte_reverse(uint8_t * bytes, uint8_t num) 00654 { 00655 uint8_t tempbyte; 00656 00657 uint8_t i, j; 00658 00659 i = 0; 00660 j = num - 1; 00661 00662 while(i < j) { 00663 tempbyte = bytes[i]; 00664 bytes[i] = bytes[j]; 00665 bytes[j] = tempbyte; 00666 00667 j--; 00668 i++; 00669 } 00670 00671 return; 00672 }