Merge branch 'develop' into contrib/ci-frag-large

This commit is contained in:
Joakim Eriksson 2018-08-11 00:16:00 +02:00 committed by GitHub
commit 00cd589c84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 1523 additions and 254 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@ obj_*
Makefile.target
Makefile.*.defines
tools/doxygen/html
tools/readthedocs/_build
patches-*
tools/serial-io/tunslip6
tools/serial-io/serialdump

View File

@ -7,7 +7,7 @@ notifications:
# Environment setup before test script. Runs for each build
before_install:
# Check if anything has changed within the docker directory
- DOCKER_CHANGED=`git diff --name-only $TRAVIS_BRANCH...HEAD -- tools/docker | wc -l`
- DOCKER_CHANGED=`git diff --name-only $TRAVIS_COMMIT_RANGE -- tools/docker | wc -l`
# If Docker directory has not changed, pull image from Dockerhub. Else, build
# image from Dockerifle. This needs to be done for each job. Any build error
# will count as Travis test failure. In case this updates develop, push new
@ -20,6 +20,10 @@ before_install:
else
echo "Docker image changed, build from Dockerfile"
docker build tools/docker -t $DOCKER_IMG;
if [ $? != 0 ]; then
echo "Failed to build Docker image"
exit 1
fi
if [ $TRAVIS_SECURE_ENV_VARS == true ] && [ $TRAVIS_PULL_REQUEST == false ] && [ $TRAVIS_BRANCH == 'develop' ]; then
echo "This build is for an update of branch develop. Push image to Dockerhub"
echo $DOCKERHUB_PASSWD | docker login --username contiker --password-stdin
@ -58,7 +62,7 @@ env:
- TEST_NAME='simulation-base'
- TEST_NAME='ieee802154'
- TEST_NAME='compile-nxp-ports'
- TEST_NAME='doxygen'
- TEST_NAME='documentation'
- TEST_NAME='compile-tools'
- TEST_NAME='native-runs'
- TEST_NAME='ipv6'

View File

@ -1,41 +1,30 @@
Contiki-NG is licensed under the 3-clause BSD license. This license gives
everyone the right to use and distribute the code, either in binary or
source code format, as long as the copyright license is retained in
the source code.
Copyright (c) (Year), (Name of copyright holder)
All rights reserved.
The copyright for different parts of the code is held by different
people and organizations, but the code is licensed under the same type
of license. The license text is:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
```
/*
* Copyright (c) (Year), (Name of copyright holder)
* 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 HOLDERS 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.
*/
```
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 HOLDERS 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.

View File

@ -9,7 +9,10 @@
Contiki-NG is an open-source, cross-platform operating system for Next-Generation IoT devices. It focuses on dependable (secure and reliable) low-power communication and standard protocols, such as IPv6/6LoWPAN, 6TiSCH, RPL, and CoAP. Contiki-NG comes with extensive documentation, tutorials, a roadmap, release cycle, and well-defined development flow for smooth integration of community contributions.
Unless excplicitly stated otherwise, Contiki-NG sources are distributed under
the terms of the [3-clause BSD license](LICENSE.md).
the terms of the [3-clause BSD license](LICENSE.md). This license gives
everyone the right to use and distribute the code, either in binary or
source code format, as long as the copyright license is retained in
the source code.
Contiki-NG started as a fork of the Contiki OS and retains some of its original features.

View File

@ -45,6 +45,7 @@
#include "net/netstack.h"
#include "sys/energest.h"
#include "sys/clock.h"
#include "sys/critical.h"
#include "sys/rtimer.h"
#include "sys/cc.h"
#include "lpm.h"
@ -766,6 +767,7 @@ send(const void *payload, unsigned short payload_len)
static int
read_frame(void *buf, unsigned short buf_len)
{
int_master_status_t status;
rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry;
uint8_t *data_ptr = &entry->data;
int len = 0;
@ -795,6 +797,14 @@ read_frame(void *buf, unsigned short buf_len)
entry->status = DATA_ENTRY_STATUS_PENDING;
}
status = critical_enter();
if(rx_is_full) {
rx_is_full = false;
PRINTF("RXQ was full, re-enabling radio!\n");
rx_on_prop();
}
critical_exit(status);
return len;
}
/*---------------------------------------------------------------------------*/

View File

@ -76,7 +76,7 @@
/*---------------------------------------------------------------------------*/
/* RF interrupts */
#define RX_FRAME_IRQ IRQ_RX_ENTRY_DONE
#define ERROR_IRQ IRQ_INTERNAL_ERROR
#define ERROR_IRQ (IRQ_INTERNAL_ERROR | IRQ_RX_BUF_FULL)
#define RX_NOK_IRQ IRQ_RX_NOK
/* Those IRQs are enabled all the time */
@ -103,6 +103,9 @@ static const rf_core_primary_mode_t *primary_mode = NULL;
int32_t rat_offset = 0;
static bool rat_offset_known = false;
/*---------------------------------------------------------------------------*/
/* Buffer full flag */
volatile bool rx_is_full = false;
/*---------------------------------------------------------------------------*/
PROCESS(rf_core_process, "CC13xx / CC26xx RF driver");
/*---------------------------------------------------------------------------*/
#define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \
@ -575,6 +578,16 @@ cc26xx_rf_cpe1_isr(void)
}
}
if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & IRQ_RX_BUF_FULL) {
PRINTF("\nRF: BUF_FULL\n\n");
/* set a flag that the buffer is full*/
rx_is_full = true;
/* make sure read_frame() will be called to make space in RX buffer */
process_poll(&rf_core_process);
/* Clear the IRQ_RX_BUF_FULL interrupt flag by writing zero to bit */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ~(IRQ_RX_BUF_FULL);
}
/* Clear INTERNAL_ERROR interrupt flag */
HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x7FFFFFFF;
}

View File

