Merge branch 'release-4.1' into develop

This commit is contained in:
George Oikonomou 2018-05-09 22:18:01 +01:00
commit b45d284be2
54 changed files with 696 additions and 309 deletions

View File

@ -46,10 +46,21 @@ AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data) PROCESS_THREAD(hello_world_process, ev, data)
{ {
static struct etimer timer;
PROCESS_BEGIN(); PROCESS_BEGIN();
/* Setup a periodic timer that expires after 10 seconds. */
etimer_set(&timer, CLOCK_SECOND * 10);
while(1) {
printf("Hello, world\n"); 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(); PROCESS_END();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -12,16 +12,3 @@ MODULES += os/services/ipso-objects
CONTIKI=../.. CONTIKI=../..
include $(CONTIKI)/Makefile.include 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

View File

@ -3,8 +3,8 @@ LWM2M with IPSO Objects Example
This is an OMA LWM2M example implementing IPSO Objects. This is an OMA LWM2M example implementing IPSO Objects.
It can connect to a Leshan server out-of-the-box. It can connect to a Leshan server out-of-the-box.
Important configuration paramters: Important configuration parameters:
* `LWM2M_SERVER_ADDRESS`: the address of the server to register to (or bosstrap from) * `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 * `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. A tutorial for setting up this example is provided on the wiki.

View File

@ -38,20 +38,24 @@
#include "contiki.h" #include "contiki.h"
#include "net/ipv6/uip.h" #include "net/ipv6/uip.h"
#include "net/ipv6/uip-ds6.h"
#include "net/netstack.h" #include "net/netstack.h"
#include "net/routing/routing.h" #include "net/routing/routing.h"
#include "coap-constants.h" #include "coap-transport.h"
#include "coap-engine.h" #include "coap-blocking-api.h"
#include "lwm2m-engine.h" #include "lwm2m-engine.h"
#include "lwm2m-tlv.h" #include "lwm2m-tlv.h"
#include "dev/serial-line.h" #include "dev/serial-line.h"
#include "serial-protocol.h" #include "serial-protocol.h"
#include <stdbool.h>
#define DEBUG DEBUG_PRINT #define DEBUG DEBUG_PRINT
#include "net/ipv6/uip-debug.h" #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_WELL_KNOWN ".well-known/core"
#define URL_DEVICE_MODEL "/3/0/1" #define URL_DEVICE_MODEL "/3/0/1"
#define URL_DEVICE_FIRMWARE_VERSION "/3/0/3" #define URL_DEVICE_FIRMWARE_VERSION "/3/0/3"
@ -63,8 +67,8 @@
#define NODE_HAS_TYPE (1 << 0) #define NODE_HAS_TYPE (1 << 0)
struct node { struct node {
uip_ipaddr_t ipaddr; coap_endpoint_t endpoint;
char type[32]; char type[64];
uint8_t flags; uint8_t flags;
uint8_t retries; uint8_t retries;
}; };
@ -86,13 +90,15 @@ add_node(const uip_ipaddr_t *addr)
{ {
int i; int i;
for(i = 0; i < node_count; 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 */ /* Node already added */
return &nodes[i]; return &nodes[i];
} }
} }
if(node_count < MAX_NODES) { 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 &nodes[node_count++];
} }
return NULL; 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); printf(" URI: %s Value: %s\n", uri, value);
for(i = 0; i < node_count; 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)) {
/* setup command */ /* setup command */
current_target = &nodes[i]; current_target = &nodes[i];
current_request = COAP_PUT; current_request = COAP_PUT;
strncpy(current_uri, uri, sizeof(current_uri) - 1); strncpy(current_uri, uri, sizeof(current_uri) - 1);
strncpy(current_value, value, sizeof(current_value) - 1); strncpy(current_value, value, sizeof(current_value) - 1);
process_poll(&router_process); process_post(&router_process, EVENT_RUN_NOW, NULL);
break; break;
} }
} }
@ -128,13 +134,13 @@ get_value(const uip_ipaddr_t *addr, char *uri)
printf(" URI: %s\n", uri); printf(" URI: %s\n", uri);
for(i = 0; i < node_count; 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)) {
/* setup command */ /* setup command */
current_target = &nodes[i]; current_target = &nodes[i];
current_request = COAP_GET; current_request = COAP_GET;
strncpy(current_uri, uri, sizeof(current_uri) - 1); strncpy(current_uri, uri, sizeof(current_uri) - 1);
current_value[0] = 0; current_value[0] = 0;
process_poll(&router_process); process_post(&router_process, EVENT_RUN_NOW, NULL);
break; break;
} }
} }
@ -151,7 +157,7 @@ print_node_list(void)
printf(";"); printf(";");
} }
printf("%s,", nodes[i].type); printf("%s,", nodes[i].type);
uip_debug_ipaddr_print(&nodes[i].ipaddr); uip_debug_ipaddr_print(&nodes[i].endpoint.ipaddr);
} }
} }
printf("\n"); printf("\n");
@ -162,7 +168,7 @@ print_node_list(void)
* handle responses. * handle responses.
*/ */
static void static void
client_chunk_handler(void *response) client_chunk_handler(coap_message_t *response)
{ {
const uint8_t *chunk; const uint8_t *chunk;
unsigned int format; unsigned int format;
@ -172,7 +178,9 @@ client_chunk_handler(void *response)
/* if(len > 0) { */ /* if(len > 0) { */
/* printf("|%.*s (%d,%d)", len, (char *)chunk, len, format); */ /* 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) { if(len > sizeof(current_target->type) - 1) {
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; current_target->flags |= NODE_HAS_TYPE;
PRINTF("\nNODE "); PRINTF("\nNODE ");
PRINT6ADDR(&current_target->ipaddr); PRINT6ADDR(&current_target->endpoint.ipaddr);
PRINTF(" HAS TYPE %s\n", current_target->type); PRINTF(" HAS TYPE %s\n", current_target->type);
} else { } else {
/* otherwise update the current value */ /* otherwise update the current value */
@ -193,7 +201,9 @@ client_chunk_handler(void *response)
/* tlv.type, tlv.length, tlv.id, tlv.value[0]); */ /* tlv.type, tlv.length, tlv.id, tlv.value[0]); */
int value = lwm2m_tlv_get_int32(&tlv); 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 { } else {
if(len > sizeof(current_value) - 1) { if(len > sizeof(current_value) - 1) {
@ -205,82 +215,48 @@ client_chunk_handler(void *response)
} }
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void #if UIP_CONF_IPV6_RPL
setup_network(void) static bool
check_rpl_routes(void)
{ {
uip_ipaddr_t ipaddr; uip_sr_node_t *link;
struct uip_ds6_addr *root_if; uip_ipaddr_t child_ipaddr;
rpl_dag_t *dag; uip_ipaddr_t parent_ipaddr;
int i;
uint8_t state;
#if UIP_CONF_ROUTER /* Our routing links */
/** for(link = uip_sr_node_head(); link != NULL; link = uip_sr_node_next(link)) {
* The choice of server address determines its 6LoWPAN header compression. NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link);
* 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
NETSTACK_ROUTING.root_set_prefix(&ipaddr, &ipaddr); if(link->parent == NULL) {
NETSTACK_ROUTING.root_start(); /* Igore the DAG root */
#endif /* UIP_CONF_ROUTER */ continue;
}
PRINTF("IPv6 addresses: "); current_target = add_node(&child_ipaddr);
for(i = 0; i < UIP_DS6_ADDR_NB; i++) { if(current_target == NULL ||
state = uip_ds6_if.addr_list[i].state; (current_target->flags & NODE_HAS_TYPE) != 0 ||
if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) { current_target->retries > 5) {
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); continue;
}
NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent);
PRINTF(" ");
PRINT6ADDR(&child_ipaddr);
PRINTF(" -> ");
PRINT6ADDR(&parent_ipaddr);
PRINTF("\n"); PRINTF("\n");
/* hack to make address "final" */ return true;
if (state == ADDR_TENTATIVE) {
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
}
}
} }
return false;
} }
#endif /* UIP_CONF_IPV6_RPL */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
PROCESS_THREAD(router_process, ev, data) #if (UIP_MAX_ROUTES != 0)
static bool
check_routes(void)
{ {
/* 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_ds6_route_t *r;
uip_ipaddr_t *nexthop;
int n;
PROCESS_BEGIN();
PROCESS_PAUSE();
setup_network();
while(1) {
etimer_set(&timer, CLOCK_SECOND * 5);
PROCESS_YIELD();
/* Handle serial line input */
if(ev == serial_line_event_message) {
serial_protocol_input((char *) data);
}
if(etimer_expired(&timer)) {
current_target = NULL;
n = 0;
for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) { for(r = uip_ds6_route_head(); r != NULL; r = uip_ds6_route_next(r)) {
current_target = add_node(&r->ipaddr); current_target = add_node(&r->ipaddr);
if(current_target == NULL || if(current_target == NULL ||
@ -294,14 +270,47 @@ PROCESS_THREAD(router_process, ev, data)
nexthop = uip_ds6_route_nexthop(r); nexthop = uip_ds6_route_nexthop(r);
if(nexthop != NULL) { if(nexthop != NULL) {
PRINT6ADDR(nexthop); PRINT6ADDR(nexthop);
PRINTF("\n");
} else { } else {
PRINTF("-"); PRINTF("-");
} }
PRINTF("\n"); PRINTF("\n");
n++; return true;
break;
} }
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;
PROCESS_BEGIN();
/* Initialize DAG root */
NETSTACK_ROUTING.root_start();
while(1) {
etimer_set(&timer, CLOCK_SECOND * 5);
PROCESS_YIELD();
/* Handle serial line input */
if(ev == serial_line_event_message) {
serial_protocol_input((char *) data);
}
if(etimer_expired(&timer)) {
current_target = NULL;
#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 */ /* This is a node type discovery */
@ -316,15 +325,15 @@ PROCESS_THREAD(router_process, ev, data)
current_target->retries++; current_target->retries++;
PRINTF("CoAP request to ["); PRINTF("CoAP request to [");
PRINT6ADDR(&current_target->ipaddr); PRINT6ADDR(&current_target->endpoint.ipaddr);
PRINTF("]:%u (%u tx)\n", UIP_HTONS(REMOTE_PORT), PRINTF("]:%u (%u tx)\n", UIP_HTONS(current_target->endpoint.port),
current_target->retries); current_target->retries);
fetching_type = 1; fetching_type = 1;
COAP_BLOCKING_REQUEST(&current_target->ipaddr, REMOTE_PORT, request, COAP_BLOCKING_REQUEST(&current_target->endpoint, request,
client_chunk_handler); client_chunk_handler);
fetching_type = 0; 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"); printf("\n--Done--\n");
} }
@ -341,10 +350,11 @@ PROCESS_THREAD(router_process, ev, data)
} }
PRINTF("CoAP request to ["); PRINTF("CoAP request to [");
PRINT6ADDR(&current_target->ipaddr); PRINT6ADDR(&current_target->endpoint.ipaddr);
PRINTF("]:%u %s\n", UIP_HTONS(REMOTE_PORT), current_uri); PRINTF("]:%u %s\n", UIP_HTONS(current_target->endpoint.port),
current_uri);
COAP_BLOCKING_REQUEST(&current_target->ipaddr, REMOTE_PORT, request, COAP_BLOCKING_REQUEST(&current_target->endpoint, request,
client_chunk_handler); client_chunk_handler);
/* print out result of command */ /* print out result of command */
@ -353,13 +363,12 @@ PROCESS_THREAD(router_process, ev, data)
} else { } else {
printf("g "); printf("g ");
} }
uip_debug_ipaddr_print(&current_target->ipaddr); uip_debug_ipaddr_print(&current_target->endpoint.ipaddr);
printf(" %s %s\n", current_uri, current_value); printf(" %s %s\n", current_uri, current_value);
current_target = NULL; current_target = NULL;
current_uri[0] = 0; current_uri[0] = 0;
current_value[0] = 0; current_value[0] = 0;
} }
} }

