Add examples for NXP JN516x using TSCH

This commit is contained in:
Theo van Daele 2015-12-17 13:29:42 +01:00
parent af35e04ad7
commit 654bb913f0
31 changed files with 2657 additions and 1 deletions

View file

@ -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.

View file

@ -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 += rich.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

View file

@ -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

View file

@ -0,0 +1,290 @@
/*
* 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 <theo.van.daele@nxp.com>
*
*/
#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 "rich.h"
#include "node-id.h"
#include "waveform.h"
#include "leds.h"
#include "net/ip/uiplib.h"
#include "net/ip/uip-udp-packet.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 void print_network_status(void);
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
print_network_status(void)
{
int i;
uint8_t state;
uip_ds6_defrt_t *default_route;
uip_ds6_route_t *route;
printf("--- Network status ---\n");
/* Our IPv6 addresses */
printf("- 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 */
printf("- Default route:\n");
default_route = uip_ds6_defrt_lookup(uip_ds6_defrt_choose());
if(default_route != NULL) {
printf("-- ");
uip_debug_ipaddr_print(&default_route->ipaddr);;
printf(" (lifetime: %lu seconds)\n", (unsigned long)default_route->lifetime.interval);
} else {
printf("-- None\n");
}
/* Our routing entries */
printf("- Routing entries (%u in total):\n", uip_ds6_route_num_routes());
route = uip_ds6_route_head();
while(route != NULL) {
printf("-- ");
uip_debug_ipaddr_print(&route->ipaddr);
printf(" via ");
uip_debug_ipaddr_print(uip_ds6_route_nexthop(route));
printf(" (lifetime: %lu seconds)\n", (unsigned long)route->state.lifetime);
route = uip_ds6_route_next(route);
}
printf("----------------------\n");
}
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, "RICH 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);
rich_init(&prefix);
} else {
rich_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();
}

View file

@ -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 <theo.van.daele@nxp.com>
*
*/
#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__ */

View file

@ -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 <theo.van.daele@nxp.com>
*
*/
/* 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
};

View file

@ -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 += rich.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)

View file

@ -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.

View file

@ -0,0 +1,178 @@
/*
* 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 <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#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 "rich.h"
#include "net/netstack.h"
#include "dev/slip.h"
#include "rich.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#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);
/*---------------------------------------------------------------------------*/
static 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");
}
/*---------------------------------------------------------------------------*/
void
request_prefix(void)
{
/* mess up uip_buf with a dirty request... */
uip_buf[0] = '?';
uip_buf[1] = 'P';
// uip_buf[2] = '\n';
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");
rich_init(&prefix);
etimer_set(&et, CLOCK_SECOND * 60);
while(1) {
print_network_status();
PROCESS_YIELD_UNTIL(etimer_expired(&et));
etimer_reset(&et);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -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_ */

View file

@ -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 <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
* Joel Hoglund <joel@sics.se>
* Nicolas Tsiftes <nvt@sics.se>
*/
#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 <string.h>
#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
};
/*---------------------------------------------------------------------------*/

View file

@ -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 <theo.van.daele@nxp.com>
#
#
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)