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
00033
00034
00035
00036
00037
00038
00039 #include <jni.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042
00043 #include "contiki.h"
00044
00045 #include "sys/clock.h"
00046 #include "sys/etimer.h"
00047 #include "sys/cooja_mt.h"
00048 #include "sys/autostart.h"
00049
00050 #include "lib/random.h"
00051 #include "lib/simEnvChange.h"
00052
00053 #include "net/rime.h"
00054 #include "net/netstack.h"
00055
00056 #include "dev/serial-line.h"
00057 #include "dev/cooja-radio.h"
00058 #include "dev/button-sensor.h"
00059 #include "dev/pir-sensor.h"
00060 #include "dev/vib-sensor.h"
00061
00062 #include "node-id.h"
00063
00064
00065
00066 #ifndef CLASSNAME
00067 #error CLASSNAME is undefined, required by contiki-cooja-main.c
00068 #endif
00069 #define COOJA__QUOTEME(a,b,c) COOJA_QUOTEME(a,b,c)
00070 #define COOJA_QUOTEME(a,b,c) a##b##c
00071 #define COOJA_JNI_PATH Java_se_sics_cooja_corecomm_
00072 #define Java_se_sics_cooja_corecomm_CLASSNAME_init COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_init)
00073 #define Java_se_sics_cooja_corecomm_CLASSNAME_getMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_getMemory)
00074 #define Java_se_sics_cooja_corecomm_CLASSNAME_setMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setMemory)
00075 #define Java_se_sics_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
00076 #define Java_se_sics_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
00077
00078 #ifndef WITH_UIP
00079 #define WITH_UIP 0
00080 #endif
00081 #if WITH_UIP
00082 #include "dev/rs232.h"
00083 #include "dev/slip.h"
00084 #include "net/uip.h"
00085 #include "net/uip-fw.h"
00086 #include "net/uip-fw-drv.h"
00087 #include "net/uip-over-mesh.h"
00088 static struct uip_fw_netif slipif =
00089 {UIP_FW_NETIF(0,0,0,0, 255,255,255,255, slip_send)};
00090 static struct uip_fw_netif meshif =
00091 {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
00092
00093 #define UIP_OVER_MESH_CHANNEL 8
00094 static uint8_t is_gateway;
00095 #endif
00096
00097 #ifndef WITH_UIP6
00098 #define WITH_UIP6 0
00099 #endif
00100 #if WITH_UIP6
00101 #include "net/uip.h"
00102 #include "net/uip-ds6.h"
00103 #define PRINT6ADDR(addr) printf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15])
00104 #endif
00105
00106 PROCINIT(&etimer_process,&sensors_process);
00107
00108
00109 SIM_INTERFACE_NAME(moteid_interface);
00110 SIM_INTERFACE_NAME(vib_interface);
00111 SIM_INTERFACE_NAME(rs232_interface);
00112 SIM_INTERFACE_NAME(simlog_interface);
00113 SIM_INTERFACE_NAME(beep_interface);
00114 SIM_INTERFACE_NAME(radio_interface);
00115 SIM_INTERFACE_NAME(button_interface);
00116 SIM_INTERFACE_NAME(pir_interface);
00117 SIM_INTERFACE_NAME(clock_interface);
00118 SIM_INTERFACE_NAME(leds_interface);
00119 SIM_INTERFACE_NAME(cfs_interface);
00120 SIM_INTERFACES(&vib_interface, &moteid_interface, &rs232_interface, &simlog_interface, &beep_interface, &radio_interface, &button_interface, &pir_interface, &clock_interface, &leds_interface, &cfs_interface);
00121
00122
00123
00124
00125
00126 SENSORS(&button_sensor, &pir_sensor, &vib_sensor);
00127
00128
00129
00130
00131
00132 long referenceVar;
00133
00134
00135
00136
00137 static struct cooja_mt_thread rtimer_thread;
00138 static struct cooja_mt_thread process_run_thread;
00139
00140 #define MIN(a, b) ( (a)<(b) ? (a) : (b) )
00141
00142
00143 #if WITH_UIP
00144 static void
00145 set_gateway(void)
00146 {
00147 if(!is_gateway) {
00148 printf("%d.%d: making myself the IP network gateway.\n\n",
00149 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00150 printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
00151 uip_ipaddr_to_quad(&uip_hostaddr));
00152 uip_over_mesh_set_gateway(&rimeaddr_node_addr);
00153 uip_over_mesh_make_announced_gateway();
00154 is_gateway = 1;
00155 }
00156 }
00157 #endif
00158
00159 static void
00160 print_processes(struct process * const processes[])
00161 {
00162
00163 printf("Starting");
00164 while(*processes != NULL) {
00165 printf(" '%s'", (*processes)->name);
00166 processes++;
00167 }
00168 putchar('\n');
00169 }
00170
00171 static void
00172 rtimer_thread_loop(void *data)
00173 {
00174 while(1)
00175 {
00176 rtimer_arch_check();
00177
00178
00179 cooja_mt_yield();
00180 }
00181 }
00182
00183 void
00184 contiki_init()
00185 {
00186
00187
00188
00189 process_init();
00190
00191
00192 procinit_init();
00193
00194
00195 printf(CONTIKI_VERSION_STRING " started. ");
00196 if(node_id > 0) {
00197 printf("Node id is set to %u.\n", node_id);
00198 } else {
00199 printf("Node id is not set.\n");
00200 }
00201
00202
00203 {
00204 int i;
00205 rimeaddr_t rimeaddr;
00206
00207
00208 ctimer_init();
00209 rimeaddr.u8[0] = node_id & 0xff;
00210 rimeaddr.u8[1] = node_id >> 8;
00211 rimeaddr_set_node_addr(&rimeaddr);
00212 printf("Rime address: ");
00213 for(i = 0; i < sizeof(rimeaddr_node_addr.u8) - 1; i++) {
00214 printf("%d.", rimeaddr_node_addr.u8[i]);
00215 }
00216 printf("%d\n", rimeaddr_node_addr.u8[i]);
00217 }
00218
00219 queuebuf_init();
00220
00221
00222 netstack_init();
00223 printf("MAC %s RDC %s NETWORK %s\n", NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name);
00224
00225 #if WITH_UIP
00226
00227 {
00228 uip_ipaddr_t hostaddr, netmask;
00229
00230 process_start(&tcpip_process, NULL);
00231 process_start(&uip_fw_process, NULL);
00232 process_start(&slip_process, NULL);
00233
00234 slip_set_input_callback(set_gateway);
00235
00236 uip_init();
00237 uip_fw_init();
00238 uip_ipaddr(&hostaddr, 172,16,rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00239 uip_ipaddr(&netmask, 255,255,0,0);
00240 uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
00241
00242 uip_sethostaddr(&hostaddr);
00243 uip_setnetmask(&netmask);
00244 uip_over_mesh_set_net(&hostaddr, &netmask);
00245 uip_over_mesh_set_gateway_netif(&slipif);
00246 uip_fw_default(&meshif);
00247 uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
00248
00249 rs232_set_input(slip_input_byte);
00250 printf("IPv4 address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&hostaddr));
00251 }
00252 #endif
00253
00254 #if WITH_UIP6
00255
00256 {
00257 int i;
00258 uint8_t addr[sizeof(uip_lladdr.addr)];
00259 for (i=0; i < sizeof(uip_lladdr.addr); i++) {
00260 addr[i] = node_id & 0xff;
00261 }
00262 memcpy(&uip_lladdr.addr, addr, sizeof(uip_lladdr.addr));
00263 process_start(&tcpip_process, NULL);
00264
00265 printf("Tentative link-local IPv6 address ");
00266 {
00267 int i, a;
00268 for(a = 0; a < UIP_DS6_ADDR_NB; a++) {
00269 if (uip_ds6_if.addr_list[a].isused) {
00270 for(i = 0; i < 7; ++i) {
00271 printf("%02x%02x:",
00272 uip_ds6_if.addr_list[a].ipaddr.u8[i * 2],
00273 uip_ds6_if.addr_list[a].ipaddr.u8[i * 2 + 1]);
00274 }
00275 printf("%02x%02x\n",
00276 uip_ds6_if.addr_list[a].ipaddr.u8[14],
00277 uip_ds6_if.addr_list[a].ipaddr.u8[15]);
00278 }
00279 }
00280 }
00281
00282 if(1) {
00283 uip_ipaddr_t ipaddr;
00284 int i;
00285 uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
00286 uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
00287 uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
00288 printf("Tentative global IPv6 address ");
00289 for(i = 0; i < 7; ++i) {
00290 printf("%02x%02x:",
00291 ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
00292 }
00293 printf("%02x%02x\n",
00294 ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
00295 }
00296 }
00297 #endif
00298
00299
00300 serial_line_init();
00301
00302
00303 print_processes(autostart_processes);
00304 autostart_start(autostart_processes);
00305 }
00306
00307 static void
00308 process_run_thread_loop(void *data)
00309 {
00310
00311 simProcessRunValue = 1;
00312 cooja_mt_yield();
00313
00314 contiki_init();
00315
00316 while(1)
00317 {
00318 simProcessRunValue = process_run();
00319 while(simProcessRunValue-- > 0) {
00320 process_run();
00321 }
00322 simProcessRunValue = process_nevents();
00323
00324
00325 if(simDontFallAsleep) {
00326 simDontFallAsleep=0;
00327 simProcessRunValue = 1;
00328 }
00329
00330
00331 cooja_mt_yield();
00332 }
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 JNIEXPORT void JNICALL
00345 Java_se_sics_cooja_corecomm_CLASSNAME_init(JNIEnv *env, jobject obj)
00346 {
00347
00348 cooja_mt_start(&rtimer_thread, &rtimer_thread_loop, NULL);
00349 cooja_mt_start(&process_run_thread, &process_run_thread_loop, NULL);
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 JNIEXPORT void JNICALL
00367 Java_se_sics_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
00368 {
00369 (*env)->SetByteArrayRegion(
00370 env,
00371 mem_arr,
00372 0,
00373 (size_t) length,
00374 (jbyte *) (((long)rel_addr) + referenceVar)
00375 );
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 JNIEXPORT void JNICALL
00392 Java_se_sics_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
00393 {
00394 jbyte *mem = (*env)->GetByteArrayElements(env, mem_arr, 0);
00395 memcpy(
00396 (char*) (((long)rel_addr) + referenceVar),
00397 mem,
00398 length);
00399 (*env)->ReleaseByteArrayElements(env, mem_arr, mem, 0);
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 JNIEXPORT void JNICALL
00420 Java_se_sics_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj)
00421 {
00422 clock_time_t nextEtimer;
00423 rtimer_clock_t nextRtimer;
00424
00425 simProcessRunValue = 0;
00426
00427
00428 doActionsBeforeTick();
00429
00430
00431 if (etimer_pending()) {
00432 etimer_request_poll();
00433 }
00434
00435
00436
00437 cooja_mt_exec(&rtimer_thread);
00438
00439 if(simProcessRunValue == 0) {
00440
00441
00442 cooja_mt_exec(&process_run_thread);
00443 }
00444
00445
00446 doActionsAfterTick();
00447
00448
00449 simEtimerPending = etimer_pending() || rtimer_arch_pending();
00450 if(!simEtimerPending) {
00451 return;
00452 }
00453
00454
00455 nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime;
00456 nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime;
00457 if(etimer_pending() && rtimer_arch_pending()) {
00458 simNextExpirationTime = MIN(nextEtimer, nextRtimer);
00459 } else if (etimer_pending()) {
00460 simNextExpirationTime = nextEtimer;
00461 } else if (rtimer_arch_pending()) {
00462 simNextExpirationTime = nextRtimer;
00463 }
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473 JNIEXPORT void JNICALL
00474 Java_se_sics_cooja_corecomm_CLASSNAME_setReferenceAddress(JNIEnv *env, jobject obj, jint addr)
00475 {
00476 referenceVar = (((long)&referenceVar) - ((long)addr));
00477 }