cooja-radio.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
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;
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
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
00170 memcpy(simOutDataBuffer, payload, payload_len);
00171 simOutSize = payload_len;
00172
00173
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);