View File

@ -60,7 +60,7 @@ find_next_sep(const char *str, char sep, int pos)
/* /*
* l - list all discovered devices * l - list all discovered devices
* s - set <IP> <URI> <value> * s - set <IP> <URI> <value>
* d - get <IP> <URI> * g - get <IP> <URI>
*/ */
void void
serial_protocol_input(char *data) serial_protocol_input(char *data)
@ -119,8 +119,12 @@ serial_protocol_input(char *data)
} }
break; break;
} }
case '\0':
/* Ignore empty lines */
break;
default: default:
printf("Unknown command\n"); printf("Unknown command\n");
} }
printf("> ");
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -54,7 +54,12 @@
#define UIP_MCAST6_ROUTE_CONF_ROUTES 1 #define UIP_MCAST6_ROUTE_CONF_ROUTES 1
/* Code/RAM footprint savings so that things will fit on our device */ /* Code/RAM footprint savings so that things will fit on our device */
#ifndef NETSTACK_MAX_ROUTE_ENTRIES
#define NETSTACK_MAX_ROUTE_ENTRIES 10 #define NETSTACK_MAX_ROUTE_ENTRIES 10
#endif
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define NBR_TABLE_CONF_MAX_NEIGHBORS 10 #define NBR_TABLE_CONF_MAX_NEIGHBORS 10
#endif
#endif /* PROJECT_CONF_H_ */ #endif /* PROJECT_CONF_H_ */

