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)
{
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();
}
/*---------------------------------------------------------------------------*/

View File

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

View File

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

View File

@ -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(&current_target->ipaddr);
PRINT6ADDR(&current_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(&current_target->ipaddr);
PRINTF("]:%u (%u tx)\n", UIP_HTONS(REMOTE_PORT),
PRINT6ADDR(&current_target->endpoint.ipaddr);
PRINTF("]:%u (%u tx)\n", UIP_HTONS(current_target->endpoint.port),
current_target->retries);
fetching_type = 1;
COAP_BLOCKING_REQUEST(&current_target->ipaddr, REMOTE_PORT, request,
COAP_BLOCKING_REQUEST(&current_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(&current_target->ipaddr);
PRINTF("]:%u %s\n", UIP_HTONS(REMOTE_PORT), current_uri);
PRINT6ADDR(&current_target->endpoint.ipaddr);
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);
/* print out result of command */
@ -353,13 +363,12 @@ PROCESS_THREAD(router_process, ev, data)
} else {
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);
current_target = NULL;
current_uri[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
* 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("> ");
}
/*---------------------------------------------------------------------------*/

View File

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

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

View File

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

View File

@ -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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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");

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(); \

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;
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) */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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
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__ */

View File

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

View File

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

View File

@ -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[] =

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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, "-- 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

View File

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

View File

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