Contiki 2.6
|
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 /*---------------------------------------------------------------------------*/