Contiki 2.6

sicslowmac.c

Go to the documentation of this file.
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(&params.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*)&params.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(&params, &result);
00468   
00469   /* Log if needed */
00470   LOG_FRAME(&params, &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 }