From 8b83ffec678724b5a38ef327cec1850ad580d36c Mon Sep 17 00:00:00 2001 From: Niclas Finne Date: Mon, 19 Dec 2011 13:50:50 +0100 Subject: [PATCH] Added native-border-router and slip-radio --- Makefile.include | 5 +- apps/slip-cmd/Makefile.slip-cmd | 1 + apps/slip-cmd/cmd.c | 71 +++ apps/slip-cmd/cmd.h | 53 +++ apps/slip-cmd/packetutils.c | 81 ++++ apps/slip-cmd/packetutils.h | 37 ++ core/net/tcpip.c | 2 +- core/net/uip-icmp6.c | 2 - core/net/uip6.c | 12 +- examples/ipv6/native-border-router/Makefile | 30 ++ .../ipv6/native-border-router/Makefile.target | 1 + .../native-border-router/border-router-cmds.c | 142 ++++++ .../native-border-router/border-router-cmds.h | 43 ++ .../native-border-router/border-router-rdc.c | 106 ++--- .../ipv6/native-border-router/border-router.c | 361 +++++++++++++++ .../ipv6/native-border-router/border-router.h | 58 +++ .../ipv6/native-border-router/httpd-simple.c | 261 +++++++++++ .../ipv6/native-border-router/httpd-simple.h | 74 +++ .../ipv6/native-border-router/project-conf.h | 56 +++ .../ipv6/native-border-router/slip-config.c | 177 ++++++++ examples/ipv6/native-border-router/slip-dev.c | 425 ++++++++++++++++++ .../ipv6/native-border-router/tun-bridge.c | 300 +++++++++++++ examples/ipv6/slip-radio/Makefile | 20 + examples/ipv6/slip-radio/no-framer.c | 121 +++++ examples/ipv6/slip-radio/project-conf.h | 76 ++++ examples/ipv6/slip-radio/slip-net.c | 103 +++++ examples/ipv6/slip-radio/slip-radio-cc2420.c | 60 +++ .../ipv6/slip-radio/slip-radio-sky-sensors.c | 90 ++++ examples/ipv6/slip-radio/slip-radio.c | 220 +++++++++ examples/ipv6/slip-radio/slip-radio.h | 41 ++ platform/native/Makefile.native | 4 + platform/native/contiki-conf.h | 95 +++- platform/native/contiki-main.c | 111 ++++- platform/native/dev/button-sensor.c | 8 +- platform/native/dev/dummy-sensors.c | 8 +- platform/native/dev/pir-sensor.c | 8 +- platform/native/dev/vib-sensor.c | 17 +- 37 files changed, 3176 insertions(+), 104 deletions(-) create mode 100644 apps/slip-cmd/Makefile.slip-cmd create mode 100644 apps/slip-cmd/cmd.c create mode 100644 apps/slip-cmd/cmd.h create mode 100644 apps/slip-cmd/packetutils.c create mode 100644 apps/slip-cmd/packetutils.h create mode 100644 examples/ipv6/native-border-router/Makefile create mode 100644 examples/ipv6/native-border-router/Makefile.target create mode 100644 examples/ipv6/native-border-router/border-router-cmds.c create mode 100644 examples/ipv6/native-border-router/border-router-cmds.h create mode 100644 examples/ipv6/native-border-router/border-router.c create mode 100644 examples/ipv6/native-border-router/border-router.h create mode 100644 examples/ipv6/native-border-router/httpd-simple.c create mode 100644 examples/ipv6/native-border-router/httpd-simple.h create mode 100644 examples/ipv6/native-border-router/project-conf.h create mode 100644 examples/ipv6/native-border-router/slip-config.c create mode 100644 examples/ipv6/native-border-router/slip-dev.c create mode 100644 examples/ipv6/native-border-router/tun-bridge.c create mode 100644 examples/ipv6/slip-radio/Makefile create mode 100644 examples/ipv6/slip-radio/no-framer.c create mode 100644 examples/ipv6/slip-radio/project-conf.h create mode 100644 examples/ipv6/slip-radio/slip-net.c create mode 100644 examples/ipv6/slip-radio/slip-radio-cc2420.c create mode 100644 examples/ipv6/slip-radio/slip-radio-sky-sensors.c create mode 100644 examples/ipv6/slip-radio/slip-radio.c create mode 100644 examples/ipv6/slip-radio/slip-radio.h diff --git a/Makefile.include b/Makefile.include index 92e49e5f2..9b643437e 100644 --- a/Makefile.include +++ b/Makefile.include @@ -58,7 +58,10 @@ ifdef UIP_CONF_IPV6 resolv.c tcpdump.c uiplib.c simple-udp.c NET += $(UIP) uip-icmp6.c uip-nd6.c uip-packetqueue.c \ sicslowpan.c neighbor-attr.c neighbor-info.c uip-ds6.c - include $(CONTIKI)/core/net/rpl/Makefile.rpl + ifneq ($(UIP_CONF_RPL),0) + CFLAGS += -DUIP_CONF_IPV6_RPL=1 + include $(CONTIKI)/core/net/rpl/Makefile.rpl + endif # UIP_CONF_RPL else # UIP_CONF_IPV6 UIP = uip.c uiplib.c resolv.c tcpip.c psock.c hc.c uip-split.c uip-fw.c \ uip-fw-drv.c uip_arp.c tcpdump.c uip-neighbor.c uip-udp-packet.c \ diff --git a/apps/slip-cmd/Makefile.slip-cmd b/apps/slip-cmd/Makefile.slip-cmd new file mode 100644 index 000000000..b9fb94233 --- /dev/null +++ b/apps/slip-cmd/Makefile.slip-cmd @@ -0,0 +1 @@ +slip-cmd_src = cmd.c packetutils.c diff --git a/apps/slip-cmd/cmd.c b/apps/slip-cmd/cmd.c new file mode 100644 index 000000000..ec3c6e039 --- /dev/null +++ b/apps/slip-cmd/cmd.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * A brief description of what this file is + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#include "cmd.h" + +#ifndef CMD_CONF_OUTPUT +#define CMD_OUTPUT slip_cmd_input +#else +#define CMD_OUTPUT CMD_CONF_OUTPUT +#endif /* CMD_CONF_OUTPUT */ + +void CMD_OUTPUT(const uint8_t *data, int data_len); + +extern cmd_handler_t cmd_handlers[]; + +/*---------------------------------------------------------------------------*/ +void +cmd_input(const uint8_t *data, int data_len) +{ + int i; + for(i = 0; cmd_handlers[i] != NULL; i++) { + if(cmd_handlers[i](data, data_len)) { + /* Command has been handled */ + return; + } + } + + /* Unknown command */ + cmd_send((uint8_t *)"EUnknown command", 16); +} +/*---------------------------------------------------------------------------*/ +void +cmd_send(const uint8_t *data, int data_len) +{ + CMD_OUTPUT(data, data_len); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/slip-cmd/cmd.h b/apps/slip-cmd/cmd.h new file mode 100644 index 000000000..078e95041 --- /dev/null +++ b/apps/slip-cmd/cmd.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Simple command handler + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#ifndef __CMD_H__ +#define __CMD_H__ + +#include "contiki.h" + +#define CMD_TYPE_ERR 'E' + +typedef int (* cmd_handler_t)(const uint8_t *data, int len); + +#define CMD_HANDLERS(...) \ +const cmd_handler_t cmd_handlers[] = {__VA_ARGS__, NULL} + +void cmd_input(const uint8_t *data, int data_len); +void cmd_send(const uint8_t *data, int data_len); + +#endif /* __CMD_H__ */ diff --git a/apps/slip-cmd/packetutils.c b/apps/slip-cmd/packetutils.c new file mode 100644 index 000000000..e8c7fd9aa --- /dev/null +++ b/apps/slip-cmd/packetutils.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "contiki.h" +#include "net/packetbuf.h" +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +/*---------------------------------------------------------------------------*/ +int +packetutils_serialize_atts(uint8_t *data, int size) +{ + int i; + /* set the length first later */ + int pos = 1; + int cnt = 0; + /* assume that values are 16-bit */ + uint16_t val; + PRINTF("packetutils: serializing packet atts"); + for(i = 0; i < PACKETBUF_NUM_ATTRS; i++) { + val = packetbuf_attr(i); + if(val != 0) { + if(pos + 3 > size) { + return -1; + } + data[pos++] = i; + data[pos++] = val >> 8; + data[pos++] = val & 255; + cnt++; + PRINTF(" %d=%d", i, val); + } + } + PRINTF(" (%d)\n", cnt); + + data[0] = cnt; + return pos; +} +/*---------------------------------------------------------------------------*/ +int +packetutils_deserialize_atts(const uint8_t *data, int size) +{ + int i, cnt, pos; + + pos = 0; + cnt = data[pos++]; + PRINTF("packetutils: deserializing %d packet atts:", cnt); + for(i = 0; i < cnt; i++) { + PRINTF(" %d=%d", data[pos], (data[pos + 1] << 8) | data[pos + 2]); + packetbuf_set_attr(data[pos], (data[pos + 1] << 8) | data[pos + 2]); + pos += 3; + } + PRINTF("\n"); + return pos; +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/slip-cmd/packetutils.h b/apps/slip-cmd/packetutils.h new file mode 100644 index 000000000..4e3af02f7 --- /dev/null +++ b/apps/slip-cmd/packetutils.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __PACKETUTILS_H__ +#define __PACKETUTILS_H__ + +int packetutils_serialize_atts(uint8_t *data, int size); + +int packetutils_deserialize_atts(const uint8_t *data, int size); + +#endif /* __PACKETUTILS_H__ */ diff --git a/core/net/tcpip.c b/core/net/tcpip.c index 7556b1239..53f6feb38 100644 --- a/core/net/tcpip.c +++ b/core/net/tcpip.c @@ -567,7 +567,7 @@ tcpip_ipv6_output(void) if(locrt == NULL) { if((nexthop = uip_ds6_defrt_choose()) == NULL) { #ifdef UIP_FALLBACK_INTERFACE - printf("FALLBACK: removing ext hdrs & setting proto %d %d\n", + PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n", uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40)); if(uip_ext_len > 0) { uint8_t proto = *((uint8_t *)UIP_IP_BUF + 40); diff --git a/core/net/uip-icmp6.c b/core/net/uip-icmp6.c index 73aaf2a0b..a8b01b5a4 100644 --- a/core/net/uip-icmp6.c +++ b/core/net/uip-icmp6.c @@ -60,10 +60,8 @@ #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) #define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len]) -#if UIP_CONF_IPV6_RPL #define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len]) #define UIP_FIRST_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[UIP_LLIPH_LEN]) -#endif /* UIP_CONF_IPV6_RPL */ /** \brief temporary IP address */ static uip_ipaddr_t tmp_ipaddr; diff --git a/core/net/uip6.c b/core/net/uip6.c index 9c121c3bd..b71844027 100644 --- a/core/net/uip6.c +++ b/core/net/uip6.c @@ -511,7 +511,14 @@ remove_ext_hdr(void) { /* Remove ext header before TCP/UDP processing. */ if(uip_ext_len > 0) { - PRINTF("Cutting ext-header before TCP send (%d)\n", uip_ext_len); + PRINTF("Cutting ext-header before TCP send (extlen: %d, uiplen: %d)\n", + uip_ext_len, uip_len); + if(uip_len - UIP_IPH_LEN- uip_ext_len < 0) { + PRINTF("ERROR: uip_len too short compared to ext len\n"); + uip_ext_len = 0; + uip_len = 0; + return; + } memmove(((uint8_t *)UIP_TCP_BUF) - uip_ext_len, (uint8_t *)UIP_TCP_BUF, uip_len - UIP_IPH_LEN - uip_ext_len); @@ -1349,7 +1356,7 @@ uip_process(u8_t flag) icmp6_input: /* This is IPv6 ICMPv6 processing code. */ - PRINTF("icmp6_input: length %d\n", uip_len); + PRINTF("icmp6_input: length %d type: %d \n", uip_len, UIP_ICMP_BUF->type); #if UIP_CONF_IPV6_CHECKS /* Compute and check the ICMP header checksum */ @@ -1357,6 +1364,7 @@ uip_process(u8_t flag) UIP_STAT(++uip_stat.icmp.drop); UIP_STAT(++uip_stat.icmp.chkerr); UIP_LOG("icmpv6: bad checksum."); + PRINTF("icmpv6: bad checksum."); goto drop; } #endif /*UIP_CONF_IPV6_CHECKS*/ diff --git a/examples/ipv6/native-border-router/Makefile b/examples/ipv6/native-border-router/Makefile new file mode 100644 index 000000000..687319367 --- /dev/null +++ b/examples/ipv6/native-border-router/Makefile @@ -0,0 +1,30 @@ +CONTIKI_PROJECT=border-router +all: $(CONTIKI_PROJECT) +APPS = slip-cmd + +CONTIKI=../../.. + +WITH_UIP6=1 +UIP_CONF_IPV6=1 +CFLAGS+= -DUIP_CONF_IPV6_RPL + +#linker optimizations +SMALL=1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += border-router-cmds.c tun-bridge.c border-router-rdc.c \ +slip-config.c slip-dev.c + +WITH_WEBSERVER=1 +ifeq ($(WITH_WEBSERVER),1) +CFLAGS += -DWEBSERVER=1 +PROJECT_SOURCEFILES += httpd-simple.c +else ifneq ($(WITH_WEBSERVER), 0) +APPS += $(WITH_WEBSERVER) +CFLAGS += -DWEBSERVER=2 +endif + +include $(CONTIKI)/Makefile.include + +connect-router: border-router.native + sudo ./border-router.native aaaa::1/64 diff --git a/examples/ipv6/native-border-router/Makefile.target b/examples/ipv6/native-border-router/Makefile.target new file mode 100644 index 000000000..12b0e8c74 --- /dev/null +++ b/examples/ipv6/native-border-router/Makefile.target @@ -0,0 +1 @@ +TARGET = native diff --git a/examples/ipv6/native-border-router/border-router-cmds.c b/examples/ipv6/native-border-router/border-router-cmds.c new file mode 100644 index 000000000..0e7482726 --- /dev/null +++ b/examples/ipv6/native-border-router/border-router-cmds.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Sets up some commands for the border router + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#include "contiki.h" +#include "cmd.h" +#include "border-router.h" +#include "dev/serial-line.h" +#include "net/rpl/rpl.h" +#include "net/uiplib.h" +#include + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" + +void packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx); +void nbr_print_stat(void); + +/*---------------------------------------------------------------------------*/ +PROCESS(border_router_cmd_process, "Border router cmd process"); +/*---------------------------------------------------------------------------*/ +/* TODO: the below code needs some way of identifying from where the command */ +/* comes. In this case it can be from stdin or from SLIP. */ +/*---------------------------------------------------------------------------*/ +int +border_router_cmd_handler(const uint8_t *data, int len) +{ + /* handle global repair, etc here */ + if(data[0] == '!') { + PRINTF("Got configuration message of type %c\n", data[1]); + if(data[1] == 'G') { + /* This is supposed to be from stdin */ + printf("Performing Global Repair...\n"); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + return 1; + } else if(data[1] == 'M') { + /* We need to know that this is from the slip-radio here. */ + PRINTF("Setting MAC address\n"); + border_router_set_mac(&data[2]); + return 1; + } else if(data[1] == 'C') { + /* We need to know that this is from the slip-radio here. */ + printf("Channel is:%d\n", data[2]); + return 1; + } else if(data[1] == 'R') { + /* We need to know that this is from the slip-radio here. */ + PRINTF("Packet data report for sid:%d st:%d tx:%d\n", + data[2], data[3], data[4]); + packet_sent(data[2], data[3], data[4]); + return 1; + } else if(data[1] == 'D') { + /* We need to know that this is from the slip-radio here... */ + PRINTF("Sensor data received\n"); + border_router_set_sensors((const char *)&data[2], len - 2); + return 1; + } + } else if(data[0] == '?') { + PRINTF("Got request message of type %c\n", data[1]); + if(data[1] == 'M') { + uint8_t buf[20]; + char* hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + buf[0] = '!'; + buf[1] = 'M'; + for(j = 0; j < 8; j++) { + buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + cmd_send(buf, 18); + return 1; + } else if(data[1] == 'C') { + /* send on! */ + write_to_slip(data, len); + return 1; + } else if(data[1] == 'S') { + border_router_print_stat(); + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +border_router_cmd_output(const uint8_t *data, int data_len) +{ + int i; + printf("CMD output: "); + for(i = 0; i < data_len; i++) { + printf("%c", data[i]); + } + printf("\n"); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_cmd_process, ev, data) +{ + PROCESS_BEGIN(); + PRINTF("Started br-cmd process\n"); + while(1) { + PROCESS_YIELD(); + if(ev == serial_line_event_message && data != NULL) { + PRINTF("Got serial data!!! %s of len: %d\n", + (char *)data, strlen((char *)data)); + cmd_input(data, strlen((char *)data)); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/native-border-router/border-router-cmds.h b/examples/ipv6/native-border-router/border-router-cmds.h new file mode 100644 index 000000000..8da68562b --- /dev/null +++ b/examples/ipv6/native-border-router/border-router-cmds.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Sets up some commands for the border router + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#ifndef __BORDER_ROUTER_CMDS_H__ +#define __BORDER_ROUTER_CMDS_H__ + +PROCESS_NAME(border_router_cmd_process); + +#endif /* __BORDER_ROUTER_CMDS_H__ */ diff --git a/examples/ipv6/native-border-router/border-router-rdc.c b/examples/ipv6/native-border-router/border-router-rdc.c index 0d82a167e..273926b84 100644 --- a/examples/ipv6/native-border-router/border-router-rdc.c +++ b/examples/ipv6/native-border-router/border-router-rdc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Swedish Institute of Computer Science. + * Copyright (c) 2011, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,28 +25,26 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * $Id: nullrdc.c,v 1.4 2010/11/23 18:11:00 nifi Exp $ */ /** * \file - * A null RDC implementation that uses framer for headers. + * A null RDC implementation that uses framer for headers and sends + * the packets over slip instead of radio. * \author * Adam Dunkels + * Joakim Eriksson * Niclas Finne */ #include "net/packetbuf.h" #include "net/queuebuf.h" #include "net/netstack.h" -#include -#include "packetbuf.h" #include "packetutils.h" +#include "border-router.h" +#include -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #include #define PRINTF(...) printf(__VA_ARGS__) @@ -61,101 +59,83 @@ static int callback_pos; from radio... */ struct tx_callback { mac_callback_t cback; - int status; - int tx; void *ptr; - struct packetbuf_attr attr; - struct packetbuf_addr addr; + struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS]; + struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS]; }; -static void send_callback(struct tx_callback *tx); - - static struct tx_callback callbacks[MAX_CALLBACKS]; - +/*---------------------------------------------------------------------------*/ void packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx) { if(sessionid < MAX_CALLBACKS) { struct tx_callback *callback; callback = &callbacks[sessionid]; - packetbuf_attr_copyfrom(&callback->attr, &callback->addr); - callback->status = status; - callback->tx = tx; - send_callback(callback); + packetbuf_clear(); + packetbuf_attr_copyfrom(callback->attrs, callback->addrs); + mac_call_sent_callback(callback->cback, callback->ptr, status, tx); } else { printf("*** ERROR: too high session id %d\n", sessionid); } } - +/*---------------------------------------------------------------------------*/ static int - setup_callback(mac_callback_t sent, void *ptr) +setup_callback(mac_callback_t sent, void *ptr) { - int tmp = callback_pos; struct tx_callback *callback; + int tmp = callback_pos; callback = &callbacks[callback_pos]; callback->cback = sent; callback->ptr = ptr; - packetbuf_attr_copyto(&callback->attr, &callback->addr); - + packetbuf_attr_copyto(callback->attrs, callback->addrs); + callback_pos++; - if(callback_pos >= MAX_CALLBACKS) + if(callback_pos >= MAX_CALLBACKS) { callback_pos = 0; - + } + return tmp; } /*---------------------------------------------------------------------------*/ static void send_packet(mac_callback_t sent, void *ptr) { - int ret; + int size; + /* 3 bytes per packet attribute is required for serialization */ + uint8_t buf[PACKETBUF_NUM_ATTRS * 3 + PACKETBUF_SIZE + 3]; + uint8_t sid; + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr); /* ack or not ? */ packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); - if(NETSTACK_FRAMER.create() == FRAMER_FAILED) { + if(NETSTACK_FRAMER.create() < 0) { /* Failed to allocate space for headers */ PRINTF("br-rdc: send failed, too large header\n"); - ret = MAC_TX_ERR_FATAL; + mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); + } else { - int is_broadcast; - uint8_t dsn; - uint8_t sid; - int size; - uint8_t attbuf[64]; /* 3 bytes per attribute - hopefully enough with 64 */ - - sid = setup_callback(sent, ptr); - - dsn = ((uint8_t *)packetbuf_hdrptr())[2] & 0xff; - - is_broadcast = rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), - &rimeaddr_null); - /* here we send the data over SLIP to the radio-chip */ - /* NETSTACK_RADIO.transmit(packetbuf_totlen())); */ - /* and store the "call" with a timeout - for fail and if success - we just make a callback */ - /* TODO: store the call for later "ack" / feedback handling... */ - if((size = packetutils_serialize_atts(attbuf, sizeof(attbuf))) > 0) { - /* alloc and copy attributes */ - packetbuf_hdralloc(size); - memcpy(packetbuf_hdrptr(), attbuf, size); - packetbuf_hdralloc(3); - uint8_t *buf = (uint8_t *) packetbuf_hdrptr(); + + size = packetutils_serialize_atts(&buf[3], sizeof(buf) - 3); + if(size < 0 || size + packetbuf_totlen() + 3 > sizeof(buf)) { + PRINTF("br-rdc: send failed, too large header\n"); + mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); + } else { + sid = setup_callback(sent, ptr); + buf[0] = '!'; buf[1] = 'S'; buf[2] = sid; /* sequence or session number for this packet */ - write_to_slip(packetbuf_hdrptr(), packetbuf_totlen()); + + /* Copy packet data */ + memcpy(&buf[3 + size], packetbuf_hdrptr(), packetbuf_totlen()); + + write_to_slip(buf, packetbuf_totlen() + size + 3); } } } - -/* */ -static void send_callback(struct tx_callback *tx) -{ - mac_call_sent_callback(tx->cback, tx->ptr, tx->status, tx->tx); -} - /*---------------------------------------------------------------------------*/ static void send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) @@ -169,7 +149,7 @@ send_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) static void packet_input(void) { - if(NETSTACK_FRAMER.parse() == FRAMER_FAILED) { + if(NETSTACK_FRAMER.parse() < 0) { PRINTF("br-rdc: failed to parse %u\n", packetbuf_datalen()); } else { NETSTACK_MAC.input(); diff --git a/examples/ipv6/native-border-router/border-router.c b/examples/ipv6/native-border-router/border-router.c new file mode 100644 index 000000000..e3f5af2ac --- /dev/null +++ b/examples/ipv6/native-border-router/border-router.c @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ +/** + * \file + * border-router + * \author + * Niclas Finne + * Joakim Eriksson + * Nicolas Tsiftes + */ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include "net/uip.h" +#include "net/uip-ds6.h" +#include "net/rpl/rpl.h" + +#include "net/netstack.h" +#include "dev/slip.h" +#include "cmd.h" +#include "border-router.h" +#include "border-router-cmds.h" + +#include +#include +#include +#include + +#define DEBUG DEBUG_FULL +#include "net/uip-debug.h" + +#define MAX_SENSORS 4 + +uint16_t dag_id[] = {0x1111, 0x1100, 0, 0, 0, 0, 0, 0x0011}; + +extern uip_ds6_nbr_t uip_ds6_nbr_cache[]; +extern uip_ds6_route_t uip_ds6_routing_table[]; + +extern long slip_sent; +extern long slip_received; + +static uip_ipaddr_t prefix; +static uint8_t prefix_set; +static uint8_t mac_set; + +static uint8_t sensor_count = 0; + +/* allocate MAX_SENSORS char[32]'s */ +static char sensors[MAX_SENSORS][32]; + +extern int contiki_argc; +extern char **contiki_argv; +extern const char *slip_config_ipaddr; + +CMD_HANDLERS(border_router_cmd_handler); + +PROCESS(border_router_process, "Border router process"); + +#if WEBSERVER==0 +/* No webserver */ +AUTOSTART_PROCESSES(&border_router_process,&border_router_cmd_process); +#elif WEBSERVER>1 +/* Use an external webserver application */ +#include "webserver-nogui.h" +AUTOSTART_PROCESSES(&border_router_process,&border_router_cmd_process, + &webserver_nogui_process); +#else +/* Use simple webserver with only one page */ +#include "httpd-simple.h" +PROCESS(webserver_nogui_process, "Web server"); +PROCESS_THREAD(webserver_nogui_process, ev, data) +{ + PROCESS_BEGIN(); + + httpd_init(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + httpd_appcall(data); + } + + PROCESS_END(); +} +AUTOSTART_PROCESSES(&border_router_process,&border_router_cmd_process, + &webserver_nogui_process); + +static const char *TOP = "ContikiRPL\n"; +static const char *BOTTOM = "\n"; +static char buf[128]; +static int blen; +#define ADD(...) do { \ + blen += snprintf(&buf[blen], sizeof(buf) - blen, __VA_ARGS__); \ + } while(0) +/*---------------------------------------------------------------------------*/ +static void +ipaddr_add(const uip_ipaddr_t *addr) +{ + uint16_t a; + int i, f; + for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { + a = (addr->u8[i] << 8) + addr->u8[i + 1]; + if(a == 0 && f >= 0) { + if(f++ == 0 && sizeof(buf) - blen >= 2) { + buf[blen++] = ':'; + buf[blen++] = ':'; + } + } else { + if(f > 0) { + f = -1; + } else if(i > 0 && blen < sizeof(buf)) { + buf[blen++] = ':'; + } + ADD("%x", a); + } + } +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(generate_routes(struct httpd_state *s)) +{ + static int i; + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, TOP); + + blen = 0; + ADD("Neighbors
");
+  for(i = 0; i < UIP_DS6_NBR_NB; i++) {
+    if(uip_ds6_nbr_cache[i].isused) {
+      ipaddr_add(&uip_ds6_nbr_cache[i].ipaddr);
+      ADD("\n");
+      if(blen > sizeof(buf) - 45) {
+        SEND_STRING(&s->sout, buf);
+        blen = 0;
+      }
+    }
+  }
+
+  ADD("
Routes
");
+  SEND_STRING(&s->sout, buf);
+  blen = 0;
+  for(i = 0; i < UIP_DS6_ROUTE_NB; i++) {
+    if(uip_ds6_routing_table[i].isused) {
+      ipaddr_add(&uip_ds6_routing_table[i].ipaddr);
+      ADD("/%u (via ", uip_ds6_routing_table[i].length);
+      ipaddr_add(&uip_ds6_routing_table[i].nexthop);
+      if(uip_ds6_routing_table[i].state.lifetime < 600) {
+        ADD(") %lus\n", (unsigned long)uip_ds6_routing_table[i].state.lifetime);
+      } else {
+        ADD(")\n");
+      }
+      SEND_STRING(&s->sout, buf);
+      blen = 0;
+    }
+  }
+  ADD("
"); +//if(blen > 0) { + SEND_STRING(&s->sout, buf); +// blen = 0; +//} + + if(sensor_count > 0) { + ADD("Sensors
");
+    SEND_STRING(&s->sout, buf);
+    blen = 0;
+    for(i = 0; i < sensor_count; i++) {
+      ADD("%s\n", sensors[i]);
+      SEND_STRING(&s->sout, buf);
+      blen = 0;
+    }
+    ADD("
"); + SEND_STRING(&s->sout, buf); + } + + + SEND_STRING(&s->sout, BOTTOM); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +httpd_simple_script_t +httpd_simple_get_script(const char *name) +{ + return generate_routes; +} + +#endif /* WEBSERVER */ + +/*---------------------------------------------------------------------------*/ +static void +print_local_addresses(void) +{ + int i; + uint8_t state; + + PRINTA("Server IPv6 addresses:\n"); + for(i = 0; i < UIP_DS6_ADDR_NB; i++) { + state = uip_ds6_if.addr_list[i].state; + if(uip_ds6_if.addr_list[i].isused && + (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) { + PRINTA(" %p: =>", &uip_ds6_if.addr_list[i]); + uip_debug_ipaddr_print(&(uip_ds6_if.addr_list[i]).ipaddr); + PRINTA("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +request_mac(void) +{ + write_to_slip((uint8_t *)"?M", 2); +} +/*---------------------------------------------------------------------------*/ +void +border_router_set_mac(const uint8_t *data) +{ + memcpy(uip_lladdr.addr, data, sizeof(uip_lladdr.addr)); + rimeaddr_set_node_addr((rimeaddr_t *)uip_lladdr.addr); + + /* is this ok - should instead remove all addresses and + add them back again - a bit messy... ?*/ + uip_ds6_init(); + rpl_init(); + + mac_set = 1; +} +/*---------------------------------------------------------------------------*/ +void +border_router_print_stat() +{ + printf("bytes received over SLIP: %ld\n", slip_received); + printf("bytes sent over SLIP: %ld\n", slip_sent); +} + +/*---------------------------------------------------------------------------*/ +/* Format: ;;...;*/ +/* this function just cut at ; and store in the sensor array */ +void +border_router_set_sensors(const char *data, int len) +{ + int i; + int last_pos = 0; + int sc = 0; + for(i = 0;i < len; i++) { + if(data[i] == ';') { + sensors[sc][i - last_pos] = 0; + memcpy(sensors[sc++], &data[last_pos], i - last_pos); + last_pos = i + 1; /* skip the ';' */ + } + if(sc == MAX_SENSORS) { + sensor_count = sc; + return; + } + } + sensors[sc][len - last_pos] = 0; + memcpy(sensors[sc++], &data[last_pos], len - last_pos); + sensor_count = sc; +} +/*---------------------------------------------------------------------------*/ +static void +set_prefix_64(const uip_ipaddr_t *prefix_64) +{ + uip_ipaddr_t ipaddr; + memcpy(&prefix, prefix_64, 16); + memcpy(&ipaddr, prefix_64, 16); + + prefix_set = 1; + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + static struct etimer et; + rpl_dag_t *dag; + + PROCESS_BEGIN(); + prefix_set = 0; + + PROCESS_PAUSE(); + + PRINTF("RPL-Border router started\n"); + + slip_config_handle_arguments(contiki_argc, contiki_argv); + + /* tun init is also responsible for setting up the SLIP connection */ + tun_init(); + + while(!mac_set) { + etimer_set(&et, CLOCK_SECOND); + request_mac(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + } + + if(slip_config_ipaddr != NULL) { + uip_ipaddr_t prefix; + + if(uiplib_ipaddrconv((const char *)slip_config_ipaddr, &prefix)) { + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } else { + PRINTF("Parse error: %s\n", slip_config_ipaddr); + exit(0); + } + } + + dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)dag_id); + if(dag != NULL) { + rpl_set_prefix(dag, &prefix, 64); + PRINTF("created a new RPL dag\n"); + } + +#if DEBUG + print_local_addresses(); +#endif + + /* The border router runs with a 100% duty cycle in order to ensure high + packet reception rates. */ + NETSTACK_MAC.off(1); + + while(1) { + etimer_set(&et, CLOCK_SECOND * 2); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + /* do anything here??? */ + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/native-border-router/border-router.h b/examples/ipv6/native-border-router/border-router.h new file mode 100644 index 000000000..d2e42769a --- /dev/null +++ b/examples/ipv6/native-border-router/border-router.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Border router header file + * \author + * Joakim Eriksson + */ + +#ifndef __BORDER_ROUTER_H__ +#define __BORDER_ROUTER_H__ + +#include "contiki.h" +#include "net/uip.h" + +int border_router_cmd_handler(const uint8_t *data, int len); +int slip_config_handle_arguments(int argc, char **argv); +void write_to_slip(const uint8_t *buf, int len); + +void border_router_set_prefix_64(const uip_ipaddr_t *prefix_64); +void border_router_set_mac(const uint8_t *data); +void border_router_set_sensors(const char *data, int len); +void border_router_print_stat(void); + +void tun_init(void); + +int slip_init(void); +int slip_set_fd(int maxfd, fd_set *rset, fd_set *wset); +void slip_handle_fd(fd_set *rset, fd_set *wset); + +#endif /* __BORDER_ROUTER_H__ */ diff --git a/examples/ipv6/native-border-router/httpd-simple.c b/examples/ipv6/native-border-router/httpd-simple.c new file mode 100644 index 000000000..115e54d45 --- /dev/null +++ b/examples/ipv6/native-border-router/httpd-simple.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \file + * A simple web server forwarding page generation to a protothread + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + */ + +#include +#include + +#include "contiki-net.h" + +//#include "urlconv.h" + +#include "httpd-simple.h" +#define webserver_log_file(...) +#define webserver_log(...) + +#ifndef WEBSERVER_CONF_CFS_CONNS +#define CONNS UIP_CONNS +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define CONNS WEBSERVER_CONF_CFS_CONNS +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +#ifndef WEBSERVER_CONF_CFS_URLCONV +#define URLCONV 0 +#else /* WEBSERVER_CONF_CFS_URLCONV */ +#define URLCONV WEBSERVER_CONF_CFS_URLCONV +#endif /* WEBSERVER_CONF_CFS_URLCONV */ + +#define STATE_WAITING 0 +#define STATE_OUTPUT 1 + +MEMB(conns, struct httpd_state, CONNS); + +#define ISO_nl 0x0a +#define ISO_space 0x20 +#define ISO_period 0x2e +#define ISO_slash 0x2f + +/*---------------------------------------------------------------------------*/ +static const char *NOT_FOUND = "" +"
" +"

404 - file not found

" +"
" +"" +""; +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send_string(struct httpd_state *s, const char *str)) +{ + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, str); + + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_content_type_html[] = "Content-type: text/html\r\n\r\n"; +static +PT_THREAD(send_headers(struct httpd_state *s, const char *statushdr)) +{ + /* char *ptr; */ + + PSOCK_BEGIN(&s->sout); + + SEND_STRING(&s->sout, statushdr); + + /* ptr = strrchr(s->filename, ISO_period); */ + /* if(ptr == NULL) { */ + /* s->ptr = http_content_type_plain; */ + /* } else if(strcmp(http_html, ptr) == 0) { */ + /* s->ptr = http_content_type_html; */ + /* } else if(strcmp(http_css, ptr) == 0) { */ + /* s->ptr = http_content_type_css; */ + /* } else if(strcmp(http_png, ptr) == 0) { */ + /* s->ptr = http_content_type_png; */ + /* } else if(strcmp(http_gif, ptr) == 0) { */ + /* s->ptr = http_content_type_gif; */ + /* } else if(strcmp(http_jpg, ptr) == 0) { */ + /* s->ptr = http_content_type_jpg; */ + /* } else { */ + /* s->ptr = http_content_type_binary; */ + /* } */ + /* SEND_STRING(&s->sout, s->ptr); */ + SEND_STRING(&s->sout, http_content_type_html); + PSOCK_END(&s->sout); +} +/*---------------------------------------------------------------------------*/ +const char http_header_200[] = "HTTP/1.0 200 OK\r\nServer: Contiki/2.4 http://www.sics.se/contiki/\r\nConnection: close\r\n"; +const char http_header_404[] = "HTTP/1.0 404 Not found\r\nServer: Contiki/2.4 http://www.sics.se/contiki/\r\nConnection: close\r\n"; +static +PT_THREAD(handle_output(struct httpd_state *s)) +{ + PT_BEGIN(&s->outputpt); + + s->script = NULL; + s->script = httpd_simple_get_script(&s->filename[1]); + if(s->script == NULL) { + strncpy(s->filename, "/notfound.html", sizeof(s->filename)); + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_404)); + PT_WAIT_THREAD(&s->outputpt, + send_string(s, NOT_FOUND)); + uip_close(); + webserver_log_file(&uip_conn->ripaddr, "404 - not found"); + PT_EXIT(&s->outputpt); + } else { + PT_WAIT_THREAD(&s->outputpt, + send_headers(s, http_header_200)); + PT_WAIT_THREAD(&s->outputpt, s->script(s)); + } + s->script = NULL; + PSOCK_CLOSE(&s->sout); + PT_END(&s->outputpt); +} +/*---------------------------------------------------------------------------*/ +const char http_get[] = "GET "; +const char http_index_html[] = "/index.html"; +//const char http_referer[] = "Referer:" +static +PT_THREAD(handle_input(struct httpd_state *s)) +{ + PSOCK_BEGIN(&s->sin); + + PSOCK_READTO(&s->sin, ISO_space); + + if(strncmp(s->inputbuf, http_get, 4) != 0) { + PSOCK_CLOSE_EXIT(&s->sin); + } + PSOCK_READTO(&s->sin, ISO_space); + + if(s->inputbuf[0] != ISO_slash) { + PSOCK_CLOSE_EXIT(&s->sin); + } + +#if URLCONV + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + urlconv_tofilename(s->filename, s->inputbuf, sizeof(s->filename)); +#else /* URLCONV */ + if(s->inputbuf[1] == ISO_space) { + strncpy(s->filename, http_index_html, sizeof(s->filename)); + } else { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 1] = 0; + strncpy(s->filename, s->inputbuf, sizeof(s->filename)); + } +#endif /* URLCONV */ + + webserver_log_file(&uip_conn->ripaddr, s->filename); + + s->state = STATE_OUTPUT; + + while(1) { + PSOCK_READTO(&s->sin, ISO_nl); +#if 0 + if(strncmp(s->inputbuf, http_referer, 8) == 0) { + s->inputbuf[PSOCK_DATALEN(&s->sin) - 2] = 0; + webserver_log(s->inputbuf); + } +#endif + } + + PSOCK_END(&s->sin); +} +/*---------------------------------------------------------------------------*/ +static void +handle_connection(struct httpd_state *s) +{ + handle_input(s); + if(s->state == STATE_OUTPUT) { + handle_output(s); + } +} + +/*---------------------------------------------------------------------------*/ +void +httpd_appcall(void *state) +{ + struct httpd_state *s = (struct httpd_state *)state; + + if(uip_closed() || uip_aborted() || uip_timedout()) { + if(s != NULL) { + s->script = NULL; + memb_free(&conns, s); + } + } else if(uip_connected()) { + s = (struct httpd_state *)memb_alloc(&conns); + if(s == NULL) { + uip_abort(); + webserver_log_file(&uip_conn->ripaddr, "reset (no memory block)"); + return; + } + tcp_markconn(uip_conn, s); + PSOCK_INIT(&s->sin, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PSOCK_INIT(&s->sout, (uint8_t *)s->inputbuf, sizeof(s->inputbuf) - 1); + PT_INIT(&s->outputpt); + s->script = NULL; + s->state = STATE_WAITING; + timer_set(&s->timer, CLOCK_SECOND * 10); + handle_connection(s); + } else if(s != NULL) { + if(uip_poll()) { + if(timer_expired(&s->timer)) { + uip_abort(); + s->script = NULL; + memb_free(&conns, s); + webserver_log_file(&uip_conn->ripaddr, "reset (timeout)"); + } + } else { + timer_restart(&s->timer); + } + handle_connection(s); + } else { + uip_abort(); + } +} + +/*---------------------------------------------------------------------------*/ +void +httpd_init(void) +{ + + tcp_listen(UIP_HTONS(80)); + memb_init(&conns); +#if URLCONV + urlconv_init(); +#endif /* URLCONV */ +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/native-border-router/httpd-simple.h b/examples/ipv6/native-border-router/httpd-simple.h new file mode 100644 index 000000000..4a2efa30f --- /dev/null +++ b/examples/ipv6/native-border-router/httpd-simple.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * \file + * A simple webserver + * \author + * Adam Dunkels + * Niclas Finne + * Joakim Eriksson + */ + +#ifndef __HTTPD_SIMPLE_H__ +#define __HTTPD_SIMPLE_H__ + +#include "contiki-net.h" + +/* The current internal border router webserver ignores the requested file name */ +/* and needs no per-connection output buffer, so save some RAM */ +#ifndef WEBSERVER_CONF_CFS_PATHLEN +#define HTTPD_PATHLEN 2 +#else /* WEBSERVER_CONF_CFS_CONNS */ +#define HTTPD_PATHLEN WEBSERVER_CONF_CFS_PATHLEN +#endif /* WEBSERVER_CONF_CFS_CONNS */ + +struct httpd_state; +typedef char (* httpd_simple_script_t)(struct httpd_state *s); + +struct httpd_state { + struct timer timer; + struct psock sin, sout; + struct pt outputpt; + char inputbuf[HTTPD_PATHLEN + 24]; +/*char outputbuf[UIP_TCP_MSS]; */ + char filename[HTTPD_PATHLEN]; + httpd_simple_script_t script; + char state; +}; + +void httpd_init(void); +void httpd_appcall(void *state); + +httpd_simple_script_t httpd_simple_get_script(const char *name); + +#define SEND_STRING(s, str) PSOCK_SEND(s, (uint8_t *)str, strlen(str)) + +#endif /* __HTTPD_SIMPLE_H__ */ diff --git a/examples/ipv6/native-border-router/project-conf.h b/examples/ipv6/native-border-router/project-conf.h new file mode 100644 index 000000000..4870f02a3 --- /dev/null +++ b/examples/ipv6/native-border-router/project-conf.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __PROJECT_ROUTER_CONF_H__ +#define __PROJECT_ROUTER_CONF_H__ + +#undef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface + +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 140 + +#undef UIP_CONF_RECEIVE_WINDOW +#define UIP_CONF_RECEIVE_WINDOW 60 + +#undef WEBSERVER_CONF_CFS_CONNS +#define WEBSERVER_CONF_CFS_CONNS 2 + +#define CMD_CONF_OUTPUT border_router_cmd_output + +#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; + +#endif /* __PROJECT_ROUTER_CONF_H__ */ diff --git a/examples/ipv6/native-border-router/slip-config.c b/examples/ipv6/native-border-router/slip-config.c new file mode 100644 index 000000000..452d23d35 --- /dev/null +++ b/examples/ipv6/native-border-router/slip-config.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Slip configuration + * \author + * Niclas Finne + * Joakim Eriksson + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "contiki.h" + +int slip_config_verbose = 0; +const char *slip_config_ipaddr; +int slip_config_flowcontrol = 0; +int slip_config_timestamp = 0; +const char *slip_config_siodev = NULL; +char slip_config_tundev[32] = { "" }; +uint16_t slip_config_basedelay = 0; + +#ifndef BAUDRATE +#define BAUDRATE B115200 +#endif +speed_t slip_config_b_rate = BAUDRATE; + +/*---------------------------------------------------------------------------*/ +int +slip_config_handle_arguments(int argc, char **argv) +{ + const char *prog; + char c; + int baudrate = 115200; + + slip_config_verbose = 0; + + prog = argv[0]; + while((c = getopt(argc, argv, "B:H:D:Lhs:t:v::d::a:p:T")) != -1) { + switch(c) { + case 'B': + baudrate = atoi(optarg); + break; + + case 'H': + slip_config_flowcontrol = 1; + break; + + case 'L': + slip_config_timestamp = 1; + break; + + case 's': + if(strncmp("/dev/", optarg, 5) == 0) { + slip_config_siodev = optarg + 5; + } else { + slip_config_siodev = optarg; + } + break; + + case 't': + if(strncmp("/dev/", optarg, 5) == 0) { + strncpy(slip_config_tundev, optarg + 5, sizeof(slip_config_tundev)); + } else { + strncpy(slip_config_tundev, optarg, sizeof(slip_config_tundev)); + } + break; + + case 'd': + slip_config_basedelay = 10; + if(optarg) slip_config_basedelay = atoi(optarg); + break; + + case 'v': + slip_config_verbose = 2; + if(optarg) slip_config_verbose = atoi(optarg); + break; + + case '?': + case 'h': + default: +fprintf(stderr,"usage: %s [options] ipaddress\n", prog); +fprintf(stderr,"example: border-router.native -L -v2 -s ttyUSB1 aaaa::1/64\n"); +fprintf(stderr,"Options are:\n"); +fprintf(stderr," -B baudrate 9600,19200,38400,57600,115200 (default)\n"); +fprintf(stderr," -H Hardware CTS/RTS flow control (default disabled)\n"); +fprintf(stderr," -L Log output format (adds time stamps)\n"); +fprintf(stderr," -s siodev Serial device (default /dev/ttyUSB0)\n"); +fprintf(stderr," -t tundev Name of interface (default tun0)\n"); +fprintf(stderr," -v[level] Verbosity level\n"); +fprintf(stderr," -v0 No messages\n"); +fprintf(stderr," -v1 Encapsulated SLIP debug messages (default)\n"); +fprintf(stderr," -v2 Printable strings after they are received\n"); +fprintf(stderr," -v3 Printable strings and SLIP packet notifications\n"); +fprintf(stderr," -v4 All printable characters as they are received\n"); +fprintf(stderr," -v5 All SLIP packets in hex\n"); +fprintf(stderr," -v Equivalent to -v3\n"); +fprintf(stderr," -d[basedelay] Minimum delay between outgoing SLIP packets.\n"); +fprintf(stderr," Actual delay is basedelay*(#6LowPAN fragments) milliseconds.\n"); +fprintf(stderr," -d is equivalent to -d10.\n"); +exit(1); + break; + } + } + argc -= optind - 1; + argv += optind - 1; + + if(argc != 2 && argc != 3) { + err(1, "usage: %s [-B baudrate] [-H] [-L] [-s siodev] [-t tundev] [-T] [-v verbosity] [-d delay] ipaddress", prog); + } + slip_config_ipaddr = argv[1]; + + switch(baudrate) { + case -2: + break; /* Use default. */ + case 9600: + slip_config_b_rate = B9600; + break; + case 19200: + slip_config_b_rate = B19200; + break; + case 38400: + slip_config_b_rate = B38400; + break; + case 57600: + slip_config_b_rate = B57600; + break; + case 115200: + slip_config_b_rate = B115200; + break; + default: + err(1, "unknown baudrate %d", baudrate); + break; + } + + if(*slip_config_tundev == '\0') { + /* Use default. */ + strcpy(slip_config_tundev, "tun0"); + } + return 1; +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/native-border-router/slip-dev.c b/examples/ipv6/native-border-router/slip-dev.c new file mode 100644 index 000000000..67ac2c0df --- /dev/null +++ b/examples/ipv6/native-border-router/slip-dev.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2001, Adam Dunkels. + * Copyright (c) 2009, 2010 Joakim Eriksson, Niclas Finne, Dogan Yazar. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + /* Below define allows importing saved output into Wireshark as "Raw IP" packet type */ +#define WIRESHARK_IMPORT_FORMAT 1 +#include "contiki.h" +#include "net/uip.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "cmd.h" + +extern int slip_config_verbose; +extern const char *slip_config_ipaddr; +extern int slip_config_flowcontrol; +extern const char *slip_config_siodev; +extern uint16_t slip_config_basedelay; +extern speed_t slip_config_b_rate; + + +int devopen(const char *dev, int flags); + +static FILE *inslip; + +/* for statistics */ +long slip_sent = 0; +long slip_received = 0; + +int slipfd = 0; + +void slip_send(int fd, unsigned char c); +//#define PROGRESS(s) fprintf(stderr, s) +#define PROGRESS(s) do { } while(0) + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +/*---------------------------------------------------------------------------*/ +int +is_sensible_string(const unsigned char *s, int len) +{ + int i; + for(i = 1; i < len; i++) { + if(s[i] == 0 || s[i] == '\r' || s[i] == '\n' || s[i] == '\t') { + continue; + } else if(s[i] < ' ' || '~' < s[i]) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +void +slip_packet_input(unsigned char *data, int len) +{ + packetbuf_copyfrom(data, len); + if(slip_config_verbose > 0) { + printf("Packet input over SLIP: %d\n", len); + } + NETSTACK_RDC.input(); +} +/*---------------------------------------------------------------------------*/ +/* + * Read from serial, when we have a packet call slip_packet_input. No output + * buffering, input buffered by stdio. + */ +void +serial_input(FILE *inslip) +{ + static union { + unsigned char inbuf[2000]; + } uip; + static int inbufptr = 0; + int ret,i; + unsigned char c; + +#ifdef linux + ret = fread(&c, 1, 1, inslip); + if(ret == -1 || ret == 0) err(1, "serial_input: read"); + goto after_fread; +#endif + + read_more: + if(inbufptr >= sizeof(uip.inbuf)) { + fprintf(stderr, "*** dropping large %d byte packet\n", inbufptr); + inbufptr = 0; + } + ret = fread(&c, 1, 1, inslip); +#ifdef linux + after_fread: +#endif + if(ret == -1) { + err(1, "serial_input: read"); + } + if(ret == 0) { + clearerr(inslip); + return; + } + slip_received++; + switch(c) { + case SLIP_END: + if(inbufptr > 0) { + if(uip.inbuf[0] == '!') { + cmd_input(uip.inbuf, inbufptr); + } else if(uip.inbuf[0] == '?') { +#define DEBUG_LINE_MARKER '\r' + } else if(uip.inbuf[0] == DEBUG_LINE_MARKER) { + fwrite(uip.inbuf + 1, inbufptr - 1, 1, stdout); + } else if(is_sensible_string(uip.inbuf, inbufptr)) { + if(slip_config_verbose == 1) { /* strings already echoed below for verbose>1 */ + fwrite(uip.inbuf, inbufptr, 1, stdout); + } + } else { + if(slip_config_verbose > 2) { + printf("Packet from SLIP of length %d - write TUN\n", inbufptr); + if(slip_config_verbose > 4) { +#if WIRESHARK_IMPORT_FORMAT + printf("0000"); + for(i = 0; i < inbufptr; i++) printf(" %02x", uip.inbuf[i]); +#else + printf(" "); + for(i = 0; i < inbufptr; i++) { + printf("%02x", uip.inbuf[i]); + if((i & 3) == 3) printf(" "); + if((i & 15) == 15) printf("\n "); + } +#endif + printf("\n"); + } + } + slip_packet_input(uip.inbuf, inbufptr); + } + inbufptr = 0; + } + break; + + case SLIP_ESC: + if(fread(&c, 1, 1, inslip) != 1) { + clearerr(inslip); + /* Put ESC back and give up! */ + ungetc(SLIP_ESC, inslip); + return; + } + + switch(c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + /* FALLTHROUGH */ + default: + uip.inbuf[inbufptr++] = c; + + /* Echo lines as they are received for verbose=2,3,5+ */ + /* Echo all printable characters for verbose==4 */ + if(slip_config_verbose == 4) { + if(c == 0 || c == '\r' || c == '\n' || c == '\t' || (c >= ' ' && c <= '~')) { + fwrite(&c, 1, 1, stdout); + } + } else if(slip_config_verbose >= 2) { + if(c == '\n' && is_sensible_string(uip.inbuf, inbufptr)) { + fwrite(uip.inbuf, inbufptr, 1, stdout); + inbufptr = 0; + } + } + break; + } + + goto read_more; +} + +unsigned char slip_buf[2000]; +int slip_end, slip_begin; +/*---------------------------------------------------------------------------*/ +void +slip_send(int fd, unsigned char c) +{ + if(slip_end >= sizeof(slip_buf)) { + err(1, "slip_send overflow"); + } + slip_buf[slip_end] = c; + slip_end++; + slip_sent++; +} +/*---------------------------------------------------------------------------*/ +int +slip_empty() +{ + return slip_end == 0; +} +/*---------------------------------------------------------------------------*/ +void +slip_flushbuf(int fd) +{ + int n; + + if(slip_empty()) { + return; + } + + n = write(fd, slip_buf + slip_begin, slip_end - slip_begin); + + if(n == -1 && errno != EAGAIN) { + err(1, "slip_flushbuf write failed"); + } else if(n == -1) { + PROGRESS("Q"); /* Outqueueis full! */ + } else { + slip_begin += n; + if(slip_begin == slip_end) { + slip_begin = slip_end = 0; + } + } +} +/*---------------------------------------------------------------------------*/ +static void +write_to_serial(int outfd, const uint8_t *inbuf, int len) +{ + const uint8_t *p = inbuf; + int i; + + if(slip_config_verbose > 2) { + printf("Packet from TUN of length %d - write SLIP\n", len); + if(slip_config_verbose > 4) { +#if WIRESHARK_IMPORT_FORMAT + printf("0000"); + for(i = 0; i < len; i++) printf(" %02x", p[i]); +#else + printf(" "); + for(i = 0; i < len; i++) { + printf("%02x", p[i]); + if((i & 3) == 3) printf(" "); + if((i & 15) == 15) printf("\n "); + } +#endif + printf("\n"); + } + } + + /* It would be ``nice'' to send a SLIP_END here but it's not + * really necessary. + */ + /* slip_send(outfd, SLIP_END); */ + + for(i = 0; i < len; i++) { + switch(p[i]) { + case SLIP_END: + slip_send(outfd, SLIP_ESC); + slip_send(outfd, SLIP_ESC_END); + break; + case SLIP_ESC: + slip_send(outfd, SLIP_ESC); + slip_send(outfd, SLIP_ESC_ESC); + break; + default: + slip_send(outfd, p[i]); + break; + } + } + slip_send(outfd, SLIP_END); + PROGRESS("t"); +} +/*---------------------------------------------------------------------------*/ +/* writes an 802.15.4 packet to slip-radio */ +void +write_to_slip(const uint8_t *buf, int len) +{ + /* printf("Packet to SLIP: %d\n", len); */ + write_to_serial(slipfd, buf, len); +} +/*---------------------------------------------------------------------------*/ +static void +stty_telos(int fd) +{ + struct termios tty; + speed_t speed = slip_config_b_rate; + int i; + + if(tcflush(fd, TCIOFLUSH) == -1) err(1, "tcflush"); + + if(tcgetattr(fd, &tty) == -1) err(1, "tcgetattr"); + + cfmakeraw(&tty); + + /* Nonblocking read. */ + tty.c_cc[VTIME] = 0; + tty.c_cc[VMIN] = 0; + if(slip_config_flowcontrol) { + tty.c_cflag |= CRTSCTS; + } else { + tty.c_cflag &= ~CRTSCTS; + } + tty.c_cflag &= ~HUPCL; + tty.c_cflag &= ~CLOCAL; + + cfsetispeed(&tty, speed); + cfsetospeed(&tty, speed); + + if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) err(1, "tcsetattr"); + +#if 1 + /* Nonblocking read and write. */ + /* if(fcntl(fd, F_SETFL, O_NONBLOCK) == -1) err(1, "fcntl"); */ + + tty.c_cflag |= CLOCAL; + if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) err(1, "tcsetattr"); + + i = TIOCM_DTR; + if(ioctl(fd, TIOCMBIS, &i) == -1) err(1, "ioctl"); +#endif + + usleep(10*1000); /* Wait for hardware 10ms. */ + + /* Flush input and output buffers. */ + if(tcflush(fd, TCIOFLUSH) == -1) err(1, "tcflush"); +} +/*---------------------------------------------------------------------------*/ +void +slip_init(void) +{ + setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ + + if(slip_config_siodev != NULL) { + slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK); + if(slipfd == -1) { + err(1, "can't open siodev ``/dev/%s''", slip_config_siodev); + } + } else { + static const char *siodevs[] = { + "ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */ + }; + int i; + for(i = 0; i < 3; i++) { + slip_config_siodev = siodevs[i]; + slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK); + if(slipfd != -1) { + break; + } + } + if(slipfd == -1) { + err(1, "can't open siodev"); + } + } + + fprintf(stderr, "********SLIP started on ``/dev/%s''\n", slip_config_siodev); + stty_telos(slipfd); + + slip_send(slipfd, SLIP_END); + 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 new file mode 100644 index 000000000..fc03a10ec --- /dev/null +++ b/examples/ipv6/native-border-router/tun-bridge.c @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#include "net/uip.h" +#include "net/uip-ds6.h" +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#define DEBUG DEBUG_PRINT +#include "net/uip-debug.h" + +#ifdef linux +#include +#include +#endif + +#include +#include "net/netstack.h" +#include "net/packetbuf.h" +#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; + +static int tunfd; +static int initialized = 0; + +static uint16_t delaymsec=0; +static uint32_t delaystartsec,delaystartmsec; + +int ssystem(const char *fmt, ...) + __attribute__((__format__ (__printf__, 1, 2))); +int +ssystem(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2))); + +int +ssystem(const char *fmt, ...) +{ + char cmd[128]; + va_list ap; + va_start(ap, fmt); + vsnprintf(cmd, sizeof(cmd), fmt, ap); + va_end(ap); + printf("%s\n", cmd); + fflush(stdout); + return system(cmd); +} + +/*---------------------------------------------------------------------------*/ +void +cleanup(void) +{ + ssystem("ifconfig %s down", slip_config_tundev); +#ifndef linux + ssystem("sysctl -w net.ipv6.conf.all.forwarding=1"); +#endif + ssystem("netstat -nr" + " | awk '{ if ($2 == \"%s\") print \"route delete -net \"$1; }'" + " | sh", + slip_config_tundev); +} + +/*---------------------------------------------------------------------------*/ +void +sigcleanup(int signo) +{ + fprintf(stderr, "signal %d\n", signo); + exit(0); /* exit(0) will call cleanup() */ +} + +/*---------------------------------------------------------------------------*/ +void +ifconf(const char *tundev, const char *ipaddr) +{ +#ifdef linux + ssystem("ifconfig %s inet `hostname` up", tundev); + ssystem("ifconfig %s add %s", tundev, ipaddr); +#else + ssystem("ifconfig %s inet `hostname` %s up", tundev, ipaddr); + ssystem("sysctl -w net.inet.ip.forwarding=1"); +#endif /* !linux */ + + ssystem("ifconfig %s\n", tundev); +} +/*---------------------------------------------------------------------------*/ +int +devopen(const char *dev, int flags) +{ + char t[32]; + strcpy(t, "/dev/"); + strncat(t, dev, sizeof(t) - 5); + return open(t, flags); +} +/*---------------------------------------------------------------------------*/ +#ifdef linux +int +tun_alloc(char *dev) +{ + struct ifreq ifr; + int fd, err; + + if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) { + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + + /* Flags: IFF_TUN - TUN device (no Ethernet headers) + * IFF_NO_PI - Do not provide packet information + */ + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + if(*dev != 0) + strncpy(ifr.ifr_name, dev, IFNAMSIZ); + + if((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ) { + close(fd); + return err; + } + strcpy(dev, ifr.ifr_name); + return fd; +} +#else +int +tun_alloc(char *dev) +{ + return devopen(dev, O_RDWR); +} +#endif +/*---------------------------------------------------------------------------*/ +void +tun_init() +{ + setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ + + slip_init(); + + tunfd = tun_alloc(slip_config_tundev); + if(tunfd == -1) err(1, "main: open"); + fprintf(stderr, "opened %s device ``/dev/%s''\n", + "tun", slip_config_tundev); + + atexit(cleanup); + signal(SIGHUP, sigcleanup); + signal(SIGTERM, sigcleanup); + signal(SIGINT, sigcleanup); + ifconf(slip_config_tundev, slip_config_ipaddr); + + initialized = 1; +} + +/*---------------------------------------------------------------------------*/ +void +tun_output(uint8_t *data, int len) +{ + /* fprintf(stderr, "*** Writing to tun...%d\n", len); */ + if(write(tunfd, data, len) != len) { + err(1, "serial_to_tun: write"); + } +} +/*---------------------------------------------------------------------------*/ +int +tun_input(unsigned char *data, int maxlen) +{ + int size; + if((size = read(tunfd, data, maxlen)) == -1) + err(1, "tun_input: read"); + return size; +} + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +output(void) +{ + PRINTF("SUT: %u\n", uip_len); + if(uip_len > 0) { + tun_output(&uip_buf[UIP_LLH_LEN], uip_len); + } +} + + +const struct uip_fallback_interface rpl_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ +/* tun and slip select callback */ +/*---------------------------------------------------------------------------*/ +static int +set_fd(int maxfd, 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; +} + +/*---------------------------------------------------------------------------*/ + +static void +handle_fd(fd_set *rset, fd_set *wset) +{ + if(!initialized) return; + + slip_handle_fd(rset, wset); + + /* Optional delay between outgoing packets */ + /* Base delay times number of 6lowpan fragments to be sent */ + /* delaymsec = 10; */ + if(delaymsec) { + struct timeval tv; + int dmsec; + gettimeofday(&tv, NULL); + dmsec=(tv.tv_sec-delaystartsec)*1000+tv.tv_usec/1000-delaystartmsec; + if(dmsec<0) delaymsec=0; + if(dmsec>delaymsec) delaymsec=0; + } + + if(delaymsec==0) { + int size; + + if(FD_ISSET(tunfd, rset)) { + size = tun_input(&uip_buf[UIP_LLH_LEN], sizeof(uip_buf)); + /* printf("TUN data incoming read:%d\n", size); */ + uip_len = size; + tcpip_input(); + + if(slip_config_basedelay) { + struct timeval tv; + gettimeofday(&tv, NULL) ; + delaymsec=slip_config_basedelay; + delaystartsec =tv.tv_sec; + delaystartmsec=tv.tv_usec/1000; + } + } + } +} + +/*---------------------------------------------------------------------------*/ + +struct select_callback tun_select_callback = { + set_fd, + handle_fd +}; diff --git a/examples/ipv6/slip-radio/Makefile b/examples/ipv6/slip-radio/Makefile new file mode 100644 index 000000000..f7a755961 --- /dev/null +++ b/examples/ipv6/slip-radio/Makefile @@ -0,0 +1,20 @@ +CONTIKI_PROJECT=slip-radio +all: $(CONTIKI_PROJECT) +APPS = slip-cmd + +CONTIKI=../../.. + +WITH_UIP6=1 +UIP_CONF_IPV6=1 +UIP_CONF_RPL=0 + +#linker optimizations +SMALL=1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-net.c no-framer.c +ifeq ($(TARGET),sky) + PROJECT_SOURCEFILES += slip-radio-cc2420.c slip-radio-sky-sensors.c +endif + +include $(CONTIKI)/Makefile.include diff --git a/examples/ipv6/slip-radio/no-framer.c b/examples/ipv6/slip-radio/no-framer.c new file mode 100644 index 000000000..327a3f761 --- /dev/null +++ b/examples/ipv6/slip-radio/no-framer.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2009, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: framer-nullmac.c,v 1.2 2010/06/14 19:19:16 adamdunkels Exp $ + */ + +/** + * \file + * MAC framer that does nothing... + * \author + * Niclas Finne + * Joakim Eriksson + */ +#include "net/mac/framer.h" +#include "net/mac/frame802154.h" +#include "net/packetbuf.h" +#include + +#define DEBUG 0 + +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#define PRINTADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7]) +#else +#define PRINTF(...) +#define PRINTADDR(addr) +#endif + +/** \brief The 16-bit identifier of the PAN on which the device is + * sending to. If this value is 0xffff, the device is not + * associated. + */ +static const uint16_t mac_dst_pan_id = IEEE802154_PANID; + +/** \brief The 16-bit identifier of the PAN on which the device is + * operating. If this value is 0xffff, the device is not + * associated. + */ +static const uint16_t mac_src_pan_id = IEEE802154_PANID; +/*---------------------------------------------------------------------------*/ +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +create(void) +{ + /* nothing extra... */ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +parse(void) +{ + frame802154_t frame; + int len; + len = packetbuf_datalen(); + if(frame802154_parse(packetbuf_dataptr(), len, &frame)) { + if(frame.fcf.dest_addr_mode) { + if(frame.dest_pid != mac_src_pan_id && + frame.dest_pid != FRAME802154_BROADCASTPANDID) { + /* Packet to another PAN */ + PRINTF("15.4: for another pan %u\n", frame.dest_pid); + return 0; + } + if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { + packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)&frame.dest_addr); + } + } + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *)&frame.src_addr); + packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); + /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ + packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); + + PRINTF("15.4-IN: %2X", frame.fcf.frame_type); + PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); + PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); + PRINTF("%u (%u)\n", packetbuf_datalen(), len); + + return 0; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +const struct framer no_framer = { + create, parse +}; diff --git a/examples/ipv6/slip-radio/project-conf.h b/examples/ipv6/slip-radio/project-conf.h new file mode 100644 index 000000000..89ce426d1 --- /dev/null +++ b/examples/ipv6/slip-radio/project-conf.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2010, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 4 + +#undef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 140 + +#undef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 0 + +#undef UIP_CONF_IPV6_RPL +#define UIP_CONF_IPV6_RPL 0 + +#define CMD_CONF_OUTPUT slip_radio_cmd_output + +/* add the cmd_handler_cc2420 + some sensors if TARGET_SKY */ +#ifdef CONTIKI_TARGET_SKY +#define CMD_CONF_HANDLERS slip_radio_cmd_handler,cmd_handler_cc2420 +#define SLIP_RADIO_CONF_SENSORS slip_radio_sky_sensors +#else +#define CMD_CONF_HANDLERS slip_radio_cmd_handler +#endif + + +/* configuration for the slipradio/network driver */ +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC nullmac_driver + +#undef NETSTACK_CONF_RDC +/* #define NETSTACK_CONF_RDC nullrdc_noframer_driver */ +#define NETSTACK_CONF_RDC contikimac_driver + +#undef NETSTACK_CONF_NETWORK +#define NETSTACK_CONF_NETWORK slipnet_driver + +#undef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER no_framer + +#undef CC2420_CONF_AUTOACK +#define CC2420_CONF_AUTOACK 1 + +#undef UART1_CONF_RX_WITH_DMA +#define UART1_CONF_RX_WITH_DMA 1 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/ipv6/slip-radio/slip-net.c b/examples/ipv6/slip-radio/slip-net.c new file mode 100644 index 000000000..68b2aebc0 --- /dev/null +++ b/examples/ipv6/slip-radio/slip-net.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "contiki.h" +#include "net/netstack.h" +#include "net/uip.h" +#include "net/packetbuf.h" +#include "dev/slip.h" +#include + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +#define DEBUG 0 + +/*---------------------------------------------------------------------------*/ +void +slipnet_init(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +slip_send_packet(const uint8_t *ptr, int len) +{ + uint16_t i; + uint8_t c; + + slip_arch_writeb(SLIP_END); + for(i = 0; i < len; ++i) { + c = *ptr++; + if(c == SLIP_END) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_END; + } else if(c == SLIP_ESC) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_ESC; + } + slip_arch_writeb(c); + } + slip_arch_writeb(SLIP_END); +} +/*---------------------------------------------------------------------------*/ +void +slipnet_input(void) +{ + int i; + /* radio should be configured for filtering so this should be simple */ + /* this should be sent over SLIP! */ + /* so just copy into uip-but and send!!! */ + /* Format: !R ? */ + uip_len = packetbuf_datalen(); + i = packetbuf_copyto(uip_buf); + + if(DEBUG) { + printf("Slipnet got input of len: %d, copied: %d\n", + packetbuf_datalen(), i); + + for(i = 0; i < uip_len; i++) { + printf("%02x", (unsigned char) uip_buf[i]); + if((i & 15) == 15) printf("\n"); + else if((i & 7) == 7) printf(" "); + } + printf("\n"); + } + + /* printf("SUT: %u\n", uip_len); */ + slip_send_packet(uip_buf, uip_len); +} +/*---------------------------------------------------------------------------*/ +const struct network_driver slipnet_driver = { + "slipnet", + slipnet_init, + slipnet_input +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/slip-radio/slip-radio-cc2420.c b/examples/ipv6/slip-radio/slip-radio-cc2420.c new file mode 100644 index 000000000..7d7676e1f --- /dev/null +++ b/examples/ipv6/slip-radio/slip-radio-cc2420.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Sets up some commands for the CC2420 radio chip. + */ + +#include "contiki.h" +#include "dev/cc2420.h" +#include "cmd.h" +#include + +int +cmd_handler_cc2420(const uint8_t *data, int len) +{ + if(data[0] == '!') { + if(data[1] == 'C') { + printf("cc2420_cmd: setting channel: %d\n", data[2]); + cc2420_set_channel(data[2]); + return 1; + } + } else if(data[0] == '?') { + if(data[1] == 'C') { + uint8_t buf[4]; + printf("cc2420_cmd: getting channel: %d\n", data[2]); + buf[0] = '!'; + buf[1] = 'C'; + buf[2] = cc2420_get_channel(); + cmd_send(buf, 3); + return 1; + } + } + return 0; +} diff --git a/examples/ipv6/slip-radio/slip-radio-sky-sensors.c b/examples/ipv6/slip-radio/slip-radio-sky-sensors.c new file mode 100644 index 000000000..a88d7b9d3 --- /dev/null +++ b/examples/ipv6/slip-radio/slip-radio-sky-sensors.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "contiki.h" +#include "lib/sensors.h" +#include "dev/sht11-sensor.h" +#include "slip-radio.h" +#include "cmd.h" +#include + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +write_percent_float(char *data, int maxlen, int temp) +{ + int t; + t = temp % 100; + if(t < 0) { + t = -t; + } + return snprintf(data, maxlen, "%d.%02d", temp / 100, t); +} +/*---------------------------------------------------------------------------*/ +static void +send(void) +{ +#define MAX_SIZE 40 + char data[MAX_SIZE]; + int temperature; + int ms; + long hum; + int pos = 0; + + /* SENSORS_ACTIVATE(light_sensor); */ + SENSORS_ACTIVATE(sht11_sensor); + + pos += snprintf(data, MAX_SIZE, "!D"); + /* int light1 = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC); */ + /* int light2 = light_sensor.value(LIGHT_SENSOR_TOTAL_SOLAR); */ + temperature = -3970 + sht11_sensor.value(SHT11_SENSOR_TEMP); + ms = sht11_sensor.value(SHT11_SENSOR_HUMIDITY); + /* this is in * 10000 */ + /* -2.0468 + 0.0367 * ms + -1.5955e-6 * ms * ms ...too small value... */ + hum = (-20468L + 367L * ms) / 100L; + + /* SENSORS_DEACTIVATE(light_sensor); */ + SENSORS_DEACTIVATE(sht11_sensor); + + pos += snprintf(&data[pos], MAX_SIZE - pos, "temp="); + pos += write_percent_float(&data[pos], MAX_SIZE - pos, temperature); + pos += snprintf(&data[pos], MAX_SIZE - pos, ";hum="); + pos += write_percent_float(&data[pos], MAX_SIZE - pos, hum); + + cmd_send((uint8_t *)data, pos); +} +/* ---------------------------------------------------------------------- */ +const struct slip_radio_sensors slip_radio_sky_sensors = { + init, send +}; +/* ---------------------------------------------------------------------- */ diff --git a/examples/ipv6/slip-radio/slip-radio.c b/examples/ipv6/slip-radio/slip-radio.c new file mode 100644 index 000000000..76767608a --- /dev/null +++ b/examples/ipv6/slip-radio/slip-radio.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * \file + * Slip-radio driver + * \author + * Niclas Finne + * Joakim Eriksson + */ +#include "contiki.h" +#include "net/uip.h" +#include "net/uip-ds6.h" +#include "dev/slip.h" +#include +#include "net/netstack.h" +#include "net/packetbuf.h" + +#define DEBUG DEBUG_NONE +#include "net/uip-debug.h" +#include "cmd.h" +#include "slip-radio.h" +#include "packetutils.h" + +#ifdef SLIP_RADIO_CONF_SENSORS +extern const struct slip_radio_sensors SLIP_RADIO_CONF_SENSORS; +#endif + +void slip_send_packet(const uint8_t *ptr, int len); + + /* max 16 packets at the same time??? */ +uint8_t packet_ids[16]; +int packet_pos; + +static int slip_radio_cmd_handler(const uint8_t *data, int len); +int cmd_handler_cc2420(const uint8_t *data, int len); +/*---------------------------------------------------------------------------*/ +#ifdef CMD_CONF_HANDLERS +CMD_HANDLERS(CMD_CONF_HANDLERS); +#else +CMD_HANDLERS(slip_radio_cmd_handler); +#endif +/*---------------------------------------------------------------------------*/ +static void +packet_sent(void *ptr, int status, int transmissions) +{ + uint8_t buf[20]; + uint8_t sid; + int pos; + sid = *((uint8_t *)ptr); + PRINTF("Slip-radio: packet sent! sid: %d, status: %d, tx: %d\n", + sid, status, transmissions); + /* packet callback from lower layers */ + /* neighbor_info_packet_sent(status, transmissions); */ + pos = 0; + buf[pos++] = '!'; + buf[pos++] = 'R'; + buf[pos++] = sid; + buf[pos++] = status; /* one byte ? */ + buf[pos++] = transmissions; + cmd_send(buf, pos); +} +/*---------------------------------------------------------------------------*/ +static int +slip_radio_cmd_handler(const uint8_t *data, int len) +{ + int i; + if(data[0] == '!') { + /* should send out stuff to the radio - ignore it as IP */ + /* --- s e n d --- */ + if(data[1] == 'S') { + int pos; + packet_ids[packet_pos] = data[2]; + + packetbuf_clear(); + pos = 3; + pos += packetutils_deserialize_atts(&data[pos], len - pos); + + len -= pos; + if(len > PACKETBUF_SIZE) { + len = PACKETBUF_SIZE; + } + memcpy(packetbuf_dataptr(), &data[pos], len); + packetbuf_set_datalen(len); + + PRINTF("slip-radio: sending: %d\n", packetbuf_datalen()); + + NETSTACK_MAC.send(&packet_sent, &packet_ids[packet_pos]); + + packet_pos++; + if(packet_pos >= sizeof(packet_ids)) { + packet_pos = 0; + } + + return 1; + } + } else if(uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(data[1] == 'M') { + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + uip_buf[1] = 'M'; + for(i = 0; i < 8; i++) { + uip_buf[2 + i] = uip_lladdr.addr[i]; + } + uip_len = 10; + cmd_send(uip_buf, uip_len); + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +slip_radio_cmd_output(const uint8_t *data, int data_len) +{ + slip_send_packet(data, data_len); +} +/*---------------------------------------------------------------------------*/ +static void +slip_input_callback(void) +{ + PRINTF("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]); + cmd_input(uip_buf, uip_len); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + slip_arch_init(BAUD2UBR(115200)); + process_start(&slip_process, NULL); + slip_set_input_callback(slip_input_callback); + packet_pos = 0; +} +/*---------------------------------------------------------------------------*/ +#undef putchar +int +putchar(int c) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if(!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + /* Need to also print '\n' because for example COOJA will not show + any output before line end */ + slip_arch_writeb((char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if(c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + return c; +} +/*---------------------------------------------------------------------------*/ +PROCESS(slip_radio_process, "Slip radio process"); +AUTOSTART_PROCESSES(&slip_radio_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(slip_radio_process, ev, data) +{ + static struct etimer et; + PROCESS_BEGIN(); + + init(); + NETSTACK_RDC.off(1); +#ifdef SLIP_RADIO_CONF_SENSORS + SLIP_RADIO_CONF_SENSORS.init(); +#endif + printf("Slip Radio started...\n"); + + etimer_set(&et, CLOCK_SECOND * 3); + + while(1) { + PROCESS_YIELD(); + + if(etimer_expired(&et)) { + etimer_reset(&et); +#ifdef SLIP_RADIO_CONF_SENSORS + SLIP_RADIO_CONF_SENSORS.send(); +#endif + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/slip-radio/slip-radio.h b/examples/ipv6/slip-radio/slip-radio.h new file mode 100644 index 000000000..8aad5da20 --- /dev/null +++ b/examples/ipv6/slip-radio/slip-radio.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2011, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef __SLIP_RADIO_H__ +#define __SLIP_RADIO_H__ + +struct slip_radio_sensors { + /** Initialize the driver */ + void (* init)(void); + /** Send the sensor data packet via the command send */ + void (* send)(void); +}; + +#endif /* __SLIP_RADIO_H__ */ diff --git a/platform/native/Makefile.native b/platform/native/Makefile.native index 444b34dd9..d4a692986 100644 --- a/platform/native/Makefile.native +++ b/platform/native/Makefile.native @@ -2,6 +2,10 @@ ifndef CONTIKI $(error CONTIKI not defined! You must specify where CONTIKI resides!) endif +ifdef UIP_CONF_IPV6 +CFLAGS += -DWITH_UIP6=1 +endif + CONTIKI_TARGET_DIRS = . dev CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h index 5107872f7..ddaca6a1e 100644 --- a/platform/native/contiki-conf.h +++ b/platform/native/contiki-conf.h @@ -35,6 +35,12 @@ #define __CONTIKI_CONF_H__ #include +#include + +struct select_callback { + int (* set_fd)(int maxfd, fd_set *fdr, fd_set *fdw); + void (* handle_fd)(fd_set *fdr, fd_set *fdw); +}; #define CC_CONF_REGISTER_ARGS 1 #define CC_CONF_FUNCTION_POINTER_ARGS 1 @@ -57,11 +63,51 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_BUFFER_SIZE 420 #define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN #define UIP_CONF_TCP 1 -#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_TCP_SPLIT 0 #define UIP_CONF_LOGGING 0 #define UIP_CONF_UDP_CHECKSUMS 1 #if UIP_CONF_IPV6 + +#define RIMEADDR_CONF_SIZE 8 + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC nullmac_driver +#endif /* NETSTACK_CONF_MAC */ + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver +#endif /* NETSTACK_CONF_RDC */ + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO nullradio_driver +#endif /* NETSTACK_CONF_RADIO */ + +#ifndef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 +#endif /* NETSTACK_CONF_FRAMER */ + +#define NETSTACK_CONF_NETWORK sicslowpan_driver + +#define UIP_CONF_ROUTER 1 +#ifndef UIP_CONF_IPV6_RPL +#define UIP_CONF_IPV6_RPL 1 +#endif /* UIP_CONF_IPV6_RPL */ + +#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 +#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 +#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +#endif /* SICSLOWPAN_CONF_FRAG */ +#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 +#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS +#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 +#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ + #define UIP_CONF_IPV6_CHECKS 1 #define UIP_CONF_IPV6_QUEUE_PKT 1 #define UIP_CONF_IPV6_REASSEMBLY 0 @@ -70,7 +116,45 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_ND6_MAX_NEIGHBORS 4 #define UIP_CONF_ND6_MAX_DEFROUTERS 2 #define UIP_CONF_ICMP6 1 -#endif /* UIP_CONF_ICMP6 */ + +/* configure number of neighbors and routes */ +#ifndef UIP_CONF_DS6_NBR_NBU +#define UIP_CONF_DS6_NBR_NBU 30 +#endif /* UIP_CONF_DS6_NBR_NBU */ +#ifndef UIP_CONF_DS6_ROUTE_NBU +#define UIP_CONF_DS6_ROUTE_NBU 30 +#endif /* UIP_CONF_DS6_ROUTE_NBU */ + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#define UIP_CONF_IP_FORWARD 0 +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 240 +#endif + + +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_LL_802154 1 + +#define UIP_CONF_ICMP_DEST_UNREACH 1 + +#define UIP_CONF_DHCP_LIGHT +#define UIP_CONF_RECEIVE_WINDOW 48 +#define UIP_CONF_TCP_MSS 48 +#define UIP_CONF_UDP_CONNS 12 +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + + + +#endif /* UIP_CONF_IPV6 */ typedef unsigned long clock_time_t; @@ -81,4 +165,11 @@ typedef unsigned long clock_time_t; /* Not part of C99 but actually present */ int strcasecmp(const char*, const char*); +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#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 efd3ca562..12ab49308 100644 --- a/platform/native/contiki-main.c +++ b/platform/native/contiki-main.c @@ -34,6 +34,7 @@ */ #include +#include #include #include @@ -48,18 +49,90 @@ #include "dev/pir-sensor.h" #include "dev/vib-sensor.h" +#if WITH_UIP6 +#include "net/uip-ds6.h" +#endif /* WITH_UIP6 */ + +#include "net/rime.h" + + PROCINIT(&etimer_process, &tcpip_process); SENSORS(&pir_sensor, &vib_sensor, &button_sensor); +static uint8_t serial_id[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}; + /*---------------------------------------------------------------------------*/ -int -main(void) +static void +set_rime_addr(void) { - printf("Starting Contiki\n"); + rimeaddr_t addr; + int i; + + memset(&addr, 0, sizeof(rimeaddr_t)); +#if UIP_CONF_IPV6 + memcpy(addr.u8, serial_id, sizeof(addr.u8)); +#else + if(node_id == 0) { + for(i = 0; i < sizeof(rimeaddr_t); ++i) { + addr.u8[i] = serial_id[7 - i]; + } + } else { + addr.u8[0] = node_id & 0xff; + addr.u8[1] = node_id >> 8; + } +#endif + rimeaddr_set_node_addr(&addr); + printf("Rime started with address "); + for(i = 0; i < sizeof(addr.u8) - 1; i++) { + printf("%d.", addr.u8[i]); + } + printf("%d\n", addr.u8[i]); +} + + +/*---------------------------------------------------------------------------*/ +int contiki_argc = 0; +char **contiki_argv; + +int +main(int argc, char **argv) +{ + printf("Starting Contiki: IPV6:%d \n", UIP_CONF_IPV6); + + /* crappy way of remembering and accessing argc/v */ + contiki_argc = argc; + contiki_argv = argv; + process_init(); ctimer_init(); + set_rime_addr(); + +#if WITH_UIP6 + memcpy(&uip_lladdr.addr, serial_id, sizeof(uip_lladdr.addr)); + + process_start(&tcpip_process, NULL); + + printf("Tentative link-local IPv6 address "); + { + uip_ds6_addr_t *lladdr; + int i; + lladdr = uip_ds6_get_link_local(-1); + for(i = 0; i < 7; ++i) { + printf("%02x%02x:", lladdr->ipaddr.u8[i * 2], + lladdr->ipaddr.u8[i * 2 + 1]); + } + /* make it hardcoded... */ + lladdr->state = ADDR_AUTOCONF; + + printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); + } + +#endif + + queuebuf_init(); + netstack_init(); procinit_init(); @@ -67,14 +140,15 @@ main(void) serial_line_init(); autostart_start(autostart_processes); - /* Make standard output unbuffered. */ setvbuf(stdout, (char *)NULL, _IONBF, 0); while(1) { - fd_set fds; + fd_set fdr; + fd_set fdw; int n; + int maxfd; struct timeval tv; n = process_run(); @@ -82,17 +156,28 @@ main(void) tv.tv_sec = 0; tv.tv_usec = 1; - FD_ZERO(&fds); - FD_SET(STDIN_FILENO, &fds); - if(select(1, &fds, NULL, NULL, &tv) < 0) { + FD_ZERO(&fdr); + FD_ZERO(&fdw); + FD_SET(STDIN_FILENO, &fdr); + maxfd = STDIN_FILENO; + +#ifdef SELECT_CALLBACK + maxfd = SELECT_CALLBACK->set_fd(maxfd, &fdr, &fdw); +#endif + if(select(maxfd + 1, &fdr, &fdw, NULL, &tv) < 0) { perror("select"); - } else if(FD_ISSET(STDIN_FILENO, &fds)) { - char c; - if(read(STDIN_FILENO, &c, 1) > 0) { - serial_line_input_byte(c); + } else { + if(FD_ISSET(STDIN_FILENO, &fdr)) { + char c; + if(read(STDIN_FILENO, &c, 1) > 0) { + serial_line_input_byte(c); + } } +#ifdef SELECT_CALLBACK + SELECT_CALLBACK->handle_fd(&fdr, &fdw); +#endif } - + etimer_request_poll(); } diff --git a/platform/native/dev/button-sensor.c b/platform/native/dev/button-sensor.c index da7c73349..82dba1de9 100644 --- a/platform/native/dev/button-sensor.c +++ b/platform/native/dev/button-sensor.c @@ -10,22 +10,22 @@ button_press(void) sensors_changed(&button_sensor); } /*---------------------------------------------------------------------------*/ -static unsigned int +static int value(int type) { return 0; } /*---------------------------------------------------------------------------*/ static int -configure(int type, void *c) +configure(int type, int value) { return 0; } /*---------------------------------------------------------------------------*/ -static void * +static int status(int type) { - return NULL; + return 0; } /*---------------------------------------------------------------------------*/ SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, diff --git a/platform/native/dev/dummy-sensors.c b/platform/native/dev/dummy-sensors.c index eead12abe..4244dd3b4 100644 --- a/platform/native/dev/dummy-sensors.c +++ b/platform/native/dev/dummy-sensors.c @@ -42,22 +42,22 @@ #include "dev/temperature-sensor.h" /*---------------------------------------------------------------------------*/ -static unsigned int +static int value(int type) { return 0; } /*---------------------------------------------------------------------------*/ static int -configure(int type, void *c) +configure(int type, int c) { return 0; } /*---------------------------------------------------------------------------*/ -static void * +static int status(int type) { - return NULL; + return 0; } /*---------------------------------------------------------------------------*/ SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, diff --git a/platform/native/dev/pir-sensor.c b/platform/native/dev/pir-sensor.c index 14d9ccb5f..f13b7cc41 100644 --- a/platform/native/dev/pir-sensor.c +++ b/platform/native/dev/pir-sensor.c @@ -13,22 +13,22 @@ pir_sensor_changed(int strength) sensors_changed(&pir_sensor); } /*---------------------------------------------------------------------------*/ -static unsigned int +static int value(int type) { return pir_value; } /*---------------------------------------------------------------------------*/ static int -configure(int type, void *c) +configure(int type, int c) { return 0; } /*---------------------------------------------------------------------------*/ -static void * +static int status(int type) { - return NULL; + return 0; } /*---------------------------------------------------------------------------*/ SENSORS_SENSOR(pir_sensor, PIR_SENSOR, diff --git a/platform/native/dev/vib-sensor.c b/platform/native/dev/vib-sensor.c index 0c297179a..688fb701d 100644 --- a/platform/native/dev/vib-sensor.c +++ b/platform/native/dev/vib-sensor.c @@ -48,26 +48,27 @@ static unsigned int vib; void vib_sensor_changed(void) { + vib++; sensors_changed(&vib_sensor); } /*---------------------------------------------------------------------------*/ -static unsigned int +static int value(int type) +{ + return vib; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) { return 0; } /*---------------------------------------------------------------------------*/ static int -configure(int type, void *c) +status(int type) { return 0; } /*---------------------------------------------------------------------------*/ -static void * -status(int type) -{ - return NULL; -} -/*---------------------------------------------------------------------------*/ SENSORS_SENSOR(vib_sensor, VIB_SENSOR, value, configure, status);