@ -263,6 +263,9 @@ typedef struct rf_core_primary_mode_s {
/* Radio timer register */
#define RATCNT 0x00000004
/*---------------------------------------------------------------------------*/
/* Buffer full flag */
extern volatile bool rx_is_full;
/*---------------------------------------------------------------------------*/
/* Make the main driver process visible to mode drivers */
PROCESS_NAME(rf_core_process);
/*---------------------------------------------------------------------------*/

View File

@ -108,7 +108,7 @@ print_cell_list(const uint8_t *cell_list, uint16_t cell_list_len)
uint16_t i;
sf_simple_cell_t cell;
for(i = 0; i < (cell_list_len / sizeof(cell)); i++) {
for(i = 0; i < cell_list_len; i += sizeof(cell)) {
read_cell(&cell_list[i], &cell);
PRINTF("%u ", cell.timeslot_offset);
}
@ -132,7 +132,7 @@ add_links_to_schedule(const linkaddr_t *peer_addr, uint8_t link_option,
return;
}
for(i = 0; i < (cell_list_len / sizeof(cell)); i++) {
for(i = 0; i < cell_list_len; i += sizeof(cell)) {
read_cell(&cell_list[i], &cell);
if(cell.timeslot_offset == 0xffff) {
continue;
@ -166,7 +166,7 @@ remove_links_to_schedule(const uint8_t *cell_list, uint16_t cell_list_len)
return;
}
for(i = 0; i < (cell_list_len / sizeof(cell)); i++) {
for(i = 0; i < cell_list_len; i += sizeof(cell)) {
read_cell(&cell_list[i], &cell);
if(cell.timeslot_offset == 0xffff) {
continue;
@ -335,7 +335,7 @@ delete_req_input(const uint8_t *body, uint16_t body_len,
if(num_cells > 0 && cell_list_len > 0) {
/* ensure before delete */
for(i = 0, removed_link = 0; i < (cell_list_len / sizeof(cell)); i++) {
for(i = 0, removed_link = 0; i < cell_list_len; i += sizeof(cell)) {
read_cell(&cell_list[i], &cell);
if(tsch_schedule_get_link_by_timeslot(slotframe,
cell.timeslot_offset) != NULL) {

View File

@ -0,0 +1,7 @@
CONTIKI_PROJECT = node
all: $(CONTIKI_PROJECT)
MODULES += os/services/deployment
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View File

@ -0,0 +1,3 @@
A simple example of how to use the deployment module. Intended for Cooja,
with a Cooja motes, as in the provided simulation file `sim.csc`. For use
in a real deployment, set DEPLOYMENT_MAPPING to your own ID-MAC mapping table.

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2018, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Benchmark: the root sends requests to all nodes in a randomized
* order, and receives resopnses back.
* \author
* Simon Duquennoy <simon.duquennoy@ri.se>
*/
#include "contiki.h"
#include "contiki-net.h"
#include "services/deployment/deployment.h"
/* Log configuration */
#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_INFO
#include "services/deployment/deployment.h"
/** \brief A mapping table for a 8-node Cooja mote simulation.
* Define your own for any given deployment environment */
const struct id_mac deployment_cooja8[] = {
{ 1, {{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01}}},
{ 2, {{0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02}}},
{ 3, {{0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03}}},
{ 4, {{0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04}}},
{ 5, {{0x00,0x05,0x00,0x05,0x00,0x05,0x00,0x05}}},
{ 6, {{0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06}}},
{ 7, {{0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07}}},
{ 8, {{0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08}}},
{ 0, {{0}}}
};
/** \brief An example mapping for Openmotes in Flocklab.
* To use, set DEPLOYMENT_MAPPING to deployment_flocklab_openmotes */
const struct id_mac deployment_flocklab_openmotes[] = {
{ 3, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x29}}},
{ 6, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x34}}},
{ 8, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x1f}}},
{ 15, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x85}}},
{ 16, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x00}}},
{ 18, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x37}}},
{ 22, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x08}}},
{ 23, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0x5f}}},
{ 31, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0x9b,0xb1}}},
{ 0, {{0}}}
};
/*---------------------------------------------------------------------------*/
PROCESS(app_process, "App process");
AUTOSTART_PROCESSES(&app_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(app_process, ev, data)
{
static struct etimer timer;
static uip_ipaddr_t ipaddr;
static linkaddr_t lladdr;
static int i;
PROCESS_BEGIN();
if(node_id == ROOT_ID) {
/* We are the root, start a DAG */
NETSTACK_ROUTING.root_start();
/* Setup a periodic timer that expires after 10 seconds. */
etimer_set(&timer, CLOCK_SECOND * 10);
/* Wait until all nodes have joined */
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
etimer_reset(&timer);
/* Log expected IPv6 addresses of all nodes */
LOG_INFO("Node list:\n");
for(i = 0; i<deployment_node_count(); i++) {
int id;
id = deployment_id_from_index(i);
/* Set ipaddr with DODAG ID, so we get the prefix */
NETSTACK_ROUTING.get_root_ipaddr(&ipaddr);
/* Set IID */
deployment_iid_from_id(&ipaddr, id);
/* Get lladdr */
deployment_lladdr_from_id(&lladdr, id);
LOG_INFO("-- ID: %02u, Link-layer address: ", id);
LOG_INFO_LLADDR(&lladdr);
LOG_INFO_(", IPv6 address: ");
LOG_INFO_6ADDR(&ipaddr);
LOG_INFO_("\n");
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,12 @@
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
/* The node-id of the root */
#define ROOT_ID 1
/* The deployment map (ID<->MAC) */
#define DEPLOYMENT_MAPPING deployment_cooja8
/* Compact address logging (both link-layer and IPv6).
* Shows an abbreviated form that contains the node-id */
#define LOG_CONF_WITH_COMPACT_ADDR 1
#endif /* PROJECT_CONF_H_ */

View File

@ -0,0 +1,275 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<identifier>mtype90</identifier>
<description>Cooja Mote Type #1</description>
<source>[CONTIKI_DIR]/examples/libs/deployment/node.c</source>
<commands>make node.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>12.478629242391953</x>
<y>42.201041276604826</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>25.625935608473608</x>
<y>82.53975431376661</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>51.615094138350024</x>
<y>59.70602651475372</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>41.04314122620578</x>
<y>121.24693889311891</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>64.9463558635099</x>
<y>104.25039302469283</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>5</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>93.59263858654369</x>
<y>75.40399148300003</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>6</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>75.6297158696234</x>
<y>139.97002035548905</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>7</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>104.34293924684245</x>
<y>116.07658566915099</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>8</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype90</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>280</width>
<z>2</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<moterelations>true</moterelations>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.TrafficVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<viewport>2.4250860844175466 0.0 0.0 2.4250860844175466 35.26895372864869 -46.9106236441515</viewport>
</plugin_config>
<width>400</width>
<z>3</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter>App</filter>
<formatted_time />
<coloring />
</plugin_config>
<width>827</width>
<z>0</z>
<height>665</height>
<location_x>681</location_x>
<location_y>-1</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.TimeLine
<plugin_config>
<mote>0</mote>
<mote>1</mote>
<mote>2</mote>
<mote>3</mote>
<mote>4</mote>
<mote>5</mote>
<mote>6</mote>
<mote>7</mote>
<showRadioRXTX />
<showRadioHW />
<showLEDs />
<zoomfactor>500.0</zoomfactor>
</plugin_config>
<width>1539</width>
<z>1</z>
<height>263</height>
<location_x>0</location_x>
<location_y>709</location_y>
</plugin>
</simconf>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Swedish Institute of Computer Science.
* Copyright (c) 2018, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Swedish Institute of Computer Science.
* Copyright (c) 2018, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -64,7 +64,7 @@
#define LWM2M_QUEUE_MODE_CONF_INCLUDE_DYNAMIC_ADAPTATION 1
#define LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_AWAKE_TIME 2000
#define LWM2M_QUEUE_MODE_CONF_DEFAULT_CLIENT_SLEEP_TIME 10000
#define LWM2M_QUEUE_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG 1
#define LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED 0 */
#define LWM2M_QUEUE_MODE_CONF_DEFAULT_DYNAMIC_ADAPTATION_FLAG 0
#define LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED 1 */
#endif /* PROJECT_CONF_H_ */

View File

@ -493,6 +493,7 @@ publish(void)
int len;
int remaining = APP_BUFFER_SIZE;
int i;
char def_rt_str[64];
seq_nr_value++;
@ -519,7 +520,6 @@ publish(void)
buf_ptr += len;
/* Put our Default route's string representation in a buffer */
char def_rt_str[64];
memset(def_rt_str, 0, sizeof(def_rt_str));
ipaddr_sprintf(def_rt_str, sizeof(def_rt_str), uip_ds6_defrt_choose());

View File

@ -60,37 +60,36 @@
void
coap_blocking_request_callback(void *callback_data, coap_message_t *response)
{
coap_request_state_t *state = (coap_request_state_t *)callback_data;
coap_blocking_request_state_t *blocking_state = (coap_blocking_request_state_t *)callback_data;
state->response = response;
process_poll(state->process);
blocking_state->state.response = response;
process_poll(blocking_state->process);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(coap_blocking_request
(coap_request_state_t *state, process_event_t ev,
(coap_blocking_request_state_t *blocking_state, process_event_t ev,
coap_endpoint_t *remote_ep,
coap_message_t *request,
coap_blocking_response_handler_t request_callback))
{
PT_BEGIN(&state->pt);
/* Before PT_BEGIN in order to not be a local variable in the PT_Thread and maintain it */
coap_request_state_t *state = &blocking_state->state;
static uint32_t res_block;
static uint8_t more;
static uint8_t block_error;
PT_BEGIN(&blocking_state->pt);
state->block_num = 0;
state->response = NULL;
state->process = PROCESS_CURRENT();
blocking_state->process = PROCESS_CURRENT();
more = 0;
res_block = 0;
block_error = 0;
state->more = 0;
state->res_block = 0;
state->block_error = 0;
do {
request->mid = coap_get_mid();
if((state->transaction = coap_new_transaction(request->mid, remote_ep))) {
state->transaction->callback = coap_blocking_request_callback;
state->transaction->callback_data = state;
state->transaction->callback_data = blocking_state;
if(state->block_num > 0) {
coap_set_header_block2(request, state->block_num, 0,
@ -104,33 +103,46 @@ PT_THREAD(coap_blocking_request
coap_send_transaction(state->transaction);
LOG_DBG("Requested #%"PRIu32" (MID %u)\n", state->block_num, request->mid);
PT_YIELD_UNTIL(&state->pt, ev == PROCESS_EVENT_POLL);
PT_YIELD_UNTIL(&blocking_state->pt, ev == PROCESS_EVENT_POLL);
if(!state->response) {
LOG_WARN("Server not responding\n");
PT_EXIT(&state->pt);
state->status = COAP_REQUEST_STATUS_TIMEOUT;
PT_EXIT(&blocking_state->pt);
}
coap_get_header_block2(state->response, &res_block, &more, NULL, NULL);
coap_get_header_block2(state->response, &state->res_block, &state->more, NULL, NULL);
LOG_DBG("Received #%"PRIu32"%s (%u bytes)\n", res_block, more ? "+" : "",
LOG_DBG("Received #%"PRIu32"%s (%u bytes)\n", state->res_block, state->more ? "+" : "",
state->response->payload_len);
if(state->more) {
state->status = COAP_REQUEST_STATUS_MORE;
} else {
state->status = COAP_REQUEST_STATUS_RESPONSE;
}
if(res_block == state->block_num) {
if(state->res_block == state->block_num) {
request_callback(state->response);
++(state->block_num);
} else {
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n",
res_block, state->block_num);
++block_error;
state->res_block, state->block_num);
++(state->block_error);
}
} else {
LOG_WARN("Could not allocate transaction buffer");
PT_EXIT(&state->pt);
PT_EXIT(&blocking_state->pt);
}
} while(more && block_error < COAP_MAX_ATTEMPTS);
} while(state->more && (state->block_error) < COAP_MAX_ATTEMPTS);
PT_END(&state->pt);
if((state->block_error) >= COAP_MAX_ATTEMPTS) {
/* failure - now we give up */
state->status = COAP_REQUEST_STATUS_BLOCK_ERROR;
} else {
/* No more blocks, request finished */
state->status = COAP_REQUEST_STATUS_FINISHED;
}
PT_END(&blocking_state->pt);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -39,31 +39,30 @@
#include "sys/pt.h"
#include "coap-transactions.h"
#include "coap-request-state.h"
/*---------------------------------------------------------------------------*/
/*- Client Part -------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
typedef struct coap_request_state {
typedef struct coap_blocking_request_state {
coap_request_state_t state;
struct pt pt;
struct process *process;
coap_transaction_t *transaction;
coap_message_t *response;
uint32_t block_num;
} coap_request_state_t;
} coap_blocking_request_state_t;
typedef void (* coap_blocking_response_handler_t)(coap_message_t *response);
PT_THREAD(coap_blocking_request
(coap_request_state_t *state, process_event_t ev,
(coap_blocking_request_state_t *blocking_state, process_event_t ev,
coap_endpoint_t *remote,
coap_message_t *request,
coap_blocking_response_handler_t request_callback));
#define COAP_BLOCKING_REQUEST(server_endpoint, request, chunk_handler) \
{ \
static coap_request_state_t request_state; \
PT_SPAWN(process_pt, &request_state.pt, \
coap_blocking_request(&request_state, ev, \
static coap_blocking_request_state_t blocking_state; \
PT_SPAWN(process_pt, &blocking_state.pt, \
coap_blocking_request(&blocking_state, ev, \
server_endpoint, \
request, chunk_handler) \
); \

View File

@ -54,19 +54,13 @@
#define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP
/* These should go into the state struct so that we can have multiple
requests */
static uint32_t res_block;
static uint8_t more;
static uint8_t block_error;
static void coap_request_callback(void *callback_data, coap_message_t *response);
/*---------------------------------------------------------------------------*/
static int
progress_request(coap_request_state_t *state) {
progress_request(coap_callback_request_state_t *callback_state) {
coap_request_state_t *state = &callback_state->state;
coap_message_t *request = state->request;
request->mid = coap_get_mid();
if((state->transaction =
@ -93,7 +87,9 @@ progress_request(coap_request_state_t *state) {
static void
coap_request_callback(void *callback_data, coap_message_t *response)
{
coap_request_state_t *state = (coap_request_state_t *)callback_data;
coap_callback_request_state_t *callback_state = (coap_callback_request_state_t*)callback_data;
coap_request_state_t *state = &callback_state->state;
uint32_t res_block1;
state->response = response;
@ -102,58 +98,70 @@ coap_request_callback(void *callback_data, coap_message_t *response)
if(!state->response) {
LOG_WARN("Server not responding giving up...\n");
state->callback(state);
state->status = COAP_REQUEST_STATUS_TIMEOUT;
callback_state->callback(callback_state);
return;
}
/* Got a response */
coap_get_header_block2(state->response, &res_block, &more, NULL, NULL);
coap_get_header_block2(state->response, &state->res_block, &state->more, NULL, NULL);
coap_get_header_block1(state->response, &res_block1, NULL, NULL, NULL);
LOG_DBG("Received #%lu%s B1:%lu (%u bytes)\n",
(unsigned long)res_block, (unsigned)more ? "+" : "",
(unsigned long)state->res_block, (unsigned)state->more ? "+" : "",
(unsigned long)res_block1,
state->response->payload_len);
if(res_block == state->block_num) {
if(state->res_block == state->block_num) {
/* Call the callback function as we have more data */
state->callback(state);
if(state->more) {
state->status = COAP_REQUEST_STATUS_MORE;
} else {
state->status = COAP_REQUEST_STATUS_RESPONSE;
}
callback_state->callback(callback_state);
/* this is only for counting BLOCK2 blocks.*/
++(state->block_num);
} else {
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n", res_block, state->block_num);
++block_error;
LOG_WARN("WRONG BLOCK %"PRIu32"/%"PRIu32"\n", state->res_block, state->block_num);
++(state->block_error);
}
if(more && block_error < COAP_MAX_ATTEMPTS) {
progress_request(state);
if(state->more) {
if((state->block_error) < COAP_MAX_ATTEMPTS) {
progress_request(callback_state);
} else {
/* failure - now we give up and notify the callback */
state->status = COAP_REQUEST_STATUS_BLOCK_ERROR;
callback_state->callback(callback_state);
}
} else {
/* No more blocks, finish and notify the callback */
state->status = COAP_REQUEST_STATUS_FINISHED;
state->response = NULL;
state->callback(state);
callback_state->callback(callback_state);
}
}
/*---------------------------------------------------------------------------*/
int
coap_send_request(coap_request_state_t *state, coap_endpoint_t *endpoint,
coap_send_request(coap_callback_request_state_t *callback_state, coap_endpoint_t *endpoint,
coap_message_t *request,
void (*callback)(coap_request_state_t *state))
void (*callback)(coap_callback_request_state_t *callback_state))
{
/* can we have these variables shared between multiple requests? */
/* ripped from blocking request */
more = 0;
res_block = 0;
block_error = 0;
coap_request_state_t *state = &callback_state->state;
state->more = 0;
state->res_block = 0;
state->block_error = 0;
state->block_num = 0;
state->response = NULL;
state->request = request;
state->remote_endpoint = endpoint;
state->callback = callback;
callback_state->callback = callback;
return progress_request(state);
return progress_request(callback_state);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -47,35 +47,30 @@
#include "coap-engine.h"
#include "coap-transactions.h"
#include "coap-request-state.h"
#include "sys/cc.h"
/*---------------------------------------------------------------------------*/
/*- Client Part -------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
typedef struct coap_request_state coap_request_state_t;
typedef struct coap_callback_request_state coap_callback_request_state_t;
struct coap_request_state {
coap_transaction_t *transaction;
coap_message_t *response;
coap_message_t *request;
coap_endpoint_t *remote_endpoint;
uint32_t block_num;
void *user_data;
coap_timer_t coap_timer;
void (*callback)(coap_request_state_t *state);
struct coap_callback_request_state {
coap_request_state_t state;
void (*callback)(coap_callback_request_state_t *state);
};
/**
* \brief Send a CoAP request to a remote endpoint
* \param state The state to handle the CoAP request
* \param callback_state The callback state to handle the CoAP request
* \param endpoint The destination endpoint
* \param request The request to be sent
* \param callback callback to execute when the response arrives or the timeout expires
* \return 1 if there is a transaction available to send, 0 otherwise
*/
int coap_send_request(coap_request_state_t *state, coap_endpoint_t *endpoint,
int coap_send_request(coap_callback_request_state_t *callback_state, coap_endpoint_t *endpoint,
coap_message_t *request,
void (*callback)(coap_request_state_t *state));
void (*callback)(coap_callback_request_state_t *callback_state));
#endif /* COAP_CALLBACK_API_H_ */
/** @} */

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2018, RISE SICS AB.
* 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.
*/
/**
* \addtogroup coap
* @{
*/
/**
* \file
* Common request state for all the APIs
* \author
* Carlos Gonzalo Peces <carlosgp143@gmail.com>
*/
#ifndef COAP_REQUEST_STATE_H_
#define COAP_REQUEST_STATE_H_
typedef enum {
COAP_REQUEST_STATUS_RESPONSE, /* Response received and no more blocks */
COAP_REQUEST_STATUS_MORE, /* Response received and there are more blocks */
COAP_REQUEST_STATUS_FINISHED, /* Request finished */
COAP_REQUEST_STATUS_TIMEOUT, /* Request Timeout after all retransmissions */
COAP_REQUEST_STATUS_BLOCK_ERROR /* Blocks in wrong order */
} coap_request_status_t;
typedef struct coap_request_state {
coap_transaction_t *transaction;
coap_message_t *response;
coap_message_t *request;
coap_endpoint_t *remote_endpoint;
uint32_t block_num;
uint32_t res_block;
uint8_t more;
uint8_t block_error;
void *user_data;
coap_request_status_t status;
} coap_request_state_t;
#endif /* COAP_REQUEST_STATE_H_ */
/** @} */

View File

@ -49,6 +49,7 @@
#include "contiki.h"
#include "net/ipv6/uip-udp-packet.h"
#include "net/ipv6/uiplib.h"
#include "net/routing/routing.h"
#include "coap.h"
#include "coap-engine.h"
#include "coap-endpoint.h"
@ -58,10 +59,6 @@
#include "coap-keystore.h"
#include "coap-keystore-simple.h"
#if UIP_CONF_IPV6_RPL
#include "rpl.h"
#endif /* UIP_CONF_IPV6_RPL */
/* Log configuration */
#include "coap-log.h"
#define LOG_MODULE "coap-uip"
@ -260,13 +257,12 @@ coap_endpoint_is_secure(const coap_endpoint_t *ep)
int
coap_endpoint_is_connected(const coap_endpoint_t *ep)
{
#if UIP_CONF_IPV6_RPL
#ifndef CONTIKI_TARGET_NATIVE
if(rpl_get_any_dag() == NULL) {
if(!uip_is_addr_linklocal(&ep->ipaddr)
&& NETSTACK_ROUTING.node_is_reachable() == 0) {
return 0;
}
#endif
#endif /* UIP_CONF_IPV6_RPL */
#ifdef WITH_DTLS
if(ep != NULL && ep->secure != 0) {

View File

@ -253,10 +253,6 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
void
uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
{
LOG_INFO("Sending ICMPv6 packet to ");
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
LOG_INFO_(", type %u, code %u, len %u\n", type, code, payload_len);
UIP_IP_BUF->vtc = 0x60;
UIP_IP_BUF->tcflow = 0;
UIP_IP_BUF->flow = 0;
@ -279,6 +275,10 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
UIP_STAT(++uip_stat.icmp.sent);
UIP_STAT(++uip_stat.ip.sent);
LOG_INFO("Sending ICMPv6 packet to ");
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
LOG_INFO_(", type %u, code %u, len %u\n", type, code, payload_len);
tcpip_ipv6_output();
}
/*---------------------------------------------------------------------------*/

View File

@ -258,7 +258,11 @@ uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link)
NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link);
NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent);
if(LOG_WITH_COMPACT_ADDR) {
index += log_6addr_compact_snprint(buf+index, buflen-index, &child_ipaddr);
} else {
index += uiplib_ipaddr_snprint(buf+index, buflen-index, &child_ipaddr);
}
if(index >= buflen) {
return index;
}
@ -273,7 +277,11 @@ uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link)
if(index >= buflen) {
return index;
}
if(LOG_WITH_COMPACT_ADDR) {
index += log_6addr_compact_snprint(buf+index, buflen-index, &parent_ipaddr);
} else {
index += uiplib_ipaddr_snprint(buf+index, buflen-index, &parent_ipaddr);
}
if(index >= buflen) {
return index;
}

View File

@ -53,6 +53,10 @@
#include <stdio.h>
#include <string.h>
#if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS
#error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset
#endif /* LLSEC802154_ENABLED */
/* The two keys K1 and K2 from 6TiSCH minimal configuration
* K1: well-known, used for EBs
* K2: secret, used for data and ACK

View File

@ -54,10 +54,6 @@
* - set LLSEC802154_CONF_USES_EXPLICIT_KEYS
* */
#if LLSEC802154_ENABLED && !LLSEC802154_USES_EXPLICIT_KEYS
#error LLSEC802154_ENABLED set but LLSEC802154_USES_EXPLICIT_KEYS unset
#endif /* LLSEC802154_ENABLED */
/* K1, defined in 6TiSCH minimal, is well-known (offers no security) and used for EBs only */
#ifdef TSCH_SECURITY_CONF_K1
#define TSCH_SECURITY_K1 TSCH_SECURITY_CONF_K1

View File

@ -94,7 +94,11 @@ rpl_neighbor_snprint(char *buf, int buflen, rpl_nbr_t *nbr)
const struct link_stats *stats = rpl_neighbor_get_link_stats(nbr);
clock_time_t clock_now = clock_time();
if(LOG_WITH_COMPACT_ADDR) {
index += log_6addr_compact_snprint(buf+index, buflen-index, rpl_neighbor_get_ipaddr(nbr));
} else {
index += uiplib_ipaddr_snprint(buf+index, buflen-index, rpl_neighbor_get_ipaddr(nbr));
}
if(index >= buflen) {
return index;
}

View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2018, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/**
* \addtogroup deployment
* @{
*/
/**
* \file
* Code managing id<->mac address<->IPv6 address mapping, and doing this
* for different deployment scenarios: Cooja, Nodes, Indriya or Twist testbeds
*
* \author Simon Duquennoy <simonduq@sics.se>
*/
#include "contiki.h"
#include "contiki-net.h"
#include "deployment.h"
#include "sys/node-id.h"
#include <string.h>
#include <stdio.h>
/**
* \brief List of ID<->MAC mapping used for different deployments
*/
extern const struct id_mac DEPLOYMENT_MAPPING[];
/**
* \brief The number of nodes in the deployment
*/
static int node_count = 0;
/*---------------------------------------------------------------------------*/
void
deployment_init(void)
{
const struct id_mac *curr = DEPLOYMENT_MAPPING;
/* Initialize node_id */
node_id = deployment_id_from_lladdr((const linkaddr_t *)&linkaddr_node_addr);
/* Count nodes */
node_count = 0;
while(curr->id != 0) {
node_count++;
curr++;
}
}
/*---------------------------------------------------------------------------*/
int
deployment_node_count(void)
{
return node_count;
}
/*---------------------------------------------------------------------------*/
uint16_t
deployment_id_from_lladdr(const linkaddr_t *lladdr)
{
const struct id_mac *curr = DEPLOYMENT_MAPPING;
if(lladdr == NULL) {
return 0;
}
while(curr->id != 0) {
/* Assume network-wide unique 16-bit MAC addresses */
if(linkaddr_cmp(lladdr, &curr->mac)) {
return curr->id;
}
curr++;
}
return 0;
}
/*---------------------------------------------------------------------------*/
void
deployment_lladdr_from_id(linkaddr_t *lladdr, uint16_t id)
{
const struct id_mac *curr = DEPLOYMENT_MAPPING;
if(id == 0 || lladdr == NULL) {
return;
}
while(curr->id != 0) {
if(curr->id == id) {
linkaddr_copy(lladdr, &curr->mac);
return;
}
curr++;
}
}
/*---------------------------------------------------------------------------*/
uint16_t
deployment_id_from_iid(const uip_ipaddr_t *ipaddr)
{
const linkaddr_t lladdr;
uip_ds6_set_lladdr_from_iid((uip_lladdr_t *)&lladdr, ipaddr);
return deployment_id_from_lladdr(&lladdr);
}
/*---------------------------------------------------------------------------*/
void
deployment_iid_from_id(uip_ipaddr_t *ipaddr, uint16_t id)
{
linkaddr_t lladdr;
deployment_lladdr_from_id(&lladdr, id);
uip_ds6_set_addr_iid(ipaddr, (uip_lladdr_t *)&lladdr);
}
/*---------------------------------------------------------------------------*/
uint16_t
deployment_id_from_index(uint16_t index)
{
if(index < deployment_node_count()) {
return DEPLOYMENT_MAPPING[index].id;
} else {
return 0;
}
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2018, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/**
* \addtogroup deployment
* @{
*
* \file
Per-deployment MAC <-> nodeid mapping
* \author Simon Duquennoy <simon.duquennoy@ri.se>
*
*/
#ifndef DEPLOYMENT_H_
#define DEPLOYMENT_H_
#include "contiki-conf.h"
#include "sys/node-id.h"
#include "net/ipv6/uip.h"
#include "net/linkaddr.h"
/**
* \brief ID<->MAC address mapping structure
*/
struct id_mac {
uint16_t id;
linkaddr_t mac;
};
/**
* DEPLOYMENT_MAPPING:
* A table of struct id_mac that provides ID-MAC mapping for a deployment.
* Example with four nodes:
* In configuration file:
* \#define DEPLOYMENT_MAPPING custom_array
* In a .c file:
* const struct id_mac custom_array[] = {
{ 1, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0xb6,0x14}}},
{ 2, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0xb1,0xe7}}},
{ 3, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0xb4,0x35}}},
{ 4, {{0x00,0x12,0x4b,0x00,0x06,0x0d,0xb1,0xcf}}},
{ 0, {{0}}}
};
*/
/**
* Initialize the deployment module
*/
void deployment_init(void);
/**
* Get the number of nodes for the deployment (length of mapping table)
*
* \return The number of nodes in the deployment
*/
int deployment_node_count(void);
/**
* Get node ID from a link-layer address, from the deployment mapping table
*
* \param lladdr The link-layer address to look up for
* \return Node ID from a corresponding link-layer address
*/
uint16_t deployment_id_from_lladdr(const linkaddr_t *lladdr);
/**
* Get node link-layer address from a node ID, from the deployment mapping table
*
* \param lladdr A pointer where to write the link-layer address
* \param id The node ID to look up for
*/
void deployment_lladdr_from_id(linkaddr_t *lladdr, uint16_t id);
/**
* Get node ID from the IID of an IPv6 address
*
* \param ipaddr The IPv6 (global or link-local) address that contains the IID
* \return Node ID from a corresponding IID
*/
uint16_t deployment_id_from_iid(const uip_ipaddr_t *ipaddr);
/**
* Get IPv6 IID from node IDs
*
* \param ipaddr The IPv6 where to write the IID
* \param id The node ID
*/
void deployment_iid_from_id(uip_ipaddr_t *ipaddr, uint16_t id);
/**
* Get node ID from index in mapping table
*
* \param index The index in the deployment mapping table
* \return Node ID at the corresponding index
*/
uint16_t deployment_id_from_index(uint16_t index);
#endif /* DEPLOYMENT_H_ */
/** @} */

View File

@ -0,0 +1 @@
#define BUILD_WITH_DEPLOYMENT 1

View File

@ -84,7 +84,7 @@
#define STATE_MACHINE_UPDATE_INTERVAL 500
static struct lwm2m_session_info session_info;
static coap_request_state_t rd_request_state;
static coap_callback_request_state_t rd_request_state;
static coap_message_t request[1]; /* This way the message can be treated as pointer as usual. */
@ -118,7 +118,6 @@ static uint8_t rd_state = 0;
static uint8_t rd_flags = FLAG_RD_DATA_UPDATE_ON_DIRTY;
static uint64_t wait_until_network_check = 0;
static uint64_t last_update;
static uint64_t last_rd_progress = 0;
static char query_data[64]; /* allocate some data for queries and updates */
static uint8_t rd_data[128]; /* allocate some data for the RD */
@ -126,7 +125,7 @@ static uint8_t rd_data[128]; /* allocate some data for the RD */
static uint32_t rd_block1;
static uint8_t rd_more;
static coap_timer_t rd_timer;
static void (*rd_callback)(coap_request_state_t *state);
static void (*rd_callback)(coap_callback_request_state_t *callback_state);
static coap_timer_t block1_timer;
@ -143,7 +142,7 @@ static void queue_mode_awake_timer_callback(coap_timer_t *timer);
#endif
static void check_periodic_observations();
static void update_callback(coap_request_state_t *state);
static void update_callback(coap_callback_request_state_t *callback_state);
static int
set_rd_data(coap_message_t *request)
@ -370,10 +369,11 @@ update_bootstrap_server(void)
* TODO
*/
static void
bootstrap_callback(coap_request_state_t *state)
bootstrap_callback(coap_callback_request_state_t *callback_state)
{
coap_request_state_t *state = &callback_state->state;
LOG_DBG("Bootstrap callback Response: %d, ", state->response != NULL);
if(state->response) {
if(state->status == COAP_REQUEST_STATUS_RESPONSE) {
if(CHANGED_2_04 == state->response->code) {
LOG_DBG_("Considered done!\n");
rd_state = BOOTSTRAP_DONE;
@ -383,12 +383,14 @@ bootstrap_callback(coap_request_state_t *state)
LOG_DBG_("Failed with code %d. Retrying\n", state->response->code);
/* TODO Application callback? */
rd_state = INIT;
} else if(BOOTSTRAP_SENT == rd_state) { /* this can handle double invocations */
/* Failure! */
LOG_DBG("Bootstrap failed! Retry?");
} else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) {
LOG_DBG_("Server not responding! Retry?");
rd_state = DO_BOOTSTRAP;
} else if(state->status == COAP_REQUEST_STATUS_FINISHED) {
LOG_DBG_("Request finished. Ignore\n");
} else {
LOG_DBG("Ignore\n");
LOG_DBG_("Unexpected error! Retry?");
rd_state = DO_BOOTSTRAP;
}
}
/*---------------------------------------------------------------------------*/
@ -427,10 +429,11 @@ block1_rd_callback(coap_timer_t *timer)
* Page 65-66 in 07 April 2016 spec.
*/
static void
registration_callback(coap_request_state_t *state)
registration_callback(coap_callback_request_state_t *callback_state)
{
LOG_DBG("Registration callback. Response: %d, ", state->response != NULL);
if(state->response) {
coap_request_state_t *state = &callback_state->state;
LOG_DBG("Registration callback. Status: %d. Response: %d, ", state->status, state->response != NULL);
if(state->status == COAP_REQUEST_STATUS_RESPONSE) {
/* check state and possibly set registration to done */
/* If we get a continue - we need to call the rd generator one more time */
if(CONTINUE_2_31 == state->response->code) {
@ -472,10 +475,14 @@ registration_callback(coap_request_state_t *state)
}
/* TODO Application callback? */
rd_state = INIT;
/* remember last progress time */
last_rd_progress = coap_timer_uptime();
} else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) {
LOG_DBG_("Server not responding, trying to reconnect\n");
rd_state = INIT;
} else if(state->status == COAP_REQUEST_STATUS_FINISHED){
LOG_DBG_("Request finished. Ignore\n");
} else {
LOG_DBG_("Ignore\n");
LOG_DBG_("Unexpected error, trying to reconnect\n");
rd_state = INIT;
}
}
/*---------------------------------------------------------------------------*/
@ -483,11 +490,12 @@ registration_callback(coap_request_state_t *state)
* Page 65-66 in 07 April 2016 spec.
*/
static void
update_callback(coap_request_state_t *state)
update_callback(coap_callback_request_state_t *callback_state)
{
LOG_DBG("Update callback. Response: %d, ", state->response != NULL);
coap_request_state_t *state = &callback_state->state;
LOG_DBG("Update callback. Status: %d. Response: %d, ", state->status, state->response != NULL);
if(state->response) {
if(state->status == COAP_REQUEST_STATUS_RESPONSE) {
/* If we get a continue - we need to call the rd generator one more time */
if(CONTINUE_2_31 == state->response->code) {
/* We assume that size never change?! */
@ -522,20 +530,26 @@ update_callback(coap_request_state_t *state)
state->response->code);
rd_state = DO_REGISTRATION;
}
/* remember last progress */
last_rd_progress = coap_timer_uptime();
} else if(state->status == COAP_REQUEST_STATUS_TIMEOUT) {
LOG_DBG_("Server not responding, trying to reconnect\n");
rd_state = INIT;
} else if(state->status == COAP_REQUEST_STATUS_FINISHED){
LOG_DBG_("Request finished. Ignore\n");
} else {
LOG_DBG("Ignore\n");
LOG_DBG_("Unexpected error, trying to reconnect\n");
rd_state = INIT;
}
}
/*---------------------------------------------------------------------------*/
static void
deregister_callback(coap_request_state_t *state)
deregister_callback(coap_callback_request_state_t *callback_state)
{
LOG_DBG("Deregister callback. Response Code: %d\n",
coap_request_state_t *state = &callback_state->state;
LOG_DBG("Deregister callback. Status: %d. Response Code: %d\n",
state->status,
state->response != NULL ? state->response->code : 0);
if(state->response && (DELETED_2_02 == state->response->code)) {
if(state->status == COAP_REQUEST_STATUS_RESPONSE && (DELETED_2_02 == state->response->code)) {
LOG_DBG("Deregistration success\n");
rd_state = DEREGISTERED;
perform_session_callback(LWM2M_RD_CLIENT_DEREGISTERED);
@ -548,13 +562,6 @@ deregister_callback(coap_request_state_t *state)
}
}
/*---------------------------------------------------------------------------*/
static void
recover_from_rd_delay(void)
{
/* This can be improved in the future... */
rd_state = INIT;
}
/*---------------------------------------------------------------------------*/
/* CoAP timer callback */
static void
periodic_process(coap_timer_t *timer)
@ -611,12 +618,12 @@ periodic_process(coap_timer_t *timer)
LOG_INFO_COAP_EP(&session_info.bs_server_ep);
LOG_INFO_("] as '%s'\n", query_data);
coap_send_request(&rd_request_state, &session_info.bs_server_ep,
request, bootstrap_callback);
if(coap_send_request(&rd_request_state, &session_info.bs_server_ep,
request, bootstrap_callback)) {
rd_state = BOOTSTRAP_SENT;
}
}
}
break;
case BOOTSTRAP_SENT:
/* Just wait for bootstrap to be done... */
@ -710,18 +717,14 @@ periodic_process(coap_timer_t *timer)
}
LOG_INFO_("' More:%d\n", rd_more);
coap_send_request(&rd_request_state, &session_info.server_ep,
request, registration_callback);
last_rd_progress = coap_timer_uptime();
if(coap_send_request(&rd_request_state, &session_info.server_ep,
request, registration_callback)){
rd_state = REGISTRATION_SENT;
}
}
break;
case REGISTRATION_SENT:
/* just wait until the callback kicks us to the next state... */
if(last_rd_progress + MAX_RD_UPDATE_WAIT < coap_timer_uptime()) {
/* Timeout on the update - something is wrong? */
recover_from_rd_delay();
}
break;
case REGISTRATION_DONE:
/* All is done! */
@ -733,11 +736,11 @@ periodic_process(coap_timer_t *timer)
((uint32_t)session_info.lifetime * 500) <= now - last_update) {
/* triggered or time to send an update to the server, at half-time! sec vs ms */
prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED);
coap_send_request(&rd_request_state, &session_info.server_ep, request,
update_callback);
last_rd_progress = coap_timer_uptime();
if(coap_send_request(&rd_request_state, &session_info.server_ep, request,
update_callback)) {
rd_state = UPDATE_SENT;
}
}
break;
#if LWM2M_QUEUE_MODE_ENABLED
case QUEUE_MODE_AWAKE:
@ -754,27 +757,24 @@ periodic_process(coap_timer_t *timer)
LWM2M_QUEUE_MODE_WAKE_UP();
#endif /* LWM2M_QUEUE_MODE_WAKE_UP */
prepare_update(request, rd_flags & FLAG_RD_DATA_UPDATE_TRIGGERED);
coap_send_request(&rd_request_state, &session_info.server_ep, request,
update_callback);
last_rd_progress = coap_timer_uptime();
if(coap_send_request(&rd_request_state, &session_info.server_ep, request,
update_callback)) {
rd_state = UPDATE_SENT;
}
break;
#endif /* LWM2M_QUEUE_MODE_ENABLED */
case UPDATE_SENT:
/* just wait until the callback kicks us to the next state... */
if(last_rd_progress + MAX_RD_UPDATE_WAIT < coap_timer_uptime()) {
/* Timeout on the update - something is wrong? */
recover_from_rd_delay();
}
break;
case DEREGISTER:
LOG_INFO("DEREGISTER %s\n", session_info.assigned_ep);
coap_init_message(request, COAP_TYPE_CON, COAP_DELETE, 0);
coap_set_header_uri_path(request, session_info.assigned_ep);
coap_send_request(&rd_request_state, &session_info.server_ep, request,
deregister_callback);
if(coap_send_request(&rd_request_state, &session_info.server_ep, request,
deregister_callback)) {
rd_state = DEREGISTER_SENT;
}
break;
case DEREGISTER_SENT:
break;

View File

@ -45,6 +45,7 @@
#include "contiki.h"
#include "shell.h"
#include "shell-commands.h"
#include "lib/list.h"
#include "sys/log.h"
#include "dev/watchdog.h"
#include "net/ipv6/uip.h"
@ -76,7 +77,8 @@ static uint16_t curr_ping_datalen;
#if TSCH_WITH_SIXTOP
static shell_command_6top_sub_cmd_t sixtop_sub_cmd = NULL;
#endif /* TSCH_WITH_SIXTOP */
static struct shell_command_set_t builtin_shell_command_set;
LIST(shell_command_sets);
/*---------------------------------------------------------------------------*/
static const char *
ds6_nbr_state_to_str(uint8_t state)
@ -345,15 +347,16 @@ PT_THREAD(cmd_log(struct pt *pt, shell_output_func output, char *args))
static
PT_THREAD(cmd_help(struct pt *pt, shell_output_func output, char *args))
{
struct shell_command_t *cmd_ptr;
struct shell_command_set_t *set;
const struct shell_command_t *cmd;
PT_BEGIN(pt);
SHELL_OUTPUT(output, "Available commands:\n");
cmd_ptr = shell_commands;
while(cmd_ptr->name != NULL) {
SHELL_OUTPUT(output, "%s\n", cmd_ptr->help);
cmd_ptr++;
/* Note: we explicitly don't expend any code space to deal with shadowing */
for(set = list_head(shell_command_sets); set != NULL; set = list_item_next(set)) {
for(cmd = set->commands; cmd->name != NULL; ++cmd) {
SHELL_OUTPUT(output, "%s\n", cmd->help);
}
}
PT_END(pt);
@ -729,12 +732,48 @@ PT_THREAD(cmd_6top(struct pt *pt, shell_output_func output, char *args))
void
shell_commands_init(void)
{
list_init(shell_command_sets);
list_add(shell_command_sets, &builtin_shell_command_set);
/* Set up Ping Reply callback */
uip_icmp6_echo_reply_callback_add(&echo_reply_notification,
echo_reply_handler);
}
/*---------------------------------------------------------------------------*/
struct shell_command_t shell_commands[] = {
void
shell_command_set_register(struct shell_command_set_t *set)
{
list_push(shell_command_sets, set);
}
/*---------------------------------------------------------------------------*/
int
shell_command_set_deregister(struct shell_command_set_t *set)
{
if(!list_contains(shell_command_sets, set)) {
return !0;
}
list_remove(shell_command_sets, set);
return 0;
}
/*---------------------------------------------------------------------------*/
const struct shell_command_t *
shell_command_lookup(const char *name)
{
struct shell_command_set_t *set;
const struct shell_command_t *cmd;
for(set = list_head(shell_command_sets);
set != NULL;
set = list_item_next(set)) {
for(cmd = set->commands; cmd->name != NULL; ++cmd) {
if(!strcmp(cmd->name, name)) {
return cmd;
}
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
const struct shell_command_t builtin_shell_commands[] = {
{ "help", cmd_help, "'> help': Shows this help" },
{ "reboot", cmd_reboot, "'> reboot': Reboot the board by watchdog_reboot()" },
{ "ip-addr", cmd_ipaddr, "'> ip-addr': Shows all IPv6 addresses" },
@ -765,4 +804,8 @@ struct shell_command_t shell_commands[] = {
{ NULL, NULL, NULL },
};
static struct shell_command_set_t builtin_shell_command_set = {
.next = NULL,
.commands = builtin_shell_commands,
};
/** @} */

View File

@ -53,8 +53,14 @@ struct shell_command_t {
const char *help;
};
/* The set of supported commands */
extern struct shell_command_t shell_commands[];
struct shell_command_set_t {
struct shell_command_set_t *next;
const struct shell_command_t *const commands;
};
void shell_command_set_register(struct shell_command_set_t *);
int shell_command_set_deregister(struct shell_command_set_t *);
const struct shell_command_t *shell_command_lookup(const char *);
/**
* Initializes Shell-commands module

View File

@ -89,7 +89,7 @@ output_prompt(shell_output_func output)
PT_THREAD(shell_input(struct pt *pt, shell_output_func output, const char *cmd))
{
static char *args;
static struct shell_command_t *cmd_ptr;
static const struct shell_command_t *cmd_descr = NULL;
PT_BEGIN(pt);
@ -105,20 +105,14 @@ PT_THREAD(shell_input(struct pt *pt, shell_output_func output, const char *cmd))
args++;
}
/* Lookup for command */
cmd_ptr = shell_commands;
while(cmd_ptr->name != NULL) {
if(strcmp(cmd, cmd_ptr->name) == 0) {
cmd_descr = shell_command_lookup(cmd);
if(cmd_descr != NULL) {
static struct pt cmd_pt;
PT_SPAWN(pt, &cmd_pt, cmd_ptr->func(&cmd_pt, output, args));
goto done;
}
cmd_ptr++;
}
PT_SPAWN(pt, &cmd_pt, cmd_descr->func(&cmd_pt, output, args));
} else {
SHELL_OUTPUT(output, "Command not found. Type 'help' for a list of commands\n");
}
done:
output_prompt(output);
PT_END(pt);
}

View File

@ -46,7 +46,8 @@
#ifndef __LOG_CONF_H__
#define __LOG_CONF_H__
/* Log only the last 16 bytes of link-layer and IPv6 addresses */
/* Log only the last 16 bytes of link-layer and IPv6 addresses (or, if)
* the deployment module is enabled, the node IDs */
#ifdef LOG_CONF_WITH_COMPACT_ADDR
#define LOG_WITH_COMPACT_ADDR LOG_CONF_WITH_COMPACT_ADDR
#else /* LOG_CONF_WITH_COMPACT_ADDR */

View File

@ -51,6 +51,7 @@
#include "sys/log.h"
#include "net/ipv6/ip64-addr.h"
#include "net/ipv6/uiplib.h"
#include "deployment/deployment.h"
int curr_log_level_rpl = LOG_CONF_LEVEL_RPL;
int curr_log_level_tcpip = LOG_CONF_LEVEL_TCPIP;
@ -90,22 +91,36 @@ log_6addr(const uip_ipaddr_t *ipaddr)
LOG_OUTPUT("%s", buf);
}
/*---------------------------------------------------------------------------*/
int
log_6addr_compact_snprint(char *buf, size_t size, const uip_ipaddr_t *ipaddr)
{
if(ipaddr == NULL) {
return snprintf(buf, size, "6A-NULL");
} else {
char *prefix = NULL;
if(uip_is_addr_mcast(ipaddr)) {
prefix = "6M";
} else if(uip_is_addr_linklocal(ipaddr)) {
prefix = "6L";
} else {
prefix = "6G";
}
#if BUILD_WITH_DEPLOYMENT
return snprintf(buf, size, "%s-%03u", prefix, deployment_id_from_iid(ipaddr));
#else /* BUILD_WITH_DEPLOYMENT */
return snprintf(buf, size, "%s-%04x", prefix, UIP_HTONS(ipaddr->u16[sizeof(uip_ipaddr_t)/2-1]));
#endif /* BUILD_WITH_DEPLOYMENT */
}
}
/*---------------------------------------------------------------------------*/
void
log_6addr_compact(const uip_ipaddr_t *ipaddr)
{
if(ipaddr == NULL) {
LOG_OUTPUT("6A-NULL");
} else if(uip_is_addr_mcast(ipaddr)) {
LOG_OUTPUT("6M-%04x", UIP_HTONS(ipaddr->u16[sizeof(uip_ipaddr_t)/2-1]));
} else if(uip_is_addr_linklocal(ipaddr)) {
LOG_OUTPUT("6L-%04x", UIP_HTONS(ipaddr->u16[sizeof(uip_ipaddr_t)/2-1]));
} else {
LOG_OUTPUT("6G-%04x", UIP_HTONS(ipaddr->u16[sizeof(uip_ipaddr_t)/2-1]));
}
char buf[8];
log_6addr_compact_snprint(buf, sizeof(buf), ipaddr);
LOG_OUTPUT("%s", buf);
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
void
log_lladdr(const linkaddr_t *lladdr)
@ -130,11 +145,15 @@ log_lladdr_compact(const linkaddr_t *lladdr)
if(lladdr == NULL || linkaddr_cmp(lladdr, &linkaddr_null)) {
LOG_OUTPUT("LL-NULL");
} else {
#if BUILD_WITH_DEPLOYMENT
LOG_OUTPUT("LL-%04u", deployment_id_from_lladdr(lladdr));
#else /* BUILD_WITH_DEPLOYMENT */
#if LINKADDR_SIZE == 8
LOG_OUTPUT("LL-%04x", UIP_HTONS(lladdr->u16[LINKADDR_SIZE/2-1]));
#elif LINKADDR_SIZE == 2
LOG_OUTPUT("LL-%04x", UIP_HTONS(lladdr->u16));
#endif
#endif /* BUILD_WITH_DEPLOYMENT */
}
}
/*---------------------------------------------------------------------------*/

View File

@ -194,6 +194,17 @@ void log_6addr(const uip_ipaddr_t *ipaddr);
*/
void log_6addr_compact(const uip_ipaddr_t *ipaddr);
/**
* Write at most size - 1 characters of the IP address to the output string,
* in a compact representation. The output is always null-terminated, unless
* size is 0.
*
* \param buf A pointer to an output string with at least size bytes.
* \param size The max number of characters to write to the output string.
* \param ipaddr A pointer to a uip_ipaddr_t that will be printed with printf().
*/
int log_6addr_compact_snprint(char *buf, size_t size, const uip_ipaddr_t *ipaddr);
#endif /* NETSTACK_CONF_WITH_IPV6 */
/**

View File

@ -40,12 +40,17 @@
#include "contiki.h"
#include "sys/node-id.h"
#include "net/linkaddr.h"
#include "services/deployment/deployment.h"
uint16_t node_id = 0;
void
node_id_init(void) {
#if BUILD_WITH_DEPLOYMENT
deployment_init();
#else /* BUILD_WITH_DEPLOYMENT */
/* Initialize with a default value derived from linkaddr */
node_id = linkaddr_node_addr.u8[LINKADDR_SIZE - 1]
+ (linkaddr_node_addr.u8[LINKADDR_SIZE - 2] << 8);
#endif /* BUILD_WITH_DEPLOYMENT */
}

View File

@ -24,35 +24,56 @@
# 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.
TOOLS_DIR = ../../tools
DOCDIR=../../tools/doxygen
DOXYGEN = doxygen
DOXYGEN_DIR = $(TOOLS_DIR)/doxygen
DOXYGEN_LOG = $(DOXYGEN).log
DOXYGEN_ERR = $(DOXYGEN).err
RAEDTHEDOCS = readthedocs
READTHEDOCS_DIR = $(TOOLS_DIR)/readthedocs
READTHEDOCS_LOG = $(RAEDTHEDOCS).log
READTHEDOCS_ERR = $(RAEDTHEDOCS).err
CLEAN_TARGETS += $(DOXYGEN_LOG) $(DOXYGEN_ERR)
CLEAN_TARGETS += $(READTHEDOCS_LOG) $(READTHEDOCS_ERR)
all: clean summary
doxygen:
-@$(MAKE) -C $(DOCDIR) 2> doxygen.err > /dev/null
-@$(MAKE) -C $(DOXYGEN_DIR) 2> $(DOXYGEN_ERR) > /dev/null
summary: doxygen
readthedocs:
-@$(MAKE) -C $(READTHEDOCS_DIR) 2> $(READTHEDOCS_ERR) > /dev/null
summary: doxygen readthedocs
@( \
1> summary; \
if [ -s doxygen.err ] ; then \
echo "Doxygen: TEST FAIL" | tee summary; \
if [ -s $(DOXYGEN_ERR) ] ; then \
echo "Doxygen: TEST FAIL" | tee -a summary; \
echo "Errors:"; \
cat doxygen.err; \
cat $(DOXYGEN_ERR); \
fi ; \
if [ -s $(DOCDIR)/doxygen.log ] ; then \
echo "Doxygen: TEST FAIL" | tee summary; \
if [ -s $(DOXYGEN_DIR)/doxygen.log ] ; then \
echo "Doxygen: TEST FAIL" | tee -a summary; \
echo "Warnings:"; \
cat $(DOCDIR)/doxygen.log; \
cat $(DOXYGEN_DIR)/doxygen.log; \
fi ; \
if [ -s $(READTHEDOCS_ERR) ] ; then \
echo "Readthedocs: TEST FAIL" | tee -a summary; \
echo "Errors:"; \
cat $(READTHEDOCS_ERR); \
fi ; \
if [ ! -s summary ] ; then \
echo "Doxygen: TEST OK (no warning nor error)" | tee summary; \
echo "Documentation: TEST OK (no warning nor error)" | tee summary; \
fi ; \
)
@rm doxygen.err
@rm -f $(CLEAN_TARGETS)
@echo "========== Summary =========="
@cat summary
clean:
@rm -f summary doxygen.err
@$(MAKE) -C $(DOCDIR) clean
@rm -f summary $(CLEAN_TARGETS)
@$(MAKE) -C $(DOXYGEN_DIR) clean
@$(MAKE) -C $(READTHEDOCS_DIR) clean

View File

@ -66,6 +66,7 @@ rpl-border-router/openmote-cc2538 \
libs/ipv6-hooks/openmote-cc2538 \
libs/shell/openmote-cc2538 \
libs/simple-energest/openmote-cc2538 \
libs/deployment/openmote-cc2538 \
TOOLS=

@ -1 +1 @@
Subproject commit 81cd4cbe5e05e4fa97782d1859ed15b769f4bf2b
Subproject commit edb3c8c73c4688ebd336b278450db216512a769b

View File

@ -3,9 +3,9 @@ FROM 32bit/ubuntu:16.04
# Tools
RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential doxygen git wget unzip python-serial \
build-essential doxygen git wget unzip python-serial python-pip \
default-jdk ant srecord iputils-tracepath rlwrap \
mosquitto mosquitto-clients \
mosquitto mosquitto-clients gdb \
&& apt-get clean
# Install ARM toolchain
@ -42,6 +42,12 @@ RUN wget https://developer.nordicsemi.com/nRF5_IoT_SDK/nRF5_IoT_SDK_v0.9.x/nrf5_
ENV NRF52_SDK_ROOT /usr/nrf52-sdk
# Install sphinx and sphinx_rtd_theme, required for building and testing the
# readthedocs API documentation
RUN pip install --upgrade pip
RUN pip install setuptools
RUN pip install sphinx_rtd_theme sphinx
# Create user, enable X forwarding, add to group dialout
# -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix
RUN export uid=1000 gid=1000 && \

View File

@ -0,0 +1,19 @@
# Makefile used to generate documentation with sphinx, which is used on
# readthedocs. Use this Makefile to test readthedocs generation locally on
# your computer.
#
# For this to work, you will need to install sphinx and sphinx_rtd_theme. They
# can be installed through pip
.PHONY = clean all readthedocs
SPHINX = sphinx-build
SPHINX_CONF_DIR = .
SPHINX_OUT_DIR = _build
all: readthedocs
clean:
rm -rf $(SPHINX_OUT_DIR)
readthedocs:
$(SPHINX) -b html $(SPHINX_CONF_DIR) $(SPHINX_OUT_DIR)

View File

@ -0,0 +1,65 @@
# Sphinx extension that builds Contiki-NG documentation and copies it over to
# the sphinx build dir
import subprocess
from sphinx.util import logging
logger = logging.getLogger(__name__)
api_doc_defaults = {
'doxygen_src_dir': '../doxygen',
'doxygen_out_dir': 'html',
'doxygen_suppress_out': True,
'doxygen_build': True,
}
def api_doc_build(app, exception):
if exception is not None:
logger.warning('%s exiting without building' % (__name__,))
return
if app.config.api_doc_doxygen_build:
make_invocation_suffix = ('> /dev/null'
if app.config.api_doc_doxygen_suppress_out
else '')
make_invocation = ' '.join(('make -C',
app.config.api_doc_doxygen_src_dir,
make_invocation_suffix))
logger.info('%s building API docs from "%s"'
% (__name__, app.config.api_doc_doxygen_src_dir))
logger.info('%s executing "%s"'
% (__name__, make_invocation))
subprocess.call(make_invocation, shell=True)
api_doc_build_dir = "/".join((app.config.api_doc_doxygen_src_dir,
app.config.api_doc_doxygen_out_dir))
api_doc_static_api_dir = "/".join((app.outdir, '_api'))
logger.info('%s moving "%s" to "%s"'
% (__name__, api_doc_build_dir, api_doc_static_api_dir))
subprocess.call(' '.join(('mv', api_doc_build_dir,
api_doc_static_api_dir)),
shell=True)
# Fundamentally a workaround: Readthedocs doxygen build plain refulses
# to build the same html/*.js files as local builds do. So we ship them
# and we copy them over to the output dir by force, till readthedocs
# starts behaving, hopefully in the near future
subprocess.call(' '.join(('cp js/dynsections.js',
api_doc_static_api_dir)),
shell=True)
def setup(app):
for k, v in api_doc_defaults.items():
config_val = 'api_doc_' + k
logger.debug('Add config value %s: %s' %(config_val, v))
app.add_config_value(config_val, v, '')
# We will build and copy the docs after the end of the sphinx build, and.
# only if it has been successful. Regsiter for the build-finished event.
app.connect('build-finished', api_doc_build)
logger.info('%s initialised' % (__name__,))

112
tools/readthedocs/conf.py Normal file
View File

@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
#
# This file does only contain a selection of the most common options. For a
# full list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = u'Contiki-NG'
copyright = u'2018, Contiki-NG maintainers and contributors'
author = u'Contiki-NG maintainers and contributors'
# The short X.Y version
version = u''
# The full version, including alpha/beta/rc tags
release = u''
# -- General configuration ---------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'api-doc'
]
# api-doc configuration
api_doc_doxygen_src_dir = '../doxygen'
api_doc_doxygen_out_dir = 'html'
api_doc_doxygen_suppress_out = True
api_doc_doxygen_build = True
# Add any paths that contain templates here, relative to this directory.
#templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
#
# The default sidebars (for documents that don't match any pattern) are
# defined by theme itself. Builtin themes are using these templates by
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
# 'searchbox.html']``.
#
# html_sidebars = {}
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'Contiki-NGdoc'

View File

@ -0,0 +1,23 @@
Contiki-NG API documentation!
=============================
These pages host Contiki-NG's API documentation.
The primary target audience
consists developers who want to develop an application with Contiki-NG or who
want to modify Contiki-NG itself.
For guides and tutorials, visit the `Contiki-NG wiki`_.
Index
=====
* `API Home`_
* `List of Modules`_
* `Data Structure Index`_
* `Index of Files`_
.. _Contiki-NG wiki: https://github.com/contiki-ng/contiki-ng/wiki
.. _API Home: _api/index.html
.. _List of Modules: _api/modules.html
.. _Data Structure Index: _api/annotated.html
.. _Index of Files: _api/files.html

View File

@ -0,0 +1,127 @@
/*
@licstart The following is the entire license notice for the
JavaScript code in this file.
Copyright (C) 1997-2017 by Dimitri van Heesch
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@licend The above is the entire license notice
for the JavaScript code in this file
*/
function toggleVisibility(linkObj)
{
var base = $(linkObj).attr('id');
var summary = $('#'+base+'-summary');
var content = $('#'+base+'-content');
var trigger = $('#'+base+'-trigger');
var src=$(trigger).attr('src');
if (content.is(':visible')===true) {
content.hide();
summary.show();
$(linkObj).addClass('closed').removeClass('opened');
$(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
} else {
content.show();
summary.hide();
$(linkObj).removeClass('closed').addClass('opened');
$(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
}
return false;
}
function updateStripes()
{
$('table.directory tr').
removeClass('even').filter(':visible:even').addClass('even');
}
function toggleLevel(level)
{
$('table.directory tr').each(function() {
var l = this.id.split('_').length-1;
var i = $('#img'+this.id.substring(3));
var a = $('#arr'+this.id.substring(3));
if (l<level+1) {
i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
a.html('&#9660;');
$(this).show();
} else if (l==level+1) {
i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
a.html('&#9654;');
$(this).show();
} else {
$(this).hide();
}
});
updateStripes();
}
function toggleFolder(id)
{
// the clicked row
var currentRow = $('#row_'+id);
// all rows after the clicked row
var rows = currentRow.nextAll("tr");
var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
// only match elements AFTER this one (can't hide elements before)
var childRows = rows.filter(function() { return this.id.match(re); });
// first row is visible we are HIDING
if (childRows.filter(':first').is(':visible')===true) {
// replace down arrow by right arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
currentRowSpans.filter(".arrow").html('&#9654;');
rows.filter("[id^=row_"+id+"]").hide(); // hide all children
} else { // we are SHOWING
// replace right arrow by down arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
currentRowSpans.filter(".arrow").html('&#9660;');
// replace down arrows by right arrows for child rows
var childRowsSpans = childRows.find("span");
childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
childRowsSpans.filter(".arrow").html('&#9654;');
childRows.show(); //show all children
}
updateStripes();
}
function toggleInherit(id)
{
var rows = $('tr.inherit.'+id);
var img = $('tr.inherit_header.'+id+' img');
var src = $(img).attr('src');
if (rows.filter(':first').is(':visible')===true) {
rows.css('display','none');
$(img).attr('src',src.substring(0,src.length-8)+'closed.png');
} else {
rows.css('display','table-row'); // using show() causes jump in firefox
$(img).attr('src',src.substring(0,src.length-10)+'open.png');
}
}
/* @license-end */
$(document).ready(function() {
$('.code,.codeRef').each(function() {
$(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());
$(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });
});
});

View File

@ -885,6 +885,17 @@ exit(1);
}
}
#ifdef __APPLE__
if(*tundev == '\0') {
/* Use default. */
if(tap) {
strcpy(tundev, "tap0");
} else {
strcpy(tundev, "tun0");
}
}
#endif
if(host != NULL) {
struct addrinfo hints, *servinfo, *p;
int rv;