Contiki 3.x
contiki-main.c
1 /*
2  * Copyright (c) 2002, Adam Dunkels.
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
11  * copyright notice, this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided
13  * with the distribution.
14  * 3. The name of the author may not be used to endorse or promote
15  * products derived from this software without specific prior
16  * written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This file is part of the Contiki OS
31  *
32  */
33 
34 /**
35  * \ingroup platform
36  *
37  * \defgroup native_platform Native platform
38  *
39  * Platform running in the host (Windows or Linux) environment.
40  *
41  * Used mainly for development and debugging.
42  * @{
43  */
44 
45 #include <stdio.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <sys/select.h>
49 #include <errno.h>
50 
51 #ifdef __CYGWIN__
52 #include "net/wpcap-drv.h"
53 #endif /* __CYGWIN__ */
54 
55 #include "contiki.h"
56 #include "net/netstack.h"
57 
58 #include "ctk/ctk.h"
59 #include "ctk/ctk-curses.h"
60 
61 #include "dev/serial-line.h"
62 
63 #include "net/ip/uip.h"
64 
65 #include "dev/button-sensor.h"
66 #include "dev/pir-sensor.h"
67 #include "dev/vib-sensor.h"
68 
69 #if WITH_UIP6
70 #include "net/ipv6/uip-ds6.h"
71 #endif /* WITH_UIP6 */
72 
73 #include "net/rime/rime.h"
74 
75 #ifdef SELECT_CONF_MAX
76 #define SELECT_MAX SELECT_CONF_MAX
77 #else
78 #define SELECT_MAX 8
79 #endif
80 
81 static const struct select_callback *select_callback[SELECT_MAX];
82 static int select_max = 0;
83 
84 SENSORS(&pir_sensor, &vib_sensor, &button_sensor);
85 
86 static uint8_t serial_id[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
87 static uint16_t node_id = 0x0102;
88 /*---------------------------------------------------------------------------*/
89 int
90 select_set_callback(int fd, const struct select_callback *callback)
91 {
92  int i;
93  if(fd >= 0 && fd < SELECT_MAX) {
94  /* Check that the callback functions are set */
95  if(callback != NULL &&
96  (callback->set_fd == NULL || callback->handle_fd == NULL)) {
97  callback = NULL;
98  }
99 
100  select_callback[fd] = callback;
101 
102  /* Update fd max */
103  if(callback != NULL) {
104  if(fd > select_max) {
105  select_max = fd;
106  }
107  } else {
108  select_max = 0;
109  for(i = SELECT_MAX - 1; i > 0; i--) {
110  if(select_callback[i] != NULL) {
111  select_max = i;
112  break;
113  }
114  }
115  }
116  return 1;
117  }
118  return 0;
119 }
120 /*---------------------------------------------------------------------------*/
121 static int
122 stdin_set_fd(fd_set *rset, fd_set *wset)
123 {
124  FD_SET(STDIN_FILENO, rset);
125  return 1;
126 }
127 static void
128 stdin_handle_fd(fd_set *rset, fd_set *wset)
129 {
130  char c;
131  if(FD_ISSET(STDIN_FILENO, rset)) {
132  if(read(STDIN_FILENO, &c, 1) > 0) {
134  }
135  }
136 }
137 const static struct select_callback stdin_fd = {
138  stdin_set_fd, stdin_handle_fd
139 };
140 /*---------------------------------------------------------------------------*/
141 static void
142 set_rime_addr(void)
143 {
144  linkaddr_t addr;
145  int i;
146 
147  memset(&addr, 0, sizeof(linkaddr_t));
148 #if UIP_CONF_IPV6
149  memcpy(addr.u8, serial_id, sizeof(addr.u8));
150 #else
151  if(node_id == 0) {
152  for(i = 0; i < sizeof(linkaddr_t); ++i) {
153  addr.u8[i] = serial_id[7 - i];
154  }
155  } else {
156  addr.u8[0] = node_id & 0xff;
157  addr.u8[1] = node_id >> 8;
158  }
159 #endif
160  linkaddr_set_node_addr(&addr);
161  printf("Rime started with address ");
162  for(i = 0; i < sizeof(addr.u8) - 1; i++) {
163  printf("%d.", addr.u8[i]);
164  }
165  printf("%d\n", addr.u8[i]);
166 }
167 
168 
169 /*---------------------------------------------------------------------------*/
170 int contiki_argc = 0;
171 char **contiki_argv;
172 
173 int
174 main(int argc, char **argv)
175 {
176 #if UIP_CONF_IPV6
177 #if UIP_CONF_IPV6_RPL
178  printf(CONTIKI_VERSION_STRING " started with IPV6, RPL\n");
179 #else
180  printf(CONTIKI_VERSION_STRING " started with IPV6\n");
181 #endif
182 #else
183  printf(CONTIKI_VERSION_STRING " started\n");
184 #endif
185 
186  /* crappy way of remembering and accessing argc/v */
187  contiki_argc = argc;
188  contiki_argv = argv;
189 
190  /* native under windows is hardcoded to use the first one or two args */
191  /* for wpcap configuration so this needs to be "removed" from */
192  /* contiki_args (used by the native-border-router) */
193 #ifdef __CYGWIN__
194  contiki_argc--;
195  contiki_argv++;
196 #ifdef UIP_FALLBACK_INTERFACE
197  contiki_argc--;
198  contiki_argv++;
199 #endif
200 #endif
201 
202  process_init();
203  process_start(&etimer_process, NULL);
204  ctimer_init();
205  rtimer_init();
206 
207 #if WITH_GUI
208  process_start(&ctk_process, NULL);
209 #endif
210 
211  set_rime_addr();
212 
213  netstack_init();
214  printf("MAC %s RDC %s NETWORK %s\n", NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name);
215 
216 #if WITH_UIP6
217  queuebuf_init();
218 
219  memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr));
220 
221  process_start(&tcpip_process, NULL);
222 #ifdef __CYGWIN__
223  process_start(&wpcap_process, NULL);
224 #endif
225  printf("Tentative link-local IPv6 address ");
226  {
227  uip_ds6_addr_t *lladdr;
228  int i;
229  lladdr = uip_ds6_get_link_local(-1);
230  for(i = 0; i < 7; ++i) {
231  printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
232  lladdr->ipaddr.u8[i * 2 + 1]);
233  }
234  /* make it hardcoded... */
235  lladdr->state = ADDR_AUTOCONF;
236 
237  printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
238  }
239 #else
240  process_start(&tcpip_process, NULL);
241 #endif
242 
243  serial_line_init();
244 
245  autostart_start(autostart_processes);
246 
247  /* Make standard output unbuffered. */
248  setvbuf(stdout, (char *)NULL, _IONBF, 0);
249 
250  select_set_callback(STDIN_FILENO, &stdin_fd);
251  while(1) {
252  fd_set fdr;
253  fd_set fdw;
254  int maxfd;
255  int i;
256  int retval;
257  struct timeval tv;
258 
259  retval = process_run();
260 
261  tv.tv_sec = 0;
262  tv.tv_usec = retval ? 1 : 1000;
263 
264  FD_ZERO(&fdr);
265  FD_ZERO(&fdw);
266  maxfd = 0;
267  for(i = 0; i <= select_max; i++) {
268  if(select_callback[i] != NULL && select_callback[i]->set_fd(&fdr, &fdw)) {
269  maxfd = i;
270  }
271  }
272 
273  retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv);
274  if(retval < 0) {
275  if(errno != EINTR) {
276  perror("select");
277  }
278  } else if(retval > 0) {
279  /* timeout => retval == 0 */
280  for(i = 0; i <= maxfd; i++) {
281  if(select_callback[i] != NULL) {
282  select_callback[i]->handle_fd(&fdr, &fdw);
283  }
284  }
285  }
286 
288 
289 #if WITH_GUI
290  if(console_resize()) {
291  ctk_restore();
292  }
293 #endif /* WITH_GUI */
294  }
295 
296  return 0;
297 }
298 /*---------------------------------------------------------------------------*/
299 void
300 log_message(char *m1, char *m2)
301 {
302  fprintf(stderr, "%s%s\n", m1, m2);
303 }
304 /*---------------------------------------------------------------------------*/
305 void
306 uip_log(char *m)
307 {
308  fprintf(stderr, "%s\n", m);
309 }
310 /*---------------------------------------------------------------------------*/
311 /** @} */
312 
int serial_line_input_byte(unsigned char c)
Get one byte of input from the serial driver.
Definition: serial-line.c:60
CCIF uip_lladdr_t uip_lladdr
Host L2 address.
Definition: uip6.c:115
Unicast address structure.
Definition: uip-ds6.h:172
Header file for the uIP TCP/IP stack.
void rtimer_init(void)
Initialize the real-time scheduler.
Definition: rtimer.c:61
Network interface and stateless autoconfiguration (RFC 4862)
#define NULL
The null pointer.
void uip_log(char *msg)
Print out a uIP log message.
Definition: uip-log.c:3
int main(void)
This is main...
Definition: ethconfig.c:49
void process_init(void)
Initialize the process module.
Definition: process.c:208
Header file for the Rime stack
Generic serial I/O process header filer.
void ctimer_init(void)
Initialize the callback timer library.
Definition: ctimer.c:91
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition: etimer.c:145
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
int process_run(void)
Run the system once - call poll handlers and process one event.
Definition: process.c:302
void linkaddr_set_node_addr(linkaddr_t *t)
Set the address of the current node.
Definition: linkaddr.c:72
CTK header file.
Include file for the Contiki low-layer network stack (NETSTACK)