diff --git a/cpu/native/Makefile.native b/cpu/native/Makefile.native index 44be5be73..eaf716424 100644 --- a/cpu/native/Makefile.native +++ b/cpu/native/Makefile.native @@ -18,10 +18,15 @@ CFLAGSWERROR=-Werror -pedantic -std=c99 -Werror endif CFLAGSNO = -Wall -g -I/usr/local/include $(CFLAGSWERROR) CFLAGS += $(CFLAGSNO) -O -ifeq ($(HOST_OS),Linux) - LDFLAGS += -Wl,-Map=contiki-$(TARGET).map,-export-dynamic + +ifeq ($(HOST_OS),Darwin) +AROPTS = -r +LDFLAGS += -Wl,-flat_namespace +CFLAGS += -DHAVE_SNPRINTF=1 -U__ASSERT_USE_STDERR else - LDFLAGS += -Wl +ifeq ($(HOST_OS),Linux) +LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic +endif endif ### Compilation rules diff --git a/cpu/native/net/tapdev-drv.c b/cpu/native/net/tapdev-drv.c index 0e4c0a29d..a4f50899e 100644 --- a/cpu/native/net/tapdev-drv.c +++ b/cpu/native/net/tapdev-drv.c @@ -59,7 +59,6 @@ tapdev_output(void) static void pollhandler(void) { - process_poll(&tapdev_process); uip_len = tapdev_poll(); if(uip_len > 0) { diff --git a/cpu/native/net/tapdev-drv.h b/cpu/native/net/tapdev-drv.h index 25014ea29..3241fc344 100644 --- a/cpu/native/net/tapdev-drv.h +++ b/cpu/native/net/tapdev-drv.h @@ -38,5 +38,6 @@ PROCESS_NAME(tapdev_process); uint8_t tapdev_output(void); +int tapdev_fd(void); #endif /* __TAPDEV_DRV_H__ */ diff --git a/cpu/native/net/tapdev.c b/cpu/native/net/tapdev.c index cc294d7a7..ecf018fcc 100644 --- a/cpu/native/net/tapdev.c +++ b/cpu/native/net/tapdev.c @@ -69,12 +69,19 @@ static unsigned long lasttime; #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) +/*---------------------------------------------------------------------------*/ +int +tapdev_fd(void) +{ + return fd; +} + /*---------------------------------------------------------------------------*/ static void remove_route(void) { char buf[1024]; - snprintf(buf, sizeof(buf), "route delete -net 172.16.0.0"); + snprintf(buf, sizeof(buf), "route delete -net 172.18.0.0"); system(buf); printf("%s\n", buf); @@ -103,15 +110,15 @@ tapdev_init(void) } #endif /* Linux */ - snprintf(buf, sizeof(buf), "ifconfig tap0 inet 192.168.1.1"); + snprintf(buf, sizeof(buf), "ifconfig tap0 inet 172.18.0.1/16"); system(buf); printf("%s\n", buf); #ifdef linux /* route add for linux */ - snprintf(buf, sizeof(buf), "route add -net 172.16.0.0/16 gw 192.168.1.2"); + snprintf(buf, sizeof(buf), "route add -net 172.18.0.0/16 dev tap0"); #else /* linux */ /* route add for freebsd */ - snprintf(buf, sizeof(buf), "route add -net 172.16.0.0/16 192.168.1.2"); + snprintf(buf, sizeof(buf), "route add -net 172.18.0.0/16 -iface tap0"); #endif /* linux */ system(buf); diff --git a/cpu/native/net/tapdev6.c b/cpu/native/net/tapdev6.c index e687ada10..9f85c47c2 100644 --- a/cpu/native/net/tapdev6.c +++ b/cpu/native/net/tapdev6.c @@ -56,6 +56,17 @@ #define DEVTAP "/dev/tap0" #endif /* linux */ +#ifdef __APPLE__ +#include +#include +#include +#include // ND6_INFINITE_LIFETIME +#include +#include +#include +#include // struct sockaddr_dl +#include // AF_ROUTE things +#endif #include "tapdev6.h" #include "contiki-net.h" @@ -66,7 +77,7 @@ static int drop = 0; #endif -static int fd; +static int fd = -1; static unsigned long lasttime; @@ -85,6 +96,13 @@ static unsigned long lasttime; static void do_send(void); uint8_t tapdev_send(uip_lladdr_t *lladdr); +/*---------------------------------------------------------------------------*/ +int +tapdev_fd(void) +{ + return fd; +} + uint16_t tapdev_poll(void) @@ -116,6 +134,159 @@ tapdev_poll(void) return ret; } /*---------------------------------------------------------------------------*/ +#if defined(__APPLE__) +static int reqfd = -1, sfd = -1, interface_index; + +static void +tapdev_init_darwin_routes(void) +{ + struct stat st; + + if(-1 == fstat(fd, &st)) { + perror("tapdev: fstat failed."); + exit(EXIT_FAILURE); + } + + /************* Add address *************/ + + struct in6_aliasreq addreq6 = { }; + reqfd = socket(AF_INET6, SOCK_DGRAM, 0); + + if(-1 == fcntl(reqfd, F_SETFD, FD_CLOEXEC)) { + perror("tapdev: fcntl failed."); + exit(EXIT_FAILURE); + } + + devname_r(st.st_rdev, S_IFCHR, addreq6.ifra_name, + sizeof(addreq6.ifra_name)); + + addreq6.ifra_addr.sin6_family = AF_INET6; + addreq6.ifra_addr.sin6_len = sizeof(addreq6.ifra_addr); + addreq6.ifra_addr.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xAAAA); + addreq6.ifra_addr.sin6_addr.__u6_addr.__u6_addr16[7] = UIP_HTONS(0x0001); + + addreq6.ifra_prefixmask.sin6_family = AF_INET6; + addreq6.ifra_prefixmask.sin6_len = sizeof(addreq6.ifra_prefixmask); + addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[0] = + UIP_HTONS(0xFFFF); + addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[1] = + UIP_HTONS(0xFFFF); + addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[2] = + UIP_HTONS(0xFFFF); + addreq6.ifra_prefixmask.sin6_addr.__u6_addr.__u6_addr16[3] = + UIP_HTONS(0xFFFF); + + addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; + addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; + addreq6.ifra_lifetime.ia6t_expire = ND6_INFINITE_LIFETIME; + addreq6.ifra_lifetime.ia6t_preferred = ND6_INFINITE_LIFETIME; + + if(-1 == ioctl(reqfd, SIOCAIFADDR_IN6, &addreq6)) { + perror("tapdev: Uable to add address, call to ioctl failed."); + exit(EXIT_FAILURE); + } + + /************* Add route *************/ + + int s = socket(AF_ROUTE, SOCK_RAW, AF_INET6); + + if(s == -1) { + perror("tapdev: Unable to add route, call to socket() failed."); + + // Failing to add the route is not fatal, so just return. + return; + } + + sfd = s; + interface_index = if_nametoindex(devname(st.st_rdev, S_IFCHR)); + + PRINTF("tapdev: if_nametoindex(devname(st.st_rdev, S_IFCHR)) = %d\n", + interface_index); + PRINTF("tapdev: devname(st.st_rdev, S_IFCHR) = %s\n", + devname(st.st_rdev, S_IFCHR)); + + struct { + struct rt_msghdr hdr; + struct sockaddr_in6 dst; + struct sockaddr_dl gw; + struct sockaddr_in6 mask; + } msg = {}; + + msg.hdr.rtm_msglen = sizeof(msg); + msg.hdr.rtm_version = RTM_VERSION; + msg.hdr.rtm_type = RTM_ADD; + msg.hdr.rtm_index = interface_index; + msg.hdr.rtm_flags = RTF_UP | RTF_STATIC; + msg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; + msg.hdr.rtm_pid = getpid(); + msg.hdr.rtm_seq = 0; + + msg.dst.sin6_family = AF_INET6; + msg.dst.sin6_len = sizeof(msg.dst); + msg.dst.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xAAAA); + + msg.gw.sdl_family = AF_LINK; + msg.gw.sdl_len = sizeof(msg.gw); + msg.gw.sdl_index = interface_index; + + msg.mask.sin6_family = AF_INET6; + msg.mask.sin6_len = sizeof(msg.mask); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xFFFF); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[1] = UIP_HTONS(0xFFFF); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[2] = UIP_HTONS(0xFFFF); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[3] = UIP_HTONS(0xFFFF); + + if(-1 == write(s, &msg, sizeof(msg))) { + perror("tapdev: Unable to add route, call to write() failed."); + + // Failing to add the route is not fatal, so just return. + return; + } +} +/*---------------------------------------------------------------------------*/ +static void +tapdev_cleanup_darwin_routes(void) +{ + struct { + struct rt_msghdr hdr; + struct sockaddr_in6 dst; + struct sockaddr_dl gw; + struct sockaddr_in6 mask; + } msg = {}; + + msg.hdr.rtm_msglen = sizeof(msg); + msg.hdr.rtm_version = RTM_VERSION; + msg.hdr.rtm_type = RTM_DELETE; + msg.hdr.rtm_index = interface_index; + msg.hdr.rtm_flags = RTF_UP | RTF_STATIC; + msg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; + msg.hdr.rtm_pid = getpid(); + msg.hdr.rtm_seq = 0; + + msg.dst.sin6_family = AF_INET6; + msg.dst.sin6_len = sizeof(msg.dst); + msg.dst.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xAAAA); + + msg.gw.sdl_family = AF_LINK; + msg.gw.sdl_len = sizeof(msg.gw); + msg.gw.sdl_index = interface_index; + + msg.mask.sin6_family = AF_INET6; + msg.mask.sin6_len = sizeof(msg.mask); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[0] = UIP_HTONS(0xFFFF); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[1] = UIP_HTONS(0xFFFF); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[2] = UIP_HTONS(0xFFFF); + msg.mask.sin6_addr.__u6_addr.__u6_addr16[3] = UIP_HTONS(0xFFFF); + if(-1 == write(sfd, &msg, sizeof(msg))) { + perror("tapdev: Unable to delete route"); + exit(EXIT_FAILURE); + } + + close(reqfd); + close(sfd); +} +#endif // defined(__APPLE__) +/*---------------------------------------------------------------------------*/ void tapdev_init(void) { @@ -139,6 +310,10 @@ tapdev_init(void) } #endif /* Linux */ +#ifdef __APPLE__ + tapdev_init_darwin_routes(); +#endif + /* Linux (ubuntu) snprintf(buf, sizeof(buf), "ip link set tap0 up"); system(buf); @@ -161,6 +336,7 @@ tapdev_init(void) /* gdk_input_add(fd, GDK_INPUT_READ, read_callback, NULL);*/ + atexit(&tapdev_exit); } /*---------------------------------------------------------------------------*/ static void @@ -228,5 +404,12 @@ tapdev_do_send(void) void tapdev_exit(void) { + PRINTF("tapdev: Closing...\n"); + +#ifdef __APPLE__ + tapdev_cleanup_darwin_routes(); +#endif + + close(fd); } /*---------------------------------------------------------------------------*/ diff --git a/platform/minimal-net/contiki-main.c b/platform/minimal-net/contiki-main.c index 64301d38f..89ddf00f0 100644 --- a/platform/minimal-net/contiki-main.c +++ b/platform/minimal-net/contiki-main.c @@ -33,6 +33,8 @@ */ #include +#include +#include #include #include #include @@ -40,6 +42,7 @@ #include "contiki.h" #include "contiki-net.h" +#include "lib/assert.h" #include "dev/serial-line.h" @@ -233,21 +236,21 @@ main(void) uip_gethostaddr(&addr); if(addr.u8[0] == 0) { - uip_ipaddr(&addr, 10,1,1,1); + uip_ipaddr(&addr, 172,18,0,2); } printf("IP Address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_sethostaddr(&addr); uip_getnetmask(&addr); if(addr.u8[0] == 0) { - uip_ipaddr(&addr, 255,0,0,0); + uip_ipaddr(&addr, 255,255,0,0); uip_setnetmask(&addr); } printf("Subnet Mask: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_getdraddr(&addr); if(addr.u8[0] == 0) { - uip_ipaddr(&addr, 10,1,1,100); + uip_ipaddr(&addr, 172,18,0,1); uip_setdraddr(&addr); } printf("Def. Router: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); @@ -267,9 +270,15 @@ main(void) (ipaddr.u16[2] != 0) || (ipaddr.u16[3] != 0)) { #if UIP_CONF_ROUTER - uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0); + if(!uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0)) { + fprintf(stderr,"uip_ds6_prefix_add() failed.\n"); + exit(EXIT_FAILURE); + } #else /* UIP_CONF_ROUTER */ - uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0); + if(!uip_ds6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0)) { + fprintf(stderr,"uip_ds6_prefix_add() failed.\n"); + exit(EXIT_FAILURE); + } #endif /* UIP_CONF_ROUTER */ uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); @@ -290,14 +299,17 @@ main(void) #if UIP_CONF_IPV6 && !RPL_BORDER_ROUTER /* Border router process prints addresses later */ { - uint8_t i; + int i = 0; + int interface_count = 0; for(i = 0; i < UIP_DS6_ADDR_NB; i++) { if(uip_ds6_if.addr_list[i].isused) { - printf("IPV6 Addresss: "); - sprint_ip6(uip_ds6_if.addr_list[i].ipaddr); - printf("\n"); + printf("IPV6 Addresss: "); + sprint_ip6(uip_ds6_if.addr_list[i].ipaddr); + printf("\n"); + interface_count++; } } + assert(0 < interface_count); } #endif @@ -305,14 +317,40 @@ main(void) fd_set fds; int n; struct timeval tv; + clock_time_t next_event; n = process_run(); + next_event = etimer_next_expiration_time() - clock_time(); + +#if DEBUG_SLEEP + if(n > 0) + printf("sleep: %d events pending\n",n); + else + printf("sleep: next event @ T-%.03f\n",(double)next_event / (double)CLOCK_SECOND); +#endif + +#ifdef __CYGWIN__ + /* wpcap doesn't appear to support select, so + * we can't idle the process on windows. */ + next_event = 0; +#endif + + if(next_event > (CLOCK_SECOND * 2)) + next_event = CLOCK_SECOND * 2; + tv.tv_sec = n ? 0 : (next_event / CLOCK_SECOND); + tv.tv_usec = n ? 0 : ((next_event % 1000) * 1000); - tv.tv_sec = 0; - tv.tv_usec = 1000; FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); +#ifdef __CYGWIN__ select(1, &fds, NULL, NULL, &tv); +#else + FD_SET(tapdev_fd(), &fds); + if(0 > select(tapdev_fd() + 1, &fds, NULL, NULL, &tv)) { + perror("Call to select() failed."); + exit(EXIT_FAILURE); + } +#endif if(FD_ISSET(STDIN_FILENO, &fds)) { char c; @@ -320,6 +358,7 @@ main(void) serial_line_input_byte(c); } } + process_poll(&tapdev_process); etimer_request_poll(); } @@ -338,6 +377,14 @@ uip_log(char *m) printf("uIP: '%s'\n", m); } /*---------------------------------------------------------------------------*/ +void +_xassert(const char *file, int line) +{ + fprintf(stderr, "%s:%u: failed assertion\n", file, line); + abort(); +} + + unsigned short sensors_light1(void) { diff --git a/platform/minimal-net/leds-arch.c b/platform/minimal-net/leds-arch.c index 1308c57dc..ca2245481 100644 --- a/platform/minimal-net/leds-arch.c +++ b/platform/minimal-net/leds-arch.c @@ -37,6 +37,7 @@ * Adam Dunkels */ +#include #include "dev/leds.h" static unsigned char leds; /*---------------------------------------------------------------------------*/ @@ -55,6 +56,15 @@ leds_arch_get(void) void leds_arch_set(unsigned char l) { + int i; + + for(i = 0; i < 8 && ((1 << i) & LEDS_ALL); i++) { + if(((1 << i) & leds) && !((1 << i) & l)) { + printf("LED %d OFF\n", i); + } else if(!((1 << i) & leds) && ((1 << i) & l)) { + printf("LED %d ON\n", i); + } + } leds = l; } /*---------------------------------------------------------------------------*/