Contiki 2.5
contiki-cooja-main.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $Id: contiki-cooja-main.c,v 1.9 2010/09/24 12:59:06 fros4943 Exp $
30  */
31 
32 /**
33  * \file
34  * COOJA Contiki mote main file.
35  * \author
36  * Fredrik Osterlind <fros@sics.se>
37  */
38 
39 #include <jni.h>
40 #include <stdio.h>
41 #include <string.h>
42 
43 #include "contiki.h"
44 
45 #include "sys/clock.h"
46 #include "sys/etimer.h"
47 #include "sys/cooja_mt.h"
48 #include "sys/autostart.h"
49 
50 #include "lib/random.h"
51 #include "lib/simEnvChange.h"
52 
53 #include "net/rime.h"
54 #include "net/netstack.h"
55 
56 #include "dev/serial-line.h"
57 #include "dev/cooja-radio.h"
58 #include "dev/button-sensor.h"
59 #include "dev/pir-sensor.h"
60 #include "dev/vib-sensor.h"
61 
62 #include "node-id.h"
63 
64 
65 /* JNI-defined functions, depends on the environment variable CLASSNAME */
66 #ifndef CLASSNAME
67 #error CLASSNAME is undefined, required by contiki-cooja-main.c
68 #endif /* CLASSNAME */
69 #define COOJA__QUOTEME(a,b,c) COOJA_QUOTEME(a,b,c)
70 #define COOJA_QUOTEME(a,b,c) a##b##c
71 #define COOJA_JNI_PATH Java_se_sics_cooja_corecomm_
72 #define Java_se_sics_cooja_corecomm_CLASSNAME_init COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_init)
73 #define Java_se_sics_cooja_corecomm_CLASSNAME_getMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_getMemory)
74 #define Java_se_sics_cooja_corecomm_CLASSNAME_setMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setMemory)
75 #define Java_se_sics_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
76 #define Java_se_sics_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
77 
78 #ifndef WITH_UIP
79 #define WITH_UIP 0
80 #endif
81 #if WITH_UIP
82 #include "dev/rs232.h"
83 #include "dev/slip.h"
84 #include "net/uip.h"
85 #include "net/uip-fw.h"
86 #include "net/uip-fw-drv.h"
87 #include "net/uip-over-mesh.h"
88 static struct uip_fw_netif slipif =
89  {UIP_FW_NETIF(0,0,0,0, 255,255,255,255, slip_send)};
90 static struct uip_fw_netif meshif =
91  {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
92 
93 #define UIP_OVER_MESH_CHANNEL 8
94 static uint8_t is_gateway;
95 #endif /* WITH_UIP */
96 
97 #ifndef WITH_UIP6
98 #define WITH_UIP6 0
99 #endif
100 #if WITH_UIP6
101 #include "net/uip.h"
102 #include "net/uip-ds6.h"
103 #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])
104 #endif /* WITH_UIP6 */
105 
106 PROCINIT(&etimer_process,&sensors_process);
107 
108 /* Simulation mote interfaces */
109 SIM_INTERFACE_NAME(moteid_interface);
110 SIM_INTERFACE_NAME(vib_interface);
111 SIM_INTERFACE_NAME(rs232_interface);
112 SIM_INTERFACE_NAME(simlog_interface);
113 SIM_INTERFACE_NAME(beep_interface);
114 SIM_INTERFACE_NAME(radio_interface);
115 SIM_INTERFACE_NAME(button_interface);
116 SIM_INTERFACE_NAME(pir_interface);
117 SIM_INTERFACE_NAME(clock_interface);
118 SIM_INTERFACE_NAME(leds_interface);
119 SIM_INTERFACE_NAME(cfs_interface);
120 SIM_INTERFACES(&vib_interface, &moteid_interface, &rs232_interface, &simlog_interface, &beep_interface, &radio_interface, &button_interface, &pir_interface, &clock_interface, &leds_interface, &cfs_interface);
121 /* Example: manually add mote interfaces */
122 //SIM_INTERFACE_NAME(dummy_interface);
123 //SIM_INTERFACES(..., &dummy_interface);
124 
125 /* Sensors */
126 SENSORS(&button_sensor, &pir_sensor, &vib_sensor);
127 
128 /*
129  * referenceVar is used for comparing absolute and process relative memory.
130  * (this must not be static due to memory locations)
131  */
132 long referenceVar;
133 
134 /*
135  * Contiki and rtimer threads.
136  */
137 static struct cooja_mt_thread rtimer_thread;
138 static struct cooja_mt_thread process_run_thread;
139 
140 #define MIN(a, b) ( (a)<(b) ? (a) : (b) )
141 
142 /*---------------------------------------------------------------------------*/
143 #if WITH_UIP
144 static void
145 set_gateway(void)
146 {
147  if(!is_gateway) {
148  printf("%d.%d: making myself the IP network gateway.\n\n",
150  printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
151  uip_ipaddr_to_quad(&uip_hostaddr));
152  uip_over_mesh_set_gateway(&rimeaddr_node_addr);
153  uip_over_mesh_make_announced_gateway();
154  is_gateway = 1;
155  }
156 }
157 #endif /* WITH_UIP */
158 /*---------------------------------------------------------------------------*/
159 static void
160 print_processes(struct process * const processes[])
161 {
162  /* const struct process * const * p = processes;*/
163  printf("Starting");
164  while(*processes != NULL) {
165  printf(" '%s'", (*processes)->name);
166  processes++;
167  }
168  putchar('\n');
169 }
170 /*---------------------------------------------------------------------------*/
171 static void
172 rtimer_thread_loop(void *data)
173 {
174  while(1)
175  {
176  rtimer_arch_check();
177 
178  /* Return to COOJA */
179  cooja_mt_yield();
180  }
181 }
182 /*---------------------------------------------------------------------------*/
183 void
184 contiki_init()
185 {
186  /* Initialize random generator (moved to moteid.c) */
187 
188  /* Start process handler */
189  process_init();
190 
191  /* Start Contiki processes */
192  procinit_init();
193 
194  /* Print startup information */
195  printf(CONTIKI_VERSION_STRING " started. ");
196  if(node_id > 0) {
197  printf("Node id is set to %u.\n", node_id);
198  } else {
199  printf("Node id is not set.\n");
200  }
201 
202  /* RIME CONFIGURATION */
203  {
204  int i;
205  rimeaddr_t rimeaddr;
206 
207  /* Init Rime */
208  ctimer_init();
209  rimeaddr.u8[0] = node_id & 0xff;
210  rimeaddr.u8[1] = node_id >> 8;
211  rimeaddr_set_node_addr(&rimeaddr);
212  printf("Rime address: ");
213  for(i = 0; i < sizeof(rimeaddr_node_addr.u8) - 1; i++) {
214  printf("%d.", rimeaddr_node_addr.u8[i]);
215  }
216  printf("%d\n", rimeaddr_node_addr.u8[i]);
217  }
218 
219  queuebuf_init();
220 
221  /* Initialize communication stack */
222  netstack_init();
223  printf("MAC %s RDC %s NETWORK %s\n", NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name);
224 
225 #if WITH_UIP
226  /* IPv4 CONFIGURATION */
227  {
228  uip_ipaddr_t hostaddr, netmask;
229 
230  process_start(&tcpip_process, NULL);
231  process_start(&uip_fw_process, NULL);
232  process_start(&slip_process, NULL);
233 
234  slip_set_input_callback(set_gateway);
235 
236  uip_init();
237  uip_fw_init();
238  uip_ipaddr(&hostaddr, 172,16,rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
239  uip_ipaddr(&netmask, 255,255,0,0);
240  uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
241 
242  uip_sethostaddr(&hostaddr);
243  uip_setnetmask(&netmask);
244  uip_over_mesh_set_net(&hostaddr, &netmask);
245  uip_over_mesh_set_gateway_netif(&slipif);
246  uip_fw_default(&meshif);
247  uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
248 
249  rs232_set_input(slip_input_byte);
250  printf("IPv4 address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&hostaddr));
251  }
252 #endif /* WITH_UIP */
253 
254 #if WITH_UIP6
255  /* IPv6 CONFIGURATION */
256  {
257  int i;
258  uint8_t addr[sizeof(uip_lladdr.addr)];
259  for (i=0; i < sizeof(uip_lladdr.addr); i++) {
260  addr[i] = node_id & 0xff;
261  }
262  memcpy(&uip_lladdr.addr, addr, sizeof(uip_lladdr.addr));
263  process_start(&tcpip_process, NULL);
264 
265  printf("Tentative link-local IPv6 address ");
266  {
267  int i, a;
268  for(a = 0; a < UIP_DS6_ADDR_NB; a++) {
269  if (uip_ds6_if.addr_list[a].isused) {
270  for(i = 0; i < 7; ++i) {
271  printf("%02x%02x:",
272  uip_ds6_if.addr_list[a].ipaddr.u8[i * 2],
273  uip_ds6_if.addr_list[a].ipaddr.u8[i * 2 + 1]);
274  }
275  printf("%02x%02x\n",
276  uip_ds6_if.addr_list[a].ipaddr.u8[14],
277  uip_ds6_if.addr_list[a].ipaddr.u8[15]);
278  }
279  }
280  }
281 
282  if(1) {
283  uip_ipaddr_t ipaddr;
284  int i;
285  uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
286  uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
287  uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
288  printf("Tentative global IPv6 address ");
289  for(i = 0; i < 7; ++i) {
290  printf("%02x%02x:",
291  ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
292  }
293  printf("%02x%02x\n",
294  ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
295  }
296  }
297 #endif /* WITH_UIP6 */
298 
299  /* Start serial process */
300  serial_line_init();
301 
302  /* Start autostart processes (defined in Contiki application) */
303  print_processes(autostart_processes);
304  autostart_start(autostart_processes);
305 }
306 /*---------------------------------------------------------------------------*/
307 static void
308 process_run_thread_loop(void *data)
309 {
310  /* Yield once during bootup */
311  simProcessRunValue = 1;
312  cooja_mt_yield();
313 
314  contiki_init();
315 
316  while(1)
317  {
318  simProcessRunValue = process_run();
319  while(simProcessRunValue-- > 0) {
320  process_run();
321  }
322  simProcessRunValue = process_nevents();
323 
324  /* Check if we must stay awake */
325  if(simDontFallAsleep) {
326  simDontFallAsleep=0;
327  simProcessRunValue = 1;
328  }
329 
330  /* Return to COOJA */
331  cooja_mt_yield();
332  }
333 }
334 /*---------------------------------------------------------------------------*/
335 /**
336  * \brief Initialize a mote by starting processes etc.
337  *
338  * This function initializes a mote by starting certain
339  * processes and setting up the environment.
340  *
341  * This is a JNI function and should only be called via the
342  * responsible Java part (MoteType.java).
343  */
344 JNIEXPORT void JNICALL
346 {
347  /* Create rtimers and Contiki threads */
348  cooja_mt_start(&rtimer_thread, &rtimer_thread_loop, NULL);
349  cooja_mt_start(&process_run_thread, &process_run_thread_loop, NULL);
350  }
351 /*---------------------------------------------------------------------------*/
352 /**
353  * \brief Get a segment from the process memory.
354  * \param start Start address of segment
355  * \param length Size of memory segment
356  * \return Java byte array containing a copy of memory segment.
357  *
358  * Fetches a memory segment from the process memory starting at
359  * (start), with size (length). This function does not perform
360  * ANY error checking, and the process may crash if addresses are
361  * not available/readable.
362  *
363  * This is a JNI function and should only be called via the
364  * responsible Java part (MoteType.java).
365  */
366 JNIEXPORT void JNICALL
367 Java_se_sics_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
368 {
369  (*env)->SetByteArrayRegion(
370  env,
371  mem_arr,
372  0,
373  (size_t) length,
374  (jbyte *) (((long)rel_addr) + referenceVar)
375  );
376 }
377 /*---------------------------------------------------------------------------*/
378 /**
379  * \brief Replace a segment of the process memory with given byte array.
380  * \param start Start address of segment
381  * \param length Size of memory segment
382  * \param mem_arr Byte array contaning new memory
383  *
384  * Replaces a process memory segment with given byte array.
385  * This function does not perform ANY error checking, and the
386  * process may crash if addresses are not available/writable.
387  *
388  * This is a JNI function and should only be called via the
389  * responsible Java part (MoteType.java).
390  */
391 JNIEXPORT void JNICALL
392 Java_se_sics_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
393 {
394  jbyte *mem = (*env)->GetByteArrayElements(env, mem_arr, 0);
395  memcpy(
396  (char*) (((long)rel_addr) + referenceVar),
397  mem,
398  length);
399  (*env)->ReleaseByteArrayElements(env, mem_arr, mem, 0);
400 }
401 /*---------------------------------------------------------------------------*/
402 /**
403  * \brief Let mote execute one "block" of code (tick mote).
404  *
405  * Let mote defined by the active contiki processes and current
406  * process memory execute some program code. This code must not block
407  * or else this function will never return. A typical contiki
408  * process will return when it executes PROCESS_WAIT..() statements.
409  *
410  * Before the control is left to contiki processes, any messages
411  * from the Java part are handled. These may for example be
412  * incoming network data. After the contiki processes return control,
413  * messages to the Java part are also handled (those which may need
414  * special attention).
415  *
416  * This is a JNI function and should only be called via the
417  * responsible Java part (MoteType.java).
418  */
419 JNIEXPORT void JNICALL
421 {
422  clock_time_t nextEtimer;
423  rtimer_clock_t nextRtimer;
424 
425  simProcessRunValue = 0;
426 
427  /* Let all simulation interfaces act first */
428  doActionsBeforeTick();
429 
430  /* Poll etimer process */
431  if (etimer_pending()) {
433  }
434 
435  /* Let rtimers run.
436  * Sets simProcessRunValue */
437  cooja_mt_exec(&rtimer_thread);
438 
439  if(simProcessRunValue == 0) {
440  /* Rtimers done: Let Contiki handle a few events.
441  * Sets simProcessRunValue */
442  cooja_mt_exec(&process_run_thread);
443  }
444 
445  /* Let all simulation interfaces act before returning to java */
446  doActionsAfterTick();
447 
448  /* Do we have any pending timers */
449  simEtimerPending = etimer_pending() || rtimer_arch_pending();
450  if(!simEtimerPending) {
451  return;
452  }
453 
454  /* Save nearest expiration time */
455  nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime;
456  nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime;
457  if(etimer_pending() && rtimer_arch_pending()) {
458  simNextExpirationTime = MIN(nextEtimer, nextRtimer);
459  } else if (etimer_pending()) {
460  simNextExpirationTime = nextEtimer;
461  } else if (rtimer_arch_pending()) {
462  simNextExpirationTime = nextRtimer;
463  }
464 }
465 /*---------------------------------------------------------------------------*/
466 /**
467  * \brief Set the relative memory address of the reference variable.
468  * \return Relative memory address.
469  *
470  * This is a JNI function and should only be called via the
471  * responsible Java part (MoteType.java).
472  */
473 JNIEXPORT void JNICALL
475 {
476  referenceVar = (((long)&referenceVar) - ((long)addr));
477 }