Merge branch 'develop' into fix/rpl-urgent-probing
This commit is contained in:
commit
1963c43fad
@ -57,8 +57,6 @@
|
||||
typedef uint32_t clock_time_t;
|
||||
typedef uint32_t uip_stats_t;
|
||||
|
||||
typedef uint32_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b)))
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
|
@ -79,6 +79,9 @@ typedef long off_t;
|
||||
/* Our clock resolution, this is the same as Unix HZ. */
|
||||
#define CLOCK_CONF_SECOND 128UL
|
||||
|
||||
/* Use 16-bit rtimer (default in Contiki-NG is 32) */
|
||||
#define RTIMER_CONF_CLOCK_SIZE 2
|
||||
|
||||
typedef int spl_t;
|
||||
spl_t splhigh_(void);
|
||||
|
||||
|
@ -42,11 +42,7 @@
|
||||
|
||||
#include "sys/rtimer.h"
|
||||
|
||||
#ifdef RTIMER_CONF_SECOND
|
||||
#define RTIMER_ARCH_SECOND RTIMER_CONF_SECOND
|
||||
#else
|
||||
#define RTIMER_ARCH_SECOND (4096U*8)
|
||||
#endif
|
||||
|
||||
/* Do the math in 32bits to save precision.
|
||||
* Round to nearest integer rather than truncate. */
|
||||
|
@ -113,8 +113,9 @@ typedef unsigned short uip_stats_t;
|
||||
|
||||
#define CLOCK_CONF_SECOND 1000L
|
||||
typedef unsigned long clock_time_t;
|
||||
typedef uint64_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a,b) ((int64_t)((a)-(b)))
|
||||
|
||||
/* Use 64-bit rtimer (default in Contiki-NG is 32) */
|
||||
#define RTIMER_CONF_CLOCK_SIZE 8
|
||||
|
||||
#define RADIO_DELAY_BEFORE_TX 0
|
||||
#define RADIO_DELAY_BEFORE_RX 0
|
||||
|
@ -43,19 +43,15 @@
|
||||
|
||||
#include "sys/rtimer.h"
|
||||
|
||||
#ifdef RTIMER_CONF_SECOND
|
||||
# define RTIMER_ARCH_SECOND RTIMER_CONF_SECOND
|
||||
#else
|
||||
#if RTIMER_USE_32KHZ
|
||||
# if JN516X_EXTERNAL_CRYSTAL_OSCILLATOR
|
||||
# define RTIMER_ARCH_SECOND 32768
|
||||
# else
|
||||
# define RTIMER_ARCH_SECOND 32000
|
||||
#if JN516X_EXTERNAL_CRYSTAL_OSCILLATOR
|
||||
#define RTIMER_ARCH_SECOND 32768
|
||||
#else
|
||||
#define RTIMER_ARCH_SECOND 32000
|
||||
#endif
|
||||
#else
|
||||
/* 32MHz CPU clock => 16MHz timer */
|
||||
# define RTIMER_ARCH_SECOND (F_CPU / 2)
|
||||
#endif
|
||||
#define RTIMER_ARCH_SECOND (F_CPU / 2)
|
||||
#endif
|
||||
|
||||
#if RTIMER_USE_32KHZ
|
||||
|
@ -79,10 +79,6 @@
|
||||
#define JN516X_EXTERNAL_CRYSTAL_OSCILLATOR (RTIMER_USE_32KHZ || JN516X_SLEEP_ENABLED)
|
||||
#endif /* JN516X_EXTERNAL_CRYSTAL_OSCILLATOR */
|
||||
|
||||
/* Core rtimer.h defaults to 16 bit timer unless RTIMER_CLOCK_DIFF is defined */
|
||||
typedef uint32_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b)))
|
||||
|
||||
/* 8ms timer tick */
|
||||
#define CLOCK_CONF_SECOND 125
|
||||
|
||||
|
@ -72,7 +72,7 @@ dht22_read(void)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t j = 0;
|
||||
uint8_t last_state;
|
||||
uint8_t last_state = 0xFF;
|
||||
uint8_t counter = 0;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
@ -95,7 +95,6 @@ dht22_read(void)
|
||||
* if the line is high between 70-74us the bit sent will be "1" (one).
|
||||
*/
|
||||
GPIO_SET_INPUT(DHT22_PORT_BASE, DHT22_PIN_MASK);
|
||||
last_state = GPIO_READ_PIN(DHT22_PORT_BASE, DHT22_PIN_MASK);
|
||||
|
||||
for(i = 0; i < DHT22_MAX_TIMMING; i++) {
|
||||
counter = 0;
|
||||
@ -208,8 +207,8 @@ value(int type)
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
dht22_read_all(int *temperature, int *humidity)
|
||||
int16_t
|
||||
dht22_read_all(int16_t *temperature, int16_t *humidity)
|
||||
{
|
||||
if((temperature == NULL) || (humidity == NULL)) {
|
||||
PRINTF("DHT22: Invalid arguments\n");
|
||||
|
@ -90,7 +90,7 @@
|
||||
#define DHT22_COUNT 8 /**< Minimum ticks to detect a "1" bit */
|
||||
#define DHT22_MAX_TIMMING 85 /**< Maximum ticks in a single operation */
|
||||
#define DHT22_READING_DELAY 1 /**< 1 us */
|
||||
#define DHT22_READY_TIME 20 /**< 40 us */
|
||||
#define DHT22_READY_TIME 40 /**< 40 us */
|
||||
#define DHT22_START_TIME (RTIMER_SECOND / 50) /**< 20 ms */
|
||||
#define DHT22_AWAKE_TIME (RTIMER_SECOND / 4) /**< 250 ms */
|
||||
/** @} */
|
||||
@ -99,7 +99,7 @@
|
||||
* \name DHT22 auxiliary functions
|
||||
* @{
|
||||
*/
|
||||
int dht22_read_all(int *temperature, int *humidity);
|
||||
int16_t dht22_read_all(int16_t *temperature, int16_t *humidity);
|
||||
/** @} */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#define DHT22_SENSOR "DHT22 sensor"
|
||||
|
@ -46,10 +46,21 @@ AUTOSTART_PROCESSES(&hello_world_process);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(hello_world_process, ev, data)
|
||||
{
|
||||
static struct etimer timer;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
printf("Hello, world\n");
|
||||
|
||||
/* Setup a periodic timer that expires after 10 seconds. */
|
||||
etimer_set(&timer, CLOCK_SECOND * 10);
|
||||
|
||||
while(1) {
|
||||
printf("Hello, world\n");
|
||||
|
||||
/* Wait for the periodic timer to expire and then restart the timer. */
|
||||
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
|
||||
etimer_reset(&timer);
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -12,16 +12,3 @@ MODULES += os/services/ipso-objects
|
||||
|
||||
CONTIKI=../..
|
||||
include $(CONTIKI)/Makefile.include
|
||||
|
||||
# border router rules
|
||||
$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c
|
||||
(cd $(CONTIKI)/tools && $(MAKE) tunslip6)
|
||||
|
||||
connect-router: $(CONTIKI)/tools/tunslip6
|
||||
sudo $(CONTIKI)/tools/tunslip6 aaaa::1/64
|
||||
|
||||
connect-router-cooja: $(CONTIKI)/tools/tunslip6
|
||||
sudo $(CONTIKI)/tools/tunslip6 -a 127.0.0.1 -p 60001 aaaa::1/64
|
||||
|
||||
connect-router-native: $(CONTIKI)/examples/native-border-router/border-router.native
|
||||
sudo $(CONTIKI)/examples/native-border-router/border-router.native -a 127.0.0.1 -p 60001 aaaa::1/64
|
||||
|
@ -3,8 +3,8 @@ LWM2M with IPSO Objects Example
|
||||
|
||||
This is an OMA LWM2M example implementing IPSO Objects.
|
||||
It can connect to a Leshan server out-of-the-box.
|
||||
Important configuration paramters:
|
||||
* `LWM2M_SERVER_ADDRESS`: the address of the server to register to (or bosstrap from)
|
||||
Important configuration parameters:
|
||||
* `LWM2M_SERVER_ADDRESS`: the address of the server to register to (or bootstrap from)
|
||||
* `REGISTER_WITH_LWM2M_BOOTSTRAP_SERVER`: set to bootstrap via `LWM2M_SERVER_ADDRESS` and then obtain the registration server address
|
||||
|
||||
A tutorial for setting up this example is provided on the wiki.
|
||||
|
@ -38,19 +38,23 @@
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "net/netstack.h"
|
||||
#include "net/routing/routing.h"
|
||||
#include "coap-constants.h"
|
||||
#include "coap-engine.h"
|
||||
#include "coap-transport.h"
|
||||
#include "coap-blocking-api.h"
|
||||
#include "lwm2m-engine.h"
|
||||
#include "lwm2m-tlv.h"
|
||||
#include "dev/serial-line.h"
|
||||
#include "serial-protocol.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
|
||||
#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT)
|
||||
#define REMOTE_PORT UIP_HTONS(COAP_DEFAULT_PORT)
|
||||
|
||||
#define EVENT_RUN_NOW 0
|
||||
|
||||
#define URL_WELL_KNOWN ".well-known/core"
|
||||
#define URL_DEVICE_MODEL "/3/0/1"
|
||||
@ -63,8 +67,8 @@
|
||||
#define NODE_HAS_TYPE (1 << 0)
|
||||
|
||||
struct node {
|
||||
uip_ipaddr_t ipaddr;
|
||||
char type[32];
|
||||
coap_endpoint_t endpoint;
|
||||
char type[64];
|
||||
uint8_t flags;
|
||||
uint8_t retries;
|
||||
};
|
||||
@ -86,13 +90,15 @@ add_node(const uip_ipaddr_t *addr)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < node_count; i++) {
|
||||
if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) {
|
||||
if(uip_ipaddr_cmp(&nodes[i].endpoint.ipaddr, addr)) {
|
||||
/* Node already added */
|
||||
return &nodes[i];
|
||||
}
|
||||
}
|
||||
if(node_count < MAX_NODES) {
|
||||
uip_ipaddr_copy(&nodes[node_count].ipaddr, addr);
|
||||
memset(&nodes[node_count].endpoint, 0, sizeof(coap_endpoint_t));
|
||||
uip_ipaddr_copy(&nodes[node_count].endpoint.ipaddr, addr);
|
||||
nodes[node_count].endpoint.port = REMOTE_PORT;
|
||||
return &nodes[node_count++];
|
||||
}
|
||||
return NULL;
|
||||
@ -107,13 +113,13 @@ set_value(const uip_ipaddr_t *addr, char *uri, char *value)
|
||||
printf(" URI: %s Value: %s\n", uri, value);
|
||||
|
||||
for(i = 0; i < node_count; i++) {
|
||||
if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) {
|
||||
if(uip_ipaddr_cmp(&nodes[i].endpoint.ipaddr, addr)) {
|
||||
/* setup command */
|
||||
current_target = &nodes[i];
|
||||
current_request = COAP_PUT;
|
||||
strncpy(current_uri, uri, sizeof(current_uri) - 1);
|
||||
strncpy(current_value, value, sizeof(current_value) - 1);
|
||||
process_poll(&router_process);
|
||||
process_post(&router_process, EVENT_RUN_NOW, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -128,13 +134,13 @@ get_value(const uip_ipaddr_t *addr, char *uri)
|
||||
printf(" URI: %s\n", uri);
|
||||
|
||||
for(i = 0; i < node_count; i++) {
|
||||
if(uip_ipaddr_cmp(&nodes[i].ipaddr, addr)) {
|
||||
if(uip_ipaddr_cmp(&nodes[i].endpoint.ipaddr, addr)) {
|
||||
/* setup command */
|
||||
current_target = &nodes[i];
|
||||
current_request = COAP_GET;
|
||||
strncpy(current_uri, uri, sizeof(current_uri) - 1);
|
||||
current_value[0] = 0;
|
||||
process_poll(&router_process);
|
||||
process_post(&router_process, EVENT_RUN_NOW, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -151,7 +157,7 @@ print_node_list(void)
|
||||
printf(";");
|
||||
}
|
||||
printf("%s,", nodes[i].type);
|
||||
uip_debug_ipaddr_print(&nodes[i].ipaddr);
|
||||
uip_debug_ipaddr_print(&nodes[i].endpoint.ipaddr);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
@ -162,7 +168,7 @@ print_node_list(void)
|
||||
* handle responses.
|
||||
*/
|
||||
static void
|
||||
client_chunk_handler(void *response)
|
||||
client_chunk_handler(coap_message_t *response)
|
||||
{
|
||||
const uint8_t *chunk;
|
||||
unsigned int format;
|
||||
@ -172,7 +178,9 @@ client_chunk_handler(void *response)
|
||||
/* if(len > 0) { */
|
||||
/* printf("|%.*s (%d,%d)", len, (char *)chunk, len, format); */
|
||||
/* } */
|
||||
if(current_target != NULL && fetching_type) {
|
||||
if(response->code >= BAD_REQUEST_4_00) {
|
||||
PRINTF("\nReceived error %u: %.*s\n", response->code, len, (char *)chunk);
|
||||
} else if(current_target != NULL && fetching_type) {
|
||||
if(len > sizeof(current_target->type) - 1) {
|
||||
len = sizeof(current_target->type) - 1;
|
||||
}
|
||||
@ -181,7 +189,7 @@ client_chunk_handler(void *response)
|
||||
current_target->flags |= NODE_HAS_TYPE;
|
||||
|
||||
PRINTF("\nNODE ");
|
||||
PRINT6ADDR(¤t_target->ipaddr);
|
||||
PRINT6ADDR(¤t_target->endpoint.ipaddr);
|
||||
PRINTF(" HAS TYPE %s\n", current_target->type);
|
||||
} else {
|
||||
/* otherwise update the current value */
|
||||
@ -193,7 +201,9 @@ client_chunk_handler(void *response)
|
||||
/* tlv.type, tlv.length, tlv.id, tlv.value[0]); */
|
||||
|
||||
int value = lwm2m_tlv_get_int32(&tlv);
|
||||
snprintf(current_value, sizeof(current_value), "%d", value);
|
||||
snprintf(current_value, sizeof(current_value) - 1, "%d", value);
|
||||
} else {
|
||||
PRINTF("Failed to parse LWM2M TLV\n");
|
||||
}
|
||||
} else {
|
||||
if(len > sizeof(current_value) - 1) {
|
||||
@ -205,69 +215,81 @@ client_chunk_handler(void *response)
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
setup_network(void)
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
static bool
|
||||
check_rpl_routes(void)
|
||||
{
|
||||
uip_ipaddr_t ipaddr;
|
||||
struct uip_ds6_addr *root_if;
|
||||
rpl_dag_t *dag;
|
||||
int i;
|
||||
uint8_t state;
|
||||
uip_sr_node_t *link;
|
||||
uip_ipaddr_t child_ipaddr;
|
||||
uip_ipaddr_t parent_ipaddr;
|
||||
|
||||
#if UIP_CONF_ROUTER
|
||||
/**
|
||||
* The choice of server address determines its 6LoWPAN header compression.
|
||||
* Obviously the choice made here must also be selected in udp-client.c.
|
||||
*
|
||||
* For correct Wireshark decoding using a sniffer, add the /64 prefix to the 6LowPAN protocol preferences,
|
||||
* e.g. set Context 0 to fd00::. At present Wireshark copies Context/128 and then overwrites it.
|
||||
* (Setting Context 0 to fd00::1111:2222:3333:4444 will report a 16 bit compressed address of fd00::1111:22ff:fe33:xxxx)
|
||||
* Note Wireshark's IPCMV6 checksum verification depends on the correct uncompressed addresses.
|
||||
*/
|
||||
#if 0
|
||||
/* Mode 1 - 64 bits inline */
|
||||
uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 1);
|
||||
#elif 1
|
||||
/* Mode 2 - 16 bits inline */
|
||||
uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0x00ff, 0xfe00, 1);
|
||||
#else
|
||||
/* Mode 3 - derived from link local (MAC) address */
|
||||
uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);
|
||||
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
|
||||
#endif
|
||||
/* Our routing links */
|
||||
for(link = uip_sr_node_head(); link != NULL; link = uip_sr_node_next(link)) {
|
||||
NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link);
|
||||
|
||||
NETSTACK_ROUTING.root_set_prefix(&ipaddr, &ipaddr);
|
||||
NETSTACK_ROUTING.root_start();
|
||||
#endif /* UIP_CONF_ROUTER */
|
||||
|
||||
PRINTF("IPv6 addresses: ");
|
||||
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
|
||||
state = uip_ds6_if.addr_list[i].state;
|
||||
if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) {
|
||||
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
|
||||
PRINTF("\n");
|
||||
/* hack to make address "final" */
|
||||
if (state == ADDR_TENTATIVE) {
|
||||
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
|
||||
}
|
||||
if(link->parent == NULL) {
|
||||
/* Igore the DAG root */
|
||||
continue;
|
||||
}
|
||||
|
||||
current_target = add_node(&child_ipaddr);
|
||||
if(current_target == NULL ||
|
||||
(current_target->flags & NODE_HAS_TYPE) != 0 ||
|
||||
current_target->retries > 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent);
|
||||
PRINTF(" ");
|
||||
PRINT6ADDR(&child_ipaddr);
|
||||
PRINTF(" -> ");
|
||||
PRINT6ADDR(&parent_ipaddr);
|
||||
PRINTF("\n");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if (UIP_MAX_ROUTES != 0)
|
||||
static bool
|
||||
check_routes(void)
|
||||
{
|
||||
uip_ds6_route_t *r;
|
||||
|
||||
for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) {
|
||||
current_target = add_node(&r->ipaddr);
|
||||
if(current_target == NULL ||
|
||||
(current_target->flags & NODE_HAS_TYPE) != 0 ||
|
||||
current_target->retries > 5) {
|
||||
continue;
|
||||
}
|
||||
PRINTF(" ");
|
||||
PRINT6ADDR(&r->ipaddr);
|
||||
PRINTF(" -> ");
|
||||
nexthop = uip_ds6_route_nexthop(r);
|
||||
if(nexthop != NULL) {
|
||||
PRINT6ADDR(nexthop);
|
||||
} else {
|
||||
PRINTF("-");
|
||||
}
|
||||
PRINTF("\n");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif /* (UIP_MAX_ROUTES != 0) */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(router_process, ev, data)
|
||||
{
|
||||
/* This way the message can be treated as pointer as usual. */
|
||||
static coap_message_t request[1];
|
||||
static struct etimer timer;
|
||||
uip_ds6_route_t *r;
|
||||
uip_ipaddr_t *nexthop;
|
||||
int n;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
||||
PROCESS_PAUSE();
|
||||
|
||||
setup_network();
|
||||
/* Initialize DAG root */
|
||||
NETSTACK_ROUTING.root_start();
|
||||
|
||||
while(1) {
|
||||
etimer_set(&timer, CLOCK_SECOND * 5);
|
||||
@ -280,28 +302,15 @@ PROCESS_THREAD(router_process, ev, data)
|
||||
|
||||
if(etimer_expired(&timer)) {
|
||||
current_target = NULL;
|
||||
n = 0;
|
||||
for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) {
|
||||
current_target = add_node(&r->ipaddr);
|
||||
if(current_target == NULL ||
|
||||
(current_target->flags & NODE_HAS_TYPE) != 0 ||
|
||||
current_target->retries > 5) {
|
||||
continue;
|
||||
}
|
||||
PRINTF(" ");
|
||||
PRINT6ADDR(&r->ipaddr);
|
||||
PRINTF(" -> ");
|
||||
nexthop = uip_ds6_route_nexthop(r);
|
||||
if(nexthop != NULL) {
|
||||
PRINT6ADDR(nexthop);
|
||||
PRINTF("\n");
|
||||
} else {
|
||||
PRINTF("-");
|
||||
}
|
||||
PRINTF("\n");
|
||||
n++;
|
||||
break;
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
check_rpl_routes();
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
|
||||
#if (UIP_MAX_ROUTES != 0)
|
||||
if(current_target == NULL) {
|
||||
check_routes();
|
||||
}
|
||||
#endif /* (UIP_MAX_ROUTES != 0) */
|
||||
}
|
||||
|
||||
/* This is a node type discovery */
|
||||
@ -316,15 +325,15 @@ PROCESS_THREAD(router_process, ev, data)
|
||||
current_target->retries++;
|
||||
|
||||
PRINTF("CoAP request to [");
|
||||
PRINT6ADDR(¤t_target->ipaddr);
|
||||
PRINTF("]:%u (%u tx)\n", UIP_HTONS(REMOTE_PORT),
|
||||
PRINT6ADDR(¤t_target->endpoint.ipaddr);
|
||||
PRINTF("]:%u (%u tx)\n", UIP_HTONS(current_target->endpoint.port),
|
||||
current_target->retries);
|
||||
|
||||
fetching_type = 1;
|
||||
COAP_BLOCKING_REQUEST(¤t_target->ipaddr, REMOTE_PORT, request,
|
||||
COAP_BLOCKING_REQUEST(¤t_target->endpoint, request,
|
||||
client_chunk_handler);
|
||||
fetching_type = 0;
|
||||
strncpy(current_uri, URL_LIGHT_CONTROL, sizeof(current_uri));
|
||||
strncpy(current_uri, URL_LIGHT_CONTROL, sizeof(current_uri) - 1);
|
||||
printf("\n--Done--\n");
|
||||
}
|
||||
|
||||
@ -341,10 +350,11 @@ PROCESS_THREAD(router_process, ev, data)
|
||||
}
|
||||
|
||||
PRINTF("CoAP request to [");
|
||||
PRINT6ADDR(¤t_target->ipaddr);
|
||||
PRINTF("]:%u %s\n", UIP_HTONS(REMOTE_PORT), current_uri);
|
||||
PRINT6ADDR(¤t_target->endpoint.ipaddr);
|
||||
PRINTF("]:%u %s\n", UIP_HTONS(current_target->endpoint.port),
|
||||
current_uri);
|
||||
|
||||
COAP_BLOCKING_REQUEST(¤t_target->ipaddr, REMOTE_PORT, request,
|
||||
COAP_BLOCKING_REQUEST(¤t_target->endpoint, request,
|
||||
client_chunk_handler);
|
||||
|
||||
/* print out result of command */
|
||||
@ -353,13 +363,12 @@ PROCESS_THREAD(router_process, ev, data)
|
||||
} else {
|
||||
printf("g ");
|
||||
}
|
||||
uip_debug_ipaddr_print(¤t_target->ipaddr);
|
||||
uip_debug_ipaddr_print(¤t_target->endpoint.ipaddr);
|
||||
printf(" %s %s\n", current_uri, current_value);
|
||||
|
||||
current_target = NULL;
|
||||
current_uri[0] = 0;
|
||||
current_value[0] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ find_next_sep(const char *str, char sep, int pos)
|
||||
/*
|
||||
* l - list all discovered devices
|
||||
* s - set <IP> <URI> <value>
|
||||
* d - get <IP> <URI>
|
||||
* g - get <IP> <URI>
|
||||
*/
|
||||
void
|
||||
serial_protocol_input(char *data)
|
||||
@ -119,8 +119,12 @@ serial_protocol_input(char *data)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '\0':
|
||||
/* Ignore empty lines */
|
||||
break;
|
||||
default:
|
||||
printf("Unknown command\n");
|
||||
}
|
||||
printf("> ");
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -13,25 +13,34 @@ The demo will give some visual feedback with a LED (configurable):
|
||||
This example is known to work with all platforms that support the new button
|
||||
API.
|
||||
|
||||
This example can operate in two modes: A default mode to be used with the
|
||||
mosquitto MQTT broker and a second mode to be used with the IBM Watson IoT
|
||||
platform.
|
||||
|
||||
To enable Watson mode, define `MQTT_CLIENT_CONF_WITH_IBM_WATSON` as 1 in the
|
||||
example's `project-conf.h`.
|
||||
|
||||
Publishing
|
||||
----------
|
||||
By default the example will attempt to publish readings to an MQTT broker
|
||||
running on the IPv6 address specified as `MQTT_DEMO_BROKER_IP_ADDR` in
|
||||
running on the IPv6 address specified as `MQTT_CLIENT_CONF_BROKER_IP_ADDR` in
|
||||
`project-conf.h`. This functionality was tested successfully with
|
||||
[mosquitto](http://mosquitto.org/).
|
||||
[mosquitto](http://mosquitto.org/). This define will be ignored in IBM Watson
|
||||
mode.
|
||||
|
||||
The publish messages include sensor readings but also some other information,
|
||||
such as device uptime in seconds and a message sequence number. The demo will
|
||||
publish to topic `iot-2/evt/status/fmt/json`. The device will connect using
|
||||
client-id `d:contiki-ng:mqtt-client:<device-id>`, where `<device-id>` gets
|
||||
constructed from the device's IEEE address.
|
||||
client-id `d:<org-id>:mqtt-client:<device-id>`, where `<device-id>` gets
|
||||
constructed from the device's IEEE address. `<org-id>` can be controlled
|
||||
through the `MQTT_CLIENT_CONF_ORG_ID` define.
|
||||
|
||||
Subscribing
|
||||
-----------
|
||||
You can also subscribe to topics and receive commands, but this will only
|
||||
work if you use "Org ID" != 'quickstart'. To achieve this, you will need to
|
||||
change 'Org ID' (`DEFAULT_ORG_ID`). In this scenario, the device will subscribe
|
||||
to:
|
||||
change `MQTT_CLIENT_CONF_ORG_ID` in `project-conf.h`. In this scenario, the
|
||||
device will subscribe to:
|
||||
|
||||
`iot-2/cmd/+/fmt/json`
|
||||
|
||||
@ -53,13 +62,18 @@ messages, outgoing publish messages use proper json payload.
|
||||
IBM Quickstart Service
|
||||
----------------------
|
||||
It is also possible to publish to IBM's quickstart service. To do so, you need
|
||||
to undefine `MQTT_DEMO_BROKER_IP_ADDR`.
|
||||
to enable this mode by setting `MQTT_CLIENT_CONF_WITH_IBM_WATSON` to 1 in
|
||||
`project-conf.h`.
|
||||
|
||||
The device will then try to connect to IBM's quickstart over NAT64, so you will
|
||||
need a NAT64 gateway in your network to make this work. A guide on how to
|
||||
setup NAT64 is out of scope here.
|
||||
setup NAT64 is out of scope here, but you can find one in the
|
||||
[Contiki-NG wiki](https://github.com/contiki-ng/contiki-ng/wiki/NAT64-for-Contiki%E2%80%90NG).
|
||||
|
||||
If you want to use IBM's cloud service with a registered device, change
|
||||
'Org ID' (`DEFAULT_ORG_ID`) and provide the 'Auth Token' (`DEFAULT_AUTH_TOKEN`),
|
||||
which acts as a 'password', but bear in mind that it gets transported in clear
|
||||
text.
|
||||
If you want to use IBM's cloud service with a registered device, you will need
|
||||
to set `MQTT_CLIENT_CONF_ORG_ID` and then also to provide the 'Auth Token'
|
||||
(`MQTT_CLIENT_CONF_AUTH_TOKEN`), which acts as a 'password'. You will also
|
||||
need to configure your Organisation / Registered device on Watson such that
|
||||
TLS is optional.
|
||||
|
||||
Note: The token will be transported in cleartext.
|
||||
|
@ -49,22 +49,61 @@
|
||||
#define LOG_MODULE "mqtt-client"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* IBM server: messaging.quickstart.internetofthings.ibmcloud.com
|
||||
* (184.172.124.189) mapped in an NAT64 (prefix 64:ff9b::/96) IPv6 address
|
||||
* Note: If not able to connect; lookup the IP address again as it may change.
|
||||
*
|
||||
* Alternatively, publish to a local MQTT broker (e.g. mosquitto) running on
|
||||
* the node that hosts your border router
|
||||
*/
|
||||
#ifdef MQTT_CLIENT_CONF_BROKER_IP_ADDR
|
||||
static const char *broker_ip = MQTT_CLIENT_CONF_BROKER_IP_ADDR;
|
||||
#define DEFAULT_ORG_ID "contiki-ng"
|
||||
/* Controls whether the example will work in IBM Watson IoT platform mode */
|
||||
#ifdef MQTT_CLIENT_CONF_WITH_IBM_WATSON
|
||||
#define MQTT_CLIENT_WITH_IBM_WATSON MQTT_CLIENT_CONF_WITH_IBM_WATSON
|
||||
#else
|
||||
static const char *broker_ip = "0064:ff9b:0000:0000:0000:0000:b8ac:7cbd";
|
||||
#define DEFAULT_ORG_ID "quickstart"
|
||||
#define MQTT_CLIENT_WITH_IBM_WATSON 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* MQTT broker address. Ignored in Watson mode */
|
||||
#ifdef MQTT_CLIENT_CONF_BROKER_IP_ADDR
|
||||
#define MQTT_CLIENT_BROKER_IP_ADDR MQTT_CLIENT_CONF_BROKER_IP_ADDR
|
||||
#else
|
||||
#define MQTT_CLIENT_BROKER_IP_ADDR "fd00::1"
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* MQTT Org ID.
|
||||
*
|
||||
* If it equals "quickstart", the client will connect without authentication.
|
||||
* In all other cases, the client will connect with authentication mode.
|
||||
*
|
||||
* In Watson mode, the username will be "use-token-auth". In non-Watson mode
|
||||
* the username will be MQTT_CLIENT_USERNAME.
|
||||
*
|
||||
* In all cases, the password will be MQTT_CLIENT_AUTH_TOKEN.
|
||||
*/
|
||||
#ifdef MQTT_CLIENT_CONF_ORG_ID
|
||||
#define MQTT_CLIENT_ORG_ID MQTT_CLIENT_CONF_ORG_ID
|
||||
#else
|
||||
#define MQTT_CLIENT_ORG_ID "quickstart"
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* MQTT token */
|
||||
#ifdef MQTT_CLIENT_CONF_AUTH_TOKEN
|
||||
#define MQTT_CLIENT_AUTH_TOKEN MQTT_CLIENT_CONF_AUTH_TOKEN
|
||||
#else
|
||||
#define MQTT_CLIENT_AUTH_TOKEN "AUTHTOKEN"
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if MQTT_CLIENT_WITH_IBM_WATSON
|
||||
/* With IBM Watson support */
|
||||
static const char *broker_ip = "0064:ff9b:0000:0000:0000:0000:b8ac:7cbd";
|
||||
#define MQTT_CLIENT_USERNAME "use-token-auth"
|
||||
|
||||
#else /* MQTT_CLIENT_WITH_IBM_WATSON */
|
||||
/* Without IBM Watson support. To be used with other brokers, e.g. Mosquitto */
|
||||
static const char *broker_ip = MQTT_CLIENT_BROKER_IP_ADDR;
|
||||
|
||||
#ifdef MQTT_CLIENT_CONF_USERNAME
|
||||
#define MQTT_CLIENT_USERNAME MQTT_CLIENT_CONF_USERNAME
|
||||
#else
|
||||
#define MQTT_CLIENT_USERNAME "use-token-auth"
|
||||
#endif
|
||||
|
||||
#endif /* MQTT_CLIENT_WITH_IBM_WATSON */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef MQTT_CLIENT_CONF_STATUS_LED
|
||||
#define MQTT_CLIENT_STATUS_LED MQTT_CLIENT_CONF_STATUS_LED
|
||||
#else
|
||||
@ -122,18 +161,12 @@ static uint8_t state;
|
||||
#define CONFIG_CMD_TYPE_LEN 8
|
||||
#define CONFIG_IP_ADDR_STR_LEN 64
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define RSSI_MEASURE_INTERVAL_MAX 86400 /* secs: 1 day */
|
||||
#define RSSI_MEASURE_INTERVAL_MIN 5 /* secs */
|
||||
#define PUBLISH_INTERVAL_MAX 86400 /* secs: 1 day */
|
||||
#define PUBLISH_INTERVAL_MIN 5 /* secs */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* A timeout used when waiting to connect to a network */
|
||||
#define NET_CONNECT_PERIODIC (CLOCK_SECOND >> 2)
|
||||
#define NO_NET_LED_DURATION (NET_CONNECT_PERIODIC >> 1)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Default configuration values */
|
||||
#define DEFAULT_TYPE_ID "mqtt-client"
|
||||
#define DEFAULT_AUTH_TOKEN "AUTHZ"
|
||||
#define DEFAULT_EVENT_TYPE_ID "status"
|
||||
#define DEFAULT_SUBSCRIBE_CMD_TYPE "+"
|
||||
#define DEFAULT_BROKER_PORT 1883
|
||||
@ -423,9 +456,10 @@ init_config()
|
||||
/* Populate configuration with default values */
|
||||
memset(&conf, 0, sizeof(mqtt_client_config_t));
|
||||
|
||||
memcpy(conf.org_id, DEFAULT_ORG_ID, strlen(DEFAULT_ORG_ID));
|
||||
memcpy(conf.org_id, MQTT_CLIENT_ORG_ID, strlen(MQTT_CLIENT_ORG_ID));
|
||||
memcpy(conf.type_id, DEFAULT_TYPE_ID, strlen(DEFAULT_TYPE_ID));
|
||||
memcpy(conf.auth_token, DEFAULT_AUTH_TOKEN, strlen(DEFAULT_AUTH_TOKEN));
|
||||
memcpy(conf.auth_token, MQTT_CLIENT_AUTH_TOKEN,
|
||||
strlen(MQTT_CLIENT_AUTH_TOKEN));
|
||||
memcpy(conf.event_type_id, DEFAULT_EVENT_TYPE_ID,
|
||||
strlen(DEFAULT_EVENT_TYPE_ID));
|
||||
memcpy(conf.broker_ip, broker_ip, strlen(broker_ip));
|
||||
@ -568,7 +602,7 @@ state_machine(void)
|
||||
state = STATE_ERROR;
|
||||
break;
|
||||
} else {
|
||||
mqtt_set_username_password(&conn, "use-token-auth",
|
||||
mqtt_set_username_password(&conn, MQTT_CLIENT_USERNAME,
|
||||
conf.auth_token);
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,40 @@
|
||||
/* Enable TCP */
|
||||
#define UIP_CONF_TCP 1
|
||||
|
||||
/* If undefined, the demo will attempt to connect to IBM's quickstart */
|
||||
/* Change to 1 to use with the IBM Watson IoT platform */
|
||||
#define MQTT_CLIENT_CONF_WITH_IBM_WATSON 0
|
||||
|
||||
/*
|
||||
* The IPv6 address of the MQTT broker to connect to.
|
||||
* Ignored if MQTT_CLIENT_CONF_WITH_IBM_WATSON is 1
|
||||
*/
|
||||
#define MQTT_CLIENT_CONF_BROKER_IP_ADDR "fd00::1"
|
||||
|
||||
/*
|
||||
* The Organisation ID.
|
||||
*
|
||||
* When in Watson mode, the example will default to Org ID "quickstart" and
|
||||
* will connect using non-authenticated mode. If you want to use registered
|
||||
* devices, set your Org ID here and then make sure you set the correct token
|
||||
* through MQTT_CLIENT_CONF_AUTH_TOKEN.
|
||||
*/
|
||||
#define MQTT_CLIENT_CONF_ORG_ID "quickstart"
|
||||
|
||||
/*
|
||||
* The MQTT username.
|
||||
*
|
||||
* Ignored in Watson mode: In this mode the username is always "use-token-auth"
|
||||
*/
|
||||
#define MQTT_CLIENT_CONF_USERNAME "mqtt-client-username"
|
||||
|
||||
/*
|
||||
* The MQTT auth token (password) used when connecting to the MQTT broker.
|
||||
*
|
||||
* Used with as well as without Watson.
|
||||
*
|
||||
* Transported in cleartext!
|
||||
*/
|
||||
#define MQTT_CLIENT_CONF_AUTH_TOKEN "AUTHTOKEN"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* PROJECT_CONF_H_ */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -54,7 +54,12 @@
|
||||
#define UIP_MCAST6_ROUTE_CONF_ROUTES 1
|
||||
|
||||
/* Code/RAM footprint savings so that things will fit on our device */
|
||||
#ifndef NETSTACK_MAX_ROUTE_ENTRIES
|
||||
#define NETSTACK_MAX_ROUTE_ENTRIES 10
|
||||
#endif
|
||||
|
||||
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
|
||||
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10
|
||||
#endif
|
||||
|
||||
#endif /* PROJECT_CONF_H_ */
|
||||
|
34
examples/multicast/srf06-cc26xx/module-macros.h
Normal file
34
examples/multicast/srf06-cc26xx/module-macros.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018, University of Bristol - http://www.bristol.ac.uk/
|
||||
* 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 copyright holder 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 COPYRIGHT HOLDER 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
|
||||
* COPYRIGHT HOLDER 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.
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Code/RAM footprint savings so that things will fit on sensortags */
|
||||
#define NETSTACK_MAX_ROUTE_ENTRIES 4
|
||||
#define NBR_TABLE_CONF_MAX_NEIGHBORS 4
|
||||
#define QUEUEBUF_CONF_NUM 4
|
@ -54,33 +54,38 @@ tab, as per the image below.
|
||||
|
||||
CoAP Server
|
||||
-----------
|
||||
For this functionality to work, you will need to install the
|
||||
[Copper (Cu)](https://addons.mozilla.org/en-US/firefox/addon/copper-270430/)
|
||||
addon to your browser.
|
||||
For this functionality to work, you will need to install a CoAP client.
|
||||
You can achieve this by following the guides on how to set up your system
|
||||
[in the wiki](https://github.com/contiki-ng/contiki-ng/wiki#setting-up-contiki-ng).
|
||||
|
||||
From the sensors tab in the 6lbr web page, click the 'coap' link in the line
|
||||
corresponding to your CC26xx device. Once the addon fires up, select
|
||||
".well-known/core" in the left pane and then hit the 'Get' button at the top.
|
||||
You should start by sending a CoAP GET request for the `.well-known/core`
|
||||
resource. If you are using libcoap's CoAP client, this can be achieved by:
|
||||
|
||||
![CoAP Resources](img/coap-resources.png)
|
||||
```
|
||||
coap-client -m get coap://[<device IPv6 address here>]/.well-known/core
|
||||
```
|
||||
|
||||
Adjust the above command to match the command line arguments of your CoAP
|
||||
client.
|
||||
|
||||
The Device will respond with a list of all available CoAP resources. This list
|
||||
will be different between the Srf and the SensorTag. The screenshot below shows
|
||||
a (partial) list of resources exported by the SensorTag CoAP server. Select
|
||||
a resource on the left pane and hit 'Get' to retrieve its value. Select
|
||||
`lt/g` and hit 'Post' to toggle the green LED, `lt/r` for the red one.
|
||||
will be different between the various CC13x0/CC26x0 boards.
|
||||
|
||||
You can also use CoAP to enable/disable BLE advertisements! Select
|
||||
`dev/ble_advd` and then hit the "Outgoing" button in the payload panel. Type in
|
||||
the desired payload, which can be:
|
||||
Send a CoAP GET request for any of those resrouces to retrieve its value.
|
||||
|
||||
Send a CoAP POST to the `lt/g` or `lt/r` to toggle the green/red LED
|
||||
respectively.
|
||||
|
||||
You can also use CoAP to enable/disable BLE advertisements! This can be done
|
||||
by sending a PUT or POST request to the `dev/ble_advd` resource. Your request
|
||||
should contain the desired payload, which can be:
|
||||
|
||||
* `mode=on|off`
|
||||
* `name=<name>`
|
||||
* `interval=<secs>`
|
||||
|
||||
or a combination of both delimited with an amp. For example, you can set as
|
||||
payload `mode=on&name=My CC26xx Device 4&interval=5`. Once you have set the
|
||||
payload, hit either the POST or PUT button.
|
||||
or a combination of the above delimited with an amp. For example, you can set
|
||||
as payload `mode=on&name=My CC26xx Device 4&interval=5`.
|
||||
|
||||
Bear in mind that you must set `name` at least once before enabling BLE
|
||||
advertisements. If you fail to do so, the RF will refuse to enter BLE mode and
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 274 KiB |
@ -33,7 +33,7 @@
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Change to match your configuration */
|
||||
#define IEEE802154_CONF_PANID 0xABCD
|
||||
#define IEEE802154_CONF_DEFAULT_CHANNEL 25
|
||||
#define IEEE802154_CONF_DEFAULT_CHANNEL 26
|
||||
#define RF_BLE_CONF_ENABLED 1
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
CONTIKI_PROJECT = test-tsl256x test-sht25 test-servo.c
|
||||
CONTIKI_PROJECT = test-tsl256x test-sht25 test-servo
|
||||
CONTIKI_PROJECT += test-bmp085-bmp180 test-motion test-rotation-sensor
|
||||
CONTIKI_PROJECT += test-grove-light-sensor test-grove-loudness-sensor
|
||||
CONTIKI_PROJECT += test-weather-meter test-grove-gyro test-lcd test-iaq
|
||||
CONTIKI_PROJECT += test-pm10-sensor test-vac-sensor test-aac-sensor
|
||||
CONTIKI_PROJECT += test-zonik test-dht22.c test-ac-dimmer.c
|
||||
CONTIKI_PROJECT += test-zonik test-dht22 test-ac-dimmer
|
||||
CONTIKI_PROJECT += test-bme280
|
||||
|
||||
CONTIKI_TARGET_SOURCEFILES += tsl256x.c sht25.c bmpx8x.c motion-sensor.c
|
||||
|
@ -187,8 +187,8 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
} else if(uip_buf[0] == '?') {
|
||||
LOG_DBG("Got request message of type %c\n", uip_buf[1]);
|
||||
} else if(data[0] == '?') {
|
||||
LOG_DBG("Got request message of type %c\n", data[1]);
|
||||
if(data[1] == 'M') {
|
||||
/* this is just a test so far... just to see if it works */
|
||||
uip_buf[0] = '!';
|
||||
@ -226,8 +226,9 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
|
||||
static void
|
||||
slip_input_callback(void)
|
||||
{
|
||||
LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]);
|
||||
if(!cmd_input(uip_buf, uip_len)) {
|
||||
LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len,
|
||||
uip_buf[UIP_LLH_LEN], uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(!cmd_input(&uip_buf[UIP_LLH_LEN], uip_len)) {
|
||||
cmd_send((uint8_t *)"EUnknown command", 16);
|
||||
}
|
||||
uip_clear_buf();
|
||||
|
@ -3,7 +3,7 @@ CONTIKI = ../../..
|
||||
MODULES += os/storage/antelope os/services/unit-test
|
||||
|
||||
# does not fit on Sky
|
||||
PLATFORMS_ONLY= cc2538
|
||||
PLATFORMS_ONLY= cc2538dk zoul
|
||||
|
||||
CONTIKI_PROJECT = shell-db
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
@ -1,6 +1,6 @@
|
||||
CONTIKI = ../../..
|
||||
|
||||
PLATFORMS_ONLY= cc2538 sky
|
||||
PLATFORMS_ONLY= cc2538dk zoul sky
|
||||
|
||||
MODULES += os/services/unit-test
|
||||
MODULES += os/storage/cfs
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-block1"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-blocking-api"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-callback-api"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/* These should go into the state struct so that we can have multiple
|
||||
|
@ -55,7 +55,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-observe-client"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
MEMB(obs_subjects_memb, coap_observee_t, COAP_MAX_OBSERVEES);
|
||||
|
@ -50,7 +50,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-observe"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-res-well-known-core"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
#define ADD_CHAR_IF_POSSIBLE(char) \
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-separate"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -52,7 +52,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-timer-default"
|
||||
#define LOG_MODULE "coap-timer"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
|
||||
PROCESS(coap_timer_process, "coap timer process");
|
||||
|
@ -50,7 +50,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "coap-transactions"
|
||||
#define LOG_MODULE "coap"
|
||||
#define LOG_LEVEL LOG_LEVEL_COAP
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Log configuration */
|
||||
#define LOG_MODULE "dtls-support"
|
||||
#define LOG_MODULE "dtls"
|
||||
#define LOG_LEVEL LOG_LEVEL_DTLS
|
||||
#include "dtls-log.h"
|
||||
#include "coap-log.h"
|
||||
|
@ -250,9 +250,11 @@ uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr)
|
||||
}
|
||||
}
|
||||
|
||||
if(n >= size - 1) {
|
||||
buf[size - 1] = '\0';
|
||||
}
|
||||
/*
|
||||
* Make sure the output string is always null-terminated.
|
||||
*/
|
||||
buf[MIN(n, size - 1)] = '\0';
|
||||
|
||||
return n;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -64,7 +64,7 @@
|
||||
/* ETX fixed point divisor. 128 is the value used by RPL (RFC 6551 and RFC 6719) */
|
||||
#define ETX_DIVISOR LINK_STATS_ETX_DIVISOR
|
||||
/* Number of Tx used to update the ETX EWMA in case of no-ACK */
|
||||
#define ETX_NOACK_PENALTY 16
|
||||
#define ETX_NOACK_PENALTY 20
|
||||
/* Initial ETX value */
|
||||
#define ETX_DEFAULT 2
|
||||
|
||||
|
@ -50,10 +50,10 @@
|
||||
#include "lib/list.h"
|
||||
#include "lib/memb.h"
|
||||
|
||||
#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64
|
||||
#if CONTIKI_TARGET_COOJA
|
||||
#include "lib/simEnvChange.h"
|
||||
#include "sys/cooja_mt.h"
|
||||
#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */
|
||||
#endif /* CONTIKI_TARGET_COOJA */
|
||||
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
@ -207,10 +207,10 @@ send_one_packet(void *ptr)
|
||||
wt = RTIMER_NOW();
|
||||
watchdog_periodic();
|
||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + CSMA_ACK_WAIT_TIME)) {
|
||||
#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64
|
||||
#if CONTIKI_TARGET_COOJA
|
||||
simProcessRunValue = 1;
|
||||
cooja_mt_yield();
|
||||
#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */
|
||||
#endif /* CONTIKI_TARGET_COOJA */
|
||||
}
|
||||
|
||||
ret = MAC_TX_NOACK;
|
||||
@ -225,10 +225,10 @@ send_one_packet(void *ptr)
|
||||
watchdog_periodic();
|
||||
while(RTIMER_CLOCK_LT(RTIMER_NOW(),
|
||||
wt + CSMA_AFTER_ACK_DETECTED_WAIT_TIME)) {
|
||||
#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64
|
||||
#if CONTIKI_TARGET_COOJA
|
||||
simProcessRunValue = 1;
|
||||
cooja_mt_yield();
|
||||
#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */
|
||||
#endif /* CONTIKI_TARGET_COOJA */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH adaptive time synchronization
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_ADAPTIVE_TIMESYNC_H__
|
||||
@ -44,15 +46,30 @@
|
||||
|
||||
/***** External Variables *****/
|
||||
|
||||
/* The neighbor last used as our time source */
|
||||
/** \brief The neighbor last used as our time source */
|
||||
extern struct tsch_neighbor *last_timesource_neighbor;
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/**
|
||||
* \brief Updates timesync information for a given neighbor
|
||||
* \param n The neighbor
|
||||
* \param time_delta_asn ASN time delta since last synchronization, i.e. number of slots elapsed
|
||||
* \param drift_correction The measured drift in ticks since last synchronization
|
||||
*/
|
||||
void tsch_timesync_update(struct tsch_neighbor *n, uint16_t time_delta_asn, int32_t drift_correction);
|
||||
|
||||
/**
|
||||
* \brief Computes time compensation for a given point in the future
|
||||
* \param delta_ticks The number of ticks in the future we want to calculate compensation for
|
||||
* \return The time compensation
|
||||
*/
|
||||
int32_t tsch_timesync_adaptive_compensate(rtimer_clock_t delta_ticks);
|
||||
|
||||
/**
|
||||
* \brief Gives the estimated clock drift w.r.t. the time source in PPM (parts per million)
|
||||
* \return The time drift in PPM
|
||||
*/
|
||||
long int tsch_adaptive_timesync_get_drift_ppm(void);
|
||||
|
||||
#endif /* __TSCH_ADAPTIVE_TIMESYNC_H__ */
|
||||
|
@ -31,16 +31,12 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH 5-Byte Absolute Slot Number (ASN) management
|
||||
* \author
|
||||
* Simon Duquennoy <simonduq@sics.se>
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_ASN_H__
|
||||
@ -48,13 +44,13 @@
|
||||
|
||||
/************ Types ***********/
|
||||
|
||||
/* The ASN is an absolute slot number over 5 bytes. */
|
||||
/** \brief The ASN is an absolute slot number over 5 bytes. */
|
||||
struct tsch_asn_t {
|
||||
uint32_t ls4b; /* least significant 4 bytes */
|
||||
uint8_t ms1b; /* most significant 1 byte */
|
||||
};
|
||||
|
||||
/* For quick modulo operation on ASN */
|
||||
/** \brief For quick modulo operation on ASN */
|
||||
struct tsch_asn_divisor_t {
|
||||
uint16_t val; /* Divisor value */
|
||||
uint16_t asn_ms1b_remainder; /* Remainder of the operation 0x100000000 / val */
|
||||
@ -62,37 +58,37 @@ struct tsch_asn_divisor_t {
|
||||
|
||||
/************ Macros **********/
|
||||
|
||||
/* Initialize ASN */
|
||||
/** \brief Initialize ASN */
|
||||
#define TSCH_ASN_INIT(asn, ms1b_, ls4b_) do { \
|
||||
(asn).ms1b = (ms1b_); \
|
||||
(asn).ls4b = (ls4b_); \
|
||||
} while(0);
|
||||
|
||||
/* Increment an ASN by inc (32 bits) */
|
||||
/** \brief Increment an ASN by inc (32 bits) */
|
||||
#define TSCH_ASN_INC(asn, inc) do { \
|
||||
uint32_t new_ls4b = (asn).ls4b + (inc); \
|
||||
if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \
|
||||
(asn).ls4b = new_ls4b; \
|
||||
} while(0);
|
||||
|
||||
/* Decrement an ASN by inc (32 bits) */
|
||||
/** \brief Decrement an ASN by inc (32 bits) */
|
||||
#define TSCH_ASN_DEC(asn, dec) do { \
|
||||
uint32_t new_ls4b = (asn).ls4b - (dec); \
|
||||
if(new_ls4b > (asn).ls4b) { (asn).ms1b--; } \
|
||||
(asn).ls4b = new_ls4b; \
|
||||
} while(0);
|
||||
|
||||
/* Returns the 32-bit diff between asn1 and asn2 */
|
||||
/** \brief Returns the 32-bit diff between asn1 and asn2 */
|
||||
#define TSCH_ASN_DIFF(asn1, asn2) \
|
||||
((asn1).ls4b - (asn2).ls4b)
|
||||
|
||||
/* Initialize a struct asn_divisor_t */
|
||||
/** \brief Initialize a struct asn_divisor_t */
|
||||
#define TSCH_ASN_DIVISOR_INIT(div, val_) do { \
|
||||
(div).val = (val_); \
|
||||
(div).asn_ms1b_remainder = ((0xffffffff % (val_)) + 1) % (val_); \
|
||||
} while(0);
|
||||
|
||||
/* Returns the result (16 bits) of a modulo operation on ASN,
|
||||
/** \brief Returns the result (16 bits) of a modulo operation on ASN,
|
||||
* with divisor being a struct asn_divisor_t */
|
||||
#define TSCH_ASN_MOD(asn, div) \
|
||||
((uint16_t)((asn).ls4b % (div).val) \
|
||||
|
@ -31,17 +31,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH configuration
|
||||
* \author
|
||||
* Simon Duquennoy <simonduq@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_CONF_H__
|
||||
#define __TSCH_CONF_H__
|
||||
|
||||
|
@ -31,17 +31,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH configuration
|
||||
* TSCH constants
|
||||
* \author
|
||||
* Simon Duquennoy <simonduq@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_CONST_H__
|
||||
#define __TSCH_CONST_H__
|
||||
|
||||
|
@ -33,6 +33,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH per-slot logging
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_LOG_H__
|
||||
@ -70,7 +72,7 @@
|
||||
|
||||
/************ Types ***********/
|
||||
|
||||
/* Structure for a log. Union of different types of logs */
|
||||
/** \brief Structure for a log. Union of different types of logs */
|
||||
struct tsch_log_t {
|
||||
enum { tsch_log_tx,
|
||||
tsch_log_rx,
|
||||
@ -107,21 +109,31 @@ struct tsch_log_t {
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/* Prepare addition of a new log.
|
||||
* Returns pointer to log structure if success, NULL otherwise */
|
||||
/**
|
||||
* \brief Prepare addition of a new log.
|
||||
* \return A pointer to log structure if success, NULL otherwise
|
||||
*/
|
||||
struct tsch_log_t *tsch_log_prepare_add(void);
|
||||
/* Actually add the previously prepared log */
|
||||
/**
|
||||
* \brief Actually add the previously prepared log
|
||||
*/
|
||||
void tsch_log_commit(void);
|
||||
/* Initialize log module */
|
||||
/**
|
||||
* \brief Initialize log module
|
||||
*/
|
||||
void tsch_log_init(void);
|
||||
/* Process pending log messages */
|
||||
/**
|
||||
* \brief Process pending log messages
|
||||
*/
|
||||
void tsch_log_process_pending(void);
|
||||
/* Stop logging module */
|
||||
/**
|
||||
* \brief Stop logging module
|
||||
*/
|
||||
void tsch_log_stop(void);
|
||||
|
||||
/************ Macros **********/
|
||||
|
||||
/* Use this macro to add a log to the queue (will be printed out
|
||||
/** \brief Use this macro to add a log to the queue (will be printed out
|
||||
* later, after leaving interrupt context) */
|
||||
#define TSCH_LOG_ADD(log_type, init_code) do { \
|
||||
struct tsch_log_t *log = tsch_log_prepare_add(); \
|
||||
|
@ -390,8 +390,7 @@ tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset)
|
||||
struct ieee802154_ies ies;
|
||||
ies.ie_asn = tsch_current_asn;
|
||||
ies.ie_join_priority = tsch_join_priority;
|
||||
frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies);
|
||||
return 1;
|
||||
return frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies) != -1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Parse a IEEE 802.15.4e TSCH Enhanced Beacon (EB) */
|
||||
|
@ -33,6 +33,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH packet parsing and creation. EBs and EACKs.
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_PACKET_H__
|
||||
@ -46,18 +48,56 @@
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/* Construct enhanced ACK packet and return ACK length */
|
||||
/**
|
||||
* \brief Construct Enhanced ACK packet
|
||||
* \param buf The buffer where to build the EACK
|
||||
* \param buf_size The buffer size
|
||||
* \param dest_addr The link-layer address of the neighbor we are ACKing
|
||||
* \param seqno The sequence number we are ACKing
|
||||
* \param drift The time offset in usec measured at Rx of the packer we are ACKing
|
||||
* \param nack Value of the NACK bit
|
||||
* \return The length of the packet that was created. -1 if failure.
|
||||
*/
|
||||
int tsch_packet_create_eack(uint8_t *buf, uint16_t buf_size,
|
||||
const linkaddr_t *dest_addr, uint8_t seqno,
|
||||
int16_t drift, int nack);
|
||||
/* Parse enhanced ACK packet, extract drift and nack */
|
||||
/**
|
||||
* \brief Parse enhanced ACK packet
|
||||
* \param buf The buffer where to parse the EACK from
|
||||
* \param buf_size The buffer size
|
||||
* \param seqno The sequence number we are expecting
|
||||
* \param frame The frame structure where to store parsed fields
|
||||
* \param ies The IE structure where to store parsed IEs
|
||||
* \param hdr_len A pointer where to store the length of the parsed header
|
||||
* \return 1 if the EACK is correct and acknowledges the specified frame, 0 otherwise
|
||||
*/
|
||||
int tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
|
||||
uint8_t seqno, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len);
|
||||
/* Create an EB packet */
|
||||
/**
|
||||
* \brief Create an EB packet directly in packetbuf
|
||||
* \param hdr_len A pointer where to store the length of the created header
|
||||
* \param tsch_sync_ie_ptr A pointer where to store the address of the TSCH synchronization IE
|
||||
* \return The total length of the EB
|
||||
*/
|
||||
int tsch_packet_create_eb(uint8_t *hdr_len, uint8_t *tsch_sync_ie_ptr);
|
||||
/* Update ASN in EB packet */
|
||||
/**
|
||||
* \brief Update ASN in EB packet
|
||||
* \param buf The buffer that contains the EB
|
||||
* \param buf_size The buffer size
|
||||
* \param tsch_sync_ie_offset The offset of the TSCH synchronization IE, in which the ASN is to be written
|
||||
* \return 1 if success, 0 otherwise
|
||||
*/
|
||||
int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset);
|
||||
/* Parse EB and extract ASN and join priority */
|
||||
/**
|
||||
* \brief Parse EB
|
||||
* \param buf The buffer where to parse the EB from
|
||||
* \param buf_size The buffer sizecting
|
||||
* \param frame The frame structure where to store parsed fields
|
||||
* \param ies The IE structure where to store parsed IEs
|
||||
* \param hdrlen A pointer where to store the length of the parsed header
|
||||
* \param frame_without_mic When set, the security MIC will not be parsed
|
||||
* \return The length of the parsed EB
|
||||
*/
|
||||
int tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
|
||||
frame802154_t *frame, struct ieee802154_ies *ies,
|
||||
uint8_t *hdrlen, int frame_without_mic);
|
||||
|
@ -33,6 +33,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH queues
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_QUEUE_H__
|
||||
@ -53,50 +55,128 @@ extern struct tsch_neighbor *n_eb;
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/* Add a TSCH neighbor */
|
||||
/**
|
||||
* \brief Add a TSCH neighbor queue
|
||||
* \param addr The link-layer address of the neighbor to be added
|
||||
*/
|
||||
struct tsch_neighbor *tsch_queue_add_nbr(const linkaddr_t *addr);
|
||||
/* Get a TSCH neighbor */
|
||||
/**
|
||||
* \brief Get a TSCH neighbor
|
||||
* \param addr The link-layer address of the neighbor we are looking for
|
||||
* \return A pointer to the neighbor queue, NULL if not found
|
||||
*/
|
||||
struct tsch_neighbor *tsch_queue_get_nbr(const linkaddr_t *addr);
|
||||
/* Get a TSCH time source (we currently assume there is only one) */
|
||||
/**
|
||||
* \brief Get the TSCH time source (we currently assume there is only one)
|
||||
* \return The neighbor queue associated to the time source
|
||||
*/
|
||||
struct tsch_neighbor *tsch_queue_get_time_source(void);
|
||||
/* Update TSCH time source */
|
||||
/**
|
||||
* \brief Update TSCH time source
|
||||
* \param new_addr The address of the new TSCH time source
|
||||
*/
|
||||
int tsch_queue_update_time_source(const linkaddr_t *new_addr);
|
||||
/* Add packet to neighbor queue. Use same lockfree implementation as ringbuf.c (put is atomic) */
|
||||
/**
|
||||
* \brief Add packet to neighbor queue. Use same lockfree implementation as ringbuf.c (put is atomic)
|
||||
* \param addr The address of the targetted neighbor, &tsch_broadcast_address for broadcast
|
||||
* \param max_transmissions The number of MAC retries
|
||||
* \param sent The MAC packet sent callback
|
||||
* \param ptr The MAC packet send callback parameter
|
||||
* \return The newly created packet if any, NULL otherwise
|
||||
*/
|
||||
struct tsch_packet *tsch_queue_add_packet(const linkaddr_t *addr, uint8_t max_transmissions,
|
||||
mac_callback_t sent, void *ptr);
|
||||
/* Returns the number of packets currently in any TSCH queue */
|
||||
/**
|
||||
* \brief Returns the number of packets currently in all TSCH queues
|
||||
* \return The number of packets currently in all TSCH queues
|
||||
*/
|
||||
int tsch_queue_global_packet_count(void);
|
||||
/* Returns the number of packets currently a given neighbor queue */
|
||||
/**
|
||||
* \brief Returns the number of packets currently a given neighbor queue
|
||||
* \param addr The link-layer address of the neighbor we are interested in
|
||||
* \return The number of packets in the neighbor's queue
|
||||
*/
|
||||
int tsch_queue_packet_count(const linkaddr_t *addr);
|
||||
/* Remove first packet from a neighbor queue. The packet is stored in a separate
|
||||
* dequeued packet list, for later processing. Return the packet. */
|
||||
/**
|
||||
* \brief Remove first packet from a neighbor queue. The packet is stored in a separate
|
||||
* dequeued packet list, for later processing.
|
||||
* \param n The neighbor queue
|
||||
* \return The packet that was removed if any, NULL otherwise
|
||||
*/
|
||||
struct tsch_packet *tsch_queue_remove_packet_from_queue(struct tsch_neighbor *n);
|
||||
/* Free a packet */
|
||||
/**
|
||||
* \brief Free a packet
|
||||
* \param p The packet to be freed
|
||||
*/
|
||||
void tsch_queue_free_packet(struct tsch_packet *p);
|
||||
/* Updates neighbor queue state after a transmission */
|
||||
/**
|
||||
* \brief Updates neighbor queue state after a transmission
|
||||
* \param n The neighbor queue we just sent from
|
||||
* \param p The packet that was just sent
|
||||
* \param link The TSCH link used for Tx
|
||||
* \param mac_tx_status The MAC status (see mac.h)
|
||||
* \return 1 if the packet remains in queue after the call, 0 if it was removed
|
||||
*/
|
||||
int tsch_queue_packet_sent(struct tsch_neighbor *n, struct tsch_packet *p, struct tsch_link *link, uint8_t mac_tx_status);
|
||||
/* Reset neighbor queues */
|
||||
/**
|
||||
* \brief Reset neighbor queues module
|
||||
*/
|
||||
void tsch_queue_reset(void);
|
||||
/* Deallocate neighbors with empty queue */
|
||||
/**
|
||||
* \brief Deallocate all neighbors with empty queue
|
||||
*/
|
||||
void tsch_queue_free_unused_neighbors(void);
|
||||
/* Is the neighbor queue empty? */
|
||||
/**
|
||||
* \brief Is the neighbor queue empty?
|
||||
* \param n The neighbor queue
|
||||
* \return 1 if empty, 0 otherwise
|
||||
*/
|
||||
int tsch_queue_is_empty(const struct tsch_neighbor *n);
|
||||
/* Returns the first packet from a neighbor queue */
|
||||
/**
|
||||
* \brief Returns the first packet that can be sent from a queue on a given link
|
||||
* \param n The neighbor queue
|
||||
* \param link The link
|
||||
* \return The next packet to be sent for the neighbor on the given link, if any, else NULL
|
||||
*/
|
||||
struct tsch_packet *tsch_queue_get_packet_for_nbr(const struct tsch_neighbor *n, struct tsch_link *link);
|
||||
/* Returns the head packet from a neighbor queue (from neighbor address) */
|
||||
/**
|
||||
* \brief Returns the first packet that can be sent to a given address on a given link
|
||||
* \param addr The target link-layer address
|
||||
* \param link The link
|
||||
* \return The next packet to be sent for to the given address on the given link, if any, else NULL
|
||||
*/
|
||||
struct tsch_packet *tsch_queue_get_packet_for_dest_addr(const linkaddr_t *addr, struct tsch_link *link);
|
||||
/* Returns the head packet of any neighbor queue with zero backoff counter.
|
||||
* Writes pointer to the neighbor in *n */
|
||||
/**
|
||||
* \brief Gets the head packet of any neighbor queue with zero backoff counter.
|
||||
* \param n A pointer where to store the neighbor queue to be used for Tx
|
||||
* \param link The link to be used for Tx
|
||||
* \return The packet if any, else NULL
|
||||
*/
|
||||
struct tsch_packet *tsch_queue_get_unicast_packet_for_any(struct tsch_neighbor **n, struct tsch_link *link);
|
||||
/* May the neighbor transmit over a share link? */
|
||||
/**
|
||||
* \brief Is the neighbor backoff timer expired?
|
||||
* \param n The neighbor queue
|
||||
* \return 1 if the backoff has expired (neighbor ready to transmit on a shared link), 0 otherwise
|
||||
*/
|
||||
int tsch_queue_backoff_expired(const struct tsch_neighbor *n);
|
||||
/* Reset neighbor backoff */
|
||||
/**
|
||||
* \brief Reset neighbor backoff
|
||||
* \param n The neighbor queue
|
||||
*/
|
||||
void tsch_queue_backoff_reset(struct tsch_neighbor *n);
|
||||
/* Increment backoff exponent, pick a new window */
|
||||
/**
|
||||
* \brief Increment backoff exponent of a given neighbor queue, pick a new window
|
||||
* \param n The neighbor queue
|
||||
*/
|
||||
void tsch_queue_backoff_inc(struct tsch_neighbor *n);
|
||||
/* Decrement backoff window for all queues directed at dest_addr */
|
||||
/**
|
||||
* \brief Decrement backoff window for the queue(s) able to Tx to a given address
|
||||
* \param dest_addr The target address, &tsch_broadcast_address for broadcast
|
||||
*/
|
||||
void tsch_queue_update_all_backoff_windows(const linkaddr_t *dest_addr);
|
||||
/* Initialize TSCH queue module */
|
||||
/**
|
||||
* \brief Initialize TSCH queue module
|
||||
*/
|
||||
void tsch_queue_init(void);
|
||||
|
||||
#endif /* __TSCH_QUEUE_H__ */
|
||||
|
@ -31,6 +31,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH-RPL interaction
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_RPL_H__
|
||||
@ -47,20 +49,35 @@
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/* Keep-alives packet sent callback.
|
||||
* To use, set #define TSCH_CALLBACK_KA_SENT tsch_rpl_callback_ka_sent */
|
||||
/**
|
||||
* \brief Report statiscs from KA packet sent in RPL.
|
||||
* To use, set TSCH_CALLBACK_KA_SENT to tsch_rpl_callback_ka_sent
|
||||
* \param status The packet sent status
|
||||
* \param transmissions The total number of transmissions
|
||||
*/
|
||||
void tsch_rpl_callback_ka_sent(int status, int transmissions);
|
||||
/* To use, set #define TSCH_CALLBACK_JOINING_NETWORK tsch_rpl_callback_joining_network */
|
||||
/**
|
||||
* \brief Let RPL know that TSCH joined a new network.
|
||||
* To use, set TSCH_CALLBACK_JOINING_NETWORK to tsch_rpl_callback_joining_network
|
||||
*/
|
||||
void tsch_rpl_callback_joining_network(void);
|
||||
/* Upon leaving a TSCH network, perform a local repair
|
||||
* (cleanup neighbor state, reset Trickle timer etc)
|
||||
* To use, set #define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network */
|
||||
/**
|
||||
* \brief Let RPL know that TSCH joined a new network. Triggers a local repair.
|
||||
* To use, set TSCH_CALLBACK_LEAVING_NETWORK to tsch_rpl_callback_leaving_network
|
||||
*/
|
||||
void tsch_rpl_callback_leaving_network(void);
|
||||
/* Set TSCH EB period based on current RPL DIO period.
|
||||
* To use, set #define RPL_CALLBACK_NEW_DIO_INTERVAL tsch_rpl_callback_new_dio_interval */
|
||||
/**
|
||||
* \brief Set TSCH EB period based on current RPL DIO period.
|
||||
* To use, set RPL_CALLBACK_NEW_DIO_INTERVAL to tsch_rpl_callback_new_dio_interval
|
||||
* \param dio_interval The new DIO interval in clock ticks
|
||||
*/
|
||||
void tsch_rpl_callback_new_dio_interval(clock_time_t dio_interval);
|
||||
/* Set TSCH time source based on current RPL preferred parent.
|
||||
* To use, set #define RPL_CALLBACK_PARENT_SWITCH tsch_rpl_callback_parent_switch */
|
||||
/**
|
||||
* \brief Set TSCH time source based on current RPL preferred parent.
|
||||
* To use, set RPL_CALLBACK_PARENT_SWITCH to tsch_rpl_callback_parent_switch
|
||||
* \param old The old RPL parent
|
||||
* \param new The new RPL parent
|
||||
*/
|
||||
void tsch_rpl_callback_parent_switch(rpl_parent_t *old, rpl_parent_t *new);
|
||||
|
||||
#endif /* __TSCH_RPL_H__ */
|
||||
|
@ -33,6 +33,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH scheduling engine
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_SCHEDULE_H__
|
||||
@ -45,42 +47,115 @@
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/* Module initialization, call only once at startup. Returns 1 is success, 0 if failure. */
|
||||
/**
|
||||
* \brief Module initialization, call only once at init
|
||||
* \return 1 if success, 0 if failure
|
||||
*/
|
||||
int tsch_schedule_init(void);
|
||||
/* Create a 6TiSCH minimal schedule */
|
||||
/**
|
||||
* \brief Create a 6tisch minimal schedule with length TSCH_SCHEDULE_DEFAULT_LENGTH
|
||||
*/
|
||||
void tsch_schedule_create_minimal(void);
|
||||
/* Prints out the current schedule (all slotframes and links) */
|
||||
/**
|
||||
* \brief Prints out the current schedule (all slotframes and links)
|
||||
*/
|
||||
void tsch_schedule_print(void);
|
||||
|
||||
/* Adds and returns a slotframe (NULL if failure) */
|
||||
|
||||
/**
|
||||
* \brief Creates and adds a new slotframe
|
||||
* \param handle the slotframe handle
|
||||
* \param size the slotframe size
|
||||
* \return the new slotframe, NULL if failure
|
||||
*/
|
||||
struct tsch_slotframe *tsch_schedule_add_slotframe(uint16_t handle, uint16_t size);
|
||||
/* Looks for a slotframe from a handle */
|
||||
|
||||
/**
|
||||
* \brief Looks up a slotframe by handle
|
||||
* \param handle the slotframe handle
|
||||
* \return the slotframe with required handle, if any. NULL otherwise.
|
||||
*/
|
||||
struct tsch_slotframe *tsch_schedule_get_slotframe_by_handle(uint16_t handle);
|
||||
/* Removes a slotframe Return 1 if success, 0 if failure */
|
||||
|
||||
/**
|
||||
* \brief Removes a slotframe
|
||||
* \param slotframe The slotframe to be removed
|
||||
* \return 1 if success, 0 if failure
|
||||
*/
|
||||
int tsch_schedule_remove_slotframe(struct tsch_slotframe *slotframe);
|
||||
/* Removes all slotframes, resulting in an empty schedule */
|
||||
|
||||
/**
|
||||
* \brief Removes all slotframes, resulting in an empty schedule
|
||||
* \return 1 if success, 0 if failure
|
||||
*/
|
||||
int tsch_schedule_remove_all_slotframes(void);
|
||||
|
||||
/* Returns next slotframe */
|
||||
struct tsch_slotframe *tsch_schedule_slotframes_next(struct tsch_slotframe *sf);
|
||||
/* Adds a link to a slotframe, return a pointer to it (NULL if failure) */
|
||||
/**
|
||||
* \brief Adds a link to a slotframe
|
||||
* \param slotframe The slotframe that will contain the new link
|
||||
* \param link_options The link options, as a bitfield (LINK_OPTION_* flags)
|
||||
* \param link_type The link type (advertising, normal)
|
||||
* \param address The link address of the intended destination. Use &tsch_broadcast_address for a slot towards any neighbor
|
||||
* \param timeslot The link timeslot within the slotframe
|
||||
* \param channel_offset The link channel offset
|
||||
* \return A pointer to the new link, NULL if failure
|
||||
*/
|
||||
struct tsch_link *tsch_schedule_add_link(struct tsch_slotframe *slotframe,
|
||||
uint8_t link_options, enum link_type link_type, const linkaddr_t *address,
|
||||
uint16_t timeslot, uint16_t channel_offset);
|
||||
/* Looks for a link from a handle */
|
||||
/**
|
||||
* \brief Looks for a link from a handle
|
||||
* \param handle The target handle
|
||||
* \return The link with required handle, if any. Otherwise, NULL
|
||||
*/
|
||||
struct tsch_link *tsch_schedule_get_link_by_handle(uint16_t handle);
|
||||
/* Looks within a slotframe for a link with a given timeslot */
|
||||
|
||||
/**
|
||||
* \brief Looks within a slotframe for a link with a given timeslot
|
||||
* \param slotframe The desired slotframe
|
||||
* \param timeslot The desired timeslot
|
||||
* \return The link if found, NULL otherwise
|
||||
*/
|
||||
struct tsch_link *tsch_schedule_get_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot);
|
||||
/* Removes a link. Return 1 if success, 0 if failure */
|
||||
|
||||
/**
|
||||
* \brief Removes a link
|
||||
* \param slotframe The slotframe the link belongs to
|
||||
* \param l The link to be removed
|
||||
* \return 1 if success, 0 if failure
|
||||
*/
|
||||
int tsch_schedule_remove_link(struct tsch_slotframe *slotframe, struct tsch_link *l);
|
||||
/* Removes a link from slotframe and timeslot. Return a 1 if success, 0 if failure */
|
||||
|
||||
/**
|
||||
* \brief Removes a link from a slotframe and timeslot
|
||||
* \param slotframe The slotframe where to look for the link
|
||||
* \param timeslot The timeslot where to look for the link within the target slotframe
|
||||
* \return 1 if success, 0 if failure
|
||||
*/
|
||||
int tsch_schedule_remove_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot);
|
||||
|
||||
/* Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag) */
|
||||
|
||||
/**
|
||||
* \brief Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag)
|
||||
* \param asn The base ASN, from which we look for the next active link
|
||||
* \param time_offset A pointer to uint16_t where to store the time offset between base ASN and link found
|
||||
* \param backup_link A pointer where to write the address of a backup link, to be executed should the original be no longer active at wakeup
|
||||
* \return The next active link if any, NULL otherwise
|
||||
*/
|
||||
struct tsch_link * tsch_schedule_get_next_active_link(struct tsch_asn_t *asn, uint16_t *time_offset,
|
||||
struct tsch_link **backup_link);
|
||||
/* Access to slotframe list */
|
||||
|
||||
/**
|
||||
* \brief Access the first item in the list of slotframes
|
||||
* \return The first slotframe in the schedule if any, NULL otherwise
|
||||
*/
|
||||
struct tsch_slotframe *tsch_schedule_slotframe_head(void);
|
||||
|
||||
/**
|
||||
* \brief Access the next item in the list of slotframes
|
||||
* \param sf The current slotframe (item in the list)
|
||||
* \return The next slotframe if any, NULL otherwise
|
||||
*/
|
||||
struct tsch_slotframe *tsch_schedule_slotframe_next(struct tsch_slotframe *sf);
|
||||
|
||||
#endif /* __TSCH_SCHEDULE_H__ */
|
||||
|
@ -33,6 +33,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH security
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_SECURITY_H__
|
||||
|
@ -33,6 +33,8 @@
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH runtime operation within timeslots
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_SLOT_OPERATION_H__
|
||||
@ -58,19 +60,45 @@ extern clock_time_t last_sync_time;
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/* Returns a 802.15.4 channel from an ASN and channel offset */
|
||||
/**
|
||||
* Returns a 802.15.4 channel from an ASN and channel offset. Basically adds
|
||||
* The offset to the ASN and performs a hopping sequence lookup.
|
||||
*
|
||||
* \param asn A given ASN
|
||||
* \param channel_offset A given channel offset
|
||||
* \return The resulting channel
|
||||
*/
|
||||
uint8_t tsch_calculate_channel(struct tsch_asn_t *asn, uint8_t channel_offset);
|
||||
/* Is TSCH locked? */
|
||||
/**
|
||||
* Checks if the TSCH lock is set. Accesses to global structures outside of
|
||||
* interrupts must be done through the lock, unless the sturcutre has
|
||||
* atomic read/write
|
||||
*
|
||||
* \return 1 if the lock is taken, 0 otherwise
|
||||
*/
|
||||
int tsch_is_locked(void);
|
||||
/* Lock TSCH (no link operation) */
|
||||
/**
|
||||
* Takes the TSCH lock. When the lock is taken, slot operation will be skipped
|
||||
* until release.
|
||||
*
|
||||
* \return 1 if the lock was successfully taken, 0 otherwise
|
||||
*/
|
||||
int tsch_get_lock(void);
|
||||
/* Release TSCH lock */
|
||||
/**
|
||||
* Releases the TSCH lock.
|
||||
*/
|
||||
void tsch_release_lock(void);
|
||||
/* Set global time before starting slot operation,
|
||||
* with a rtimer time and an ASN */
|
||||
/**
|
||||
* Set global time before starting slot operation, with a rtimer time and an ASN
|
||||
*
|
||||
* \param next_slot_start the time to the start of the next slot, in rtimer ticks
|
||||
* \param next_slot_asn the ASN of the next slot
|
||||
*/
|
||||
void tsch_slot_operation_sync(rtimer_clock_t next_slot_start,
|
||||
struct tsch_asn_t *next_slot_asn);
|
||||
/* Start actual slot operation */
|
||||
/**
|
||||
* Start actual slot operation
|
||||
*/
|
||||
void tsch_slot_operation_start(void);
|
||||
|
||||
#endif /* __TSCH_SLOT_OPERATION_H__ */
|
||||
|
@ -31,17 +31,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
* \file
|
||||
* TSCH types
|
||||
* \author
|
||||
* Simon Duquennoy <simonduq@sics.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup tsch
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_TYPES_H__
|
||||
#define __TSCH_TYPES_H__
|
||||
|
||||
@ -53,10 +50,10 @@
|
||||
|
||||
/********** Data types **********/
|
||||
|
||||
/* 802.15.4e link types.
|
||||
* LINK_TYPE_ADVERTISING_ONLY is an extra one: for EB-only links. */
|
||||
/** \brief 802.15.4e link types. LINK_TYPE_ADVERTISING_ONLY is an extra one: for EB-only links. */
|
||||
enum link_type { LINK_TYPE_NORMAL, LINK_TYPE_ADVERTISING, LINK_TYPE_ADVERTISING_ONLY };
|
||||
|
||||
/** \brief An IEEE 802.15.4-2015 TSCH link (also called cell or slot) */
|
||||
struct tsch_link {
|
||||
/* Links are stored as a list: "next" must be the first field */
|
||||
struct tsch_link *next;
|
||||
@ -83,7 +80,7 @@ struct tsch_link {
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* 802.15.4e slotframe (contains links) */
|
||||
/** \brief 802.15.4e slotframe (contains links) */
|
||||
struct tsch_slotframe {
|
||||
/* Slotframes are stored as a list: "next" must be the first field */
|
||||
struct tsch_slotframe *next;
|
||||
@ -96,7 +93,7 @@ struct tsch_slotframe {
|
||||
LIST_STRUCT(links_list);
|
||||
};
|
||||
|
||||
/* TSCH packet information */
|
||||
/** \brief TSCH packet information */
|
||||
struct tsch_packet {
|
||||
struct queuebuf *qb; /* pointer to the queuebuf to be sent */
|
||||
mac_callback_t sent; /* callback for this packet */
|
||||
@ -108,7 +105,7 @@ struct tsch_packet {
|
||||
uint8_t tsch_sync_ie_offset; /* Offset within the frame used for quick update of EB ASN and join priority */
|
||||
};
|
||||
|
||||
/* TSCH neighbor information */
|
||||
/** \brief TSCH neighbor information */
|
||||
struct tsch_neighbor {
|
||||
/* Neighbors are stored as a list: "next" must be the first field */
|
||||
struct tsch_neighbor *next;
|
||||
@ -127,7 +124,7 @@ struct tsch_neighbor {
|
||||
struct ringbufindex tx_ringbuf;
|
||||
};
|
||||
|
||||
/* TSCH timeslot timing elements. Used to index timeslot timing
|
||||
/** \brief TSCH timeslot timing elements. Used to index timeslot timing
|
||||
* of different units, such as rtimer tick or micro-second */
|
||||
enum tsch_timeslot_timing_elements {
|
||||
tsch_ts_cca_offset,
|
||||
@ -145,7 +142,7 @@ enum tsch_timeslot_timing_elements {
|
||||
tsch_ts_elements_count, /* Not a timing element */
|
||||
};
|
||||
|
||||
/* Stores data about an incoming packet */
|
||||
/** \brief Stores data about an incoming packet */
|
||||
struct input_packet {
|
||||
uint8_t payload[TSCH_PACKET_MAX_LEN]; /* Packet payload */
|
||||
struct tsch_asn_t rx_asn; /* ASN when the packet was received */
|
||||
|
@ -37,6 +37,8 @@ The IEEE 802.15.4-2015 TimeSlotted Channel Hopping (TSCH) protocol. Provides
|
||||
scheduled communication on top of a globally-synchronized network. Performs
|
||||
frequency hopping for enhanced reliability.
|
||||
* @{
|
||||
* \file
|
||||
* Main API declarations for TSCH.
|
||||
*/
|
||||
|
||||
#ifndef __TSCH_H__
|
||||
@ -180,21 +182,57 @@ PROCESS_NAME(tsch_pending_events_process);
|
||||
|
||||
/********** Functions *********/
|
||||
|
||||
/* The the TSCH join priority */
|
||||
/**
|
||||
* Set the TSCH join priority (JP)
|
||||
*
|
||||
* \param jp the new join priority
|
||||
*/
|
||||
void tsch_set_join_priority(uint8_t jp);
|
||||
/* The period at which EBs are sent */
|
||||
/**
|
||||
* Set the period at wich TSCH enhanced beacons (EBs) are sent. The period can
|
||||
* not be set to exceed TSCH_MAX_EB_PERIOD. Set to 0 to stop sending EBs.
|
||||
* Actual transmissions are jittered, spaced by a random number within
|
||||
* [period*0.75, period[
|
||||
*
|
||||
* \param period The period in Clock ticks.
|
||||
*/
|
||||
void tsch_set_eb_period(uint32_t period);
|
||||
/* The keep-alive timeout */
|
||||
/**
|
||||
* Set the desynchronization timeout after which a node sends a unicasst
|
||||
* keep-alive (KA) to its time source. Set to 0 to stop sending KAs. The
|
||||
* actual timeout is a random number within
|
||||
* [timeout*0.9, timeout[
|
||||
*
|
||||
* \param timeout The timeout in Clock ticks.
|
||||
*/
|
||||
void tsch_set_ka_timeout(uint32_t timeout);
|
||||
/* Set the node as PAN coordinator */
|
||||
/**
|
||||
* Set the node as PAN coordinator
|
||||
*
|
||||
* \param enable 1 to be coordinator, 0 to be a node
|
||||
*/
|
||||
void tsch_set_coordinator(int enable);
|
||||
/* Set the pan as secured or not */
|
||||
/**
|
||||
* Enable/disable security. If done at the coordinator, the Information
|
||||
* will be included in EBs, and all nodes will adopt the same security level.
|
||||
* Enabling requires compilation with LLSEC802154_ENABLED set.
|
||||
* Note: when LLSEC802154_ENABLED is set, nodes boot with security enabled.
|
||||
*
|
||||
* \param enable 1 to enable security, 0 to disable it
|
||||
*/
|
||||
void tsch_set_pan_secured(int enable);
|
||||
/* Set TSCH to send a keepalive message after TSCH_KEEPALIVE_TIMEOUT */
|
||||
/**
|
||||
* Schedule a keep-alive transmission within [timeout*0.9, timeout[
|
||||
* @see tsch_set_ka_timeout
|
||||
*/
|
||||
void tsch_schedule_keepalive(void);
|
||||
/* Set TSCH to send a keepalive message immediately */
|
||||
/**
|
||||
* Schedule a keep-alive immediately
|
||||
*/
|
||||
void tsch_schedule_keepalive_immediately(void);
|
||||
/* Leave the TSCH network */
|
||||
/**
|
||||
* Leave the TSCH network we are currently in
|
||||
*/
|
||||
void tsch_disassociate(void);
|
||||
|
||||
#endif /* __TSCH_H__ */
|
||||
|
@ -151,7 +151,7 @@ drop_route(uip_ds6_route_t *route)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct routing_driver nullrouting_driver = {
|
||||
"Null Routing",
|
||||
"nullrouting",
|
||||
init,
|
||||
root_set_prefix,
|
||||
root_start,
|
||||
|
@ -56,14 +56,19 @@
|
||||
|
||||
/* RFC6551 and RFC6719 do not mandate the use of a specific formula to
|
||||
* compute the ETX value. This MRHOF implementation relies on the value
|
||||
* computed by the link-stats module. It has an optional feature,
|
||||
* computed by the link-stats module.It has an optional feature,
|
||||
* RPL_MRHOF_CONF_SQUARED_ETX, that consists in squaring this value.
|
||||
* This basically penalizes bad links while preserving the semantics of ETX
|
||||
*
|
||||
* Squaring basically penalizes bad links while preserving the semantics of ETX
|
||||
* (1 = perfect link, more = worse link). As a result, MRHOF will favor
|
||||
* good links over short paths. Recommended when reliability is a priority.
|
||||
* Without this feature, a hop with 50% PRR (ETX=2) is equivalent to two
|
||||
* perfect hops with 100% PRR (ETX=1+1=2). With this feature, the former
|
||||
* path obtains ETX=2*2=4 and the former ETX=1*1+1*1=2. */
|
||||
* good links over short paths. Without this feature, a hop with 50% PRR (ETX=2)
|
||||
* is equivalent to two perfect hops with 100% PRR (ETX=1+1=2). With this
|
||||
* feature, the former path obtains ETX=2*2=4 and the former ETX=1*1+1*1=2.
|
||||
*
|
||||
* While this feature helps achieve extra relaibility, it also results in
|
||||
* added churn. In networks with high congestion or poor links, this can lead
|
||||
* to poor connectivity due to more parent switches, loops, Trickle resets, etc.
|
||||
*/
|
||||
#ifdef RPL_MRHOF_CONF_SQUARED_ETX
|
||||
#define RPL_MRHOF_SQUARED_ETX RPL_MRHOF_CONF_SQUARED_ETX
|
||||
#else /* RPL_MRHOF_CONF_SQUARED_ETX */
|
||||
|
@ -56,18 +56,23 @@
|
||||
|
||||
/* RFC6551 and RFC6719 do not mandate the use of a specific formula to
|
||||
* compute the ETX value. This MRHOF implementation relies on the value
|
||||
* computed by the link-stats module. It has an optional feature,
|
||||
* computed by the link-stats module.It has an optional feature,
|
||||
* RPL_MRHOF_CONF_SQUARED_ETX, that consists in squaring this value.
|
||||
* This basically penalizes bad links while preserving the semantics of ETX
|
||||
*
|
||||
* Squaring basically penalizes bad links while preserving the semantics of ETX
|
||||
* (1 = perfect link, more = worse link). As a result, MRHOF will favor
|
||||
* good links over short paths. Recommended when reliability is a priority.
|
||||
* Without this feature, a hop with 50% PRR (ETX=2) is equivalent to two
|
||||
* perfect hops with 100% PRR (ETX=1+1=2). With this feature, the former
|
||||
* path obtains ETX=2*2=4 and the former ETX=1*1+1*1=2. */
|
||||
* good links over short paths. Without this feature, a hop with 50% PRR (ETX=2)
|
||||
* is equivalent to two perfect hops with 100% PRR (ETX=1+1=2). With this
|
||||
* feature, the former path obtains ETX=2*2=4 and the former ETX=1*1+1*1=2.
|
||||
*
|
||||
* While this feature helps achieve extra relaibility, it also results in
|
||||
* added churn. In networks with high congestion or poor links, this can lead
|
||||
* to poor connectivity due to more parent switches, loops, Trickle resets, etc.
|
||||
*/
|
||||
#ifdef RPL_MRHOF_CONF_SQUARED_ETX
|
||||
#define RPL_MRHOF_SQUARED_ETX RPL_MRHOF_CONF_SQUARED_ETX
|
||||
#else /* RPL_MRHOF_CONF_SQUARED_ETX */
|
||||
#define RPL_MRHOF_SQUARED_ETX 1
|
||||
#define RPL_MRHOF_SQUARED_ETX 0
|
||||
#endif /* RPL_MRHOF_CONF_SQUARED_ETX */
|
||||
|
||||
/* Configuration parameters of RFC6719. Reject parents that have a higher
|
||||
|
@ -57,24 +57,24 @@ static void
|
||||
input_callback(void)
|
||||
{
|
||||
/*PRINTF("SIN: %u\n", uip_len);*/
|
||||
if(uip_buf[0] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
|
||||
if(uip_buf[UIP_LLH_LEN] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
uip_clear_buf();
|
||||
#if 0
|
||||
if(uip_buf[1] == 'P') {
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
memset(&prefix, 0, 16);
|
||||
memcpy(&prefix, &uip_buf[2], 8);
|
||||
memcpy(&prefix, &uip_buf[UIP_LLH_LEN + 2], 8);
|
||||
PRINTF("Setting prefix ");
|
||||
PRINT6ADDR(&prefix);
|
||||
PRINTF("\n");
|
||||
set_prefix_64(&prefix);
|
||||
}
|
||||
#endif
|
||||
} else if(uip_buf[0] == '?') {
|
||||
PRINTF("Got request message of type %c\n", uip_buf[1]);
|
||||
if(uip_buf[1] == 'M') {
|
||||
} else if(uip_buf[UIP_LLH_LEN] == '?') {
|
||||
PRINTF("Got request message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'M') {
|
||||
const char *hexchar = "0123456789abcdef";
|
||||
int j;
|
||||
/* this is just a test so far... just to see if it works */
|
||||
@ -84,8 +84,7 @@ input_callback(void)
|
||||
uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15];
|
||||
}
|
||||
uip_len = 18;
|
||||
slip_send();
|
||||
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
uip_clear_buf();
|
||||
} else {
|
||||
@ -147,6 +146,3 @@ const struct uip_fallback_interface ip64_slip_interface = {
|
||||
init, output
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-device"
|
||||
#define LOG_MODULE "lwm2m-dev"
|
||||
#define LOG_LEVEL LOG_LEVEL_LWM2M
|
||||
|
||||
static const lwm2m_resource_id_t resources[] =
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-engine"
|
||||
#define LOG_MODULE "lwm2m-eng"
|
||||
#define LOG_LEVEL LOG_LEVEL_LWM2M
|
||||
|
||||
#ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX
|
||||
|
@ -44,7 +44,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-firmware"
|
||||
#define LOG_MODULE "lwm2m-fw"
|
||||
#define LOG_LEVEL LOG_LEVEL_LWM2M
|
||||
|
||||
#define UPDATE_PACKAGE 0
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-plain-text"
|
||||
#define LOG_MODULE "lwm2m-text"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -64,7 +64,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-rd-client"
|
||||
#define LOG_MODULE "lwm2m-rd"
|
||||
#define LOG_LEVEL LOG_LEVEL_LWM2M
|
||||
|
||||
#ifndef LWM2M_DEFAULT_CLIENT_LIFETIME
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-security"
|
||||
#define LOG_MODULE "lwm2m-sec"
|
||||
#define LOG_LEVEL LOG_LEVEL_LWM2M
|
||||
|
||||
#define MAX_COUNT LWM2M_SERVER_MAX_COUNT
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-server"
|
||||
#define LOG_MODULE "lwm2m-srv"
|
||||
#define LOG_LEVEL LOG_LEVEL_LWM2M
|
||||
|
||||
#define MAX_COUNT LWM2M_SERVER_MAX_COUNT
|
||||
|
@ -47,7 +47,7 @@
|
||||
|
||||
/* Log configuration */
|
||||
#include "coap-log.h"
|
||||
#define LOG_MODULE "lwm2m-tlv-writer"
|
||||
#define LOG_MODULE "lwm2m-tlv"
|
||||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -62,7 +62,7 @@ request_prefix(void)
|
||||
uip_buf[0] = '?';
|
||||
uip_buf[1] = 'P';
|
||||
uip_len = 2;
|
||||
slip_send();
|
||||
slip_write(uip_buf, uip_len);
|
||||
uip_clear_buf();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -70,22 +70,27 @@ static void
|
||||
slip_input_callback(void)
|
||||
{
|
||||
LOG_DBG("SIN: %u\n", uip_len);
|
||||
if(uip_buf[0] == '!') {
|
||||
LOG_INFO("Got configuration message of type %c\n", uip_buf[1]);
|
||||
uip_clear_buf();
|
||||
if(uip_buf[1] == 'P') {
|
||||
if(uip_buf[UIP_LLH_LEN] == '!') {
|
||||
LOG_INFO("Got configuration message of type %c\n",
|
||||
uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
memset(&prefix, 0, 16);
|
||||
memcpy(&prefix, &uip_buf[2], 8);
|
||||
memcpy(&prefix, &uip_buf[UIP_LLH_LEN + 2], 8);
|
||||
|
||||
uip_clear_buf();
|
||||
|
||||
LOG_INFO("Setting prefix ");
|
||||
LOG_INFO_6ADDR(&prefix);
|
||||
LOG_INFO_("\n");
|
||||
set_prefix_64(&prefix);
|
||||
}
|
||||
} else if(uip_buf[0] == '?') {
|
||||
LOG_INFO("Got request message of type %c\n", uip_buf[1]);
|
||||
if(uip_buf[1] == 'M') {
|
||||
uip_clear_buf();
|
||||
|
||||
} else if(uip_buf[UIP_LLH_LEN] == '?') {
|
||||
LOG_INFO("Got request message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'M') {
|
||||
char *hexchar = "0123456789abcdef";
|
||||
int j;
|
||||
/* this is just a test so far... just to see if it works */
|
||||
@ -95,13 +100,14 @@ slip_input_callback(void)
|
||||
uip_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15];
|
||||
}
|
||||
uip_len = 18;
|
||||
slip_send();
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
uip_clear_buf();
|
||||
} else {
|
||||
/* 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);
|
||||
}
|
||||
/* 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
|
||||
|
@ -173,8 +173,12 @@ PT_THREAD(cmd_rpl_status(struct pt *pt, shell_output_func output, char *args))
|
||||
|
||||
SHELL_OUTPUT(output, "-- State: %s\n", rpl_state_to_str(curr_instance.dag.state));
|
||||
SHELL_OUTPUT(output, "-- Preferred parent: ");
|
||||
shell_output_6addr(output, rpl_neighbor_get_ipaddr(curr_instance.dag.preferred_parent));
|
||||
SHELL_OUTPUT(output, " (last DTSN: %u)\n", curr_instance.dag.preferred_parent->dtsn);
|
||||
if(curr_instance.dag.preferred_parent) {
|
||||
shell_output_6addr(output, rpl_neighbor_get_ipaddr(curr_instance.dag.preferred_parent));
|
||||
SHELL_OUTPUT(output, " (last DTSN: %u)\n", curr_instance.dag.preferred_parent->dtsn);
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "None\n");
|
||||
}
|
||||
SHELL_OUTPUT(output, "-- Rank: %u\n", curr_instance.dag.rank);
|
||||
SHELL_OUTPUT(output, "-- Lowest rank: %u (%u)\n", curr_instance.dag.lowest_rank, curr_instance.max_rankinc);
|
||||
SHELL_OUTPUT(output, "-- DTSN out: %u\n", curr_instance.dtsn_out);
|
||||
@ -413,6 +417,7 @@ PT_THREAD(cmd_rpl_local_repair(struct pt *pt, shell_output_func output, char *ar
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if ROUTING_CONF_RPL_LITE
|
||||
static
|
||||
PT_THREAD(cmd_rpl_refresh_routes(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
@ -423,6 +428,7 @@ PT_THREAD(cmd_rpl_refresh_routes(struct pt *pt, shell_output_func output, char *
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
#endif /* ROUTING_CONF_RPL_LITE */
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
@ -732,7 +738,9 @@ struct shell_command_t shell_commands[] = {
|
||||
#if UIP_CONF_IPV6_RPL
|
||||
{ "rpl-set-root", cmd_rpl_set_root, "'> rpl-set-root 0/1 [prefix]': Sets node as root (1) or not (0). A /64 prefix can be optionally specified." },
|
||||
{ "rpl-local-repair", cmd_rpl_local_repair, "'> rpl-local-repair': Triggers a RPL local repair" },
|
||||
#if ROUTING_CONF_RPL_LITE
|
||||
{ "rpl-refresh-routes", cmd_rpl_refresh_routes, "'> rpl-refresh-routes': Refreshes all routes through a DTSN increment" },
|
||||
#endif /* ROUTING_CONF_RPL_LITE */
|
||||
{ "rpl-global-repair", cmd_rpl_global_repair, "'> rpl-global-repair': Triggers a RPL global repair" },
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
#if ROUTING_CONF_RPL_LITE
|
||||
|
@ -38,6 +38,7 @@
|
||||
#define DB_OPTIONS_H
|
||||
|
||||
#include "contiki.h"
|
||||
#include "cfs-coffee-arch.h"
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
@ -143,9 +144,17 @@
|
||||
|
||||
/* The default relation file size to reserve when using Coffee. */
|
||||
#ifndef DB_COFFEE_RESERVE_SIZE
|
||||
#define DB_COFFEE_RESERVE_SIZE (128 * 1024UL)
|
||||
#define DB_COFFEE_RESERVE_SIZE (COFFEE_SIZE / 8)
|
||||
#endif /* DB_COFFEE_RESERVE_SIZE */
|
||||
|
||||
/*
|
||||
* Ensure that the default size of Coffee file reservations is suitable
|
||||
* for the file system size.
|
||||
*/
|
||||
#if DB_COFFEE_RESERVE_SIZE > (COFFEE_SIZE / 2)
|
||||
#error DB_COFFEE_RESERVE_SIZE is too large for the file system.
|
||||
#endif
|
||||
|
||||
/* The maximum size of the physical storage of a tuple (labelled a "row"
|
||||
in Antelope's terminology. */
|
||||
#ifndef DB_MAX_CHAR_SIZE_PER_ROW
|
||||
|
@ -55,11 +55,34 @@
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
#ifndef RTIMER_CLOCK_DIFF
|
||||
typedef unsigned short rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a,b) ((signed short)((a)-(b)))
|
||||
#endif /* RTIMER_CLOCK_DIFF */
|
||||
/** \brief The rtimer size (in bytes) */
|
||||
#ifdef RTIMER_CONF_CLOCK_SIZE
|
||||
#define RTIMER_CLOCK_SIZE RTIMER_CONF_CLOCK_SIZE
|
||||
#else /* RTIMER_CONF_CLOCK_SIZE */
|
||||
/* Default: 32bit rtimer*/
|
||||
#define RTIMER_CLOCK_SIZE 4
|
||||
#endif /* RTIMER_CONF_CLOCK_SIZE */
|
||||
|
||||
#if RTIMER_CLOCK_SIZE == 2
|
||||
/* 16-bit rtimer */
|
||||
typedef uint16_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a,b) ((int16_t)((a)-(b)))
|
||||
|
||||
#elif RTIMER_CLOCK_SIZE == 4
|
||||
/* 32-bit rtimer */
|
||||
typedef uint32_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a, b) ((int32_t)((a) - (b)))
|
||||
|
||||
#elif RTIMER_CLOCK_SIZE == 8
|
||||
/* 64-bit rtimer */
|
||||
typedef uint64_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_DIFF(a,b) ((int64_t)((a)-(b)))
|
||||
|
||||
#else
|
||||
#error Unsupported rtimer size (check RTIMER_CLOCK_SIZE)
|
||||
#endif
|
||||
|
||||
#define RTIMER_CLOCK_MAX ((rtimer_clock_t)-1)
|
||||
#define RTIMER_CLOCK_LT(a, b) (RTIMER_CLOCK_DIFF((a),(b)) < 0)
|
||||
|
||||
#include "rtimer-arch.h"
|
||||
|
@ -17,6 +17,7 @@ lwm2m-ipso-objects/native \
|
||||
lwm2m-ipso-objects/native:MAKE_WITH_DTLS=1 \
|
||||
rpl-udp/sky \
|
||||
rpl-border-router/native \
|
||||
rpl-border-router/native:MAKE_ROUTING=MAKE_ROUTING_RPL_CLASSIC \
|
||||
rpl-border-router/sky \
|
||||
slip-radio/sky \
|
||||
libs/ipv6-hooks/sky \
|
||||
|
14
tools/ip64/jool-start.sh
Executable file
14
tools/ip64/jool-start.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
defaultInterface=$(route | grep default | awk '{print $(NF)}')
|
||||
myIP=$(ifconfig $defaultInterface | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}')
|
||||
echo "Configuring jool for $myIP"
|
||||
|
||||
sudo sysctl -w net.ipv4.conf.all.forwarding=1
|
||||
sudo sysctl -w net.ipv6.conf.all.forwarding=1
|
||||
|
||||
sudo /sbin/modprobe jool pool6=64:ff9b::/96 disabled
|
||||
|
||||
# Assuming that we are on this IP
|
||||
sudo jool -4 --add $myIP 15000-25000
|
||||
sudo jool --enable
|
Loading…
Reference in New Issue
Block a user