Contiki 2.6

contiki-main.c

00001 /*
00002  * Copyright (c) 2002, Adam Dunkels.
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
00011  *    copyright notice, this list of conditions and the following
00012  *    disclaimer in the documentation and/or other materials provided
00013  *    with the distribution.
00014  * 3. The name of the author may not be used to endorse or promote
00015  *    products derived from this software without specific prior
00016  *    written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
00019  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00022  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00024  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00026  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * This file is part of the Contiki OS
00031  *
00032  */
00033 
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <unistd.h>
00037 #include <sys/select.h>
00038 
00039 #ifdef __CYGWIN__
00040 #include "net/wpcap-drv.h"
00041 #endif /* __CYGWIN__ */
00042 
00043 #include "contiki.h"
00044 #include "net/netstack.h"
00045 
00046 #include "dev/serial-line.h"
00047 
00048 #include "net/uip.h"
00049 
00050 #include "dev/button-sensor.h"
00051 #include "dev/pir-sensor.h"
00052 #include "dev/vib-sensor.h"
00053 
00054 #if WITH_UIP6
00055 #include "net/uip-ds6.h"
00056 #endif /* WITH_UIP6 */
00057 
00058 #include "net/rime.h"
00059 
00060 #ifdef SELECT_CONF_MAX
00061 #define SELECT_MAX SELECT_CONF_MAX
00062 #else
00063 #define SELECT_MAX 8
00064 #endif
00065 
00066 static const struct select_callback *select_callback[SELECT_MAX];
00067 static int select_max = 0;
00068 
00069 SENSORS(&pir_sensor, &vib_sensor, &button_sensor);
00070 
00071 static uint8_t serial_id[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
00072 static uint16_t node_id = 0x0102;
00073 /*---------------------------------------------------------------------------*/
00074 int
00075 select_set_callback(int fd, const struct select_callback *callback)
00076 {
00077   int i;
00078   if(fd >= 0 && fd < SELECT_MAX) {
00079     /* Check that the callback functions are set */
00080     if(callback != NULL &&
00081        (callback->set_fd == NULL || callback->handle_fd == NULL)) {
00082       callback = NULL;
00083     }
00084 
00085     select_callback[fd] = callback;
00086 
00087     /* Update fd max */
00088     if(callback != NULL) {
00089       if(fd > select_max) {
00090         select_max = fd;
00091       }
00092     } else {
00093       select_max = 0;
00094       for(i = SELECT_MAX - 1; i > 0; i--) {
00095         if(select_callback[i] != NULL) {
00096           select_max = i;
00097           break;
00098         }
00099       }
00100     }
00101     return 1;
00102   }
00103   return 0;
00104 }
00105 /*---------------------------------------------------------------------------*/
00106 static int
00107 stdin_set_fd(fd_set *rset, fd_set *wset)
00108 {
00109   FD_SET(STDIN_FILENO, rset);
00110   return 1;
00111 }
00112 static void
00113 stdin_handle_fd(fd_set *rset, fd_set *wset)
00114 {
00115   char c;
00116   if(FD_ISSET(STDIN_FILENO, rset)) {
00117     if(read(STDIN_FILENO, &c, 1) > 0) {
00118       serial_line_input_byte(c);
00119     }
00120   }
00121 }
00122 const static struct select_callback stdin_fd = {
00123   stdin_set_fd, stdin_handle_fd
00124 };
00125 /*---------------------------------------------------------------------------*/
00126 static void
00127 set_rime_addr(void)
00128 {
00129   rimeaddr_t addr;
00130   int i;
00131 
00132   memset(&addr, 0, sizeof(rimeaddr_t));
00133 #if UIP_CONF_IPV6
00134   memcpy(addr.u8, serial_id, sizeof(addr.u8));
00135 #else
00136   if(node_id == 0) {
00137     for(i = 0; i < sizeof(rimeaddr_t); ++i) {
00138       addr.u8[i] = serial_id[7 - i];
00139     }
00140   } else {
00141     addr.u8[0] = node_id & 0xff;
00142     addr.u8[1] = node_id >> 8;
00143   }
00144 #endif
00145   rimeaddr_set_node_addr(&addr);
00146   printf("Rime started with address ");
00147   for(i = 0; i < sizeof(addr.u8) - 1; i++) {
00148     printf("%d.", addr.u8[i]);
00149   }
00150   printf("%d\n", addr.u8[i]);
00151 }
00152 
00153 
00154 /*---------------------------------------------------------------------------*/
00155 int contiki_argc = 0;
00156 char **contiki_argv;
00157 
00158 int
00159 main(int argc, char **argv)
00160 {
00161 #if UIP_CONF_IPV6
00162 #if UIP_CONF_IPV6_RPL
00163   printf(CONTIKI_VERSION_STRING " started with IPV6, RPL\n");
00164 #else
00165   printf(CONTIKI_VERSION_STRING " started with IPV6\n");
00166 #endif
00167 #else
00168   printf(CONTIKI_VERSION_STRING " started\n");
00169 #endif
00170 
00171   /* crappy way of remembering and accessing argc/v */
00172   contiki_argc = argc;
00173   contiki_argv = argv;
00174 
00175   /* native under windows is hardcoded to use the first one or two args */
00176   /* for wpcap configuration so this needs to be "removed" from         */
00177   /* contiki_args (used by the native-border-router) */
00178 #ifdef __CYGWIN__
00179   contiki_argc--;
00180   contiki_argv++;
00181 #ifdef UIP_FALLBACK_INTERFACE
00182   contiki_argc--;
00183   contiki_argv++;
00184 #endif
00185 #endif
00186 
00187   process_init();
00188   process_start(&etimer_process, NULL);
00189   ctimer_init();
00190 
00191   set_rime_addr();
00192 
00193   queuebuf_init();
00194 
00195   netstack_init();
00196   printf("MAC %s RDC %s NETWORK %s\n", NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name);
00197 
00198 #if WITH_UIP6
00199   memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr));
00200 
00201   process_start(&tcpip_process, NULL);
00202 #ifdef __CYGWIN__
00203   process_start(&wpcap_process, NULL);
00204 #endif
00205   printf("Tentative link-local IPv6 address ");
00206   {
00207     uip_ds6_addr_t *lladdr;
00208     int i;
00209     lladdr = uip_ds6_get_link_local(-1);
00210     for(i = 0; i < 7; ++i) {
00211       printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
00212              lladdr->ipaddr.u8[i * 2 + 1]);
00213     }
00214     /* make it hardcoded... */
00215     lladdr->state = ADDR_AUTOCONF;
00216 
00217     printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
00218   }
00219 #else
00220   process_start(&tcpip_process, NULL);
00221 #endif
00222 
00223   serial_line_init();
00224   
00225   autostart_start(autostart_processes);
00226   
00227   /* Make standard output unbuffered. */
00228   setvbuf(stdout, (char *)NULL, _IONBF, 0);
00229 
00230   select_set_callback(STDIN_FILENO, &stdin_fd);
00231   while(1) {
00232     fd_set fdr;
00233     fd_set fdw;
00234     int maxfd;
00235     int i;
00236     int retval;
00237     struct timeval tv;
00238 
00239     retval = process_run();
00240 
00241     tv.tv_sec = 0;
00242     tv.tv_usec = retval ? 1 : 1000;
00243 
00244     FD_ZERO(&fdr);
00245     FD_ZERO(&fdw);
00246     maxfd = 0;
00247     for(i = 0; i <= select_max; i++) {
00248       if(select_callback[i] != NULL && select_callback[i]->set_fd(&fdr, &fdw)) {
00249         maxfd = i;
00250       }
00251     }
00252 
00253     retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv);
00254     if(retval < 0) {
00255       perror("select");
00256     } else if(retval > 0) {
00257       /* timeout => retval == 0 */
00258       for(i = 0; i <= maxfd; i++) {
00259         if(select_callback[i] != NULL) {
00260           select_callback[i]->handle_fd(&fdr, &fdw);
00261         }
00262       }
00263     }
00264 
00265     etimer_request_poll();
00266   }
00267 
00268   return 0;
00269 }
00270 /*---------------------------------------------------------------------------*/
00271 void
00272 log_message(char *m1, char *m2)
00273 {
00274   printf("%s%s\n", m1, m2);
00275 }
00276 /*---------------------------------------------------------------------------*/
00277 void
00278 uip_log(char *m)
00279 {
00280   printf("%s\n", m);
00281 }
00282 /*---------------------------------------------------------------------------*/