View 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

View File

@ -54,33 +54,38 @@ tab, as per the image below.
CoAP Server CoAP Server
----------- -----------
For this functionality to work, you will need to install the For this functionality to work, you will need to install a CoAP client.
[Copper (Cu)](https://addons.mozilla.org/en-US/firefox/addon/copper-270430/) You can achieve this by following the guides on how to set up your system
addon to your browser. [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 You should start by sending a CoAP GET request for the `.well-known/core`
corresponding to your CC26xx device. Once the addon fires up, select resource. If you are using libcoap's CoAP client, this can be achieved by:
".well-known/core" in the left pane and then hit the 'Get' button at the top.
![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 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 will be different between the various CC13x0/CC26x0 boards.
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.
You can also use CoAP to enable/disable BLE advertisements! Select Send a CoAP GET request for any of those resrouces to retrieve its value.
`dev/ble_advd` and then hit the "Outgoing" button in the payload panel. Type in
the desired payload, which can be: 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` * `mode=on|off`
* `name=<name>` * `name=<name>`
* `interval=<secs>` * `interval=<secs>`
or a combination of both delimited with an amp. For example, you can set as or a combination of the above delimited with an amp. For example, you can set
payload `mode=on&name=My CC26xx Device 4&interval=5`. Once you have set the as payload `mode=on&name=My CC26xx Device 4&interval=5`.
payload, hit either the POST or PUT button.
Bear in mind that you must set `name` at least once before enabling BLE 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 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

View File

@ -33,7 +33,7 @@
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Change to match your configuration */ /* Change to match your configuration */
#define IEEE802154_CONF_PANID 0xABCD #define IEEE802154_CONF_PANID 0xABCD
#define IEEE802154_CONF_DEFAULT_CHANNEL 25 #define IEEE802154_CONF_DEFAULT_CHANNEL 26
#define RF_BLE_CONF_ENABLED 1 #define RF_BLE_CONF_ENABLED 1
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -187,8 +187,8 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
} }
return 1; return 1;
} }
} else if(uip_buf[0] == '?') { } else if(data[0] == '?') {
LOG_DBG("Got request message of type %c\n", uip_buf[1]); LOG_DBG("Got request message of type %c\n", data[1]);
if(data[1] == 'M') { if(data[1] == 'M') {
/* this is just a test so far... just to see if it works */ /* this is just a test so far... just to see if it works */
uip_buf[0] = '!'; uip_buf[0] = '!';
@ -226,8 +226,9 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
static void static void
slip_input_callback(void) slip_input_callback(void)
{ {
LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]); LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len,
if(!cmd_input(uip_buf, 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); cmd_send((uint8_t *)"EUnknown command", 16);
} }
uip_clear_buf(); uip_clear_buf();

View File

@ -3,7 +3,7 @@ CONTIKI = ../../..
MODULES += os/storage/antelope os/services/unit-test MODULES += os/storage/antelope os/services/unit-test
# does not fit on Sky # does not fit on Sky
PLATFORMS_ONLY= cc2538 PLATFORMS_ONLY= cc2538dk zoul
CONTIKI_PROJECT = shell-db CONTIKI_PROJECT = shell-db
all: $(CONTIKI_PROJECT) all: $(CONTIKI_PROJECT)

View File

@ -1,6 +1,6 @@
CONTIKI = ../../.. CONTIKI = ../../..
PLATFORMS_ONLY= cc2538 sky PLATFORMS_ONLY= cc2538dk zoul sky
MODULES += os/services/unit-test MODULES += os/services/unit-test
MODULES += os/storage/cfs MODULES += os/storage/cfs

View File

@ -49,7 +49,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-block1" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -51,7 +51,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-blocking-api" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -51,7 +51,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-callback-api" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
/* These should go into the state struct so that we can have multiple /* These should go into the state struct so that we can have multiple

View File

@ -55,7 +55,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-observe-client" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
MEMB(obs_subjects_memb, coap_observee_t, COAP_MAX_OBSERVEES); MEMB(obs_subjects_memb, coap_observee_t, COAP_MAX_OBSERVEES);

View File

@ -50,7 +50,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-observe" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -47,7 +47,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-res-well-known-core" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
#define ADD_CHAR_IF_POSSIBLE(char) \ #define ADD_CHAR_IF_POSSIBLE(char) \

View File

@ -49,7 +49,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-separate" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -52,7 +52,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-timer-default" #define LOG_MODULE "coap-timer"
#define LOG_LEVEL LOG_LEVEL_NONE #define LOG_LEVEL LOG_LEVEL_NONE
PROCESS(coap_timer_process, "coap timer process"); PROCESS(coap_timer_process, "coap timer process");

View File

@ -50,7 +50,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "coap-transactions" #define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP #define LOG_LEVEL LOG_LEVEL_COAP
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -42,7 +42,7 @@
#include <stdarg.h> #include <stdarg.h>
/* Log configuration */ /* Log configuration */
#define LOG_MODULE "dtls-support" #define LOG_MODULE "dtls"
#define LOG_LEVEL LOG_LEVEL_DTLS #define LOG_LEVEL LOG_LEVEL_DTLS
#include "dtls-log.h" #include "dtls-log.h"
#include "coap-log.h" #include "coap-log.h"

View File

@ -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; return n;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -50,10 +50,10 @@
#include "lib/list.h" #include "lib/list.h"
#include "lib/memb.h" #include "lib/memb.h"
#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 #if CONTIKI_TARGET_COOJA
#include "lib/simEnvChange.h" #include "lib/simEnvChange.h"
#include "sys/cooja_mt.h" #include "sys/cooja_mt.h"
#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ #endif /* CONTIKI_TARGET_COOJA */
/* Log configuration */ /* Log configuration */
#include "sys/log.h" #include "sys/log.h"
@ -207,10 +207,10 @@ send_one_packet(void *ptr)
wt = RTIMER_NOW(); wt = RTIMER_NOW();
watchdog_periodic(); watchdog_periodic();
while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + CSMA_ACK_WAIT_TIME)) { 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; simProcessRunValue = 1;
cooja_mt_yield(); cooja_mt_yield();
#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ #endif /* CONTIKI_TARGET_COOJA */
} }
ret = MAC_TX_NOACK; ret = MAC_TX_NOACK;
@ -225,10 +225,10 @@ send_one_packet(void *ptr)
watchdog_periodic(); watchdog_periodic();
while(RTIMER_CLOCK_LT(RTIMER_NOW(), while(RTIMER_CLOCK_LT(RTIMER_NOW(),
wt + CSMA_AFTER_ACK_DETECTED_WAIT_TIME)) { wt + CSMA_AFTER_ACK_DETECTED_WAIT_TIME)) {
#if CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 #if CONTIKI_TARGET_COOJA
simProcessRunValue = 1; simProcessRunValue = 1;
cooja_mt_yield(); cooja_mt_yield();
#endif /* CONTIKI_TARGET_COOJA || CONTIKI_TARGET_COOJA_IP64 */ #endif /* CONTIKI_TARGET_COOJA */
} }
} }

View File

@ -33,6 +33,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH adaptive time synchronization
*/ */
#ifndef __TSCH_ADAPTIVE_TIMESYNC_H__ #ifndef __TSCH_ADAPTIVE_TIMESYNC_H__
@ -44,15 +46,30 @@
/***** External Variables *****/ /***** 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; extern struct tsch_neighbor *last_timesource_neighbor;
/********** Functions *********/ /********** 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); 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); 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); long int tsch_adaptive_timesync_get_drift_ppm(void);
#endif /* __TSCH_ADAPTIVE_TIMESYNC_H__ */ #endif /* __TSCH_ADAPTIVE_TIMESYNC_H__ */

View File

@ -31,16 +31,12 @@
*/ */
/** /**
* \addtogroup tsch
* @{
* \file * \file
* TSCH 5-Byte Absolute Slot Number (ASN) management * TSCH 5-Byte Absolute Slot Number (ASN) management
* \author * \author
* Simon Duquennoy <simonduq@sics.se> * Simon Duquennoy <simonduq@sics.se>
*
*/
/**
* \addtogroup tsch
* @{
*/ */
#ifndef __TSCH_ASN_H__ #ifndef __TSCH_ASN_H__
@ -48,13 +44,13 @@
/************ Types ***********/ /************ 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 { struct tsch_asn_t {
uint32_t ls4b; /* least significant 4 bytes */ uint32_t ls4b; /* least significant 4 bytes */
uint8_t ms1b; /* most significant 1 byte */ 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 { struct tsch_asn_divisor_t {
uint16_t val; /* Divisor value */ uint16_t val; /* Divisor value */
uint16_t asn_ms1b_remainder; /* Remainder of the operation 0x100000000 / val */ uint16_t asn_ms1b_remainder; /* Remainder of the operation 0x100000000 / val */
@ -62,37 +58,37 @@ struct tsch_asn_divisor_t {
/************ Macros **********/ /************ Macros **********/
/* Initialize ASN */ /** \brief Initialize ASN */
#define TSCH_ASN_INIT(asn, ms1b_, ls4b_) do { \ #define TSCH_ASN_INIT(asn, ms1b_, ls4b_) do { \
(asn).ms1b = (ms1b_); \ (asn).ms1b = (ms1b_); \
(asn).ls4b = (ls4b_); \ (asn).ls4b = (ls4b_); \
} while(0); } while(0);
/* Increment an ASN by inc (32 bits) */ /** \brief Increment an ASN by inc (32 bits) */
#define TSCH_ASN_INC(asn, inc) do { \ #define TSCH_ASN_INC(asn, inc) do { \
uint32_t new_ls4b = (asn).ls4b + (inc); \ uint32_t new_ls4b = (asn).ls4b + (inc); \
if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \ if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \
(asn).ls4b = new_ls4b; \ (asn).ls4b = new_ls4b; \
} while(0); } while(0);
/* Decrement an ASN by inc (32 bits) */ /** \brief Decrement an ASN by inc (32 bits) */
#define TSCH_ASN_DEC(asn, dec) do { \ #define TSCH_ASN_DEC(asn, dec) do { \
uint32_t new_ls4b = (asn).ls4b - (dec); \ uint32_t new_ls4b = (asn).ls4b - (dec); \
if(new_ls4b > (asn).ls4b) { (asn).ms1b--; } \ if(new_ls4b > (asn).ls4b) { (asn).ms1b--; } \
(asn).ls4b = new_ls4b; \ (asn).ls4b = new_ls4b; \
} while(0); } 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) \ #define TSCH_ASN_DIFF(asn1, asn2) \
((asn1).ls4b - (asn2).ls4b) ((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 { \ #define TSCH_ASN_DIVISOR_INIT(div, val_) do { \
(div).val = (val_); \ (div).val = (val_); \
(div).asn_ms1b_remainder = ((0xffffffff % (val_)) + 1) % (val_); \ (div).asn_ms1b_remainder = ((0xffffffff % (val_)) + 1) % (val_); \
} while(0); } 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 */ * with divisor being a struct asn_divisor_t */
#define TSCH_ASN_MOD(asn, div) \ #define TSCH_ASN_MOD(asn, div) \
((uint16_t)((asn).ls4b % (div).val) \ ((uint16_t)((asn).ls4b % (div).val) \

View File

@ -31,17 +31,14 @@
*/ */
/** /**
* \addtogroup tsch
* @{
* \file * \file
* TSCH configuration * TSCH configuration
* \author * \author
* Simon Duquennoy <simonduq@sics.se> * Simon Duquennoy <simonduq@sics.se>
*/ */
/**
* \addtogroup tsch
* @{
*/
#ifndef __TSCH_CONF_H__ #ifndef __TSCH_CONF_H__
#define __TSCH_CONF_H__ #define __TSCH_CONF_H__

View File

@ -31,17 +31,14 @@
*/ */
/** /**
* \addtogroup tsch
* @{
* \file * \file
* TSCH configuration * TSCH constants
* \author * \author
* Simon Duquennoy <simonduq@sics.se> * Simon Duquennoy <simonduq@sics.se>
*/ */
/**
* \addtogroup tsch
* @{
*/
#ifndef __TSCH_CONST_H__ #ifndef __TSCH_CONST_H__
#define __TSCH_CONST_H__ #define __TSCH_CONST_H__

View File

@ -33,6 +33,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH per-slot logging
*/ */
#ifndef __TSCH_LOG_H__ #ifndef __TSCH_LOG_H__
@ -70,7 +72,7 @@
/************ Types ***********/ /************ 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 { struct tsch_log_t {
enum { tsch_log_tx, enum { tsch_log_tx,
tsch_log_rx, tsch_log_rx,
@ -107,21 +109,31 @@ struct tsch_log_t {
/********** Functions *********/ /********** 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); 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); void tsch_log_commit(void);
/* Initialize log module */ /**
* \brief Initialize log module
*/
void tsch_log_init(void); void tsch_log_init(void);
/* Process pending log messages */ /**
* \brief Process pending log messages
*/
void tsch_log_process_pending(void); void tsch_log_process_pending(void);
/* Stop logging module */ /**
* \brief Stop logging module
*/
void tsch_log_stop(void); void tsch_log_stop(void);
/************ Macros **********/ /************ 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) */ * later, after leaving interrupt context) */
#define TSCH_LOG_ADD(log_type, init_code) do { \ #define TSCH_LOG_ADD(log_type, init_code) do { \
struct tsch_log_t *log = tsch_log_prepare_add(); \ struct tsch_log_t *log = tsch_log_prepare_add(); \

View File

@ -390,8 +390,7 @@ tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset)
struct ieee802154_ies ies; struct ieee802154_ies ies;
ies.ie_asn = tsch_current_asn; ies.ie_asn = tsch_current_asn;
ies.ie_join_priority = tsch_join_priority; 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 frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies) != -1;
return 1;
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Parse a IEEE 802.15.4e TSCH Enhanced Beacon (EB) */ /* Parse a IEEE 802.15.4e TSCH Enhanced Beacon (EB) */

View File

@ -33,6 +33,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH packet parsing and creation. EBs and EACKs.
*/ */
#ifndef __TSCH_PACKET_H__ #ifndef __TSCH_PACKET_H__
@ -46,18 +48,56 @@
/********** Functions *********/ /********** 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, int tsch_packet_create_eack(uint8_t *buf, uint16_t buf_size,
const linkaddr_t *dest_addr, uint8_t seqno, const linkaddr_t *dest_addr, uint8_t seqno,
int16_t drift, int nack); 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, 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); 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); 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); 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, int tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
frame802154_t *frame, struct ieee802154_ies *ies, frame802154_t *frame, struct ieee802154_ies *ies,
uint8_t *hdrlen, int frame_without_mic); uint8_t *hdrlen, int frame_without_mic);

View File

@ -33,6 +33,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH queues
*/ */
#ifndef __TSCH_QUEUE_H__ #ifndef __TSCH_QUEUE_H__
@ -53,50 +55,128 @@ extern struct tsch_neighbor *n_eb;
/********** Functions *********/ /********** 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); 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); 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); 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); 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, struct tsch_packet *tsch_queue_add_packet(const linkaddr_t *addr, uint8_t max_transmissions,
mac_callback_t sent, void *ptr); 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); 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); 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); 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); 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); 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); void tsch_queue_reset(void);
/* Deallocate neighbors with empty queue */ /**
* \brief Deallocate all neighbors with empty queue
*/
void tsch_queue_free_unused_neighbors(void); 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); 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); 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); 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); 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); 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); 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); 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); 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); void tsch_queue_init(void);
#endif /* __TSCH_QUEUE_H__ */ #endif /* __TSCH_QUEUE_H__ */

View File

@ -31,6 +31,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH-RPL interaction
*/ */
#ifndef __TSCH_RPL_H__ #ifndef __TSCH_RPL_H__
@ -47,20 +49,35 @@
/********** Functions *********/ /********** 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); 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); void tsch_rpl_callback_joining_network(void);
/* Upon leaving a TSCH network, perform a local repair /**
* (cleanup neighbor state, reset Trickle timer etc) * \brief Let RPL know that TSCH joined a new network. Triggers a local repair.
* To use, set #define TSCH_CALLBACK_LEAVING_NETWORK tsch_rpl_callback_leaving_network */ * To use, set TSCH_CALLBACK_LEAVING_NETWORK to tsch_rpl_callback_leaving_network
*/
void tsch_rpl_callback_leaving_network(void); 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); 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); void tsch_rpl_callback_parent_switch(rpl_parent_t *old, rpl_parent_t *new);
#endif /* __TSCH_RPL_H__ */ #endif /* __TSCH_RPL_H__ */

View File

@ -33,6 +33,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH scheduling engine
*/ */
#ifndef __TSCH_SCHEDULE_H__ #ifndef __TSCH_SCHEDULE_H__
@ -45,42 +47,115 @@
/********** Functions *********/ /********** 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); 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); 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); 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); 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); 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); 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); int tsch_schedule_remove_all_slotframes(void);
/* Returns next slotframe */ /**
struct tsch_slotframe *tsch_schedule_slotframes_next(struct tsch_slotframe *sf); * \brief Adds a link to a slotframe
/* Adds a link to a slotframe, return a pointer to it (NULL if failure) */ * \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, struct tsch_link *tsch_schedule_add_link(struct tsch_slotframe *slotframe,
uint8_t link_options, enum link_type link_type, const linkaddr_t *address, uint8_t link_options, enum link_type link_type, const linkaddr_t *address,
uint16_t timeslot, uint16_t channel_offset); 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); 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); 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); 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); 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 * tsch_schedule_get_next_active_link(struct tsch_asn_t *asn, uint16_t *time_offset,
struct tsch_link **backup_link); 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); 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); struct tsch_slotframe *tsch_schedule_slotframe_next(struct tsch_slotframe *sf);
#endif /* __TSCH_SCHEDULE_H__ */ #endif /* __TSCH_SCHEDULE_H__ */

View File

@ -33,6 +33,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH security
*/ */
#ifndef __TSCH_SECURITY_H__ #ifndef __TSCH_SECURITY_H__

View File

@ -33,6 +33,8 @@
/** /**
* \addtogroup tsch * \addtogroup tsch
* @{ * @{
* \file
* TSCH runtime operation within timeslots
*/ */
#ifndef __TSCH_SLOT_OPERATION_H__ #ifndef __TSCH_SLOT_OPERATION_H__
@ -58,19 +60,45 @@ extern clock_time_t last_sync_time;
/********** Functions *********/ /********** 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); 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); 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); int tsch_get_lock(void);
/* Release TSCH lock */ /**
* Releases the TSCH lock.
*/
void tsch_release_lock(void); 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, void tsch_slot_operation_sync(rtimer_clock_t next_slot_start,
struct tsch_asn_t *next_slot_asn); struct tsch_asn_t *next_slot_asn);
/* Start actual slot operation */ /**
* Start actual slot operation
*/
void tsch_slot_operation_start(void); void tsch_slot_operation_start(void);
#endif /* __TSCH_SLOT_OPERATION_H__ */ #endif /* __TSCH_SLOT_OPERATION_H__ */

View File

@ -31,17 +31,14 @@
*/ */
/** /**
* \addtogroup tsch
* @{
* \file * \file
* TSCH types * TSCH types
* \author * \author
* Simon Duquennoy <simonduq@sics.se> * Simon Duquennoy <simonduq@sics.se>
*/ */
/**
* \addtogroup tsch
* @{
*/
#ifndef __TSCH_TYPES_H__ #ifndef __TSCH_TYPES_H__
#define __TSCH_TYPES_H__ #define __TSCH_TYPES_H__
@ -53,10 +50,10 @@
/********** Data types **********/ /********** Data types **********/
/* 802.15.4e link types. /** \brief 802.15.4e link types. LINK_TYPE_ADVERTISING_ONLY is an extra one: for EB-only links. */
* 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 }; 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 { struct tsch_link {
/* Links are stored as a list: "next" must be the first field */ /* Links are stored as a list: "next" must be the first field */
struct tsch_link *next; struct tsch_link *next;
@ -83,7 +80,7 @@ struct tsch_link {
void *data; void *data;
}; };
/* 802.15.4e slotframe (contains links) */ /** \brief 802.15.4e slotframe (contains links) */
struct tsch_slotframe { struct tsch_slotframe {
/* Slotframes are stored as a list: "next" must be the first field */ /* Slotframes are stored as a list: "next" must be the first field */
struct tsch_slotframe *next; struct tsch_slotframe *next;
@ -96,7 +93,7 @@ struct tsch_slotframe {
LIST_STRUCT(links_list); LIST_STRUCT(links_list);
}; };
/* TSCH packet information */ /** \brief TSCH packet information */
struct tsch_packet { struct tsch_packet {
struct queuebuf *qb; /* pointer to the queuebuf to be sent */ struct queuebuf *qb; /* pointer to the queuebuf to be sent */
mac_callback_t sent; /* callback for this packet */ 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 */ 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 { struct tsch_neighbor {
/* Neighbors are stored as a list: "next" must be the first field */ /* Neighbors are stored as a list: "next" must be the first field */
struct tsch_neighbor *next; struct tsch_neighbor *next;
@ -127,7 +124,7 @@ struct tsch_neighbor {
struct ringbufindex tx_ringbuf; 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 */ * of different units, such as rtimer tick or micro-second */
enum tsch_timeslot_timing_elements { enum tsch_timeslot_timing_elements {
tsch_ts_cca_offset, tsch_ts_cca_offset,
@ -145,7 +142,7 @@ enum tsch_timeslot_timing_elements {
tsch_ts_elements_count, /* Not a timing element */ tsch_ts_elements_count, /* Not a timing element */
}; };
/* Stores data about an incoming packet */ /** \brief Stores data about an incoming packet */
struct input_packet { struct input_packet {
uint8_t payload[TSCH_PACKET_MAX_LEN]; /* Packet payload */ uint8_t payload[TSCH_PACKET_MAX_LEN]; /* Packet payload */
struct tsch_asn_t rx_asn; /* ASN when the packet was received */ struct tsch_asn_t rx_asn; /* ASN when the packet was received */

View File

@ -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 scheduled communication on top of a globally-synchronized network. Performs
frequency hopping for enhanced reliability. frequency hopping for enhanced reliability.
* @{ * @{
* \file
* Main API declarations for TSCH.
*/ */
#ifndef __TSCH_H__ #ifndef __TSCH_H__
@ -180,21 +182,57 @@ PROCESS_NAME(tsch_pending_events_process);
/********** Functions *********/ /********** 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); 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); 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); 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); 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); 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); void tsch_schedule_keepalive(void);
/* Set TSCH to send a keepalive message immediately */ /**
* Schedule a keep-alive immediately
*/
void tsch_schedule_keepalive_immediately(void); void tsch_schedule_keepalive_immediately(void);
/* Leave the TSCH network */ /**
* Leave the TSCH network we are currently in
*/
void tsch_disassociate(void); void tsch_disassociate(void);
#endif /* __TSCH_H__ */ #endif /* __TSCH_H__ */

View File

@ -151,7 +151,7 @@ drop_route(uip_ds6_route_t *route)
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
const struct routing_driver nullrouting_driver = { const struct routing_driver nullrouting_driver = {
"Null Routing", "nullrouting",
init, init,
root_set_prefix, root_set_prefix,
root_start, root_start,

View File

@ -57,24 +57,24 @@ static void
input_callback(void) input_callback(void)
{ {
/*PRINTF("SIN: %u\n", uip_len);*/ /*PRINTF("SIN: %u\n", uip_len);*/
if(uip_buf[0] == '!') { if(uip_buf[UIP_LLH_LEN] == '!') {
PRINTF("Got configuration message of type %c\n", uip_buf[1]); PRINTF("Got configuration message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
uip_clear_buf(); uip_clear_buf();
#if 0 #if 0
if(uip_buf[1] == 'P') { if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
uip_ipaddr_t prefix; uip_ipaddr_t prefix;
/* Here we set a prefix !!! */ /* Here we set a prefix !!! */
memset(&prefix, 0, 16); memset(&prefix, 0, 16);
memcpy(&prefix, &uip_buf[2], 8); memcpy(&prefix, &uip_buf[UIP_LLH_LEN + 2], 8);
PRINTF("Setting prefix "); PRINTF("Setting prefix ");
PRINT6ADDR(&prefix); PRINT6ADDR(&prefix);
PRINTF("\n"); PRINTF("\n");
set_prefix_64(&prefix); set_prefix_64(&prefix);
} }
#endif #endif
} else if(uip_buf[0] == '?') { } else if(uip_buf[UIP_LLH_LEN] == '?') {
PRINTF("Got request message of type %c\n", uip_buf[1]); PRINTF("Got request message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
if(uip_buf[1] == 'M') { if(uip_buf[UIP_LLH_LEN + 1] == 'M') {
const char *hexchar = "0123456789abcdef"; const char *hexchar = "0123456789abcdef";
int j; int j;
/* this is just a test so far... just to see if it works */ /* 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_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15];
} }
uip_len = 18; uip_len = 18;
slip_send(); slip_write(uip_buf, uip_len);
} }
uip_clear_buf(); uip_clear_buf();
} else { } else {
@ -147,6 +146,3 @@ const struct uip_fallback_interface ip64_slip_interface = {
init, output init, output
}; };
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -48,7 +48,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-device" #define LOG_MODULE "lwm2m-dev"
#define LOG_LEVEL LOG_LEVEL_LWM2M #define LOG_LEVEL LOG_LEVEL_LWM2M
static const lwm2m_resource_id_t resources[] = static const lwm2m_resource_id_t resources[] =

View File

@ -63,7 +63,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-engine" #define LOG_MODULE "lwm2m-eng"
#define LOG_LEVEL LOG_LEVEL_LWM2M #define LOG_LEVEL LOG_LEVEL_LWM2M
#ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX #ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX

View File

@ -44,7 +44,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-firmware" #define LOG_MODULE "lwm2m-fw"
#define LOG_LEVEL LOG_LEVEL_LWM2M #define LOG_LEVEL LOG_LEVEL_LWM2M
#define UPDATE_PACKAGE 0 #define UPDATE_PACKAGE 0

View File

@ -49,7 +49,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-plain-text" #define LOG_MODULE "lwm2m-text"
#define LOG_LEVEL LOG_LEVEL_NONE #define LOG_LEVEL LOG_LEVEL_NONE
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -64,7 +64,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-rd-client" #define LOG_MODULE "lwm2m-rd"
#define LOG_LEVEL LOG_LEVEL_LWM2M #define LOG_LEVEL LOG_LEVEL_LWM2M
#ifndef LWM2M_DEFAULT_CLIENT_LIFETIME #ifndef LWM2M_DEFAULT_CLIENT_LIFETIME

View File

@ -54,7 +54,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-security" #define LOG_MODULE "lwm2m-sec"
#define LOG_LEVEL LOG_LEVEL_LWM2M #define LOG_LEVEL LOG_LEVEL_LWM2M
#define MAX_COUNT LWM2M_SERVER_MAX_COUNT #define MAX_COUNT LWM2M_SERVER_MAX_COUNT

View File

@ -51,7 +51,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-server" #define LOG_MODULE "lwm2m-srv"
#define LOG_LEVEL LOG_LEVEL_LWM2M #define LOG_LEVEL LOG_LEVEL_LWM2M
#define MAX_COUNT LWM2M_SERVER_MAX_COUNT #define MAX_COUNT LWM2M_SERVER_MAX_COUNT

View File

@ -47,7 +47,7 @@
/* Log configuration */ /* Log configuration */
#include "coap-log.h" #include "coap-log.h"
#define LOG_MODULE "lwm2m-tlv-writer" #define LOG_MODULE "lwm2m-tlv"
#define LOG_LEVEL LOG_LEVEL_NONE #define LOG_LEVEL LOG_LEVEL_NONE
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/

View File

@ -62,7 +62,7 @@ request_prefix(void)
uip_buf[0] = '?'; uip_buf[0] = '?';
uip_buf[1] = 'P'; uip_buf[1] = 'P';
uip_len = 2; uip_len = 2;
slip_send(); slip_write(uip_buf, uip_len);
uip_clear_buf(); uip_clear_buf();
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
@ -70,22 +70,27 @@ static void
slip_input_callback(void) slip_input_callback(void)
{ {
LOG_DBG("SIN: %u\n", uip_len); LOG_DBG("SIN: %u\n", uip_len);
if(uip_buf[0] == '!') { if(uip_buf[UIP_LLH_LEN] == '!') {
LOG_INFO("Got configuration message of type %c\n", uip_buf[1]); LOG_INFO("Got configuration message of type %c\n",
uip_clear_buf(); uip_buf[UIP_LLH_LEN + 1]);
if(uip_buf[1] == 'P') { if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
uip_ipaddr_t prefix; uip_ipaddr_t prefix;
/* Here we set a prefix !!! */ /* Here we set a prefix !!! */
memset(&prefix, 0, 16); 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("Setting prefix ");
LOG_INFO_6ADDR(&prefix); LOG_INFO_6ADDR(&prefix);
LOG_INFO_("\n"); LOG_INFO_("\n");
set_prefix_64(&prefix); set_prefix_64(&prefix);
} }
} else if(uip_buf[0] == '?') { uip_clear_buf();
LOG_INFO("Got request message of type %c\n", uip_buf[1]);
if(uip_buf[1] == 'M') { } 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"; char *hexchar = "0123456789abcdef";
int j; int j;
/* this is just a test so far... just to see if it works */ /* 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_buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15];
} }
uip_len = 18; uip_len = 18;
slip_send(); slip_write(uip_buf, uip_len);
} }
uip_clear_buf(); uip_clear_buf();
} } else {
/* Save the last sender received over SLIP to avoid bouncing the /* Save the last sender received over SLIP to avoid bouncing the
packet back if no route is found */ packet back if no route is found */
uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr); uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
}
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void static void

View File

@ -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, "-- State: %s\n", rpl_state_to_str(curr_instance.dag.state));
SHELL_OUTPUT(output, "-- Preferred parent: "); SHELL_OUTPUT(output, "-- Preferred parent: ");
if(curr_instance.dag.preferred_parent) {
shell_output_6addr(output, rpl_neighbor_get_ipaddr(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); 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, "-- 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, "-- 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); 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); PT_END(pt);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if ROUTING_CONF_RPL_LITE
static static
PT_THREAD(cmd_rpl_refresh_routes(struct pt *pt, shell_output_func output, char *args)) 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); PT_END(pt);
} }
#endif /* ROUTING_CONF_RPL_LITE */
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static static
@ -732,7 +738,9 @@ struct shell_command_t shell_commands[] = {
#if UIP_CONF_IPV6_RPL #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-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" }, { "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" }, { "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" }, { "rpl-global-repair", cmd_rpl_global_repair, "'> rpl-global-repair': Triggers a RPL global repair" },
#endif /* UIP_CONF_IPV6_RPL */ #endif /* UIP_CONF_IPV6_RPL */
#if ROUTING_CONF_RPL_LITE #if ROUTING_CONF_RPL_LITE

View File

@ -38,6 +38,7 @@
#define DB_OPTIONS_H #define DB_OPTIONS_H
#include "contiki.h" #include "contiki.h"
#include "cfs-coffee-arch.h"
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -143,9 +144,17 @@
/* The default relation file size to reserve when using Coffee. */ /* The default relation file size to reserve when using Coffee. */
#ifndef DB_COFFEE_RESERVE_SIZE #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 */ #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" /* The maximum size of the physical storage of a tuple (labelled a "row"
in Antelope's terminology. */ in Antelope's terminology. */
#ifndef DB_MAX_CHAR_SIZE_PER_ROW #ifndef DB_MAX_CHAR_SIZE_PER_ROW

View File

@ -17,6 +17,7 @@ lwm2m-ipso-objects/native \
lwm2m-ipso-objects/native:MAKE_WITH_DTLS=1 \ lwm2m-ipso-objects/native:MAKE_WITH_DTLS=1 \
rpl-udp/sky \ rpl-udp/sky \
rpl-border-router/native \ rpl-border-router/native \
rpl-border-router/native:MAKE_ROUTING=MAKE_ROUTING_RPL_CLASSIC \
rpl-border-router/sky \ rpl-border-router/sky \
slip-radio/sky \ slip-radio/sky \
libs/ipv6-hooks/sky \ libs/ipv6-hooks/sky \

14
tools/ip64/jool-start.sh Executable file
View 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