diff --git a/examples/ipv6/native-border-router/project-conf.h b/examples/ipv6/native-border-router/project-conf.h index 4870f02a3..6258b4eca 100644 --- a/examples/ipv6/native-border-router/project-conf.h +++ b/examples/ipv6/native-border-router/project-conf.h @@ -50,7 +50,7 @@ #undef NETSTACK_CONF_RDC #define NETSTACK_CONF_RDC border_router_rdc_driver -#define SELECT_CALLBACK (&tun_select_callback) -extern struct select_callback tun_select_callback; +/* used by wpcap (see /cpu/native/net/wpcap-drv.c) */ +#define SELECT_CALLBACK 1 #endif /* __PROJECT_ROUTER_CONF_H__ */ diff --git a/examples/ipv6/native-border-router/slip-dev.c b/examples/ipv6/native-border-router/slip-dev.c index 6cf22e5e7..eb1fab1c4 100644 --- a/examples/ipv6/native-border-router/slip-dev.c +++ b/examples/ipv6/native-border-router/slip-dev.c @@ -368,6 +368,31 @@ stty_telos(int fd) if(tcflush(fd, TCIOFLUSH) == -1) err(1, "tcflush"); } /*---------------------------------------------------------------------------*/ +static int +set_fd(fd_set *rset, fd_set *wset) +{ + if(!slip_empty()) { /* Anything to flush? */ + FD_SET(slipfd, wset); + } + + FD_SET(slipfd, rset); /* Read from slip ASAP! */ + return 1; +} +/*---------------------------------------------------------------------------*/ +static void +handle_fd(fd_set *rset, fd_set *wset) +{ + if(FD_ISSET(slipfd, rset)) { + serial_input(inslip); + } + + if(FD_ISSET(slipfd, wset)) { + slip_flushbuf(slipfd); + } +} +/*---------------------------------------------------------------------------*/ +static const struct select_callback slip_callback = { set_fd, handle_fd }; +/*---------------------------------------------------------------------------*/ void slip_init(void) { @@ -395,6 +420,8 @@ slip_init(void) } } + select_set_callback(slipfd, &slip_callback); + fprintf(stderr, "********SLIP started on ``/dev/%s''\n", slip_config_siodev); stty_telos(slipfd); @@ -402,28 +429,3 @@ slip_init(void) inslip = fdopen(slipfd, "r"); if(inslip == NULL) err(1, "main: fdopen"); } -/*---------------------------------------------------------------------------*/ -int -slip_set_fd(int maxfd, fd_set *rset, fd_set *wset) -{ - if(!slip_empty()) { /* Anything to flush? */ - FD_SET(slipfd, wset); - } - - FD_SET(slipfd, rset); /* Read from slip ASAP! */ - if(slipfd > maxfd) maxfd = slipfd; - - return maxfd; -} -/*---------------------------------------------------------------------------*/ -void -slip_handle_fd(fd_set *rset, fd_set *wset) -{ - if(FD_ISSET(slipfd, rset)) { - serial_input(inslip); - } - - if(FD_ISSET(slipfd, wset)) { - slip_flushbuf(slipfd); - } -} diff --git a/examples/ipv6/native-border-router/tun-bridge.c b/examples/ipv6/native-border-router/tun-bridge.c index 65dfb24cf..db695c289 100644 --- a/examples/ipv6/native-border-router/tun-bridge.c +++ b/examples/ipv6/native-border-router/tun-bridge.c @@ -51,7 +51,7 @@ #include -#define DEBUG DEBUG_PRINT +#define DEBUG DEBUG_NONE #include "net/uip-debug.h" #ifdef linux @@ -65,14 +65,20 @@ #include "cmd.h" #include "border-router.h" -extern int slip_config_verbose; extern const char *slip_config_ipaddr; -extern int slip_config_flowcontrol; extern char slip_config_tundev[32]; extern uint16_t slip_config_basedelay; +#ifndef __CYGWIN__ static int tunfd; -static int initialized = 0; + +static int set_fd(fd_set *rset, fd_set *wset); +static void handle_fd(fd_set *rset, fd_set *wset); +static const struct select_callback tun_select_callback = { + set_fd, + handle_fd +}; +#endif /* __CYGWIN__ */ int ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); @@ -181,8 +187,6 @@ tun_init() setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ slip_init(); - - initialized = 1; } #else @@ -200,6 +204,9 @@ tun_init() tunfd = tun_alloc(slip_config_tundev); if(tunfd == -1) err(1, "main: open"); + + select_set_callback(tunfd, &tun_select_callback); + fprintf(stderr, "opened %s device ``/dev/%s''\n", "tun", slip_config_tundev); @@ -208,8 +215,6 @@ tun_init() signal(SIGTERM, sigcleanup); signal(SIGINT, sigcleanup); ifconf(slip_config_tundev, slip_config_ipaddr); - - initialized = 1; } /*---------------------------------------------------------------------------*/ @@ -251,22 +256,14 @@ const struct uip_fallback_interface rpl_interface = { init, output }; -#endif /* __CYGWIN_ */ - /*---------------------------------------------------------------------------*/ /* tun and slip select callback */ /*---------------------------------------------------------------------------*/ static int -set_fd(int maxfd, fd_set *rset, fd_set *wset) +set_fd(fd_set *rset, fd_set *wset) { - if(!initialized) return maxfd; - - maxfd = slip_set_fd(maxfd, rset, wset); - FD_SET(tunfd, rset); - if(tunfd > maxfd) maxfd = tunfd; - - return maxfd; + return 1; } /*---------------------------------------------------------------------------*/ @@ -274,14 +271,6 @@ set_fd(int maxfd, fd_set *rset, fd_set *wset) static void handle_fd(fd_set *rset, fd_set *wset) { - if(!initialized) return; - - slip_handle_fd(rset, wset); - -#ifdef __CYGWIN__ -/* Packets from host interface are handled by wpcap process */ -#else - /* Optional delay between outgoing packets */ /* Base delay times number of 6lowpan fragments to be sent */ /* delaymsec = 10; */ @@ -312,12 +301,7 @@ handle_fd(fd_set *rset, fd_set *wset) } } } -#endif /* __CYGWIN__ */ } +#endif /* __CYGWIN_ */ /*---------------------------------------------------------------------------*/ - -struct select_callback tun_select_callback = { - set_fd, - handle_fd -}; diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index b6a8516f8..a388ab8d5 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -38,10 +38,12 @@ #ifndef WIN32_LEAN_AND_MEAN #include #endif + struct select_callback { - int (* set_fd)(int maxfd, fd_set *fdr, fd_set *fdw); + int (* set_fd)(fd_set *fdr, fd_set *fdw); void (* handle_fd)(fd_set *fdr, fd_set *fdw); }; +int select_set_callback(int fd, const struct select_callback *callback); #define CC_CONF_REGISTER_ARGS 1 #define CC_CONF_FUNCTION_POINTER_ARGS 1 @@ -177,5 +179,4 @@ int strcasecmp(const char*, const char*); #include PROJECT_CONF_H #endif /* PROJECT_CONF_H */ - #endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/native/contiki-main.c b/platform/native/contiki-main.c index a377876b8..7a0be95bf 100644 --- a/platform/native/contiki-main.c +++ b/platform/native/contiki-main.c @@ -29,8 +29,6 @@ * * This file is part of the Contiki OS * - * $Id: contiki-main.c,v 1.14 2011/01/21 14:19:57 nvt-se Exp $ - * */ #include @@ -59,14 +57,72 @@ #include "net/rime.h" +#ifdef SELECT_CONF_MAX +#define SELECT_MAX SELECT_CONF_MAX +#else +#define SELECT_MAX 8 +#endif -PROCINIT(&etimer_process, &tcpip_process); +static const struct select_callback *select_callback[SELECT_MAX]; +static int select_max = 0; SENSORS(&pir_sensor, &vib_sensor, &button_sensor); static uint8_t serial_id[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}; static uint16_t node_id = 0x0102; /*---------------------------------------------------------------------------*/ +int +select_set_callback(int fd, const struct select_callback *callback) +{ + int i; + if(fd >= 0 && fd < SELECT_MAX) { + /* Check that the callback functions are set */ + if(callback != NULL && + (callback->set_fd == NULL || callback->handle_fd == NULL)) { + callback = NULL; + } + + select_callback[fd] = callback; + + /* Update fd max */ + if(callback != NULL) { + if(fd > select_max) { + select_max = fd; + } + } else { + select_max = 0; + for(i = SELECT_MAX - 1; i > 0; i--) { + if(select_callback[i] != NULL) { + select_max = i; + break; + } + } + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +stdin_set_fd(fd_set *rset, fd_set *wset) +{ + FD_SET(STDIN_FILENO, rset); + return 1; +} +static void +stdin_handle_fd(fd_set *rset, fd_set *wset) +{ + char c; + if(FD_ISSET(STDIN_FILENO, rset)) { + if(read(STDIN_FILENO, &c, 1) > 0) { + serial_line_input_byte(c); + } + } +} +const static struct select_callback stdin_fd = { + stdin_set_fd, stdin_handle_fd +}; +/*---------------------------------------------------------------------------*/ static void set_rime_addr(void) { @@ -104,12 +160,12 @@ main(int argc, char **argv) { #if UIP_CONF_IPV6 #if UIP_CONF_IPV6_RPL - printf("Starting Contiki IPV6, RPL\n"); + printf(CONTIKI_VERSION_STRING " started with IPV6, RPL\n"); #else - printf("Starting Contiki IPV6\n"); + printf(CONTIKI_VERSION_STRING " started with IPV6\n"); #endif #else - printf("Starting Contiki IPV4\n"); + printf(CONTIKI_VERSION_STRING " started\n"); #endif /* crappy way of remembering and accessing argc/v */ @@ -117,9 +173,15 @@ main(int argc, char **argv) contiki_argv = argv; process_init(); + process_start(&etimer_process, NULL); ctimer_init(); - set_rime_addr(); + set_rime_addr(); + + queuebuf_init(); + + netstack_init(); + printf("MAC %s RDC %s NETWORK %s\n", NETSTACK_MAC.name, NETSTACK_RDC.name, NETSTACK_NETWORK.name); #if WITH_UIP6 memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr)); @@ -142,60 +204,55 @@ main(int argc, char **argv) printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); } - +#else + process_start(&tcpip_process, NULL); #endif - queuebuf_init(); - - netstack_init(); - - procinit_init(); - serial_line_init(); autostart_start(autostart_processes); /* Make standard output unbuffered. */ setvbuf(stdout, (char *)NULL, _IONBF, 0); - + + select_set_callback(STDIN_FILENO, &stdin_fd); while(1) { fd_set fdr; fd_set fdw; int maxfd; + int i; int retval; struct timeval tv; - - process_run(); + + retval = process_run(); tv.tv_sec = 0; - tv.tv_usec = 1000; + tv.tv_usec = retval ? 1 : 1000; FD_ZERO(&fdr); FD_ZERO(&fdw); - FD_SET(STDIN_FILENO, &fdr); - maxfd = STDIN_FILENO; + maxfd = 0; + for(i = 0; i <= select_max; i++) { + if(select_callback[i] != NULL && select_callback[i]->set_fd(&fdr, &fdw)) { + maxfd = i; + } + } -#ifdef SELECT_CALLBACK - maxfd = SELECT_CALLBACK->set_fd(maxfd, &fdr, &fdw); -#endif - if((retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv)) < 0) { + retval = select(maxfd + 1, &fdr, &fdw, NULL, &tv); + if(retval < 0) { perror("select"); } else if(retval > 0) { /* timeout => retval == 0 */ - if(FD_ISSET(STDIN_FILENO, &fdr)) { - char c; - if(read(STDIN_FILENO, &c, 1) > 0) { - serial_line_input_byte(c); - } + for(i = 0; i <= maxfd; i++) { + if(select_callback[i] != NULL) { + select_callback[i]->handle_fd(&fdr, &fdw); + } } -#ifdef SELECT_CALLBACK - SELECT_CALLBACK->handle_fd(&fdr, &fdw); -#endif } etimer_request_poll(); } - + return 0; } /*---------------------------------------------------------------------------*/