Contiki 2.6

contiki-cooja-main.c

Go to the documentation of this file.
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: contiki-cooja-main.c,v 1.9 2010/09/24 12:59:06 fros4943 Exp $
00030  */
00031 
00032 /**
00033  * \file
00034  *         COOJA Contiki mote main file.
00035  * \author
00036  *         Fredrik Osterlind <fros@sics.se>
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 /* JNI-defined functions, depends on the environment variable CLASSNAME */
00066 #ifndef CLASSNAME
00067 #error CLASSNAME is undefined, required by contiki-cooja-main.c
00068 #endif /* CLASSNAME */
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 /* WITH_UIP */
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", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
00104 #endif /* WITH_UIP6 */
00105 
00106 PROCINIT(&etimer_process,&sensors_process);
00107 
00108 /* Simulation mote interfaces */
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 /* Example: manually add mote interfaces */
00122 //SIM_INTERFACE_NAME(dummy_interface);
00123 //SIM_INTERFACES(..., &dummy_interface);
00124 
00125 /* Sensors */
00126 SENSORS(&button_sensor, &pir_sensor, &vib_sensor);
00127 
00128 /*
00129  * referenceVar is used for comparing absolute and process relative memory.
00130  * (this must not be static due to memory locations)
00131  */
00132 long referenceVar;
00133 
00134 /*
00135  * Contiki and rtimer threads.
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 /* WITH_UIP */
00158 /*---------------------------------------------------------------------------*/
00159 static void
00160 print_processes(struct process * const processes[])
00161 {
00162   /*  const struct process * const * p = processes;*/
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     /* Return to COOJA */
00179     cooja_mt_yield();
00180   }
00181 }
00182 /*---------------------------------------------------------------------------*/
00183 void
00184 contiki_init()
00185 {
00186   /* Initialize random generator (moved to moteid.c) */
00187 
00188   /* Start process handler */
00189   process_init();
00190 
00191   /* Start Contiki processes */
00192   procinit_init();
00193 
00194   /* Print startup information */
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   /* RIME CONFIGURATION */
00203   {
00204     int i;
00205     rimeaddr_t rimeaddr;
00206 
00207     /* Init Rime */
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   /* Initialize communication stack */
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   /* IPv4 CONFIGURATION */
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 /* WITH_UIP */
00253 
00254 #if WITH_UIP6
00255   /* IPv6 CONFIGURATION */
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 /* WITH_UIP6 */
00298 
00299   /* Start serial process */
00300   serial_line_init();
00301 
00302   /* Start autostart processes (defined in Contiki application) */
00303   print_processes(autostart_processes);
00304   autostart_start(autostart_processes);
00305 }
00306 /*---------------------------------------------------------------------------*/
00307 static void
00308 process_run_thread_loop(void *data)
00309 {
00310     /* Yield once during bootup */
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         /* Check if we must stay awake */
00325         if(simDontFallAsleep) {
00326             simDontFallAsleep=0;
00327             simProcessRunValue = 1;
00328         }
00329 
00330         /* Return to COOJA */
00331         cooja_mt_yield();
00332     }
00333 }
00334 /*---------------------------------------------------------------------------*/
00335 /**
00336  * \brief      Initialize a mote by starting processes etc.
00337  *
00338  *             This function initializes a mote by starting certain
00339  *             processes and setting up the environment.
00340  *
00341  *             This is a JNI function and should only be called via the
00342  *             responsible Java part (MoteType.java).
00343  */
00344 JNIEXPORT void JNICALL
00345 Java_se_sics_cooja_corecomm_CLASSNAME_init(JNIEnv *env, jobject obj)
00346 {
00347   /* Create rtimers and Contiki threads */
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  * \brief      Get a segment from the process memory.
00354  * \param start Start address of segment
00355  * \param length Size of memory segment
00356  * \return     Java byte array containing a copy of memory segment.
00357  *
00358  *             Fetches a memory segment from the process memory starting at
00359  *             (start), with size (length). This function does not perform
00360  *             ANY error checking, and the process may crash if addresses are
00361  *             not available/readable.
00362  *
00363  *             This is a JNI function and should only be called via the
00364  *             responsible Java part (MoteType.java).
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  * \brief      Replace a segment of the process memory with given byte array.
00380  * \param start Start address of segment
00381  * \param length Size of memory segment
00382  * \param mem_arr Byte array contaning new memory
00383  *
00384  *             Replaces a process memory segment with given byte array.
00385  *             This function does not perform ANY error checking, and the
00386  *             process may crash if addresses are not available/writable.
00387  *
00388  *             This is a JNI function and should only be called via the
00389  *             responsible Java part (MoteType.java).
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  * \brief      Let mote execute one "block" of code (tick mote).
00404  *
00405  *             Let mote defined by the active contiki processes and current
00406  *             process memory execute some program code. This code must not block
00407  *             or else this function will never return. A typical contiki
00408  *             process will return when it executes PROCESS_WAIT..() statements.
00409  *
00410  *             Before the control is left to contiki processes, any messages
00411  *             from the Java part are handled. These may for example be
00412  *             incoming network data. After the contiki processes return control,
00413  *             messages to the Java part are also handled (those which may need
00414  *             special attention).
00415  *
00416  *             This is a JNI function and should only be called via the
00417  *             responsible Java part (MoteType.java).
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   /* Let all simulation interfaces act first */
00428   doActionsBeforeTick();
00429 
00430   /* Poll etimer process */
00431   if (etimer_pending()) {
00432     etimer_request_poll();
00433   }
00434 
00435   /* Let rtimers run.
00436    * Sets simProcessRunValue */
00437   cooja_mt_exec(&rtimer_thread);
00438 
00439   if(simProcessRunValue == 0) {
00440     /* Rtimers done: Let Contiki handle a few events.
00441      * Sets simProcessRunValue */
00442     cooja_mt_exec(&process_run_thread);
00443   }
00444 
00445   /* Let all simulation interfaces act before returning to java */
00446   doActionsAfterTick();
00447 
00448   /* Do we have any pending timers */
00449   simEtimerPending = etimer_pending() || rtimer_arch_pending();
00450   if(!simEtimerPending) {
00451     return;
00452   }
00453 
00454   /* Save nearest expiration time */
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  * \brief      Set the relative memory address of the reference variable.
00468  * \return     Relative memory address.
00469  *
00470  *             This is a JNI function and should only be called via the
00471  *             responsible Java part (MoteType.java).
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 }