From a0d7f1d0418986d0f533adecc5bde8dd6956dcc2 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 25 Apr 2018 01:21:58 -0700 Subject: [PATCH 01/25] CoAP: enable reaching link-local endpoints regardless of routing reachability --- os/net/app-layer/coap/coap-uip.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/os/net/app-layer/coap/coap-uip.c b/os/net/app-layer/coap/coap-uip.c index 8db2bbbbf..4f2331170 100644 --- a/os/net/app-layer/coap/coap-uip.c +++ b/os/net/app-layer/coap/coap-uip.c @@ -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" @@ -263,13 +260,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) { From 7b38f46abaea49029a5167939ecaee7b6ead7a86 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 4 Jun 2018 23:08:22 +0200 Subject: [PATCH 02/25] Travis: fix in test of whether the docker configuration has changed --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e91ee6aea..2ba80e188 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 From 4c7474da70ec2eacc04f44c964b0450b2512ed84 Mon Sep 17 00:00:00 2001 From: Martin Hermsen Date: Tue, 5 Jun 2018 13:14:00 +0200 Subject: [PATCH 03/25] rx full IRQ handling for cc13xx/cc26xx --- arch/cpu/cc26xx-cc13xx/rf-core/prop-mode.c | 10 ++++++++++ arch/cpu/cc26xx-cc13xx/rf-core/rf-core.c | 15 ++++++++++++++- arch/cpu/cc26xx-cc13xx/rf-core/rf-core.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/arch/cpu/cc26xx-cc13xx/rf-core/prop-mode.c index f4e7f66e7..66b4a4370 100644 --- a/arch/cpu/cc26xx-cc13xx/rf-core/prop-mode.c +++ b/arch/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -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; } /*---------------------------------------------------------------------------*/ diff --git a/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.c index 2baa883ad..23b78eab4 100644 --- a/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.c +++ b/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -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 \ @@ -574,6 +577,16 @@ cc26xx_rf_cpe1_isr(void) return; } } + + 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; diff --git a/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.h b/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.h index ac48bc52a..c97ab0f8a 100644 --- a/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.h +++ b/arch/cpu/cc26xx-cc13xx/rf-core/rf-core.h @@ -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); /*---------------------------------------------------------------------------*/ From 94398b0176251f1bcde902472a9d90faa63c414c Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Tue, 5 Jun 2018 15:11:32 +0200 Subject: [PATCH 04/25] CI: fail test in case building Docker image failed --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2ba80e188..da6dea283 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 From 57692d21f9a3cd8a693c9f044aa51fab165321c8 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 25 May 2018 21:07:02 +0100 Subject: [PATCH 05/25] Add support for documentation on readthedocs.io --- .gitignore | 1 + tools/readthedocs/Makefile | 19 +++++ tools/readthedocs/api-doc.py | 65 ++++++++++++++ tools/readthedocs/conf.py | 112 ++++++++++++++++++++++++ tools/readthedocs/index.rst | 23 +++++ tools/readthedocs/js/dynsections.js | 127 ++++++++++++++++++++++++++++ 6 files changed, 347 insertions(+) create mode 100644 tools/readthedocs/Makefile create mode 100644 tools/readthedocs/api-doc.py create mode 100644 tools/readthedocs/conf.py create mode 100644 tools/readthedocs/index.rst create mode 100644 tools/readthedocs/js/dynsections.js diff --git a/.gitignore b/.gitignore index 31afb98b3..91721ed08 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ obj_* Makefile.target Makefile.*.defines tools/doxygen/html +tools/readthedocs/_build patches-* tools/serial-io/tunslip6 tools/serial-io/serialdump diff --git a/tools/readthedocs/Makefile b/tools/readthedocs/Makefile new file mode 100644 index 000000000..ecf5b58d4 --- /dev/null +++ b/tools/readthedocs/Makefile @@ -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) diff --git a/tools/readthedocs/api-doc.py b/tools/readthedocs/api-doc.py new file mode 100644 index 000000000..c59b0864e --- /dev/null +++ b/tools/readthedocs/api-doc.py @@ -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__,)) diff --git a/tools/readthedocs/conf.py b/tools/readthedocs/conf.py new file mode 100644 index 000000000..50e43737e --- /dev/null +++ b/tools/readthedocs/conf.py @@ -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' diff --git a/tools/readthedocs/index.rst b/tools/readthedocs/index.rst new file mode 100644 index 000000000..794c0866b --- /dev/null +++ b/tools/readthedocs/index.rst @@ -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 diff --git a/tools/readthedocs/js/dynsections.js b/tools/readthedocs/js/dynsections.js new file mode 100644 index 000000000..537e3e498 --- /dev/null +++ b/tools/readthedocs/js/dynsections.js @@ -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 Date: Sun, 27 May 2018 15:07:55 +0100 Subject: [PATCH 06/25] Update the dockerfile to install packages required for readthedocs builds/tests --- tools/docker/Dockerfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index e1d85d003..80b719ab1 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -3,7 +3,7 @@ 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 \ && apt-get clean @@ -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 && \ From 41c0851f79a896b3f6e5fa0852bab58b668de014 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Tue, 5 Jun 2018 12:11:29 +0100 Subject: [PATCH 07/25] Test readthedocs build on travis --- .travis.yml | 2 +- .../{00-doxygen => 00-documentation}/Makefile | 47 ++++++++++++++----- 2 files changed, 35 insertions(+), 14 deletions(-) rename tests/{00-doxygen => 00-documentation}/Makefile (60%) diff --git a/.travis.yml b/.travis.yml index 2ba80e188..ba65df5ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,7 +58,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' diff --git a/tests/00-doxygen/Makefile b/tests/00-documentation/Makefile similarity index 60% rename from tests/00-doxygen/Makefile rename to tests/00-documentation/Makefile index 067090b73..ea0aa85b4 100644 --- a/tests/00-doxygen/Makefile +++ b/tests/00-documentation/Makefile @@ -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 From 9ae283031aad7c1869e9d9b695795b638a6a62e3 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 26 May 2018 05:03:08 -0700 Subject: [PATCH 08/25] Added deployment module --- os/services/deployment/deployment.c | 141 +++++++++++++++++++++++++ os/services/deployment/deployment.h | 126 ++++++++++++++++++++++ os/services/deployment/module-macros.h | 1 + os/sys/node-id.c | 5 + 4 files changed, 273 insertions(+) create mode 100644 os/services/deployment/deployment.c create mode 100644 os/services/deployment/deployment.h create mode 100644 os/services/deployment/module-macros.h diff --git a/os/services/deployment/deployment.c b/os/services/deployment/deployment.c new file mode 100644 index 000000000..c48a0cbae --- /dev/null +++ b/os/services/deployment/deployment.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2018, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** +* \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 + */ + +#include "contiki.h" +#include "contiki-net.h" +#include "deployment.h" +#include "sys/node-id.h" +#include +#include + +/** + * \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; + } +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/os/services/deployment/deployment.h b/os/services/deployment/deployment.h new file mode 100644 index 000000000..b2e3c1928 --- /dev/null +++ b/os/services/deployment/deployment.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2018, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** +* \addtogroup deployment +* @{ +* +* \file + Per-deployment MAC <-> nodeid mapping +* \author Simon Duquennoy +* +*/ + +#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_ */ +/** @} */ diff --git a/os/services/deployment/module-macros.h b/os/services/deployment/module-macros.h new file mode 100644 index 000000000..ed2d639ef --- /dev/null +++ b/os/services/deployment/module-macros.h @@ -0,0 +1 @@ +#define BUILD_WITH_DEPLOYMENT 1 diff --git a/os/sys/node-id.c b/os/sys/node-id.c index 7914256e9..2fd52f8dc 100644 --- a/os/sys/node-id.c +++ b/os/sys/node-id.c @@ -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 */ } From 95208a804a61a0a3cb675fc5d3cf0aba95247734 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 26 May 2018 05:04:03 -0700 Subject: [PATCH 09/25] Deployment: use node-id for compact address logging --- os/net/ipv6/uip-sr.c | 12 ++++++-- os/net/routing/rpl-lite/rpl-neighbor.c | 6 +++- os/sys/log-conf.h | 3 +- os/sys/log.c | 41 +++++++++++++++++++------- os/sys/log.h | 11 +++++++ 5 files changed, 58 insertions(+), 15 deletions(-) diff --git a/os/net/ipv6/uip-sr.c b/os/net/ipv6/uip-sr.c index a82491827..133fd6f28 100644 --- a/os/net/ipv6/uip-sr.c +++ b/os/net/ipv6/uip-sr.c @@ -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); - index += uiplib_ipaddr_snprint(buf+index, buflen-index, &child_ipaddr); + 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; } - index += uiplib_ipaddr_snprint(buf+index, buflen-index, &parent_ipaddr); + 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; } diff --git a/os/net/routing/rpl-lite/rpl-neighbor.c b/os/net/routing/rpl-lite/rpl-neighbor.c index a066af313..a0f5d95b0 100644 --- a/os/net/routing/rpl-lite/rpl-neighbor.c +++ b/os/net/routing/rpl-lite/rpl-neighbor.c @@ -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(); - index += uiplib_ipaddr_snprint(buf+index, buflen-index, rpl_neighbor_get_ipaddr(nbr)); + 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; } diff --git a/os/sys/log-conf.h b/os/sys/log-conf.h index 24cf21f71..17d8562cc 100644 --- a/os/sys/log-conf.h +++ b/os/sys/log-conf.h @@ -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 */ diff --git a/os/sys/log.c b/os/sys/log.c index 9a02087a2..abb960b98 100644 --- a/os/sys/log.c +++ b/os/sys/log.c @@ -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 */ } } /*---------------------------------------------------------------------------*/ diff --git a/os/sys/log.h b/os/sys/log.h index e27a3007e..0f5f840d2 100644 --- a/os/sys/log.h +++ b/os/sys/log.h @@ -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 */ /** From c0a1c586be7d1aad66f090fc3c6ce64e281be16b Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 26 May 2018 05:03:21 -0700 Subject: [PATCH 10/25] Added deployment example --- examples/libs/deployment/Makefile | 7 + examples/libs/deployment/README.md | 3 + examples/libs/deployment/node.c | 111 ++++++++++ examples/libs/deployment/project-conf.h | 12 ++ examples/libs/deployment/sim.csc | 275 ++++++++++++++++++++++++ 5 files changed, 408 insertions(+) create mode 100644 examples/libs/deployment/Makefile create mode 100644 examples/libs/deployment/README.md create mode 100644 examples/libs/deployment/node.c create mode 100644 examples/libs/deployment/project-conf.h create mode 100644 examples/libs/deployment/sim.csc diff --git a/examples/libs/deployment/Makefile b/examples/libs/deployment/Makefile new file mode 100644 index 000000000..5ad17e22d --- /dev/null +++ b/examples/libs/deployment/Makefile @@ -0,0 +1,7 @@ +CONTIKI_PROJECT = node +all: $(CONTIKI_PROJECT) + +MODULES += os/services/deployment + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/libs/deployment/README.md b/examples/libs/deployment/README.md new file mode 100644 index 000000000..8484c3aee --- /dev/null +++ b/examples/libs/deployment/README.md @@ -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. diff --git a/examples/libs/deployment/node.c b/examples/libs/deployment/node.c new file mode 100644 index 000000000..188b66e14 --- /dev/null +++ b/examples/libs/deployment/node.c @@ -0,0 +1,111 @@ +/* + * 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 + */ + +#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}}} +}; + +/*---------------------------------------------------------------------------*/ +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; iMAC) */ +#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_ */ diff --git a/examples/libs/deployment/sim.csc b/examples/libs/deployment/sim.csc new file mode 100644 index 000000000..9daa11426 --- /dev/null +++ b/examples/libs/deployment/sim.csc @@ -0,0 +1,275 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/powertracker + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype90 + Cooja Mote Type #1 + [CONTIKI_DIR]/examples/libs/deployment/node.c + make node.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 12.478629242391953 + 42.201041276604826 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.interfaces.Position + 25.625935608473608 + 82.53975431376661 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.interfaces.Position + 51.615094138350024 + 59.70602651475372 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.interfaces.Position + 41.04314122620578 + 121.24693889311891 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.interfaces.Position + 64.9463558635099 + 104.25039302469283 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.interfaces.Position + 93.59263858654369 + 75.40399148300003 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.interfaces.Position + 75.6297158696234 + 139.97002035548905 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.interfaces.Position + 104.34293924684245 + 116.07658566915099 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype90 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.TrafficVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.4250860844175466 0.0 0.0 2.4250860844175466 35.26895372864869 -46.9106236441515 + + 400 + 3 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.LogListener + + App + + + + 827 + 0 + 665 + 681 + -1 + + + org.contikios.cooja.plugins.TimeLine + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + + + + 500.0 + + 1539 + 1 + 263 + 0 + 709 + + From 98338aad2df8e7c302ca2c907d4593e1fff4cad0 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 26 May 2018 05:11:42 -0700 Subject: [PATCH 11/25] Add Flocklab Openmotes as an example deployment mapping --- examples/libs/deployment/node.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/examples/libs/deployment/node.c b/examples/libs/deployment/node.c index 188b66e14..2cbe1f276 100644 --- a/examples/libs/deployment/node.c +++ b/examples/libs/deployment/node.c @@ -63,6 +63,21 @@ const struct id_mac deployment_cooja8[] = { { 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); From f968c11a2fc129b0946876e15704dd64f937d686 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 26 May 2018 05:13:09 -0700 Subject: [PATCH 12/25] Added compile test for example libs/deployment --- tests/03-compile-arm-ports-02/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/03-compile-arm-ports-02/Makefile b/tests/03-compile-arm-ports-02/Makefile index ceb1b79e3..7efb1b14b 100644 --- a/tests/03-compile-arm-ports-02/Makefile +++ b/tests/03-compile-arm-ports-02/Makefile @@ -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= From 833cf2f87d8e91fe4ce9d3d801dcacf69b59fb4d Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Wed, 6 Jun 2018 15:38:16 +0200 Subject: [PATCH 13/25] Fix copyright headers --- examples/libs/shell/example.c | 2 +- examples/libs/simple-energest/example.c | 2 +- os/services/deployment/deployment.c | 2 +- os/services/deployment/deployment.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/libs/shell/example.c b/examples/libs/shell/example.c index 9d2320c58..51cc98826 100644 --- a/examples/libs/shell/example.c +++ b/examples/libs/shell/example.c @@ -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 diff --git a/examples/libs/simple-energest/example.c b/examples/libs/simple-energest/example.c index e9d6d585c..35d1f0b8d 100644 --- a/examples/libs/simple-energest/example.c +++ b/examples/libs/simple-energest/example.c @@ -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 diff --git a/os/services/deployment/deployment.c b/os/services/deployment/deployment.c index c48a0cbae..087d9766d 100644 --- a/os/services/deployment/deployment.c +++ b/os/services/deployment/deployment.c @@ -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 diff --git a/os/services/deployment/deployment.h b/os/services/deployment/deployment.h index b2e3c1928..29cd5214b 100644 --- a/os/services/deployment/deployment.h +++ b/os/services/deployment/deployment.h @@ -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 From b0f564010191f62e66c120ad2e9cf0aaaf66f961 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Thu, 7 Jun 2018 12:56:12 +0100 Subject: [PATCH 14/25] Update cc2538-bsl to latest version --- tools/cc2538-bsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cc2538-bsl b/tools/cc2538-bsl index 81cd4cbe5..edb3c8c73 160000 --- a/tools/cc2538-bsl +++ b/tools/cc2538-bsl @@ -1 +1 @@ -Subproject commit 81cd4cbe5e05e4fa97782d1859ed15b769f4bf2b +Subproject commit edb3c8c73c4688ebd336b278450db216512a769b From 1a95aad7a72348e72f7301abe698757bba748ebd Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Thu, 7 Jun 2018 14:26:47 +0000 Subject: [PATCH 15/25] Mark shell_commands as const This enables the compiler to place the array in flash, saving us a bit of RAM. Suggested-by: g-oikonomou --- os/services/shell/shell-commands.c | 4 ++-- os/services/shell/shell-commands.h | 2 +- os/services/shell/shell.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index f2f036eda..67c81b6e1 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -345,7 +345,7 @@ 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; + const struct shell_command_t *cmd_ptr; PT_BEGIN(pt); @@ -734,7 +734,7 @@ shell_commands_init(void) echo_reply_handler); } /*---------------------------------------------------------------------------*/ -struct shell_command_t shell_commands[] = { +const struct shell_command_t 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" }, diff --git a/os/services/shell/shell-commands.h b/os/services/shell/shell-commands.h index f89703273..4d89d2e4b 100644 --- a/os/services/shell/shell-commands.h +++ b/os/services/shell/shell-commands.h @@ -54,7 +54,7 @@ struct shell_command_t { }; /* The set of supported commands */ -extern struct shell_command_t shell_commands[]; +extern const struct shell_command_t shell_commands[]; /** * Initializes Shell-commands module diff --git a/os/services/shell/shell.c b/os/services/shell/shell.c index fcf419880..e16a69b30 100644 --- a/os/services/shell/shell.c +++ b/os/services/shell/shell.c @@ -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_ptr; PT_BEGIN(pt); From f325d449641058740b8b4bb12ae333fa8f065822 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Sat, 9 Jun 2018 23:16:32 +0200 Subject: [PATCH 16/25] Dockerfile: add gdb --- tools/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 80b719ab1..9d15704ac 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends \ 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 From f8d004b92fe4c96fd48185aa7a2519832ca04065 Mon Sep 17 00:00:00 2001 From: Olav Frengstad Date: Wed, 6 Jun 2018 16:53:16 +0200 Subject: [PATCH 17/25] Move LLSEC checks from `tsch-security.h` to `tsch-security.c` Different part of the stack is pulled in from `contiki-main.c` this has the unintended side effect of including TSCH headers even when TSCH is not used. When using LLSEC for CSMA this triggers an error and compilation fails. --- os/net/mac/tsch/tsch-security.c | 4 ++++ os/net/mac/tsch/tsch-security.h | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/os/net/mac/tsch/tsch-security.c b/os/net/mac/tsch/tsch-security.c index 1c4266626..12f0de6d5 100644 --- a/os/net/mac/tsch/tsch-security.c +++ b/os/net/mac/tsch/tsch-security.c @@ -53,6 +53,10 @@ #include #include +#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 diff --git a/os/net/mac/tsch/tsch-security.h b/os/net/mac/tsch/tsch-security.h index 56c854414..4320d3a70 100644 --- a/os/net/mac/tsch/tsch-security.h +++ b/os/net/mac/tsch/tsch-security.h @@ -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 From 45b0241f94befcd85ef8d77dcf8e718b640841da Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Fri, 8 Jun 2018 10:16:49 +0000 Subject: [PATCH 18/25] Introduce dynamically registered shell command sets Commands are part of a single array, which means that their definition is static. However, different apps in the same source tree may reasonably want to add to the command set (perhaps even shadow existing commands), which would make for awkward code. Instead, allow dynamic registration/deregistration of command sets at runtime. This keeps the data overhead low (two pointers per enabled command set). --- os/services/shell/shell-commands.c | 59 ++++++++++++++++++++++++++---- os/services/shell/shell-commands.h | 10 ++++- os/services/shell/shell.c | 20 ++++------ 3 files changed, 66 insertions(+), 23 deletions(-) diff --git a/os/services/shell/shell-commands.c b/os/services/shell/shell-commands.c index 67c81b6e1..e8bb4b6b2 100644 --- a/os/services/shell/shell-commands.c +++ b/os/services/shell/shell-commands.c @@ -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)) { - const 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); } /*---------------------------------------------------------------------------*/ -const 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 @@ const 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, +}; /** @} */ diff --git a/os/services/shell/shell-commands.h b/os/services/shell/shell-commands.h index 4d89d2e4b..f510e861d 100644 --- a/os/services/shell/shell-commands.h +++ b/os/services/shell/shell-commands.h @@ -53,8 +53,14 @@ struct shell_command_t { const char *help; }; -/* The set of supported commands */ -extern const 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 diff --git a/os/services/shell/shell.c b/os/services/shell/shell.c index e16a69b30..c219b1903 100644 --- a/os/services/shell/shell.c +++ b/os/services/shell/shell.c @@ -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 const 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) { - static struct pt cmd_pt; - PT_SPAWN(pt, &cmd_pt, cmd_ptr->func(&cmd_pt, output, args)); - goto done; - } - cmd_ptr++; + cmd_descr = shell_command_lookup(cmd); + if(cmd_descr != NULL) { + static struct pt cmd_pt; + 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"); } - SHELL_OUTPUT(output, "Command not found. Type 'help' for a list of commands\n"); - -done: output_prompt(output); PT_END(pt); } From 05455f949c9845701dbac4aeab6666a46d6a0c6c Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sat, 23 Jun 2018 13:35:22 +0100 Subject: [PATCH 19/25] Enable license auto-detection This commit changes the LICENSE.md text such that it can get automatically detected by licensee and github's license detection. This will make the license appear in the project's overview on github. Additional information that was previously in LICENSE.md is moved to the README. --- LICENSE.md | 67 +++++++++++++++++++++++------------------------------- README.md | 5 +++- 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index b2f909d44..f4b1a054c 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -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. diff --git a/README.md b/README.md index df7d7ff58..e9a1005ef 100644 --- a/README.md +++ b/README.md @@ -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. From 14225300fcb17d5fe5feb814954f03c51daeb457 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Sun, 24 Jun 2018 16:29:47 +0100 Subject: [PATCH 20/25] Specify default tun/tap name on Mac OS e5c7437 fixed a bug that was preventing multiple instances of tunslip6 from running. This same commit however broke tunslip6 on Mac OS, as documented in contiki-os/contiki#1560 as well as in contiki-ng/contiki-ng#466 Basically the commit in question merely removed some code. This commit puts that code back in, but makes it conditional for Mac OS. Fixes #466 --- tools/serial-io/tunslip6.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/serial-io/tunslip6.c b/tools/serial-io/tunslip6.c index e1a72078a..aa8b5b9fd 100644 --- a/tools/serial-io/tunslip6.c +++ b/tools/serial-io/tunslip6.c @@ -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; From a4757cb723e3131fe5c67384d063df084509fece Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Wed, 27 Jun 2018 09:36:00 +0200 Subject: [PATCH 21/25] Changed default values for dynamic adaptation and Q-Mode objects --- examples/lwm2m-ipso-objects/project-conf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/lwm2m-ipso-objects/project-conf.h b/examples/lwm2m-ipso-objects/project-conf.h index 01f919866..a8603c67b 100644 --- a/examples/lwm2m-ipso-objects/project-conf.h +++ b/examples/lwm2m-ipso-objects/project-conf.h @@ -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_ */ From 2db8fa80e211eab66908deced0bc8063d6441882 Mon Sep 17 00:00:00 2001 From: "carlosgp143@gmail.com" Date: Thu, 31 May 2018 16:22:01 +0200 Subject: [PATCH 22/25] Unified coap_request_state and added status for extra information --- os/net/app-layer/coap/coap-blocking-api.c | 58 ++++++---- os/net/app-layer/coap/coap-blocking-api.h | 17 ++- os/net/app-layer/coap/coap-callback-api.c | 66 +++++++----- os/net/app-layer/coap/coap-callback-api.h | 21 ++-- os/net/app-layer/coap/coap-request-state.h | 69 ++++++++++++ os/services/lwm2m/lwm2m-rd-client.c | 118 ++++++++++----------- 6 files changed, 216 insertions(+), 133 deletions(-) create mode 100644 os/net/app-layer/coap/coap-request-state.h diff --git a/os/net/app-layer/coap/coap-blocking-api.c b/os/net/app-layer/coap/coap-blocking-api.c index 1be7cbe7c..9fd691d74 100644 --- a/os/net/app-layer/coap/coap-blocking-api.c +++ b/os/net/app-layer/coap/coap-blocking-api.c @@ -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); } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/net/app-layer/coap/coap-blocking-api.h b/os/net/app-layer/coap/coap-blocking-api.h index d9a916c04..716a261b5 100644 --- a/os/net/app-layer/coap/coap-blocking-api.h +++ b/os/net/app-layer/coap/coap-blocking-api.h @@ -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) \ ); \ diff --git a/os/net/app-layer/coap/coap-callback-api.c b/os/net/app-layer/coap/coap-callback-api.c index 0f0ab2c99..41a2ef846 100644 --- a/os/net/app-layer/coap/coap-callback-api.c +++ b/os/net/app-layer/coap/coap-callback-api.c @@ -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 { - /* failure - now we give up and notify the callback */ + /* 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); } /*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/net/app-layer/coap/coap-callback-api.h b/os/net/app-layer/coap/coap-callback-api.h index 69ceea4f5..a9019aeb8 100644 --- a/os/net/app-layer/coap/coap-callback-api.h +++ b/os/net/app-layer/coap/coap-callback-api.h @@ -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_ */ /** @} */ diff --git a/os/net/app-layer/coap/coap-request-state.h b/os/net/app-layer/coap/coap-request-state.h new file mode 100644 index 000000000..4c5881bb6 --- /dev/null +++ b/os/net/app-layer/coap/coap-request-state.h @@ -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 + */ +#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_ */ +/** @} */ diff --git a/os/services/lwm2m/lwm2m-rd-client.c b/os/services/lwm2m/lwm2m-rd-client.c index 63c9443e1..4b4b11528 100644 --- a/os/services/lwm2m/lwm2m-rd-client.c +++ b/os/services/lwm2m/lwm2m-rd-client.c @@ -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,10 +618,10 @@ 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); - - rd_state = BOOTSTRAP_SENT; + if(coap_send_request(&rd_request_state, &session_info.bs_server_ep, + request, bootstrap_callback)) { + rd_state = BOOTSTRAP_SENT; + } } } break; @@ -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(); - rd_state = REGISTRATION_SENT; + 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,10 +736,10 @@ 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(); - rd_state = UPDATE_SENT; + if(coap_send_request(&rd_request_state, &session_info.server_ep, request, + update_callback)) { + rd_state = UPDATE_SENT; + } } break; #if LWM2M_QUEUE_MODE_ENABLED @@ -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(); - rd_state = UPDATE_SENT; + 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); - rd_state = DEREGISTER_SENT; + if(coap_send_request(&rd_request_state, &session_info.server_ep, request, + deregister_callback)) { + rd_state = DEREGISTER_SENT; + } break; case DEREGISTER_SENT: break; From 840bab8f6cc80a5d6aa851369b99132275d80fa5 Mon Sep 17 00:00:00 2001 From: Toshio Ito Date: Fri, 6 Jul 2018 13:46:36 +0900 Subject: [PATCH 23/25] uip_icmp6_send: move log messages at the end of function. It prints UIP_IP_BUF->destipaddr, but this is updated in the middle of this function. Before this fix, the address was NOT the destination of the ICMPv6 packet, but was whatever destination that previous operation wrote to uip_buf. --- os/net/ipv6/uip-icmp6.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/os/net/ipv6/uip-icmp6.c b/os/net/ipv6/uip-icmp6.c index be33a1101..707a13309 100644 --- a/os/net/ipv6/uip-icmp6.c +++ b/os/net/ipv6/uip-icmp6.c @@ -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(); } /*---------------------------------------------------------------------------*/ From 4e79ba949f857e197b895fa7c46ec5899ce236c6 Mon Sep 17 00:00:00 2001 From: ohrensessel Date: Mon, 30 Jul 2018 20:53:29 +0200 Subject: [PATCH 24/25] sixtop example: fix incorrect access to uint8_t *cell_list --- examples/6tisch/sixtop/sf-simple.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/6tisch/sixtop/sf-simple.c b/examples/6tisch/sixtop/sf-simple.c index 689c668e7..f7393ab4c 100644 --- a/examples/6tisch/sixtop/sf-simple.c +++ b/examples/6tisch/sixtop/sf-simple.c @@ -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) { From c8432009e9c34a21e030a516581b22b795f97e64 Mon Sep 17 00:00:00 2001 From: George Oikonomou Date: Fri, 3 Aug 2018 19:08:56 +0100 Subject: [PATCH 25/25] Move variable definition to start of function --- examples/mqtt-client/mqtt-client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mqtt-client/mqtt-client.c b/examples/mqtt-client/mqtt-client.c index 4e128ae37..be3c97cdb 100644 --- a/examples/mqtt-client/mqtt-client.c +++ b/examples/mqtt-client/mqtt-client.c @@ -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());