cooja-radio.c

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  * $Id: cooja-radio.c,v 1.15 2010/06/14 19:19:17 adamdunkels Exp $
00030  */
00031 
00032 #include <stdio.h>
00033 #include <string.h>
00034 
00035 #include "contiki.h"
00036 
00037 #include "sys/cooja_mt.h"
00038 #include "lib/simEnvChange.h"
00039 
00040 #include "net/packetbuf.h"
00041 #include "net/rime/rimestats.h"
00042 #include "net/netstack.h"
00043 
00044 #include "dev/radio.h"
00045 #include "dev/cooja-radio.h"
00046 
00047 #define COOJA_RADIO_BUFSIZE PACKETBUF_SIZE
00048 
00049 #define CCA_SS_THRESHOLD -95
00050 
00051 const struct simInterface radio_interface;
00052 
00053 /* COOJA */
00054 char simReceiving = 0;
00055 char simInDataBuffer[COOJA_RADIO_BUFSIZE];
00056 int simInSize = 0;
00057 char simOutDataBuffer[COOJA_RADIO_BUFSIZE];
00058 int simOutSize = 0;
00059 char simRadioHWOn = 1;
00060 int simSignalStrength = -100;
00061 int simLastSignalStrength = -100;
00062 char simPower = 100;
00063 int simRadioChannel = 26;
00064 
00065 static const void *pending_data;
00066 
00067 PROCESS(cooja_radio_process, "cooja radio process");
00068 
00069 /*---------------------------------------------------------------------------*/
00070 void
00071 radio_set_channel(int channel)
00072 {
00073   simRadioChannel = channel;
00074 }
00075 /*---------------------------------------------------------------------------*/
00076 void
00077 radio_set_txpower(unsigned char power)
00078 {
00079   /* 1 - 100: Number indicating output power */
00080   simPower = power;
00081 }
00082 /*---------------------------------------------------------------------------*/
00083 int
00084 radio_signal_strength_last(void)
00085 {
00086   return simLastSignalStrength;
00087 }
00088 /*---------------------------------------------------------------------------*/
00089 int
00090 radio_signal_strength_current(void)
00091 {
00092   return simSignalStrength;
00093 }
00094 /*---------------------------------------------------------------------------*/
00095 static int
00096 radio_on(void)
00097 {
00098   simRadioHWOn = 1;
00099   return 1;
00100 }
00101 /*---------------------------------------------------------------------------*/
00102 static int
00103 radio_off(void)
00104 {
00105   simRadioHWOn = 0;
00106   return 1;
00107 }
00108 /*---------------------------------------------------------------------------*/
00109 static void
00110 doInterfaceActionsBeforeTick(void)
00111 {
00112   if (!simRadioHWOn) {
00113     simInSize = 0;
00114     return;
00115   }
00116   if (simReceiving) {
00117     simLastSignalStrength = simSignalStrength;
00118     return;
00119   }
00120 
00121   if (simInSize > 0) {
00122     process_poll(&cooja_radio_process);
00123   }
00124 }
00125 /*---------------------------------------------------------------------------*/
00126 static void
00127 doInterfaceActionsAfterTick(void)
00128 {
00129 }
00130 /*---------------------------------------------------------------------------*/
00131 static int
00132 radio_read(void *buf, unsigned short bufsize)
00133 {
00134   int tmp = simInSize;
00135 
00136   if (simInSize == 0) {
00137     return 0;
00138   }
00139   if(bufsize < simInSize) {
00140     simInSize = 0; /* rx flush */
00141     RIMESTATS_ADD(toolong);
00142     return 0;
00143   }
00144 
00145   memcpy(buf, simInDataBuffer, simInSize);
00146   simInSize = 0;
00147   return tmp;
00148 }
00149 /*---------------------------------------------------------------------------*/
00150 static int
00151 radio_send(const void *payload, unsigned short payload_len)
00152 {
00153   int radiostate = simRadioHWOn;
00154 
00155   if(!simRadioHWOn) {
00156     /* Turn on radio temporarily */
00157     simRadioHWOn = 1;
00158   }
00159   if(payload_len > COOJA_RADIO_BUFSIZE) {
00160     return RADIO_TX_ERR;
00161   }
00162   if(payload_len == 0) {
00163     return RADIO_TX_ERR;
00164   }
00165   if(simOutSize > 0) {
00166     return RADIO_TX_ERR;
00167   }
00168 
00169   /* Copy packet data to temporary storage */
00170   memcpy(simOutDataBuffer, payload, payload_len);
00171   simOutSize = payload_len;
00172 
00173   /* Transmit */
00174   while(simOutSize > 0) {
00175     cooja_mt_yield();
00176   }
00177 
00178   simRadioHWOn = radiostate;
00179   return RADIO_TX_OK;
00180 }
00181 /*---------------------------------------------------------------------------*/
00182 static int
00183 prepare_packet(const void *data, unsigned short len)
00184 {
00185   pending_data = data;
00186   return 0;
00187 }
00188 /*---------------------------------------------------------------------------*/
00189 static int
00190 transmit_packet(unsigned short len)
00191 {
00192   int ret = RADIO_TX_ERR;
00193   if(pending_data != NULL) {
00194     ret = radio_send(pending_data, len);
00195   }
00196   return ret;
00197 }
00198 /*---------------------------------------------------------------------------*/
00199 static int
00200 receiving_packet(void)
00201 {
00202   return simReceiving;
00203 }
00204 /*---------------------------------------------------------------------------*/
00205 static int
00206 pending_packet(void)
00207 {
00208   return !simReceiving && simInSize > 0;
00209 }
00210 /*---------------------------------------------------------------------------*/
00211 static int
00212 channel_clear(void)
00213 {
00214   if(simSignalStrength > CCA_SS_THRESHOLD) {
00215     return 0;
00216   }
00217   return 1;
00218 }
00219 /*---------------------------------------------------------------------------*/
00220 PROCESS_THREAD(cooja_radio_process, ev, data)
00221 {
00222   int len;
00223 
00224   PROCESS_BEGIN();
00225 
00226   while(1) {
00227     PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
00228 
00229     packetbuf_clear();
00230     len = radio_read(packetbuf_dataptr(), PACKETBUF_SIZE);
00231     if(len > 0) {
00232       packetbuf_set_datalen(len);
00233       NETSTACK_RDC.input();
00234     }
00235   }
00236 
00237   PROCESS_END();
00238 }
00239 /*---------------------------------------------------------------------------*/
00240 static int
00241 init(void)
00242 {
00243   process_start(&cooja_radio_process, NULL);
00244   return 1;
00245 }
00246 /*---------------------------------------------------------------------------*/
00247 const struct radio_driver cooja_radio_driver =
00248 {
00249     init,
00250     prepare_packet,
00251     transmit_packet,
00252     radio_send,
00253     radio_read,
00254     channel_clear,
00255     receiving_packet,
00256     pending_packet,
00257     radio_on,
00258     radio_off,
00259 };
00260 /*---------------------------------------------------------------------------*/
00261 SIM_INTERFACE(radio_interface,
00262               doInterfaceActionsBeforeTick,
00263               doInterfaceActionsAfterTick);

Generated on Mon Apr 11 14:23:43 2011 for Contiki 2.5 by  doxygen 1.6.1