diff --git a/examples/jn516x/README.md b/examples/jn516x/README.md index 06ccc0da7..0a7c6bb9e 100644 --- a/examples/jn516x/README.md +++ b/examples/jn516x/README.md @@ -2,4 +2,4 @@ Examples for the JN516x platform. * dr1175: simple Contiki application for the DR1175 evaluation board. Prints out sensor values periodically. * rime: simple Rime example. Works with ContikiMAC (default) or NullRDC * RPL: RPL examples, including border router, simple node, and coap resources. More information under rpl/README.md - \ No newline at end of file +* tsch: Examples of applications using TSCH \ No newline at end of file diff --git a/examples/jn516x/tsch/README.md b/examples/jn516x/tsch/README.md new file mode 100644 index 000000000..2bfcc036a --- /dev/null +++ b/examples/jn516x/tsch/README.md @@ -0,0 +1,8 @@ +Examples for tsch on jn516x + +simple-sensor-network: This example shows a simple sensor network consisting of node(s),an rpl-border-router and a host connected to +the IPv6 network. +tx-power-verfication: Example on TX power control and RSSI reading on JN516x. Resource available on coap client. +uart1-test-node: Example on exposing uart1 of JN516x node to a coap client + + \ No newline at end of file diff --git a/examples/jn516x/tsch/common-conf-jn516x.h b/examples/jn516x/tsch/common-conf-jn516x.h new file mode 100644 index 000000000..53773e702 --- /dev/null +++ b/examples/jn516x/tsch/common-conf-jn516x.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014, 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 Simon Duquennoy + */ + +#ifndef __COMMON_CONF_JN516X_H__ +#define __COMMON_CONF_JN516X_H__ + +/* Shall we restart after exception, or stall? + * in production code we should restart, so set this to 0 */ +#undef EXCEPTION_STALLS_SYSTEM +#define EXCEPTION_STALLS_SYSTEM 1 + + /* CoAP */ +#undef COAP_MAX_OPEN_TRANSACTIONS +#define COAP_MAX_OPEN_TRANSACTIONS 4 + +#undef REST_MAX_CHUNK_SIZE +#define REST_MAX_CHUNK_SIZE 256 + +/* Network config */ +#undef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#undef UIP_CONF_BUFFER_SIZE +//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + UIP_LLH_LEN + UIP_IPUDPH_LEN + COAP_MAX_HEADER_SIZE) +//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + 0 + 48 + 70) +#define UIP_CONF_BUFFER_SIZE 1280 /* ipv6 required minimum */ +#undef UIP_CONF_UDP_CONNS +#define UIP_CONF_UDP_CONNS 8 + +/* No IPv6 reassembly */ +#undef UIP_CONF_IPV6_REASSEMBLY +#define UIP_CONF_IPV6_REASSEMBLY 0 + +/* Timeout for packet reassembly at the 6lowpan layer (should be < 60s) */ +#undef SICSLOWPAN_CONF_MAXAGE +#define SICSLOWPAN_CONF_MAXAGE 10 + +/* Queues */ +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 32 + +#undef TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR +#define TSCH_QUEUE_CONF_NUM_PER_NEIGHBOR 32 + +#undef TSCH_CONF_DEQUEUED_ARRAY_SIZE +#define TSCH_CONF_DEQUEUED_ARRAY_SIZE 32 + +#undef TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES +#define TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES 8 + +/* The neighbor table size */ +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 + +/* The routing table size */ +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 28 + +/* Radio */ + +#undef ENABLE_COOJA_DEBUG +#define ENABLE_COOJA_DEBUG 0 + +/* max 3, min 0 */ + +#undef UART_HW_FLOW_CTRL +#define UART_HW_FLOW_CTRL 0 + +#undef UART_XONXOFF_FLOW_CTRL +#define UART_XONXOFF_FLOW_CTRL 1 + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_1000000 + +#endif /* __COMMON_CONF_JN516X_H__ */ diff --git a/examples/jn516x/tsch/common-conf.h b/examples/jn516x/tsch/common-conf.h new file mode 100644 index 000000000..3fbd8ad4b --- /dev/null +++ b/examples/jn516x/tsch/common-conf.h @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2014, 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 Simon Duquennoy + */ + +#ifndef __COMMON_CONF_H__ +#define __COMMON_CONF_H__ + +/* Global config flags */ + +#define WITH_TSCH 1 +#define WITH_TSCH_SECURITY 0 +#define TSCH_LOG_CONF_LEVEL 2 +#define WITH_COAP_RESOURCES 0 + +#undef ENABLE_COOJA_DEBUG +#define ENABLE_COOJA_DEBUG 0 + +#undef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0x5254 + +#undef TSCH_CONF_DEFAULT_HOPPING_SEQUENCE +#define TSCH_HOPPING_SEQUENCE_MY_SEQUENCE (uint8_t[]){17, 23, 15, 25, 19, 11, 13, 21} +#define TSCH_CONF_DEFAULT_HOPPING_SEQUENCE TSCH_HOPPING_SEQUENCE_MY_SEQUENCE + +#undef TSCH_CONF_JOIN_MY_PANID_ONLY +#define TSCH_CONF_JOIN_MY_PANID_ONLY 1 + +#undef TSCH_CONF_AUTOSTART +#define TSCH_CONF_AUTOSTART 0 + +#define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch +#define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval + +/* RPL Trickle timer tuning */ +#undef RPL_CONF_DIO_INTERVAL_MIN +#define RPL_CONF_DIO_INTERVAL_MIN 12 /* 4.096 s */ + +#undef RPL_CONF_DIO_INTERVAL_DOUBLINGS +#define RPL_CONF_DIO_INTERVAL_DOUBLINGS 2 /* Max factor: x4. 4.096 s * 4 = 16.384 s */ + +#define TSCH_CONF_EB_PERIOD (4 * CLOCK_SECOND) +#define TSCH_CONF_KEEPALIVE_TIMEOUT (24 * CLOCK_SECOND) + +#define TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL 0 +#define TSCH_CONF_WITH_LINK_SELECTOR 1 +#define TSCH_CALLBACK_NEW_TIME_SOURCE orchestra_callback_new_time_source +#define TSCH_CALLBACK_PACKET_READY orchestra_callback_packet_ready +#define NETSTACK_CONF_ROUTING_NEIGHBOR_ADDED_CALLBACK orchestra_callback_child_added +#define NETSTACK_CONF_ROUTING_NEIGHBOR_REMOVED_CALLBACK orchestra_callback_child_removed + +/* Dimensioning */ +#define ORCHESTRA_CONF_EBSF_PERIOD 41 +#define ORCHESTRA_CONF_COMMON_SHARED_PERIOD 7 /* Common shared slot, 7 is a very short slotframe (high energy, high capacity). Must be prime and at least equal to number of nodes (incl. BR) */ +#define ORCHESTRA_CONF_UNICAST_PERIOD 11 /* First prime greater than 10 */ + +/* Use sender-based slots */ +#define ORCHESTRA_CONF_UNICAST_SENDER_BASED 1 +/* Our "hash" is collision-free */ +#define ORCHESTRA_CONF_COLLISION_FREE_HASH 1 +/* Max hash value */ +#define ORCHESTRA_CONF_MAX_HASH (ORCHESTRA_CONF_UNICAST_PERIOD - 1) + +/* RPL probing */ +#define RPL_CONF_PROBING_INTERVAL (5 * CLOCK_SECOND) +#define RPL_CONF_PROBING_EXPIRATION_TIME (2 * 60 * CLOCK_SECOND) + +/* CoAP */ + +#undef COAP_SERVER_PORT +#define COAP_SERVER_PORT 5684 + +#undef COAP_OBSERVE_RETURNS_REPRESENTATION +#define COAP_OBSERVE_RETURNS_REPRESENTATION 1 + +/* RPL */ +#undef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 + +/* RPL storing mode */ +#undef RPL_CONF_MOP +#define RPL_CONF_MOP RPL_MOP_STORING_NO_MULTICAST + +/* Default link metric */ +#undef RPL_CONF_INIT_LINK_METRIC +#define RPL_CONF_INIT_LINK_METRIC 2 /* default 5 */ + +#define RPL_CONF_MAX_INSTANCES 1 /* default 1 */ +#define RPL_CONF_MAX_DAG_PER_INSTANCE 1 /* default 2 */ + +/* No RA, No NA */ +#undef UIP_CONF_ND6_SEND_NA +#define UIP_CONF_ND6_SEND_NA 0 + +#undef UIP_CONF_ND6_SEND_RA +#define UIP_CONF_ND6_SEND_RA 0 + +#undef UIP_CONF_TCP +#define UIP_CONF_TCP 0 +#undef UIP_CONF_DS6_ADDR_NBU +#define UIP_CONF_DS6_ADDR_NBU 1 +#undef UIP_CONF_FWCACHE_SIZE +#define UIP_CONF_FWCACHE_SIZE 1 +#undef UIP_CONF_UDP_CHECKSUMS +#define UIP_CONF_UDP_CHECKSUMS 1 + +/* Link-layer security */ + +/* Even when link-layer security is needed, we do not use a LLSEC layer, as it does not + * allow to secure MAC-layer packets, nor can run encrypt/decrupt from interrupt. + * Instead, we call AES-CCM* primitives directly from TSCH */ +#undef NETSTACK_CONF_LLSEC +#define NETSTACK_CONF_LLSEC nullsec_driver + +#if WITH_TSCH_SECURITY +/* Set security level to the maximum, even if unused, to all crypto code */ +#define LLSEC802154_CONF_SECURITY_LEVEL 7 +/* Attempt to associate from both secured and non-secured EBs */ +#define TSCH_CONF_JOIN_SECURED_ONLY 0 +/* We need explicit keys to identify k1 and k2 */ +#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 +/* TSCH uses the ASN to construct the Nonce */ +#undef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_CONF_USES_FRAME_COUNTER 0 +#endif /* WITH_TSCH_SECURITY */ + +#if WITH_TSCH + +#undef FRAME802154_CONF_VERSION +#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 + +/* Contiki netstack: MAC */ +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC tschmac_driver + +/* Contiki netstack: RDC */ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nordc_driver + +#else /* No TSCH, use Csma+NullRDC with ACK */ + +/* Contiki netstack: MAC */ +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver + +/* Contiki netstack: RDC */ +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nullrdc_driver + +#undef RF_CHANNEL +#define RF_CHANNEL 26 + +#undef MICROMAC_CONF_AUTOACK +#define MICROMAC_CONF_AUTOACK 1 + +/* increase internal radio buffering */ +#undef MIRCOMAC_CONF_BUF_NUM +#define MIRCOMAC_CONF_BUF_NUM 4 + +#endif + +#undef CONTIKI_VERSION_STRING +#define CONTIKI_VERSION_STRING "Contiki 3.x" + +#include "common-conf-jn516x.h" + +#endif /* __COMMON_CONF_H__ */ diff --git a/examples/jn516x/tsch/simple-sensor-network/README.md b/examples/jn516x/tsch/simple-sensor-network/README.md new file mode 100644 index 000000000..b9bf2588c --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/README.md @@ -0,0 +1,25 @@ +This example shows a simple sensor network consisting of node(s),an rpl-border-router and a host connected to +the IPv6 network. The nodes (see also node/README.md) regularly transmit simulated sensor data to the host. +The host visualises the received data. + +The Python script tools/Output-Visualisation.py visualises the received data from the nodes. +The script runs on Python27 and uses gnuplot for visualisation. +The following installations are needed (tested with Win32 versions: +- Python 27 (https://www.python.org/download/releases/2.7/) +- gnuplot (http://sourceforge.net/projects/gnuplot/files/gnuplot/) +- gnuplot.py (http://gnuplot-py.sourceforge.net/) +- numpy.py (e.g. http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy) +Manual modification: +Python27\Lib\site-packages\Gnuplot\gp_win32.py +Modify gnuplot_command as in example below + gnuplot_command = r'"C:\Program Files (x86)\gnuplot\bin\gnuplot.exe"' + +- The IPv6 addresses of nodes need to be entered in the dictionary "node_data" of tools/Output-Visualisation.py + A user name for the node can be entered in this table as well. +- The script will send a ping message to the next node in the list every 5 seconds. The nodes will obtain + the IPv6 address from this message and start sending "sensor" data to the host. +- Received sensor data is plotted. When no data has been received for more than 30seconds, the plot line + will be dashed. +- Plots are updated once per second. + + \ No newline at end of file diff --git a/examples/jn516x/tsch/simple-sensor-network/node/Makefile b/examples/jn516x/tsch/simple-sensor-network/node/Makefile new file mode 100644 index 000000000..2df54d578 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/Makefile @@ -0,0 +1,25 @@ +CONTIKI_PROJECT = node + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../../.. + +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/tsch/simple-sensor-network/node/README.md b/examples/jn516x/tsch/simple-sensor-network/node/README.md new file mode 100644 index 000000000..a49a8970c --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/README.md @@ -0,0 +1,10 @@ +Node is part of Simple-Sensor-Network +When node is connected to border-router (TSCH), it will wait to be addressed by a host +on port 8185. +When addressed, IPv6 address of host is acquired. Node will start to transmit samples of +a waveform ("simulated" sensor data) to the host on port 8186 at a rate of once per +10 seconds. Type of waveform and phase depend on mac address of node in order to better +distinguish the waveforms at the host side. +LED is flashed every time a sample is transmitted. +Nodes are tested with configuration JN516x_WITH_DONGLE=1 + diff --git a/examples/jn516x/tsch/simple-sensor-network/node/node.c b/examples/jn516x/tsch/simple-sensor-network/node/node.c new file mode 100644 index 000000000..48b7c4ff5 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/node.c @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2015 NXP B.V. +* 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 NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* Author: Theo van Daele +* +*/ + +#include "contiki-conf.h" +#include "net/netstack.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-private.h" +#include "net/rpl/rpl-private.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/ip/uip-debug.h" +#include "lib/random.h" +#include "rpl-tools.h" +#include "node-id.h" +#include "waveform.h" +#include "leds.h" +#include "net/ip/uiplib.h" +#include "net/ip/uip-udp-packet.h" +#include +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define INTERVAL (10) +#define BLINK_TIME (CLOCK_SECOND/4) + +typedef enum { + WAVEFORM_SIN = 0, + WAVEFORM_TRIANGLE = 1, + WAVEFORM_POS_SAWTOOTH = 2, + WAVEFORM_NEG_SAWTOOTH = 3, + NUMBER_OF_WAVEFORMS = 4 +} waveform_t; + +typedef struct { + const int8 * table; + char * str; +} wave_t; + +static const wave_t waveform_table[] = { {sin_table, "SINE"}, /* WAVEFORM_SIN */ + {triangle_table, "TRIANGLE"}, /* WAVEFORM_TRIANGLE */ + {pos_sawtooth_table, "POS-SAWTOOTH"}, /* WAVEFORM_POS_SAWTOOTH */ + {neg_sawtooth_table, "NEG_SAWTOOTH"}}; /* WAVEFORM_NEG_SAWTOOTH */ + +static int total_time = 0; +static int selected_waveform = 0; + +static void udp_rx_handler(void); +static void my_sprintf(char * udp_buf, int8_t value); + +static struct uip_udp_conn *udp_conn_rx; +static struct uip_udp_conn *udp_conn_tx; +static uip_ip6addr_t ip6addr_host; +static int host_found = 0; +static char udp_buf[120]; +static char *post_mssg = "Trigger"; + +/*******************************************************************************/ +/* Local functions */ +/*******************************************************************************/ +static void +udp_rx_handler(void) +{ + if(uip_newdata()) { + ((char *)uip_appdata)[uip_datalen()] = '\0'; + printf("UDP data from host: %s\n", (char *)uip_appdata); + if (!host_found) { + /* Create socket to talk back to host */ + uip_ipaddr_copy(&ip6addr_host, &UIP_IP_BUF->srcipaddr); + udp_conn_tx = udp_new(&ip6addr_host, UIP_HTONS(8186), NULL); + host_found = 1; + } + } +} + +static void +my_sprintf(char * udp_buf, int8_t value) +{ + /* Fill the buffer with 4 ASCII chars */ + if (value < 0) { + *udp_buf++ = '-'; + } else { + *udp_buf++ = '+'; + } + value = abs(value); + *udp_buf++ = value/100 + '0'; + value %= 100; + *udp_buf++ = value/10 + '0'; + value %= 10; + *udp_buf++ = value + '0'; + *udp_buf = 0; +} + +/*---------------------------------------------------------------------------*/ +PROCESS(node_process, "Node"); +PROCESS(led_process, "LED"); +AUTOSTART_PROCESSES(&node_process); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(node_process, ev, data) +{ + PROCESS_BEGIN(); + + static int sample_count = 0; + static struct etimer et; + extern unsigned char node_mac[8]; + + leds_init(); + + /* 3 possible roles: + * - role_6ln: simple node, will join any network, secured or not + * - role_6dr: DAG root, will advertise (unsecured) beacons + * - role_6dr_sec: DAG root, will advertise secured beacons + * */ + static int is_coordinator = 0; + static enum { role_6ln, role_6dr, role_6dr_sec } node_role; + + /* Set node with ID == 1 as coordinator, handy in Cooja. */ + if(node_id == 1) { + if(LLSEC802154_CONF_SECURITY_LEVEL) { + node_role = role_6dr_sec; + } else { + node_role = role_6dr; + } + } else { + node_role = role_6ln; + } + + printf("Init: node starting with role %s\n", + node_role == role_6ln ? "6ln" : (node_role == role_6dr) ? "6dr" : "6dr-sec"); + +#if WITH_TSCH + tsch_set_pan_secured(LLSEC802154_CONF_SECURITY_LEVEL && (node_role == role_6dr_sec)); +#endif /* WITH_TSCH */ + is_coordinator = node_role > role_6ln; + + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xbbbb, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } + + /* Selected waveform depends on LS byte of MAC */ + selected_waveform = node_mac[7] % NUMBER_OF_WAVEFORMS; + printf("LS-Byte=0x%x; waveform=%d\n", node_mac[7], selected_waveform); + + process_start(&led_process, NULL); + + /* Listen to any host on 8185 */ + udp_conn_rx = udp_new(NULL, 0, NULL); + udp_bind(udp_conn_rx, UIP_HTONS(8185)); + + /* Wait for timer event + On timer event, handle next sample */ + etimer_set(&et, INTERVAL*CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et) || (ev == tcpip_event)); + if (ev == tcpip_event) { + udp_rx_handler(); + } + if (etimer_expired(&et) ) { + /* Restart timer */ + total_time += INTERVAL; + if (host_found) { + /* Make sample count dependent on asn. After a disconnect, waveforms remain + synchronous. Use node_mac to create phase offset between waveforms in different nodes */ + sample_count = ((current_asn.ls4b/((1000/(TSCH_CONF_DEFAULT_TIMESLOT_LENGTH/1000)))/INTERVAL)+node_mac[7]) % (SIZE_OF_WAVEFORM-1); + printf("%d sec. waveform=%s. cnt=%d. value=%d\n", total_time, waveform_table[selected_waveform].str, sample_count, waveform_table[selected_waveform].table[sample_count]); + my_sprintf(udp_buf, waveform_table[selected_waveform].table[sample_count]); + uip_udp_packet_send(udp_conn_tx, udp_buf, strlen(udp_buf)); + /* Switch LED on and start blink timer (callback timer) */ + process_post(&led_process, PROCESS_EVENT_CONTINUE, post_mssg); + } else { + printf("No host\n"); + } + etimer_restart(&et); + if (total_time%60 == 0) { + /* Print network status once per minute */ + print_network_status(); + } + } + } + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(led_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Switch on leds for 0.25msec after event posted. */ + static struct etimer led_et; + + while(1) { + PROCESS_WAIT_EVENT_UNTIL((ev == PROCESS_EVENT_CONTINUE) && (!strcmp(data, post_mssg))); + leds_on(LEDS_RED); + etimer_set(&led_et, CLOCK_SECOND/4); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&led_et)); + etimer_stop(&led_et); + leds_off(LEDS_RED); + } + PROCESS_END(); +} + diff --git a/examples/jn516x/tsch/simple-sensor-network/node/project-conf.h b/examples/jn516x/tsch/simple-sensor-network/node/project-conf.h new file mode 100644 index 000000000..4e08f561c --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/project-conf.h @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2015 NXP B.V. +* 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 NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* Author: Theo van Daele +* +*/ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_115200 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/tsch/simple-sensor-network/node/waveform.h b/examples/jn516x/tsch/simple-sensor-network/node/waveform.h new file mode 100644 index 000000000..a171ff54a --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/node/waveform.h @@ -0,0 +1,214 @@ +/* +* Copyright (c) 2015 NXP B.V. +* 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 NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* Author: Theo van Daele +* +*/ + + +/* This file contains arrays with waveforms. + The arrays are of type int8. No limit on size, but for convenience of demonstrating take care that sample + period may be 10secs or more. Size for all tables should be equal !! */ + +#define SIZE_OF_WAVEFORM 40 + +static const int8 sin_table[] = { +0, +19, +39, +57, +74, +89, +102, +113, +120, +125, +127, +125, +120, +113, +102, +89, +74, +57, +39, +19, +0, +-20, +-40, +-58, +-75, +-90, +-103, +-114, +-121, +-126, +-127, +-126, +-121, +-114, +-103, +-90, +-75, +-58, +-40, +-20 +}; + +static const int8 triangle_table[] = { +-127, +-114, +-101, +-87, +-74, +-61, +-47, +-34, +-21, +-7, +6, +20, +33, +46, +60, +73, +86, +100, +113, +127, +127, +113, +100, +86, +73, +60, +46, +33, +20, +6, +-7, +-21, +-34, +-47, +-61, +-74, +-87, +-101, +-114, +-127 +}; + +static const int8 pos_sawtooth_table[] = { +-127, +-121, +-115, +-108, +-102, +-96, +-89, +-83, +-76, +-70, +-64, +-57, +-51, +-45, +-38, +-32, +-25, +-19, +-13, +-6, +0, +6, +13, +19, +26, +32, +38, +45, +51, +57, +64, +70, +77, +83, +89, +96, +102, +108, +115, +121 +}; + +static const int8 neg_sawtooth_table[] = { +127, +120, +114, +107, +101, +95, +88, +82, +76, +69, +63, +56, +50, +44, +37, +31, +25, +18, +12, +5, +-1, +-7, +-14, +-20, +-26, +-33, +-39, +-46, +-52, +-58, +-65, +-71, +-77, +-84, +-90, +-97, +-103, +-109, +-116, +-122 +}; + + diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/Makefile b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/Makefile new file mode 100644 index 000000000..1598632ef --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/Makefile @@ -0,0 +1,49 @@ +CONTIKI_PROJECT=border-router + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 +CONTIKI=../../../../.. + +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-bridge.c slip.c + +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) +include $(CONTIKI)/Makefile.include + +ifeq ($(PREFIX),) + PREFIX = bbbb::1/64 +endif + +#no flow control +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +#using XON/XOFF flow control +connect-router-sw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -X -B 1000000 $(PREFIX) + +#using hw flow control +connect-router-hw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -H -B 1000000 $(PREFIX) + +#using no flow control +connect-router-no: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX) diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/README.md b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/README.md new file mode 100644 index 000000000..da1bc21ff --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/README.md @@ -0,0 +1,2 @@ +rpl-border-router has been configured and tested to run on a JN5168-dongle in combination +with the NXP IoT Gateway. This requires the baud rate to be configured on 230400Bd. diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/border-router.c b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/border-router.c new file mode 100644 index 000000000..7657dc190 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/border-router.c @@ -0,0 +1,124 @@ +/* + * 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/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/rpl/rpl.h" +#include "simple-udp.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/netstack.h" +#include "dev/slip.h" +#include "rpl-tools.h" + +#include +#include +#include +#include + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t prefix; +static uint8_t prefix_set; + +PROCESS(border_router_process, "Border router process"); + +AUTOSTART_PROCESSES(&border_router_process); +/*---------------------------------------------------------------------------*/ +void +request_prefix(void) +{ + /* mess up uip_buf with a dirty request... */ + uip_buf[0] = '?'; + uip_buf[1] = 'P'; + uip_len = 2; + slip_send(); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +void +set_prefix_64(uip_ipaddr_t *prefix_64) +{ + memcpy(&prefix, prefix_64, 16); + prefix_set = 1; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ + prefix_set = 0; + + PROCESS_PAUSE(); + + PRINTF("RPL-Border router started\n"); + + + /* Request prefix until it has been received */ + while(!prefix_set) { + etimer_set(&et, CLOCK_SECOND); + request_prefix(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + PRINTF("Waiting for prefix\n"); + } + + PRINTF("Obtained prefix: "); + uip_debug_ipaddr_print(&prefix); + PRINTF("\n"); + + rpl_tools_init(&prefix); + + etimer_set(&et, CLOCK_SECOND * 60); + while(1) { + print_network_status(); + PROCESS_YIELD_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/project-conf.h b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/project-conf.h new file mode 100644 index 000000000..de5e4bdd6 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/project-conf.h @@ -0,0 +1,48 @@ +/* + * 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 BR_PROJECT_ROUTER_CONF_H_ +#define BR_PROJECT_ROUTER_CONF_H_ + +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface +#endif + +/* Needed for slip-bridge */ +#undef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 0 + +#include "../../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_230400 + + +#endif /* PROJECT_ROUTER_CONF_H_ */ diff --git a/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/slip-bridge.c b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/slip-bridge.c new file mode 100644 index 000000000..e4239a8e9 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/rpl-border-router/slip-bridge.c @@ -0,0 +1,164 @@ +/* + * 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 + * Slip fallback interface + * \author + * Niclas Finne + * Joakim Eriksson + * Joel Hoglund + * Nicolas Tsiftes + */ + +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/slip.h" +#if CONTIKI_TARGET_JN516X +#include "dev/uart0.h" +#else +#include "dev/uart1.h" +#endif +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif + +void set_prefix_64(uip_ipaddr_t *); + +static uip_ipaddr_t last_sender; +/*---------------------------------------------------------------------------*/ +static void +slip_input_callback(void) +{ + PRINTF("SIN: %u\n", uip_len); + if(uip_buf[0] == '!') { + PRINTF("Got configuration message of type %c\n", uip_buf[1]); + uip_len = 0; + if(uip_buf[1] == 'P') { + uip_ipaddr_t prefix; + /* Here we set a prefix !!! */ + memset(&prefix, 0, 16); + memcpy(&prefix, &uip_buf[2], 8); + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } + } else if (uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(uip_buf[1] == 'M') { + char* hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + for(j = 0; j < 8; j++) { + uip_buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + uip_len = 18; + slip_send(); + + } + uip_len = 0; + } + /* Save the last sender received over SLIP to avoid bouncing the + packet back if no route is found */ + uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + slip_arch_init(BAUD2UBR(115200)); + process_start(&slip_process, NULL); + slip_set_input_callback(slip_input_callback); +} +/*---------------------------------------------------------------------------*/ +static int +output(void) +{ + if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { + /* Do not bounce packets back over SLIP if the packet was received + over SLIP */ + PRINTF("slip-bridge: Destination off-link but no route src="); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" dst="); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + } else { + PRINTF("SUT: %u\n", uip_len); + slip_send(); + printf("\n"); + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +#if !SLIP_BRIDGE_CONF_NO_PUTCHAR +#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; +} +#endif +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface rpl_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/simple-sensor-network/script/Output-Visualisation.py b/examples/jn516x/tsch/simple-sensor-network/script/Output-Visualisation.py new file mode 100644 index 000000000..4e1699d53 --- /dev/null +++ b/examples/jn516x/tsch/simple-sensor-network/script/Output-Visualisation.py @@ -0,0 +1,148 @@ +# +# Copyright (c) 2015 NXP B.V. +# 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 NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +# +# Author: Theo van Daele +# +# + +import sys +import time +import socket +import thread +import numpy as np +import Gnuplot + +# Plot buffer length for each node buffer +SIZE_NODE_DATA = 600 + +# Repeat time for connect watchdog and ping +TICK = 5 +# Connect watchdog. Unit: [TICK] +CONNECT_WATCHDOG = 30/TICK + +TX_PORT = 8185 +RX_PORT = 8186 + +last_sample_value = 0 +x_range = np.arange(SIZE_NODE_DATA) +dummy_data = np.zeros(SIZE_NODE_DATA, dtype=np.int) +plot = Gnuplot.Data(x_range,dummy_data) +g = Gnuplot.Gnuplot() + +# Attention: Skip leading zero's in IPv6 address list, otherwise address comparison with received UDP packet address goes wrong +NODE_ALIAS = 0 # node name in plot +NODE_DATA = 1 # Time line with data to plot +NODE_CONNECTED = 2 # If 0, not connected, else connect_watchdog value +NODE_LAST_DATA = 3 # Storage for received sample +NODE_PLOT = 4 # Plot instance +node_data = {"bbbb::215:8d00:36:180" : ["NODE-001", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot], + "bbbb::215:8d00:36:892" : ["NODE-196", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot], + "bbbb::215:8d00:36:8b1" : ["NODE-193", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot], + "bbbb::215:8d00:36:8b3" : ["NODE-198", np.zeros(SIZE_NODE_DATA, dtype=np.int), 0, last_sample_value, plot]} + +# List of all nodes derived from node_data list +node_list = node_data.keys() + +def initPlots(): + for node in range(len(node_list)): + node_data_key = node_data[node_list[node]] + g.title('Sensor Network Output') + g.ylabel('Value') + g.xlabel('Time-Span[s]') + g("set yrange [-150:150]") + g("set xrange [0:"+str(SIZE_NODE_DATA)+"]") + node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS] , with_='lines lw 2') + nodes = [ node_data[node_list[i]][NODE_PLOT] for i in xrange(len(node_list)) ] + g.plot(*nodes) + + + +def udpReceive(): + """RUNS ON SEPARATE THREAD """ + while True: + data, addr = s_rx.recvfrom(128) + data = data.replace("\"","").strip("\0") # strip termination byte and possible + node_data_key = node_data[addr[0]] + # Indicate node is connected + node_data_key[NODE_CONNECTED] = CONNECT_WATCHDOG + print addr[0] + ' (' + node_data_key[NODE_ALIAS] + ') : ' + data + # Write new data at index in data buffer. Data buffer is view of plot + data_lock.acquire() + node_data_key[NODE_LAST_DATA] = int(data) + data_lock.release() + +def plotGraphs(): + while True: + data_lock.acquire() + for node in range(len(node_list)): + node_data_key = node_data[node_list[node]] + for k in range(1,SIZE_NODE_DATA,1): + node_data_key[NODE_DATA][k-1] = node_data_key[NODE_DATA][k] + node_data_key[NODE_DATA][SIZE_NODE_DATA-1] = node_data_key[NODE_LAST_DATA] + if node_data_key[NODE_CONNECTED] == 0: + node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS], with_='dots') + else: + node_data_key[NODE_PLOT] = Gnuplot.Data(x_range,node_data_key[NODE_DATA], title=node_data_key[NODE_ALIAS], with_='lines lw 2') + nodes = [ node_data[node_list[i]][NODE_PLOT] for i in xrange(len(node_list)) ] + g.plot(*nodes) + data_lock.release() + time.sleep(1) + + +##### MAIN ##### +s_tx = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) +s_rx = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) +s_rx.bind(('', RX_PORT)) +initPlots() +data_lock = thread.allocate_lock() +thread.start_new_thread(udpReceive, ()) +thread.start_new_thread(plotGraphs, ()) +ping_node_index = 0 +ping_msg = "ping" +while True: + # Every 5 secs, one node of the list in pinged + if (ping_node_index >=len(node_list)): + ping_node_index = 0; + try: + print "ping " + node_data[node_list[ping_node_index]][NODE_ALIAS] + s_tx.sendto(ping_msg, (node_list[ping_node_index], TX_PORT)) + except: + print 'Failed to send to ' + node_list[ping_node_index] + ping_node_index += 1 + # Update connect watchdog + for node in range(len(node_list)): + node_data_key = node_data[node_list[node]] + if (node_data_key[NODE_CONNECTED] > 0): + node_data_key[NODE_CONNECTED] -= 1 + time.sleep(TICK) + + + + + diff --git a/examples/jn516x/tsch/tools/rpl-tools.c b/examples/jn516x/tsch/tools/rpl-tools.c new file mode 100644 index 000000000..b61c693c2 --- /dev/null +++ b/examples/jn516x/tsch/tools/rpl-tools.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2014, 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 + * + * \author Simon Duquennoy + */ + +#include "contiki-conf.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/rpl/rpl.h" +#include "orchestra.h" +#include +#include + +#define DEBUG DEBUG_PRINT +#include "net/ip/uip-debug.h" + +void +print_network_status(void) +{ + int i; + uint8_t state; + uip_ds6_defrt_t *default_route; + uip_ds6_route_t *route; + PRINTA("--- Network status ---\n"); + /* Our IPv6 addresses */ + 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("-- "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } + /* Our default route */ + PRINTA("- Default route:\n"); + default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose()); + if(default_route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&default_route->ipaddr);; + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval); + } else { + PRINTA("-- None\n"); + } + /* Our routing entries */ + PRINTA("- Routing entries (%u in total):\n", uip_ds6_route_num_routes()); + route = uip_ds6_route_head(); + while(route != NULL) { + PRINTA("-- "); + uip_debug_ipaddr_print(&route->ipaddr); + PRINTA(" via "); + uip_debug_ipaddr_print(uip_ds6_route_nexthop(route)); + PRINTA(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime); + route = uip_ds6_route_next(route); + } + PRINTA("----------------------\n"); +} +/*---------------------------------------------------------------------------*/ +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(" "); + uip_debug_ipaddr_print(&uip_ds6_if.addr_list[i].ipaddr); + PRINTA("\n"); + } + } +} +/*---------------------------------------------------------------------------*/ +void +rpl_tools_init(uip_ipaddr_t *br_prefix) +{ + uip_ipaddr_t global_ipaddr; + +#if TSCH_CONFIG == TSCH_CONFIG_ORCHESTRA + orchestra_init(); +#endif + if(br_prefix) { /* We are root */ + /* If an RDC layer is used, turn it off (i.e. keep the radio on at the root). */ + NETSTACK_RDC.off(1); + memcpy(&global_ipaddr, br_prefix, 16); + uip_ds6_set_addr_iid(&global_ipaddr, &uip_lladdr); + uip_ds6_addr_add(&global_ipaddr, 0, ADDR_AUTOCONF); + rpl_set_root(RPL_DEFAULT_INSTANCE, &global_ipaddr); + rpl_set_prefix(rpl_get_any_dag(), br_prefix, 64); + rpl_repair_root(RPL_DEFAULT_INSTANCE); + } + + /* Start TSCH */ + NETSTACK_MAC.on(); + print_local_addresses(); +} diff --git a/examples/jn516x/tsch/tools/rpl-tools.h b/examples/jn516x/tsch/tools/rpl-tools.h new file mode 100644 index 000000000..b04cdb712 --- /dev/null +++ b/examples/jn516x/tsch/tools/rpl-tools.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, 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 Simon Duquennoy + */ + +void rpl_tools_init(uip_ipaddr_t *br_prefix); +void print_network_status(void); diff --git a/examples/jn516x/tsch/tx-power-verification/README.md b/examples/jn516x/tsch/tx-power-verification/README.md new file mode 100644 index 000000000..8a3f7e008 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/README.md @@ -0,0 +1,13 @@ +The tx-power-control example can be used to check the link between a node and an rpl-border-router. +After a link is established, the following coap rresources are exposed: + +node: +Set-Tx-Power: a PUT/POST resource to set the TX power of the device. The firmware in the device will set the + TX power to the nearest available value. +Get-Tx-Power: a GET resource to retrieve the actual Tx power that is set. + + +rpl-border-router: +Get-RSSI: a GET resource that shows the detected energy level +Get-Last-RSSI:a GET resource that shows the RSSI of the last received packet. When there is only 1 node, Get-Last-RSSI will + show the effect of changing the TX power level on that node. diff --git a/examples/jn516x/tsch/tx-power-verification/node/Makefile b/examples/jn516x/tsch/tx-power-verification/node/Makefile new file mode 100644 index 000000000..0cb2d4bcb --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/node/Makefile @@ -0,0 +1,25 @@ +CONTIKI_PROJECT = node + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../../.. +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/tsch/tx-power-verification/node/node.c b/examples/jn516x/tsch/tx-power-verification/node/node.c new file mode 100644 index 000000000..1e77d3a2e --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/node/node.c @@ -0,0 +1,120 @@ +/* +* Copyright (c) 2015 NXP B.V. +* 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 NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* Author: Theo van Daele +* +*/ +#include "contiki.h" +#include "net/netstack.h" +#include "net/ip/uip.h" +#include "net/linkaddr.h" +#include "rpl-tools.h" +#include "rest-engine.h" +#include +#include +#include + +static void set_tx_power_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_tx_power_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); } + +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +AUTOSTART_PROCESSES(&start_app); +/*---------------------------------------------------------------------------*/ + +/*********** sensor/ resource ************************************************/ +RESOURCE(resource_set_tx_power, + "title=\"Set TX Power\"", + NULL, + set_tx_power_handler, + set_tx_power_handler, + NULL); +static void +set_tx_power_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + int tx_level; + + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + tx_level = atoi((const char *)request_content); + NETSTACK_RADIO.set_value(RADIO_PARAM_TXPOWER, tx_level); + } +} + +RESOURCE(resource_get_tx_power, + "title=\"Get TX Power\"", + get_tx_power_handler, + NULL, + NULL, + NULL); +static void +get_tx_power_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int tx_level; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + NETSTACK_RADIO.get_value(RADIO_PARAM_TXPOWER, &tx_level); + CONTENT_PRINTF("%d", tx_level); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + static int is_coordinator = 0; + + /* Start network stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } + printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_set_tx_power, "Set-TX-Power"); + rest_activate_resource(&resource_get_tx_power, "Get-TX-Power"); + + PROCESS_END(); +} diff --git a/examples/jn516x/tsch/tx-power-verification/node/project-conf.h b/examples/jn516x/tsch/tx-power-verification/node/project-conf.h new file mode 100644 index 000000000..77890c46e --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/node/project-conf.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 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 Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_115200 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/Makefile b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/Makefile new file mode 100644 index 000000000..15c5da2a2 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/Makefile @@ -0,0 +1,50 @@ +CONTIKI_PROJECT=rpl-border-router + +TARGET ?= jn516x +JN516x_WITH_DONGLE = 1 + +CONTIKI=../../../../.. + +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECT_SOURCEFILES += slip-bridge.c slip.c + +PROJECTDIRS += .. ../../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) +include $(CONTIKI)/Makefile.include + +ifeq ($(PREFIX),) + PREFIX = aaaa::1/64 +endif + +#no flow control +connect-router: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +#using XON/XOFF flow control +connect-router-sw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -X -B 1000000 $(PREFIX) + +#using hw flow control +connect-router-hw: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -H -B 1000000 $(PREFIX) + +#using no flow control +connect-router-no: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -v1 -B 1000000 $(PREFIX) + +connect-router-cooja: $(CONTIKI)/tools/tunslip6 + sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 $(PREFIX) diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/project-conf.h b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/project-conf.h new file mode 100644 index 000000000..f40b47809 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/project-conf.h @@ -0,0 +1,57 @@ +/* + * 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 BR_PROJECT_ROUTER_CONF_H_ +#define BR_PROJECT_ROUTER_CONF_H_ + +#ifndef UIP_FALLBACK_INTERFACE +#define UIP_FALLBACK_INTERFACE rpl_interface +#endif + +/* Needed for slip-bridge */ +#undef SLIP_BRIDGE_CONF_NO_PUTCHAR +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 0 + +#include "../../common-conf.h" + +/* Configuration to reduce RAM */ +#undef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 + +#undef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 14 + +#undef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 + +#undef TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES +#define TSCH_QUEUE_CONF_MAX_NEIGHBOR_QUEUES 8 + +#endif /* PROJECT_ROUTER_CONF_H_ */ diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/rpl-border-router.c b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/rpl-border-router.c new file mode 100644 index 000000000..cd9e2e2a2 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/rpl-border-router.c @@ -0,0 +1,169 @@ +/* +* Copyright (c) 2015 NXP B.V. +* 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 NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* Author: Theo van Daele +* +*/ +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "net/rpl/rpl.h" +#include "simple-udp.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-schedule.h" +#include "net/netstack.h" +#include "dev/slip.h" +#include "rest-engine.h" +#include "rpl-tools.h" + +#include +#include +#include +#include + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +static uip_ipaddr_t prefix; +static uint8_t prefix_set; + +static void get_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void get_last_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); + +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; + +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); } + +PROCESS(border_router_process, "Border router process"); +AUTOSTART_PROCESSES(&border_router_process); + +RESOURCE(resource_get_rssi, + "title=\"Get RSSI\"", + get_rssi_handler, + NULL, + NULL, + NULL); +static void +get_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int rssi_level; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + NETSTACK_RADIO.get_value(RADIO_PARAM_RSSI, &rssi_level); + CONTENT_PRINTF("%d", rssi_level); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} + +RESOURCE(resource_get_last_rssi, + "title=\"Get last RSSI\"", + get_last_rssi_handler, + NULL, + NULL, + NULL); +static void +get_last_rssi_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + int last_rssi_level; + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &last_rssi_level); + CONTENT_PRINTF("%d", last_rssi_level); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} + +/*---------------------------------------------------------------------------*/ +void +request_prefix(void) +{ + /* mess up uip_buf with a dirty request... */ + uip_buf[0] = '?'; + uip_buf[1] = 'P'; + uip_len = 2; + slip_send(); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +void +set_prefix_64(uip_ipaddr_t *prefix_64) +{ + memcpy(&prefix, prefix_64, 16); + prefix_set = 1; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(border_router_process, ev, data) +{ + static struct etimer et; + + PROCESS_BEGIN(); + +/* While waiting for the prefix to be sent through the SLIP connection, the future + * border router can join an existing DAG as a parent or child, or acquire a default + * router that will later take precedence over the SLIP fallback interface. + * Prevent that by turning the radio off until we are initialized as a DAG root. + */ + prefix_set = 0; + + PROCESS_PAUSE(); + + PRINTF("RPL-Border router started\n"); + + /* Request prefix until it has been received */ + while(!prefix_set) { + etimer_set(&et, CLOCK_SECOND); + request_prefix(); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + PRINTF("Waiting for prefix\n"); + } + + PRINTF("Obtained prefix: "); + uip_debug_ipaddr_print(&prefix); + PRINTF("\n"); + + rpl_tools_init(&prefix); + + rest_init_engine(); + rest_activate_resource(&resource_get_rssi, "Get-RSSI"); + rest_activate_resource(&resource_get_last_rssi, "Get-Last-RSSI"); + + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/tx-power-verification/rpl-border-router/slip-bridge.c b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/slip-bridge.c new file mode 100644 index 000000000..e4239a8e9 --- /dev/null +++ b/examples/jn516x/tsch/tx-power-verification/rpl-border-router/slip-bridge.c @@ -0,0 +1,164 @@ +/* + * 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 + * Slip fallback interface + * \author + * Niclas Finne + * Joakim Eriksson + * Joel Hoglund + * Nicolas Tsiftes + */ + +#include "net/ip/uip.h" +#include "net/ipv6/uip-ds6.h" +#include "dev/slip.h" +#if CONTIKI_TARGET_JN516X +#include "dev/uart0.h" +#else +#include "dev/uart1.h" +#endif +#include + +#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define DEBUG DEBUG_NONE +#include "net/ip/uip-debug.h" + +#ifndef BAUD2UBR +#define BAUD2UBR(X) (X) +#endif + +void set_prefix_64(uip_ipaddr_t *); + +static uip_ipaddr_t last_sender; +/*---------------------------------------------------------------------------*/ +static void +slip_input_callback(void) +{ + PRINTF("SIN: %u\n", uip_len); + if(uip_buf[0] == '!') { + PRINTF("Got configuration message of type %c\n", uip_buf[1]); + uip_len = 0; + if(uip_buf[1] == 'P') { + uip_ipaddr_t prefix; + /* Here we set a prefix !!! */ + memset(&prefix, 0, 16); + memcpy(&prefix, &uip_buf[2], 8); + PRINTF("Setting prefix "); + PRINT6ADDR(&prefix); + PRINTF("\n"); + set_prefix_64(&prefix); + } + } else if (uip_buf[0] == '?') { + PRINTF("Got request message of type %c\n", uip_buf[1]); + if(uip_buf[1] == 'M') { + char* hexchar = "0123456789abcdef"; + int j; + /* this is just a test so far... just to see if it works */ + uip_buf[0] = '!'; + for(j = 0; j < 8; j++) { + uip_buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4]; + uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15]; + } + uip_len = 18; + slip_send(); + + } + uip_len = 0; + } + /* Save the last sender received over SLIP to avoid bouncing the + packet back if no route is found */ + uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + slip_arch_init(BAUD2UBR(115200)); + process_start(&slip_process, NULL); + slip_set_input_callback(slip_input_callback); +} +/*---------------------------------------------------------------------------*/ +static int +output(void) +{ + if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) { + /* Do not bounce packets back over SLIP if the packet was received + over SLIP */ + PRINTF("slip-bridge: Destination off-link but no route src="); + PRINT6ADDR(&UIP_IP_BUF->srcipaddr); + PRINTF(" dst="); + PRINT6ADDR(&UIP_IP_BUF->destipaddr); + PRINTF("\n"); + } else { + PRINTF("SUT: %u\n", uip_len); + slip_send(); + printf("\n"); + } + return 0; +} + +/*---------------------------------------------------------------------------*/ +#if !SLIP_BRIDGE_CONF_NO_PUTCHAR +#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; +} +#endif +/*---------------------------------------------------------------------------*/ +const struct uip_fallback_interface rpl_interface = { + init, output +}; +/*---------------------------------------------------------------------------*/ diff --git a/examples/jn516x/tsch/uart1-test-node/Makefile b/examples/jn516x/tsch/uart1-test-node/Makefile new file mode 100644 index 000000000..76a3d6252 --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/Makefile @@ -0,0 +1,26 @@ +CONTIKI_PROJECT = uart1-test-node + +TARGET = jn516x +JN516x_WITH_DR1174 = 1 +TARGET_WITH_UART1 = 1 + +CONTIKI=../../../.. +CONTIKI_WITH_IPV6 = 1 + +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +PROJECTDIRS += .. ../tools +PROJECT_SOURCEFILES += rpl-tools.c + +CFLAGS += -DWITH_COAP +CFLAGS += -DREST=coap_rest_implementation +CFLAGS += -DUIP_CONF_TCP=0 +APPS += orchestra +APPS += json +APPS += er-coap +APPS += rest-engine + +MODULES += core/net/mac/tsch + +all: $(CONTIKI_PROJECT) + +include $(CONTIKI)/Makefile.include diff --git a/examples/jn516x/tsch/uart1-test-node/README.md b/examples/jn516x/tsch/uart1-test-node/README.md new file mode 100644 index 000000000..73eefd1ac --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/README.md @@ -0,0 +1,16 @@ +This example is a simple TSCH node used to test uart1 functionality of a JN516x on a node. +Note: uart0 is usually configured as serial port for flashing the JN516x and for logging and debug output. + +The TX output of uart1 is represented as a PUT/POST resource for a Coap client. +A string entered on a Coap plug-in of a browser will be forwarded over the wireless TSCH network to the +the TX output of UART1. + +The RX input of uart1 is represented as an OBSERVABLE resource for a Coap client. +If a string is entered on uart1 that is terminated with a Line Feed or Carriage Return, +a Coap event will notify Coap clients to issue a GET event. +This will make string available at the Coap client side. + +The example has been verified on a DR1174 evaluation board + + + \ No newline at end of file diff --git a/examples/jn516x/tsch/uart1-test-node/project-conf.h b/examples/jn516x/tsch/uart1-test-node/project-conf.h new file mode 100644 index 000000000..f72569a3c --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/project-conf.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, 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 Simon Duquennoy + */ + +#ifndef __PROJECT_CONF_H__ +#define __PROJECT_CONF_H__ + +#include "../common-conf.h" + +#undef UART_BAUD_RATE +#define UART_BAUD_RATE UART_RATE_115200 + +#undef UART1_BAUD_RATE +#define UART1_BAUD_RATE UART_RATE_115200 + +#undef UART1_CONF_TX_BUFFER_SIZE +#define UART1_CONF_TX_BUFFER_SIZE 32 + +#undef UART1_CONF_RX_BUFFER_SIZE +#define UART1_CONF_RX_BUFFER_SIZE 32 + +#endif /* __PROJECT_CONF_H__ */ diff --git a/examples/jn516x/tsch/uart1-test-node/uart1-test-node.c b/examples/jn516x/tsch/uart1-test-node/uart1-test-node.c new file mode 100644 index 000000000..0a4259f95 --- /dev/null +++ b/examples/jn516x/tsch/uart1-test-node/uart1-test-node.c @@ -0,0 +1,257 @@ +/* +* Copyright (c) 2015 NXP B.V. +* 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 NXP B.V. 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 NXP B.V. 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 NXP B.V. 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. +* +* Author: Theo van Daele +* +*/ +#include "net/ip/uip.h" +#include "net/linkaddr.h" +#include "rpl-tools.h" +#include "rest-engine.h" +#include "sys/ctimer.h" +#include "dev/uart-driver.h" +#include "uart1.h" +#include + +static void get_coap_rx_uart1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void event_coap_rx_uart1_handler(void); +static void put_post_tx_uart1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset); +static void string2uart1(uint8_t *c); +static int handleRxChar(uint8_t c); +static int get_ringbuf(uint8_t *c); +static int put_ringbuf(uint8_t c); + +/* COAP helpers */ +static char content[REST_MAX_CHUNK_SIZE]; +static int content_len = 0; +#define CONTENT_PRINTF(...) { if(content_len < sizeof(content)) content_len += snprintf(content+content_len, sizeof(content)-content_len, __VA_ARGS__); } + +/* Ringbuf: written to by uart isr. Size must be power of 2 */ +#define RINGBUF_SIZE 32 +#define RINGBUF_MAX_INDEX (RINGBUF_SIZE-1) +static char ringbuf[RINGBUF_SIZE]; +static int head_index = 1; /* index to write next data */ +static int tail_index = 0; /* index where last read took place */ + +/* String aligned buffer */ +#define RX_BUFFER_SIZE RINGBUF_SIZE +static uint8_t rx_buf[RX_BUFFER_SIZE+1]; +static uint8_t rx_buf_index = 0; /* index for rx_buf */ + +/*---------------------------------------------------------------------------*/ +PROCESS(start_app, "START_APP"); +PROCESS(rx_data_process, "RX_DATA"); +AUTOSTART_PROCESSES(&start_app, &rx_data_process); +/*---------------------------------------------------------------------------*/ + +/*********** COAP resources *************************************************/ +/*****************************************************************************/ +/* Observable resource and event handler to obtain terminal input from UART1 */ +/*****************************************************************************/ +EVENT_RESOURCE(resource_coap_rx_uart1, /* name */ + "obs;title=\"rx_uart1\"", /* attributes */ + get_coap_rx_uart1_handler, /* GET handler */ + NULL, /* POST handler */ + NULL, /* PUT handler */ + NULL, /* DELETE handler */ + event_coap_rx_uart1_handler); /* event handler */ +static void +get_coap_rx_uart1_handler(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + content_len = 0; + CONTENT_PRINTF("%s", rx_buf); + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + REST.set_response_payload(response, (uint8_t *)content, content_len); + } +} + +static void +event_coap_rx_uart1_handler(void) +{ + /* Registered observers are notified and will trigger the GET handler to create the response. */ + REST.notify_subscribers(&resource_coap_rx_uart1); +} + +/*****************************************************************************/ +/* GET/PUT resource to send data to terminal on UART1 */ +/*****************************************************************************/ +RESOURCE(resource_coap_tx_uart1, /* name */ + "obs;title=\"tx_uart1\"", /* attributes */ + NULL, /* GET handler */ + put_post_tx_uart1_handler, /* POST handler */ + put_post_tx_uart1_handler, /* PUT handler */ + NULL); /* DELETE handler */ + +static void +put_post_tx_uart1_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) +{ + const uint8_t *request_content = NULL; + unsigned int accept = -1; + + REST.get_header_accept(request, &accept); + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.get_request_payload(request, &request_content); + string2uart1((uint8_t *)request_content); + } +} + + +/*********** End COAP resources *********************************************/ + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(start_app, ev, data) +{ + PROCESS_BEGIN(); + static int is_coordinator = 0; + + memset(rx_buf, '\0', sizeof(rx_buf)); + /* Define process that handles data */ + process_start(&rx_data_process ,NULL); + /* Initialise UART1 */ + uart1_init(UART1_BAUD_RATE); + /* Callback received byte */ + uart1_set_input(handleRxChar); + + /* Start network stack */ + if(is_coordinator) { + uip_ipaddr_t prefix; + uip_ip6addr(&prefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + rpl_tools_init(&prefix); + } else { + rpl_tools_init(NULL); + } + printf("Starting RPL node\n"); + + rest_init_engine(); + rest_activate_resource(&resource_coap_rx_uart1, "UART1-RX"); + rest_activate_resource(&resource_coap_tx_uart1, "UART1-TX"); + + PROCESS_END(); +} + + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rx_data_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Process is polled whenever data is available from uart isr */ + uint8_t c; + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + /* Read RX ringbuffer. ASCII chars Output when LF is seen. + If overflowed, strings are skipped */ + do { + if (get_ringbuf(&c) == -1) { + break; /* No more rx char's in ringbuffer */ + } else { + if (rx_buf_index == RX_BUFFER_SIZE) { /* Skip current content if buffer full */ + rx_buf_index = 0; + } + rx_buf[rx_buf_index++] = c; + if ((c == '\n')||(c == '\r')) { + rx_buf[rx_buf_index] = '\0'; + printf("RX on UART1: %s", rx_buf); + /* Signal event to coap clients. + Demo assumes data is consumed before new data comes in */ + event_coap_rx_uart1_handler(); + rx_buf_index = 0; + } + } + } while (1); + } + PROCESS_END(); +} + +/*************************************************************************/ +/* Local test functions */ +/*************************************************************************/ +/* TX function for UART1 */ +static void +string2uart1(uint8_t *c) +{ + while (*c!= '\0') { + uart1_writeb(*c); + c++; + } +} + +/* handleRxChar runs on uart isr */ +static int +handleRxChar(uint8_t c) +{ + if (put_ringbuf(c) == -1) { + printf("Ringbuf full. Skip char\n"); + } else { + /* Send event to rx data handler */ + process_poll(&rx_data_process); + } + return 0; +} + +/* Simple ringbuffer + if tail==head, no data has been written yet on that position. So, empty buffer + is also initial state */ +static int +get_ringbuf(uint8_t *c) +{ + int return_val = 0; + + uart1_disable_interrupts(); + if (head_index != ((tail_index + 1)&RINGBUF_MAX_INDEX)) { + tail_index = ((tail_index + 1)& RINGBUF_MAX_INDEX); + *c = ringbuf[tail_index]; + } else { + return_val = -1; + } + uart1_enable_interrupts(); + return return_val; +} + +static int +put_ringbuf(uint8_t c) +{ + int return_val = 0; + + uart1_disable_interrupts(); + if (head_index != tail_index) { + ringbuf[head_index] = c; + head_index = ((head_index+1)&RINGBUF_MAX_INDEX); + } else { + return_val = -1; + } + uart1_enable_interrupts(); + return return_val; +} + diff --git a/regression-tests/22-compile-nxp-ports/Makefile b/regression-tests/22-compile-nxp-ports/Makefile index b2c529d28..9291cd846 100644 --- a/regression-tests/22-compile-nxp-ports/Makefile +++ b/regression-tests/22-compile-nxp-ports/Makefile @@ -11,6 +11,11 @@ jn516x/rpl/node/jn516x \ jn516x/rpl/coap-dongle-node/jn516x \ jn516x/rpl/coap-dr1175-node/jn516x \ jn516x/rpl/coap-dr1199-node/jn516x \ +jn516x/tsch/simple-sensor-network/node/jn516x \ +jn516x/tsch/simple-sensor-network/rpl-border-router/jn516x \ +jn516x/tsch/tx-power-verification/node/jn516x \ +jn516x/tsch/tx-power-verification/rpl-border-router/jn516x \ +jn516x/tsch/uart1-test-node/jn516x \ ipv6/rpl-tsch/jn516x \ ipv6/rpl-tsch/jn516x:MAKE_WITH_ORCHESTRA=1 \ ipv6/rpl-tsch/jn516x:MAKE_WITH_SECURITY=1