Contiki 3.x
contiki-cooja-ip64-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  */
30 
31 /**
32  * \file
33  * COOJA Contiki mote main file.
34  * \author
35  * Fredrik Osterlind <fros@sics.se>
36  */
37 
38 #include <jni.h>
39 #include <stdio.h>
40 #include <string.h>
41 
42 #include "contiki.h"
43 
44 #include "sys/clock.h"
45 #include "sys/etimer.h"
46 #include "sys/cooja_mt.h"
47 #include "sys/autostart.h"
48 
49 #include "lib/random.h"
50 #include "lib/simEnvChange.h"
51 
52 #include "net/rime/rime.h"
53 #include "net/netstack.h"
54 #include "net/ip/uip-nameserver.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 "sys/node-id.h"
63 
64 #include "ip64.h"
65 #include "dev/slip.h"
66 
67 /* JNI-defined functions, depends on the environment variable CLASSNAME */
68 #ifndef CLASSNAME
69 #error CLASSNAME is undefined, required by contiki-cooja-main.c
70 #endif /* CLASSNAME */
71 #define COOJA__QUOTEME(a,b,c) COOJA_QUOTEME(a,b,c)
72 #define COOJA_QUOTEME(a,b,c) a##b##c
73 #define COOJA_JNI_PATH Java_org_contikios_cooja_corecomm_
74 #define Java_org_contikios_cooja_corecomm_CLASSNAME_init COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_init)
75 #define Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_getMemory)
76 #define Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setMemory)
77 #define Java_org_contikios_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
78 #define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
79 
80 #include "net/ip/uip.h"
81 #include "net/ipv6/uip-ds6.h"
82 #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])
83 
84 /* Simulation mote interfaces */
85 SIM_INTERFACE_NAME(moteid_interface);
86 SIM_INTERFACE_NAME(vib_interface);
87 SIM_INTERFACE_NAME(rs232_interface);
88 SIM_INTERFACE_NAME(simlog_interface);
89 SIM_INTERFACE_NAME(beep_interface);
90 SIM_INTERFACE_NAME(radio_interface);
91 SIM_INTERFACE_NAME(button_interface);
92 SIM_INTERFACE_NAME(pir_interface);
93 SIM_INTERFACE_NAME(clock_interface);
94 SIM_INTERFACE_NAME(leds_interface);
95 SIM_INTERFACE_NAME(cfs_interface);
96 SIM_INTERFACES(&vib_interface, &moteid_interface, &rs232_interface, &simlog_interface, &beep_interface, &radio_interface, &button_interface, &pir_interface, &clock_interface, &leds_interface, &cfs_interface);
97 /* Example: manually add mote interfaces */
98 //SIM_INTERFACE_NAME(dummy_interface);
99 //SIM_INTERFACES(..., &dummy_interface);
100 
101 /* Sensors */
102 SENSORS(&button_sensor, &pir_sensor, &vib_sensor);
103 
104 /*
105  * referenceVar is used for comparing absolute and process relative memory.
106  * (this must not be static due to memory locations)
107  */
108 long referenceVar;
109 
110 /*
111  * Contiki and rtimer threads.
112  */
113 static struct cooja_mt_thread rtimer_thread;
114 static struct cooja_mt_thread process_run_thread;
115 
116 #define MIN(a, b) ( (a)<(b) ? (a) : (b) )
117 
118 /*---------------------------------------------------------------------------*/
119 static void
120 print_processes(struct process * const processes[])
121 {
122  /* const struct process * const * p = processes;*/
123  printf("Starting");
124  while(*processes != NULL) {
125  printf(" '%s'", (*processes)->name);
126  processes++;
127  }
128  putchar('\n');
129 }
130 /*---------------------------------------------------------------------------*/
131 static void
132 rtimer_thread_loop(void *data)
133 {
134  while(1)
135  {
136  rtimer_arch_check();
137 
138  /* Return to COOJA */
139  cooja_mt_yield();
140  }
141 }
142 /*---------------------------------------------------------------------------*/
143 static void
144 set_mac_addr(void)
145 {
146  linkaddr_t addr;
147  int i;
148 
149  memset(&addr, 0, sizeof(linkaddr_t));
150  for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) {
151  addr.u8[i + 1] = node_id & 0xff;
152  addr.u8[i + 0] = node_id >> 8;
153  }
154  linkaddr_set_node_addr(&addr);
155  printf("MAC address ");
156  for(i = 0; i < sizeof(addr.u8) - 1; i++) {
157  printf("%d.", addr.u8[i]);
158  }
159  printf("%d\n", addr.u8[i]);
160 }
161 /*---------------------------------------------------------------------------*/
162 void
163 contiki_init(void)
164 {
165  int i;
166  uint8_t addr[sizeof(uip_lladdr.addr)];
167  uip_ipaddr_t ipaddr;
168  uip_ds6_addr_t *lladdr;
169  uip_ip4addr_t ipv4addr, netmask;
170 
171  /* Start process handler */
172  process_init();
173 
174  /* Start Contiki processes */
175  process_start(&etimer_process, NULL);
176  process_start(&sensors_process, NULL);
177  ctimer_init();
178 
179  /* Print startup information */
180  printf(CONTIKI_VERSION_STRING " started. ");
181  if(node_id > 0) {
182  printf("Node id is set to %u.\n", node_id);
183  } else {
184  printf("Node id is not set.\n");
185  }
186 
187  set_mac_addr();
188 
189  queuebuf_init();
190 
191  /* Initialize communication stack */
192  netstack_init();
193  printf("%s/%s/%s, channel check rate %lu Hz\n",
194  NETSTACK_NETWORK.name, NETSTACK_MAC.name, NETSTACK_RDC.name,
195  CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
196  NETSTACK_RDC.channel_check_interval()));
197 
198  /* IPv6 CONFIGURATION */
199 
200 
201  for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) {
202  addr[i + 1] = node_id & 0xff;
203  addr[i + 0] = node_id >> 8;
204  }
206  memcpy(&uip_lladdr.addr, addr, sizeof(uip_lladdr.addr));
207 
208  process_start(&tcpip_process, NULL);
209 
210  printf("Tentative link-local IPv6 address ");
211 
212  lladdr = uip_ds6_get_link_local(-1);
213  for(i = 0; i < 7; ++i) {
214  printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
215  lladdr->ipaddr.u8[i * 2 + 1]);
216  }
217  printf("%02x%02x\n", lladdr->ipaddr.u8[14],
218  lladdr->ipaddr.u8[15]);
219 
220  uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
221  uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
222  uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
223  printf("Tentative global IPv6 address ");
224  for(i = 0; i < 7; ++i) {
225  printf("%02x%02x:",
226  ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
227  }
228  printf("%02x%02x\n",
229  ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
230 
231  /* Start serial process */
232  serial_line_init();
233 
234  /* Start autostart processes (defined in Contiki application) */
235  print_processes(autostart_processes);
236  autostart_start(autostart_processes);
237 
238  /* Start the SLIP */
239  printf("Initiating SLIP with IP address is 172.16.0.2.\n");
240 
241  uip_ipaddr(&ipv4addr, 172, 16, 0, 2);
242  uip_ipaddr(&netmask, 255, 255, 255, 0);
243  ip64_set_ipv4_address(&ipv4addr, &netmask);
244 
246  log_set_putchar_with_slip(1);
247 
248  uip_ip4addr_t ip4addr;
249  uip_ip6addr_t ip6addr;
250 
251  uip_ipaddr(&ip4addr, 8,8,8,8);
252  ip64_addr_4to6(&ip4addr, &ip6addr);
253 
254  uip_nameserver_update((uip_ipaddr_t *)&ip6addr, UIP_NAMESERVER_INFINITE_LIFETIME);
255 }
256 /*---------------------------------------------------------------------------*/
257 static void
258 process_run_thread_loop(void *data)
259 {
260  /* Yield once during bootup */
261  simProcessRunValue = 1;
262  cooja_mt_yield();
263 
264  contiki_init();
265 
266  while(1) {
267  simProcessRunValue = process_run();
268  while(simProcessRunValue-- > 0) {
269  process_run();
270  }
271  simProcessRunValue = process_nevents();
272 
273  /* Check if we must stay awake */
274  if(simDontFallAsleep) {
275  simDontFallAsleep = 0;
276  simProcessRunValue = 1;
277  }
278 
279  /* Return to COOJA */
280  cooja_mt_yield();
281  }
282 }
283 /*---------------------------------------------------------------------------*/
284 /**
285  * \brief Initialize a mote by starting processes etc.
286  * \param env JNI Environment interface pointer
287  * \param obj unused
288  *
289  * This function initializes a mote by starting certain
290  * processes and setting up the environment.
291  *
292  * This is a JNI function and should only be called via the
293  * responsible Java part (MoteType.java).
294  */
295 JNIEXPORT void JNICALL
297 {
298  /* Create rtimers and Contiki threads */
299  cooja_mt_start(&rtimer_thread, &rtimer_thread_loop, NULL);
300  cooja_mt_start(&process_run_thread, &process_run_thread_loop, NULL);
301  }
302 /*---------------------------------------------------------------------------*/
303 /**
304  * \brief Get a segment from the process memory.
305  * \param env JNI Environment interface pointer
306  * \param obj unused
307  * \param rel_addr Start address of segment
308  * \param length Size of memory segment
309  * \param mem_arr Byte array destination for the fetched memory segment
310  * \return Java byte array containing a copy of memory segment.
311  *
312  * Fetches a memory segment from the process memory starting at
313  * (rel_addr), with size (length). This function does not perform
314  * ANY error checking, and the process may crash if addresses are
315  * not available/readable.
316  *
317  * This is a JNI function and should only be called via the
318  * responsible Java part (MoteType.java).
319  */
320 JNIEXPORT void JNICALL
321 Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
322 {
323  (*env)->SetByteArrayRegion(
324  env,
325  mem_arr,
326  0,
327  (size_t) length,
328  (jbyte *) (((long)rel_addr) + referenceVar)
329  );
330 }
331 /*---------------------------------------------------------------------------*/
332 /**
333  * \brief Replace a segment of the process memory with given byte array.
334  * \param env JNI Environment interface pointer
335  * \param obj unused
336  * \param rel_addr Start address of segment
337  * \param length Size of memory segment
338  * \param mem_arr Byte array contaning new memory
339  *
340  * Replaces a process memory segment with given byte array.
341  * This function does not perform ANY error checking, and the
342  * process may crash if addresses are not available/writable.
343  *
344  * This is a JNI function and should only be called via the
345  * responsible Java part (MoteType.java).
346  */
347 JNIEXPORT void JNICALL
348 Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
349 {
350  jbyte *mem = (*env)->GetByteArrayElements(env, mem_arr, 0);
351  memcpy((char *)(((long)rel_addr) + referenceVar),
352  mem,
353  length);
354  (*env)->ReleaseByteArrayElements(env, mem_arr, mem, 0);
355 }
356 /*---------------------------------------------------------------------------*/
357 /**
358  * \brief Let mote execute one "block" of code (tick mote).
359  * \param env JNI Environment interface pointer
360  * \param obj unused
361  *
362  * Let mote defined by the active contiki processes and current
363  * process memory execute some program code. This code must not block
364  * or else this function will never return. A typical contiki
365  * process will return when it executes PROCESS_WAIT..() statements.
366  *
367  * Before the control is left to contiki processes, any messages
368  * from the Java part are handled. These may for example be
369  * incoming network data. After the contiki processes return control,
370  * messages to the Java part are also handled (those which may need
371  * special attention).
372  *
373  * This is a JNI function and should only be called via the
374  * responsible Java part (MoteType.java).
375  */
376 JNIEXPORT void JNICALL
378 {
379  clock_time_t nextEtimer;
380  rtimer_clock_t nextRtimer;
381 
382  simProcessRunValue = 0;
383 
384  /* Let all simulation interfaces act first */
385  doActionsBeforeTick();
386 
387  /* Poll etimer process */
388  if(etimer_pending()) {
390  }
391 
392  /* Let rtimers run.
393  * Sets simProcessRunValue */
394  cooja_mt_exec(&rtimer_thread);
395 
396  if(simProcessRunValue == 0) {
397  /* Rtimers done: Let Contiki handle a few events.
398  * Sets simProcessRunValue */
399  cooja_mt_exec(&process_run_thread);
400  }
401 
402  /* Let all simulation interfaces act before returning to java */
403  doActionsAfterTick();
404 
405  /* Do we have any pending timers */
406  simEtimerPending = etimer_pending() || rtimer_arch_pending();
407  if(!simEtimerPending) {
408  return;
409  }
410 
411  /* Save nearest expiration time */
412  nextEtimer = etimer_next_expiration_time() - (clock_time_t) simCurrentTime;
413  nextRtimer = rtimer_arch_next() - (rtimer_clock_t) simCurrentTime;
414  if(etimer_pending() && rtimer_arch_pending()) {
415  simNextExpirationTime = MIN(nextEtimer, nextRtimer);
416  } else if(etimer_pending()) {
417  simNextExpirationTime = nextEtimer;
418  } else if(rtimer_arch_pending()) {
419  simNextExpirationTime = nextRtimer;
420  }
421 }
422 /*---------------------------------------------------------------------------*/
423 /**
424  * \brief Set the relative memory address of the reference variable.
425  * \param env JNI Environment interface pointer
426  * \param obj unused
427  * \param addr Relative memory address
428  *
429  * This is a JNI function and should only be called via the
430  * responsible Java part (MoteType.java).
431  */
432 JNIEXPORT void JNICALL
434 {
435  referenceVar = (((long)&referenceVar) - ((long)addr));
436 }
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_setMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
Replace a segment of the process memory with given byte array.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Definition: uip-nd6.c:129
#define uip_ipaddr(addr, addr0, addr1, addr2, addr3)
Construct an IP address from four bytes.
Definition: uip.h:956
clock_time_t etimer_next_expiration_time(void)
Get next event timer expiration time.
Definition: etimer.c:237
static uip_ds6_addr_t * addr
Pointer to a router list entry.
Definition: uip-nd6.c:124
Header file for IPv6-related data structures.
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_tick(JNIEnv *env, jobject obj)
Let mote execute one "block" of code (tick mote).
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition: etimer.c:145
int etimer_pending(void)
Check if there are any non-expired event timers.
Definition: etimer.c:231
int slip_input_byte(unsigned char c)
Input a SLIP byte.
Definition: slip.c:361
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_getMemory(JNIEnv *env, jobject obj, jint rel_addr, jint length, jbyteArray mem_arr)
Get a segment from the process memory.
void uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime)
Initialize the module variables.
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress(JNIEnv *env, jobject obj, jint addr)
Set the relative memory address of the reference variable.
Representation of an IP address.
Definition: uip.h:95
int process_run(void)
Run the system once - call poll handlers and process one event.
Definition: process.c:302
Unicast address structure.
Definition: uip-ds6.h:202
Header file for the Rime stack
#define NULL
The null pointer.
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
Definition: linkaddr.c:72
#define ADDR_TENTATIVE
Possible states for the an address (RFC 4862)
Definition: uip-ds6.h:153
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
void rs232_set_input(int(*f)(unsigned char))
Set an input handler for incoming RS232 data.
Definition: rs232.c:56
#define uip_ip6addr(addr, addr0, addr1, addr2, addr3, addr4, addr5, addr6, addr7)
Construct an IPv6 address from eight 16-bit words.
Definition: uip.h:970
Header file for the uIP TCP/IP stack.
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
Event timer header file.
uip_ds6_addr_t * uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
Add a unicast address to the interface.
Definition: uip-ds6.c:326
#define UIP_NAMESERVER_INFINITE_LIFETIME
Infinite Lifetime indicator.
Header file for module for automatically starting and exiting a list of processes.
uIP Name Server interface
JNIEXPORT void JNICALL Java_org_contikios_cooja_corecomm_CLASSNAME_init(JNIEnv *env, jobject obj)
Initialize a mote by starting processes etc.
Generic serial I/O process header filer.
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip.c:118
int process_nevents(void)
Number of events waiting to be processed.
Definition: process.c:316
void process_init(void)
Initialize the process module.
Definition: process.c:208
void ctimer_init(void)
Initialize the callback timer library.
Definition: ctimer.c:91
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
Definition: linkaddr.c:60
linkaddr_t linkaddr_node_addr
The Rime address of the node.
Definition: linkaddr.c:48
Include file for the Contiki low-layer network stack (NETSTACK)
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
Definition: uip-ds6.c:542