Merge branch 'develop' into fix/coap-endpoint-is-reachable

This commit is contained in:
Joakim Eriksson 2018-08-10 21:46:29 +02:00 committed by GitHub
commit 351908a1ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
173 changed files with 5064 additions and 2042 deletions

8
.gitignore vendored
View File

@ -16,9 +16,11 @@ obj_*
Makefile.target
Makefile.*.defines
tools/doxygen/html
tools/readthedocs/_build
patches-*
tools/tunslip
tools/tunslip6
tools/serial-io/tunslip6
tools/serial-io/serialdump
serialdump-*
build
tools/coffee-manager/build/
tools/coffee-manager/coffee.jar
@ -58,6 +60,8 @@ COOJA.testlog
*.err
summary
tests/[0-9][0-9]-*/org/
tests/18-coap-lwm2m/Californium.properties
tests/18-coap-lwm2m/leshan-server-demo*.jar
# x86 UEFI files
cpu/x86/uefi/Makefile.uefi

View File

@ -1,36 +1,68 @@
# Setup environment for Docker
language: generic
services: docker
notifications:
- email: false
email: false
# Environment setup before test script. Runs for each build
before_install:
# Environment setup before test script
- export CNG_HOST_PATH=`pwd`
- export DOCKER_IMG='simonduq/contiki-ng:latest'
- sudo chgrp -hR 1000 $CNG_HOST_PATH
- docker pull $DOCKER_IMG
# Check if anything has changed within the docker directory
- 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
# image to Dockerhub (secure credentials only readable on bulids to
# contiki-ng/contiki-ng branches, not forks or PRs)
- >
if [ $DOCKER_CHANGED == 0 ]; then
echo "Docker image unchanged, pull from Dockerhub"
docker pull $DOCKER_IMG;
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
docker push $DOCKER_IMG;
fi
fi
# Build Cooja
- ant -q -f $CNG_HOST_PATH/tools/cooja/build.xml jar
# Set permissions for Docker mount
- sudo chgrp -hR 1000 $CNG_HOST_PATH
script: # The test script for each build.
# The test script for each build
script:
- docker run --privileged -v $CNG_HOST_PATH:/home/user/contiki-ng -ti $DOCKER_IMG bash --login -c "make -C tests/??-$TEST_NAME";
# Check outcome of the test
- $CNG_HOST_PATH/tests/check-test.sh $CNG_HOST_PATH/tests/??-$TEST_NAME; exit $?;
# Environment variables
env:
# Parallel builds
- TEST_NAME='compile-base'
- TEST_NAME='compile-arm-ports-01'
- TEST_NAME='compile-arm-ports-02'
- TEST_NAME='rpl-lite'
- TEST_NAME='rpl-classic'
- TEST_NAME='tun-rpl-br'
- TEST_NAME='coap-lwm2m'
- TEST_NAME='simulation-base'
- TEST_NAME='ieee802154'
- TEST_NAME='compile-nxp-ports'
- TEST_NAME='doxygen'
- TEST_NAME='compile-tools'
- TEST_NAME='native-runs'
- TEST_NAME='ipv6'
# Global environment variables, i.e., set for all builds
global:
- DOCKER_IMG='contiker/contiki-ng'
- CNG_HOST_PATH=`pwd`
# Encrypted environment variables.
# Only available on builds of contiki-ng/contiki-ng branches, not PRs or forks.
- secure: 0nrV5yjpT2kE19Hlm7t619Qbmyjx/G7bSUI1c+U3kZbyuxnRlASjVcDN5uPBoimIfGiBRI0nRq690BogAJt4EKwbC1Dy8kC1XD8mRtQ2AIZ6PHaUoG9iS5sBhFBQK0XkB83bwh6omRn/04O0uuX74ooSWT7fDrWxi/y5+0ysXK6gRtOhdrJ3FU5OkNVewX8NeCdx3pOWhMOtXWdFkMIi1XRdDnvMM5/hHlHMkdXXtaZQX9UsK3Q3DSjPRLZjKRiOlcx9MIg2ebh9ITmd2Du2p2q/LKtoutJckvhbKQPWcZi/B+1ZTSff0FHBIg+EYxf6TeFuia7XSTWH7sr2CDCCtcvSR9bB5yW6jdmGfa8Af8I1TCBuqoSUo0Re50BZBZF7COleEh+IojbjXn2CIDMg5rT4Sh3qcMGvFn9OW1cz5h5UNSOk7EIAXXPcI7Aloxh2sBo4/DrvvbfIsKrvxV9Fx4bdyNtR7dZ7xsoOw6L0zttC3K9naf3VAOeBAyjBiRwm0tWxJC/buhTsKlYrthhyUrwLtYAFL4UHcazvz57hY/cEzR2X6F//9Hp7HFoNtn1E36doX3ZfeI22yxHMo9SYW7O69C45wbhJ29lAA9XXbYVyGBKFkY8C1NCZ0Xckt9H8/Ow5Sz8HmW/NNBJCn0Fsx+jezdGc4ED5naugNbLAyNg=
# Each line in the 'matrix' triggers a separate Travis build
matrix:
- TEST_NAME='compile-base'
- TEST_NAME='compile-arm-ports-01'
- TEST_NAME='compile-arm-ports-02'
- TEST_NAME='rpl-lite'
- TEST_NAME='rpl-classic'
- TEST_NAME='tun-rpl-br'
- TEST_NAME='coap-lwm2m'
- TEST_NAME='simulation-base'
- TEST_NAME='ieee802154'
- TEST_NAME='compile-nxp-ports'
- TEST_NAME='documentation'
- TEST_NAME='compile-tools'
- TEST_NAME='native-runs'
- TEST_NAME='ipv6'

View File

@ -1,41 +1,30 @@
Contiki-NG is licensed under the 3-clause BSD license. This license gives
everyone the right to use and distribute the code, either in binary or
source code format, as long as the copyright license is retained in
the source code.
Copyright (c) (Year), (Name of copyright holder)
All rights reserved.
The copyright for different parts of the code is held by different
people and organizations, but the code is licensed under the same type
of license. The license text is:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
```
/*
* Copyright (c) (Year), (Name of copyright holder)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
```
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.

33
Makefile.embedded Normal file
View File

@ -0,0 +1,33 @@
# This Makefile contains make variables and rules that are only applicable
# to builds for embedded devices (i.e. excluding platforms native and cooja).
# Future extensions to the build system that are of a similar nature (for
# embedded devices only), can be achieved by extending this Makefile here.
RLWRAPGOALS = login serialdump serialview
.PHONY: $(RLWRAPGOALS)
BAUDRATE ?= 115200
SERIALDUMP_TIME_FMT ?=
ifeq ($(HOST_OS),Windows)
SERIALDUMP = $(SERIAL_DUMP_BIN)
else
RLWRAP = $(notdir $(shell which rlwrap))
ifeq ($(RLWRAP),)
ifneq ($(filter $(RLWRAPGOALS),$(MAKECMDGOALS)),)
$(info Running serialdump without rlwrap support.)
$(info Consider installing rlwarp in order to be able to use command history)
endif
endif
SERIALDUMP = $(RLWRAP) $(SERIAL_DUMP_BIN)
endif
serialdump: $(SERIAL_DUMP_BIN)
$(SERIALDUMP) -b$(BAUDRATE) -T$(SERIALDUMP_TIME_FMT) $(PORT) | tee serialdump-`date +%Y%m%d-%H%M`
serialview: $(SERIAL_DUMP_BIN)
$(SERIALDUMP) -b$(BAUDRATE) -T$(SERIALDUMP_TIME_FMT) $(PORT)
login: $(SERIAL_DUMP_BIN)
$(SERIALDUMP) -b$(BAUDRATE) $(PORT)

View File

@ -1,3 +1,8 @@
# This Makefile can be used to identify the selected TARGET used for a
# specific build. It can be included by example Makefiles that need to take
# decisions based on TARGET. It is also automatically included by the
# top-level Makefile.include.
ifeq ($(TARGET),)
-include Makefile.target
ifeq ($(TARGET),)

View File

@ -10,6 +10,9 @@ WERROR ?= 1
include $(CONTIKI)/Makefile.identify-target
### Include Makefile.tools to pull in targets that allow us to build tools dir
include $(CONTIKI)/Makefile.tools
CONTIKI_NG_TARGET_LIB = contiki-ng-$(TARGET).a
ifeq ($(DEFINES),)
@ -49,7 +52,13 @@ CFLAGS += -DCONTIKI_BOARD_$(TARGET_BOARD_UPPERCASE)=1
CFLAGS += -DCONTIKI_BOARD_STRING=\"$(BOARD)\"
endif
LDFLAGS = -Wl,--fatal-warnings
CFLAGS += -Wno-unused-const-variable
LDFLAGS_WERROR ?= -Wl,--fatal-warnings
ifeq ($(WERROR),1)
LDFLAGS += $(LDFLAGS_WERROR)
endif
MODULES += os os/sys os/dev os/lib os/services
@ -306,8 +315,8 @@ clean:
distclean:
@for TARG in `ls $(CONTIKI)/arch/platform $(TARGETDIRS)`; do \
echo Running: make TARGET=$$TARG clean; \
make TARGET=$$TARG clean; \
echo Running: $(MAKE) TARGET=$$TARG clean; \
$(MAKE) TARGET=$$TARG clean; \
done
-include $(CONTIKI)/arch/platform/$(TARGET)/Makefile.customrules-$(TARGET)
@ -387,7 +396,7 @@ endif
usage:
@echo "Usage:"
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [DEFINES=(DEFINES)] [target]"
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [DEFINES=(DEFINES)] [PORT=(PORT)] [target]"
@echo ""
@echo "Typical usage:"
@echo " make [TARGET=(TARGET)] [BOARD=(BOARD)] [all]"
@ -408,6 +417,9 @@ usage:
@echo " %.o Produces an object file from a given source file (e.g. hello-world.o)"
@echo " %.e Produces the pre-processed version of a given source file (e.g. hello-world.e)"
@echo " %.s Produces an assembly file from a given source file (e.g. hello-world.s)"
@echo " login View the serial output of the device connected to PORT"
@echo " serialview Same as login, but prepend serial output with a unix timestamp"
@echo " serialdump same as serialview, but also save the output to a file"
help: usage
@ -434,6 +446,7 @@ savedefines:
@echo "saving Makefile.$(TARGET).defines"
@echo >Makefile.$(TARGET).defines "DEFINES = $(DEFINES)"
VIEWCONF = $(CONTIKI)/tools/viewconf/viewconf.c
viewconf:
@echo "----------------- Make variables: --------------"
@echo "##### \"TARGET\": ________________________________ $(TARGET)"
@ -445,13 +458,19 @@ ifdef MAKE_COAP_DTLS_KEYSTORE
@echo "##### \"MAKE_COAP_DTLS_KEYSTORE\": _______________ $(MAKE_COAP_DTLS_KEYSTORE)"
endif
@echo "----------------- C variables: -----------------"
$(Q)$(CC) $(CFLAGS) -E $(CONTIKI)/tools/viewconf.c | grep \#\#\#\#\#
$(Q)$(CC) $(CFLAGS) -E $(VIEWCONF) | grep \#\#\#\#\#
@echo "------------------------------------------------"
@echo "'==' Means the flag is set to a given a value"
@echo "'->' Means the flag is unset, but will default to a given value"
@echo "'><' Means the flag is unset and has no default value"
@echo "To view more Make variables, edit $(CONTIKI)/Makefile.include, rule 'viewconf'"
@echo "To view more C variables, edit $(CONTIKI)/tools/viewconf.c"
@echo "To view more C variables, edit $(VIEWCONF)"
### Include Makefile.embedded for relevant platforms, in order to pull in
### rules for login, serialview etc
ifeq ($(findstring $(TARGET),native cooja),)
include $(CONTIKI)/Makefile.embedded
endif
# Don't treat %.$(TARGET) as an intermediate file because it is
# in fact the primary target.

17
Makefile.tools Normal file
View File

@ -0,0 +1,17 @@
# Some make rules in the main build system depend on the presence of utilities
# under the tools/ dir. For those dependencies, we use this makefile here to
# recursively invoke the respective build under tools/.
TOOLS_DIR = $(CONTIKI)/tools
SERIAL_IO_TOOL_DIR = $(TOOLS_DIR)/serial-io
SERIAL_IO_TOOL_DEPS = $(addprefix $(SERIAL_IO_TOOL_DIR)/, tools-utils.c tools-utils.h)
TUNSLIP6 = $(SERIAL_IO_TOOL_DIR)/tunslip6
SERIAL_DUMP_BIN = $(SERIAL_IO_TOOL_DIR)/serialdump
$(SERIAL_DUMP_BIN): $(SERIAL_IO_TOOL_DIR)/serialdump.c $(SERIAL_IO_TOOL_DEPS)
$(MAKE) -C $(SERIAL_IO_TOOL_DIR) serialdump
$(TUNSLIP6): $(SERIAL_IO_TOOL_DIR)/tunslip6.c $(SERIAL_IO_TOOL_DEPS)
$(MAKE) -C $(SERIAL_IO_TOOL_DIR) tunslip6

View File

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

View File

@ -88,21 +88,7 @@ else
@echo "This board cannot be programmed through the ROM bootloader and therefore does not support the .upload target."
endif
# Check if we are running under Windows
ifeq ($(HOST_OS),Windows)
SERIALDUMP ?= $(CONTIKI)/tools/sky/serialdump-windows
else
ifeq ($(HOST_OS),Darwin)
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/sky/serialdump-macos
else
# Else assume Linux
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/sky/serialdump-linux
endif
endif
UART_BAUDRATE = 115200
login:
$(SERIALDUMP) -b$(UART_BAUDRATE) $(PORT)
### For the login etc targets
BAUDRATE = 115200
include $(CONTIKI)/arch/cpu/arm/cortex-m/cm3/Makefile.cm3

View File

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

View File

@ -76,7 +76,7 @@
/*---------------------------------------------------------------------------*/
/* RF interrupts */
#define RX_FRAME_IRQ IRQ_RX_ENTRY_DONE
#define ERROR_IRQ IRQ_INTERNAL_ERROR
#define ERROR_IRQ (IRQ_INTERNAL_ERROR | IRQ_RX_BUF_FULL)
#define RX_NOK_IRQ IRQ_RX_NOK
/* Those IRQs are enabled all the time */
@ -103,6 +103,9 @@ static const rf_core_primary_mode_t *primary_mode = NULL;
int32_t rat_offset = 0;
static bool rat_offset_known = false;
/*---------------------------------------------------------------------------*/
/* Buffer full flag */
volatile bool rx_is_full = false;
/*---------------------------------------------------------------------------*/
PROCESS(rf_core_process, "CC13xx / CC26xx RF driver");
/*---------------------------------------------------------------------------*/
#define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \
@ -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;

View File

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

View File

@ -22,6 +22,7 @@ CFLAGS += $(CFLAGSNO)
ifeq ($(HOST_OS),Darwin)
AROPTS = -rc
LDFLAGS_WERROR := -Wl,-fatal_warnings
LDFLAGS += -Wl,-flat_namespace,-map,$(CONTIKI_NG_PROJECT_MAP)
CFLAGS += -DHAVE_SNPRINTF=1 -U__ASSERT_USE_STDERR
else

View File

@ -29,11 +29,11 @@
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup sensortag-cc26xx-ext-flash
* \addtogroup ext-flash
* @{
*
* \file
* Sensortag/LaunchPad External Flash Driver
* Implementation of a generic external SPI flash driver
*/
/*---------------------------------------------------------------------------*/
#include "contiki.h"

View File

@ -29,14 +29,23 @@
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup common-cc26xx-peripherals
* \addtogroup dev
* @{
*
* \defgroup sensortag-cc26xx-ext-flash SensorTag/LaunchPad External Flash
* \defgroup ext-flash Generic external SPI flash driver
*
* This is a generic driver for external SPI flash memories. The driver has
* been tested and works with multiple external SPI flash parts. The list of
* parts the driver has been tested against is shown in the README in this
* directory.
*
* If you successfully use this driver with a part that is not listed in the
* README, please let us know so we can update it.
*
* @{
*
* \file
* Header file for the Sensortag/LaunchPad External Flash Driver
* Header file for the external SPI flash API
*/
/*---------------------------------------------------------------------------*/
#ifndef EXT_FLASH_H_

View File

@ -91,6 +91,11 @@
#define NBR_TABLE_CONF_MAX_NEIGHBORS 300
#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
/* configure queues */
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 64
#endif /* QUEUEBUF_CONF_NUM */
#ifndef UIP_CONF_IPV6_QUEUE_PKT
#define UIP_CONF_IPV6_QUEUE_PKT 1
#endif /* UIP_CONF_IPV6_QUEUE_PKT */

View File

@ -64,6 +64,7 @@
#include "dev/button-sensor.h"
#include "dev/pir-sensor.h"
#include "dev/vib-sensor.h"
#include "dev/moteid.h"
#include "sys/node-id.h"
#include "services/rpl-border-router/rpl-border-router.h"
@ -151,13 +152,13 @@ set_lladdr(void)
{
int i;
for(i = 0; i < sizeof(uip_lladdr.addr); i += 2) {
addr.u8[i + 1] = node_id & 0xff;
addr.u8[i + 0] = node_id >> 8;
addr.u8[i + 1] = simMoteID & 0xff;
addr.u8[i + 0] = simMoteID >> 8;
}
}
#else /* NETSTACK_CONF_WITH_IPV6 */
addr.u8[0] = node_id & 0xff;
addr.u8[1] = node_id >> 8;
addr.u8[0] = simMoteID & 0xff;
addr.u8[1] = simMoteID >> 8;
#endif /* NETSTACK_CONF_WITH_IPV6 */
linkaddr_set_node_addr(&addr);
}
@ -177,11 +178,6 @@ platform_init_stage_two()
void
platform_init_stage_three()
{
if(node_id > 0) {
LOG_INFO("Node id is set to %u.\n", node_id);
} else {
LOG_INFO("Node id is not set.\n");
}
/* Initialize eeprom */
eeprom_init();
/* Start serial process */

View File

@ -82,7 +82,7 @@ OBJDUMP:=$(CROSS_COMPILE)-objdump
ARCH = jn516x-ccm-star.c exceptions.c rtimer-arch.c rtimer-arch-slow.c \
slip_uart0.c clock.c micromac-radio.c int-master.c \
node-id.c watchdog.c slip.c dbg.c
watchdog.c slip.c dbg.c
# Default uart0 for printf and slip
TARGET_WITH_UART0 ?= 1
TARGET_WITH_UART1 ?= 0
@ -175,17 +175,14 @@ MOTELIST = python $(CONTIKI)/tools/jn516x/mote-list.py
ifeq ($(HOST_OS),Windows)
USBDEVPREFIX=/dev/com
USBDEVBASENAME=COM
SERIALDUMP ?= $(CONTIKI)/tools/jn516x/serialdump-windows
else
ifeq ($(HOST_OS),Darwin)
USBDEVPREFIX=
USBDEVBASENAME=/dev/tty.usbserial-
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/jn516x/serialdump-macos
else
# Else we assume Linux
USBDEVPREFIX=
USBDEVBASENAME=/dev/ttyUSB
SERIALDUMP ?= rlwrap $(CONTIKI)/tools/jn516x/serialdump-linux
endif
endif
@ -195,7 +192,7 @@ ifndef MOTE
$(error MOTE not defined! You must specify which MOTE (serial port) to use)
endif
endif
PORT = $(USBDEVBASENAME)$(MOTE)
DEV_PORT = $(USBDEVBASENAME)$(MOTE)
#### make targets
@ -255,19 +252,19 @@ endif
### Upload target to one jn516x mote specified by MOTE=portNumber
ifeq ($(HOST_OS),Windows)
%.upload: %.$(TARGET).bin
${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $<
${FLASH_PROGRAMMER} -a -c $(DEV_PORT) -B 1000000 -s -w -f $<
else
%.upload: %.$(TARGET).bin
${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -f $<
${FLASH_PROGRAMMER} -V 10 -v -s $(DEV_PORT) -I 38400 -P 1000000 -f $<
endif
### Flash the given file
ifeq ($(HOST_OS),Windows)
%.flash: ${FLASH_PROGRAMMER}
${FLASH_PROGRAMMER} -a -c $(PORT) -B 1000000 -s -w -f $*.$(TARGET).bin
${FLASH_PROGRAMMER} -a -c $(DEV_PORT) -B 1000000 -s -w -f $*.$(TARGET).bin
else
%.flash: ${FLASH_PROGRAMMER}
${FLASH_PROGRAMMER} -V 10 -v -s $(PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin
${FLASH_PROGRAMMER} -V 10 -v -s $(DEV_PORT) -I 38400 -P 1000000 -s -f $*.$(TARGET).bin
endif
### List the ports with connected jn516x motes
@ -297,19 +294,6 @@ serialdumpall:
### UART_BAUDRATE: i.e., 115200. default is 1000000
### example: make TARGET=jn516x UART_BAUDRATE=115200 login MOTE=1
UART_BAUDRATE ?= 1000000
$(CONTIKI)/tools/tunslip6: $(CONTIKI)/tools/tunslip6.c
($(MAKE) -C $(CONTIKI)/tools tunslip6 CFLAGS= LDFLAGS= LDLIBS= INCFLAGS=)
$(SERIALDUMP): $(CONTIKI)/tools/jn516x/serialdump.c
(cd $(CONTIKI)/tools/jn516x; ${MAKE} $(notdir $(SERIALDUMP)))
login: $(SERIALDUMP)
$(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT)
serialview: $(SERIALDUMP)
$(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp
serialdump: $(SERIALDUMP)
$(SERIALDUMP) -b${UART_BAUDRATE} $(USBDEVPREFIX)$(PORT) | $(CONTIKI)/tools/timestamp | tee serialdump-$(notdir $(PORT))-`date +%Y%m%d-%H%M`
### For the login etc targets
BAUDRATE = 1000000
PORT = $(USBDEVPREFIX)$(DEV_PORT)

View File

@ -113,8 +113,7 @@ static uint32_t sleep_start_ticks;
#define LOG_LEVEL LOG_LEVEL_MAIN
/*---------------------------------------------------------------------------*/
/* Reads MAC from SoC
* Must be called before node_id_restore()
* and network addresses initialization */
* Must be called before network addresses initialization */
static void
init_node_mac(void)
{
@ -139,14 +138,9 @@ set_linkaddr(void)
#if NETSTACK_CONF_WITH_IPV6
memcpy(addr.u8, node_mac, sizeof(addr.u8));
#else
if(node_id == 0) {
int i;
for(i = 0; i < LINKADDR_SIZE; ++i) {
addr.u8[i] = node_mac[LINKADDR_SIZE - 1 - i];
}
} else {
addr.u8[0] = node_id & 0xff;
addr.u8[1] = node_id >> 8;
int i;
for(i = 0; i < LINKADDR_SIZE; ++i) {
addr.u8[i] = node_mac[LINKADDR_SIZE - 1 - i];
}
#endif
linkaddr_set_node_addr(&addr);
@ -164,10 +158,6 @@ xosc_init(void)
return bAHI_Set32KhzClockMode(E_AHI_XTAL);
}
/*---------------------------------------------------------------------------*/
#if WITH_TINYOS_AUTO_IDS
uint16_t TOS_NODE_ID = 0x1234; /* non-zero */
uint16_t TOS_LOCAL_ADDRESS = 0x1234; /* non-zero */
#endif /* WITH_TINYOS_AUTO_IDS */
void
platform_init_stage_one(void)
{
@ -194,20 +184,6 @@ platform_init_stage_one(void)
leds_init();
leds_on(LEDS_ALL);
init_node_mac();
node_id_restore();
#if WITH_TINYOS_AUTO_IDS
node_id = TOS_NODE_ID;
#endif /* WITH_TINYOS_AUTO_IDS */
/* for setting "hardcoded" IEEE 802.15.4 MAC addresses */
#ifdef IEEE_802154_MAC_ADDRESS
{
uint8_t ieee[] = IEEE_802154_MAC_ADDRESS;
memcpy(node_mac, ieee, sizeof(uip_lladdr.addr));
node_mac[7] = node_id & 0xff;
}
#endif
}
/*---------------------------------------------------------------------------*/
void
@ -225,12 +201,6 @@ platform_init_stage_two(void)
void
platform_init_stage_three(void)
{
if(node_id > 0) {
LOG_INFO("Node id is set to %u.\n", node_id);
} else {
LOG_INFO("Node id is not set.\n");
}
#ifndef UIP_FALLBACK_INTERFACE
uart0_set_input(serial_line_input_byte);
serial_line_init();

View File

@ -120,9 +120,6 @@ static uint8_t mac_addr[] = PLATFORM_CONF_MAC_ADDR;
static uint8_t mac_addr[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
#endif /* PLATFORM_CONF_MAC_ADDR */
#if !NETSTACK_CONF_WITH_IPV6
static uint16_t node_id = 0x0102;
#endif /* !NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
int
select_set_callback(int fd, const struct select_callback *callback)
@ -187,14 +184,9 @@ set_lladdr(void)
#if NETSTACK_CONF_WITH_IPV6
memcpy(addr.u8, mac_addr, sizeof(addr.u8));
#else
if(node_id == 0) {
int i;
for(i = 0; i < sizeof(linkaddr_t); ++i) {
addr.u8[i] = mac_addr[7 - i];
}
} else {
addr.u8[0] = node_id & 0xff;
addr.u8[1] = node_id >> 8;
int i;
for(i = 0; i < sizeof(linkaddr_t); ++i) {
addr.u8[i] = mac_addr[7 - i];
}
#endif
linkaddr_set_node_addr(&addr);

View File

@ -1,6 +1,6 @@
# $Id: Makefile.common,v 1.3 2010/08/24 16:24:11 joxe Exp $
ARCH=spi-legacy.c ds2411.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c \
ARCH=spi-legacy.c ds2411.c xmem.c i2c.c sensors.c cfs-coffee.c \
cc2420.c cc2420-arch.c cc2420-arch-sfd.c \
sky-sensors.c uip-ipchksum.c \
uart1.c slip_uart1.c uart1-putchar.c platform.c
@ -54,7 +54,6 @@ else
ifeq ($(HOST_OS),Darwin)
ifndef MOTELIST
USBDEVPREFIX=
SERIALDUMP = rlwrap $(CONTIKI)/tools/sky/serialdump-macos
MOTELIST = $(CONTIKI)/tools/sky/motelist-macos
TMOTE_BSL_FILE = tmote-bsl-linux
TMOTE_BSL=$(if $(wildcard $(CONTIKI)/tools/sky/$(TMOTE_BSL_FILE)),1,0)
@ -75,7 +74,6 @@ else
# Else we assume Linux
ifndef MOTELIST
USBDEVPREFIX=
SERIALDUMP = rlwrap $(CONTIKI)/tools/sky/serialdump-linux
MOTELIST = $(CONTIKI)/tools/sky/motelist-linux
TMOTE_BSL_FILE = tmote-bsl-linux
TMOTE_BSL=$(if $(wildcard $(CONTIKI)/tools/sky/$(TMOTE_BSL_FILE)),1,0)
@ -171,21 +169,7 @@ $(CONTIKI)/tools/tunslip:
(cd $(CONTIKI)/tools; $(MAKE) tunslip)
ifdef MOTE
serialdump:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) | $(CONTIKI)/tools/timestamp | tee serialdump-`date +%Y%m%d-%H%M`
serialview:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) | $(CONTIKI)/tools/timestamp
login:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES))
PORT = $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES))
else
serialdump:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES)) | $(CONTIKI)/tools/timestamp | tee serialdump-`date +%Y%m%d-%H%M`
serialview:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES)) | $(CONTIKI)/tools/timestamp
login:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(CMOTES))
PORT = $(USBDEVPREFIX)$(firstword $(CMOTES))
endif

View File

@ -103,23 +103,14 @@ set_lladdr(void)
#if NETSTACK_CONF_WITH_IPV6
memcpy(addr.u8, ds2411_id, sizeof(addr.u8));
#else
if(node_id == 0) {
int i;
for(i = 0; i < sizeof(linkaddr_t); ++i) {
addr.u8[i] = ds2411_id[7 - i];
}
} else {
addr.u8[0] = node_id & 0xff;
addr.u8[1] = node_id >> 8;
int i;
for(i = 0; i < sizeof(linkaddr_t); ++i) {
addr.u8[i] = ds2411_id[7 - i];
}
#endif
linkaddr_set_node_addr(&addr);
}
/*---------------------------------------------------------------------------*/
#if WITH_TINYOS_AUTO_IDS
uint16_t TOS_NODE_ID = 0x1234; /* non-zero */
uint16_t TOS_LOCAL_ADDRESS = 0x1234; /* non-zero */
#endif /* WITH_TINYOS_AUTO_IDS */
void
platform_init_stage_one(void)
{
@ -153,23 +144,7 @@ platform_init_stage_two(void)
* Hardware initialization done!
*/
#if WITH_TINYOS_AUTO_IDS
node_id = TOS_NODE_ID;
#else /* WITH_TINYOS_AUTO_IDS */
/* Restore node id if such has been stored in external mem */
node_id_restore();
#endif /* WITH_TINYOS_AUTO_IDS */
/* for setting "hardcoded" IEEE 802.15.4 MAC addresses */
#ifdef IEEE_802154_MAC_ADDRESS
{
uint8_t ieee[] = IEEE_802154_MAC_ADDRESS;
memcpy(ds2411_id, ieee, sizeof(uip_lladdr.addr));
ds2411_id[7] = node_id & 0xff;
}
#endif
random_init(ds2411_id[0] + node_id);
random_init(ds2411_id[0]);
leds_off(LEDS_BLUE);
@ -198,12 +173,6 @@ platform_init_stage_three(void)
cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
if(node_id > 0) {
LOG_INFO("Node id: %u\n", node_id);
} else {
LOG_INFO("Node id: N/A\n");
}
LOG_INFO("CC2420 CCA threshold %i\n", CC2420_CONF_CCA_THRESH);
#if !NETSTACK_CONF_WITH_IPV6

View File

@ -81,8 +81,6 @@
#define LOG_MODULE "CC26xx/CC13xx"
#define LOG_LEVEL LOG_LEVEL_MAIN
/*---------------------------------------------------------------------------*/
unsigned short node_id = 0;
/*---------------------------------------------------------------------------*/
/** \brief Board specific iniatialisation */
void board_init(void);
/*---------------------------------------------------------------------------*/
@ -130,9 +128,6 @@ set_rf_params(void)
NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr);
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, IEEE802154_DEFAULT_CHANNEL);
NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8);
/* also set the global node id */
node_id = short_addr;
#endif
}
/*---------------------------------------------------------------------------*/
@ -227,8 +222,6 @@ platform_init_stage_three()
}
LOG_INFO_("\n");
LOG_INFO(" Node ID: %d\n", node_id);
#if BOARD_HAS_SENSORS
process_start(&sensors_process, NULL);
#endif

View File

@ -149,8 +149,13 @@
#define EXT_FLASH_SPI_PIN_MISO 18
#define EXT_FLASH_SPI_PIN_CS 14
#if SENSORTAG_CC2650_REV_1_2_0
#define EXT_FLASH_DEVICE_ID 0x12
#define EXT_FLASH_MID 0xEF
#else
#define EXT_FLASH_DEVICE_ID 0x14
#define EXT_FLASH_MID 0xC2
#endif
#define EXT_FLASH_PROGRAM_PAGE_SIZE 256
#define EXT_FLASH_ERASE_SECTOR_SIZE 4096

View File

@ -56,11 +56,9 @@ ifeq ($(HOST_OS),Darwin)
USBDEVPREFIX=
MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia-macos
MOTES := $(shell $(MOTELIST) -c 2>&- | cut -f 2 -d ,)
SERIALDUMP := rlwrap $(CONTIKI)/tools/sky/serialdump-macos
else
### If we are not running under Mac, we assume Linux
USBDEVPREFIX=
SERIALDUMP := rlwrap $(CONTIKI)/tools/sky/serialdump-linux
MOTELIST := $(CONTIKI)/tools/zolertia/motelist-zolertia
MOTES := $(shell $(MOTELIST) -b $(MOTELIST_ZOLERTIA) -c 2>&- | cut -f 2 -d , | \
perl -ne 'print $$1 . " " if(m-(/dev/\w+)-);')
@ -103,8 +101,6 @@ zoul-motelist:
zoul-motes:
@echo $(MOTES)
serialview:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES)) | $(CONTIKI)/tools/timestamp
login:
$(SERIALDUMP) -b115200 $(USBDEVPREFIX)$(firstword $(MOTES))
### For the login etc targets
BAUDRATE = 115200
PORT = $(USBDEVPREFIX)$(firstword $(MOTES))

View File

@ -37,7 +37,7 @@
*/
#include "contiki.h"
#include "node-id.h"
#include "sys/node-id.h"
#include "sys/log.h"
#include "net/ipv6/uip-ds6-route.h"
#include "net/mac/tsch/tsch.h"

View File

@ -37,7 +37,7 @@
*/
#include "contiki.h"
#include "node-id.h"
#include "sys/node-id.h"
#include "sys/log.h"
#include "net/ipv6/uip-ds6-route.h"
#include "net/ipv6/uip-sr.h"

View File

@ -38,7 +38,7 @@
*/
#include "contiki.h"
#include "node-id.h"
#include "sys/node-id.h"
#include "sys/log.h"
#include "net/ipv6/uip-ds6-route.h"
#include "net/mac/tsch/tsch.h"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,5 @@
CONTIKI_PROJECT = udp-client udp-server
all: $(CONTIKI_PROJECT)
CONTIKI=../../..
include $(CONTIKI)/Makefile.include

View File

@ -0,0 +1,5 @@
This example is meant to showcase the capabilities of uipbuf. It currently
focuses only on UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, which lets an application
set a custom max number of MAC transmissions. Optionally, this information
can be passed on over multiple hops, so that the attribute applies along
the full path. This requires setting UIP_CONF_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS.

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>IPv6 uipbuf Example</title>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<identifier>mtype829</identifier>
<description>Cooja Mote Type #1</description>
<source>[CONTIKI_DIR]/examples/libs/ipv6-uipbuf/udp-server.c</source>
<commands>make udp-server.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<identifier>mtype405</identifier>
<description>Cooja Mote Type #2</description>
<source>[CONTIKI_DIR]/examples/libs/ipv6-uipbuf/udp-client.c</source>
<commands>make udp-client.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>43.291897546941804</x>
<y>7.17470867058031</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype829</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>41.0074953544532</x>
<y>42.15996473110367</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype405</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>229</width>
<z>3</z>
<height>157</height>
<location_x>11</location_x>
<location_y>6</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<moterelations>true</moterelations>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<viewport>1.1719333465234514 0.0 0.0 1.1719333465234514 -4.934308660658031 20.209777273580123</viewport>
</plugin_config>
<width>234</width>
<z>1</z>
<height>257</height>
<location_x>10</location_x>
<location_y>170</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter>App</filter>
<formatted_time />
<coloring />
</plugin_config>
<width>1074</width>
<z>0</z>
<height>713</height>
<location_x>844</location_x>
<location_y>3</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.TimeLine
<plugin_config>
<mote>0</mote>
<mote>1</mote>
<showRadioRXTX />
<showRadioHW />
<showLEDs />
<zoomfactor>140.4158108891898</zoomfactor>
</plugin_config>
<width>1920</width>
<z>2</z>
<height>384</height>
<location_x>1</location_x>
<location_y>716</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.RadioLogger
<plugin_config>
<split>407</split>
<formatted_time />
<showdups>false</showdups>
<hidenodests>false</hidenodests>
</plugin_config>
<width>595</width>
<z>4</z>
<height>706</height>
<location_x>245</location_x>
<location_y>4</location_y>
</plugin>
</simconf>

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>IPv6 uipbuf Example</title>
<randomseed>generated</randomseed>
<motedelay_us>5000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>50.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
org.contikios.cooja.mspmote.SkyMoteType
<identifier>sky1</identifier>
<description>Sky Mote Type #sky1</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/libs/ipv6-uipbuf/udp-server.c</source>
<commands EXPORT="discard">make udp-server.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/libs/ipv6-uipbuf/udp-server.sky</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<motetype>
org.contikios.cooja.mspmote.SkyMoteType
<identifier>sky2</identifier>
<description>Sky Mote Type #sky2</description>
<source EXPORT="discard">[CONTIKI_DIR]/examples/libs/ipv6-uipbuf/udp-client.c</source>
<commands EXPORT="discard">make udp-client.sky TARGET=sky</commands>
<firmware EXPORT="copy">[CONTIKI_DIR]/examples/libs/ipv6-uipbuf/udp-client.sky</firmware>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.IPAddress</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspClock</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspMoteID</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyButton</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyFlash</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspSerial</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyLED</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
<moteinterface>org.contikios.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
</motetype>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>30.051578821079996</x>
<y>-64.69428746901113</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>1</id>
</interface_config>
<motetype_identifier>sky1</motetype_identifier>
</mote>
<mote>
<breakpoints />
<interface_config>
org.contikios.cooja.interfaces.Position
<x>21.31366587648077</x>
<y>-34.91404431659299</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspClock
<deviation>1.0</deviation>
</interface_config>
<interface_config>
org.contikios.cooja.mspmote.interfaces.MspMoteID
<id>2</id>
</interface_config>
<motetype_identifier>sky2</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>249</width>
<z>4</z>
<height>184</height>
<location_x>3</location_x>
<location_y>15</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
<viewport>1.3598488697820064 0.0 0.0 1.3598488697820064 6.142207908179105 118.20877091196155</viewport>
</plugin_config>
<width>234</width>
<z>1</z>
<height>227</height>
<location_x>14</location_x>
<location_y>210</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter />
<formatted_time />
<coloring />
</plugin_config>
<width>1011</width>
<z>0</z>
<height>556</height>
<location_x>759</location_x>
<location_y>7</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.TimeLine
<plugin_config>
<mote>0</mote>
<mote>1</mote>
<showRadioRXTX />
<showRadioHW />
<showLEDs />
<zoomfactor>681.712557066089</zoomfactor>
</plugin_config>
<width>1804</width>
<z>3</z>
<height>352</height>
<location_x>0</location_x>
<location_y>567</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.RadioLogger
<plugin_config>
<split>150</split>
<formatted_time />
<showdups>false</showdups>
<hidenodests>false</hidenodests>
</plugin_config>
<width>500</width>
<z>2</z>
<height>546</height>
<location_x>259</location_x>
<location_y>12</location_y>
</plugin>
</simconf>

View File

@ -0,0 +1,37 @@
/*
* 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 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.
*/
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
/* Include max MAC Tx in the IPv6 Traffic Class field */
#define UIP_CONF_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS 1
#endif /* PROJECT_CONF_H_ */

View File

@ -0,0 +1,85 @@
#include "contiki.h"
#include "net/routing/routing.h"
#include "random.h"
#include "net/netstack.h"
#include "net/ipv6/simple-udp.h"
#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_INFO
#define WITH_SERVER_REPLY 1
#define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678
static struct simple_udp_connection udp_conn;
#define START_INTERVAL (15 * CLOCK_SECOND)
#define SEND_INTERVAL (60 * CLOCK_SECOND)
static struct simple_udp_connection udp_conn;
/*---------------------------------------------------------------------------*/
PROCESS(udp_client_process, "UDP client");
AUTOSTART_PROCESSES(&udp_client_process);
/*---------------------------------------------------------------------------*/
static void
udp_rx_callback(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
unsigned count = *(unsigned *)data;
/* If tagging of traffic class is enabled tc will print number of
transmission - otherwise it will be 0 */
LOG_INFO("Received response %u (Max MAC Tx: %d) from ", count,
uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
LOG_INFO_6ADDR(sender_addr);
LOG_INFO_("\n");
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_client_process, ev, data)
{
static struct etimer periodic_timer;
static unsigned count;
uip_ipaddr_t dest_ipaddr;
PROCESS_BEGIN();
/* Initialize UDP connection */
simple_udp_register(&udp_conn, UDP_CLIENT_PORT, NULL,
UDP_SERVER_PORT, udp_rx_callback);
etimer_set(&periodic_timer, random_rand() % SEND_INTERVAL);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
if(NETSTACK_ROUTING.node_is_reachable() && NETSTACK_ROUTING.get_root_ipaddr(&dest_ipaddr)) {
/* Set the number of transmissions to use for this packet -
this can be used to create more reliable transmissions or
less reliable than the default. Works end-to-end if
UIP_CONF_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS is set to 1.
*/
uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, 1 + count % 5);
/* Send to DAG root */
LOG_INFO("Sending request %u (Max MAC Tx: %d) to ", count,
uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
LOG_INFO_6ADDR(&dest_ipaddr);
LOG_INFO_("\n");
simple_udp_sendto(&udp_conn, &count, sizeof(count), &dest_ipaddr);
count++;
} else {
LOG_INFO("Not reachable yet\n");
}
/* Add some jitter */
etimer_set(&periodic_timer, SEND_INTERVAL
- CLOCK_SECOND + (random_rand() % (2 * CLOCK_SECOND)));
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,84 @@
/*
* 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.
*
*/
#include "contiki.h"
#include "net/routing/routing.h"
#include "net/netstack.h"
#include "net/ipv6/simple-udp.h"
#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_INFO
#define WITH_SERVER_REPLY 1
#define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678
static struct simple_udp_connection udp_conn;
PROCESS(udp_server_process, "UDP server");
AUTOSTART_PROCESSES(&udp_server_process);
/*---------------------------------------------------------------------------*/
static void
udp_rx_callback(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
unsigned count = *(unsigned *)data;
LOG_INFO("Received request %u (Max MAC Tx: %d) from ", count,
uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
LOG_INFO_6ADDR(sender_addr);
LOG_INFO_("\n");
#if WITH_SERVER_REPLY
LOG_INFO("Sending response %u (Max MAC Tx: %d) to ", count,
uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
LOG_INFO_6ADDR(sender_addr);
LOG_INFO_("\n");
simple_udp_sendto(&udp_conn, &count, sizeof(count), sender_addr);
#endif /* WITH_SERVER_REPLY */
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_server_process, ev, data)
{
PROCESS_BEGIN();
/* Initialize DAG root */
NETSTACK_ROUTING.root_start();
/* Initialize UDP connection */
simple_udp_register(&udp_conn, UDP_SERVER_PORT, NULL,
UDP_CLIENT_PORT, udp_rx_callback);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,9 @@
CONTIKI_PROJECT = example
all: $(CONTIKI_PROJECT)
MODULES += os/services/shell
CONTIKI = ../../..
PLATFORMS_EXCLUDE = sky
include $(CONTIKI)/Makefile.include

View File

@ -0,0 +1 @@
This is a minimal example for the shell.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, SICS Swedish ICT.
* Copyright (c) 2018, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,30 +32,25 @@
/**
* \file
* For compatibility with Contiki node-id interface
*
* A very simple example using the shell
* \author
* Beshr Al Nahas <beshr@sics.se>
* Simon Duquennoy <simon.duquennoy@ri.se>
*/
#include "contiki.h"
#include "sys/node-id.h"
#include "contiki.h"
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
extern unsigned char node_mac[8];
unsigned short node_id = 0;
PROCESS(example_process, "Example process: shell");
AUTOSTART_PROCESSES(&example_process);
/*---------------------------------------------------------------------------*/
void
node_id_restore(void)
PROCESS_THREAD(example_process, ev, data)
{
/* base node-id on MAC address */
node_id = (node_mac[6] << 8) | node_mac[7];
PROCESS_BEGIN();
/* This process does nothing. Connect to the node with `make login`
* to use the shell. */
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
node_id_burn(unsigned short id)
{
/* does not burn anything */
node_id = id;
}

View File

@ -0,0 +1,6 @@
CONTIKI_PROJECT = example
all: $(CONTIKI_PROJECT)
MODULES += os/services/simple-energest
CONTIKI = ../../..
include $(CONTIKI)/Makefile.include

View File

@ -0,0 +1 @@
This is a minimal example for the module simple-energest.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* Copyright (c) 2018, RISE SICS.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,40 +32,25 @@
/**
* \file
* Utility to store a node id in the external flash
* A very simple example of simple-energest
* \author
* Adam Dunkels <adam@sics.se>
* Simon Duquennoy <simon.duquennoy@ri.se>
*/
#include "sys/node-id.h"
#include "contiki.h"
#include "dev/xmem.h"
unsigned short node_id = 0;
#include <stdio.h> /* For printf() */
/*---------------------------------------------------------------------------*/
void
node_id_restore(void)
PROCESS(example_process, "Example process: simple-energest");
AUTOSTART_PROCESSES(&example_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(example_process, ev, data)
{
unsigned char buf[4];
xmem_pread(buf, 4, NODE_ID_XMEM_OFFSET);
if(buf[0] == 0xad &&
buf[1] == 0xde) {
node_id = (buf[2] << 8) | buf[3];
} else {
node_id = 0;
}
}
/*---------------------------------------------------------------------------*/
void
node_id_burn(unsigned short id)
{
unsigned char buf[4];
buf[0] = 0xad;
buf[1] = 0xde;
buf[2] = id >> 8;
buf[3] = id & 0xff;
xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET);
xmem_pwrite(buf, 4, NODE_ID_XMEM_OFFSET);
PROCESS_BEGIN();
/* Do nothing, just let simple-energest write its summary
* at a period of SIMPLE_ENERGEST_CONF_PERIOD */
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -11,4 +11,7 @@ MODULES += os/services/lwm2m
MODULES += os/services/ipso-objects
CONTIKI=../..
include $(CONTIKI)/Makefile.identify-target
MODULES_REL += $(TARGET)
include $(CONTIKI)/Makefile.include

View File

@ -30,9 +30,6 @@
#ifndef PROJECT_CONF_H_
#define PROJECT_CONF_H_
/* No sleep on CC2538 to enable full 32 KiB RAM */
#define LPM_CONF_ENABLE 0
#ifdef BOARD_STRING
#define LWM2M_DEVICE_MODEL_NUMBER BOARD_STRING
#elif defined(CONTIKI_TARGET_WISMOTE)
@ -62,4 +59,12 @@
/* Enable client-side support for COAP observe */
#define COAP_OBSERVE_CLIENT 1
/* Definitions to enable Queue Mode, include the dynamic adaptation and change the default parameters */
/* #define LWM2M_QUEUE_MODE_CONF_ENABLED 1
#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 0
#define LWM2M_QUEUE_MODE_OBJECT_CONF_ENABLED 1 */
#endif /* PROJECT_CONF_H_ */

View File

@ -0,0 +1,48 @@
/*
* 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.
*/
/*---------------------------------------------------------------------------*/
/* Only sleep mode 1 on Zoul to enable full 32 KiB RAM */
#define LPM_CONF_MAX_PM 1
/*---------------------------------------------------------------------------*/
/* Macros to enter sleep mode and wake up in the Zoul module. Sleep consists
* on turn off the radio and start a RTIMER to wake up, and wake up consists on
* turn on the radio again
*/
#define LWM2M_Q_MODE_WAKE_UP() do { \
NETSTACK_MAC.on(); \
} while(0)
#define LWM2M_Q_MODE_SLEEP_MS(TIME_MS) do { \
uint64_t aux = TIME_MS * RTIMER_SECOND; \
NETSTACK_MAC.off(); \
rtimer_arch_schedule(RTIMER_NOW() + (rtimer_clock_t)(aux / 1000)); \
} while(0)

View File

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

View File

@ -10,11 +10,17 @@ demonstrate the CC26xx capability. The applications are:
* A web server which can be used to display sensor readings but also to
configure MQTT functionality
The example has been configured to run for all CC26xx-based boards: i) The
SensorTag 2.0 and ii) The Srf06EB with a CC26xx or CC13xx EM mounted on it.
The example has been configured to run for all CC26xx-based boards.
To change between target boards, follow the instructions in the platform's
REDME file. Do not forget to `make clean` when switching between the boards.
To change between target boards, follow the instructions in the wiki.
Do not forget to `make clean` when switching between the boards.
Specifically for some older CC2650 SensorTags, you may also need to change
`project-conf.h` such that `SENSORTAG_CC2650_REV_1_2_0` is defined as 1. To
check if your sensortag is one of those older ones, look for "REV: 1.2"
printed on the PCB. There may also be a sticker that reads "HW Rev 1.2.0". An
indication that you may need to do this is if you get a "Could not open flash
to load config" error on device startup.
You can disable some of those individual components by changing the respective
defines in `project-conf.h`. For instance, to disable the CoAP functionality,

View File

@ -53,6 +53,16 @@
*/
#define CC26XX_WEB_DEMO_CONF_ADC_DEMO 0
/*---------------------------------------------------------------------------*/
/*
* Change to 1 if you are using an older CC2650 Sensortag (look for Rev: 1.2
* printed on the PCB, or for a sticker reading "HW Rev 1.2.0").
*
* This may be the case if you are getting this error:
* "Could not open flash to load config"
* when your sensortag is starting up.
*/
#define SENSORTAG_CC2650_REV_1_2_0 0
/*---------------------------------------------------------------------------*/
/* Enable the ROM bootloader */
#define ROM_BOOTLOADER_ENABLE 1
/*---------------------------------------------------------------------------*/

View File

@ -38,7 +38,7 @@
#include "net/routing/routing.h"
#include "net/ipv6/uip-debug.h"
#include "lib/random.h"
#include "node-id.h"
#include "sys/node-id.h"
#include "waveform.h"
#include "leds.h"
#include "net/ipv6/uiplib.h"

View File

@ -33,10 +33,7 @@ udp_rx_callback(struct simple_udp_connection *c,
uint16_t datalen)
{
unsigned count = *(unsigned *)data;
/* If tagging of traffic class is enabled tc will print number of
transmission - otherwise it will be 0 */
LOG_INFO("Received response %u (tc:%d) from ", count,
uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
LOG_INFO("Received response %u from ", count);
LOG_INFO_6ADDR(sender_addr);
LOG_INFO_("\n");
}
@ -62,12 +59,6 @@ PROCESS_THREAD(udp_client_process, ev, data)
LOG_INFO("Sending request %u to ", count);
LOG_INFO_6ADDR(&dest_ipaddr);
LOG_INFO_("\n");
/* Set the number of transmissions to use for this packet -
this can be used to create more reliable transmissions or
less reliable than the default. Works end-to-end if
UIP_CONF_TAG_TC_WITH_VARIABLE_RETRANSMISSIONS is set to 1.
*/
uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS, 1 + count % 5);
simple_udp_sendto(&udp_conn, &count, sizeof(count), &dest_ipaddr);
count++;
} else {

View File

@ -143,7 +143,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
packetbuf_clear();
pos = packetutils_deserialize_atts(&data[3], len - 3);
if(pos < 0) {
LOG_ERR("slip-radio: illegal packet attributes\n");
LOG_ERR("illegal packet attributes\n");
return 1;
}
pos += 3;
@ -154,7 +154,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
memcpy(packetbuf_dataptr(), &data[pos], len);
packetbuf_set_datalen(len);
LOG_DBG("slip-radio: sending %u (%d bytes)\n",
LOG_DBG("sending %u (%d bytes)\n",
data[2], packetbuf_datalen());
/* parse frame before sending to get addresses, etc. */

View File

@ -42,6 +42,7 @@
/*---------------------------------------------------------------------------*/
#include "contiki.h"
#include "contiki-net.h"
#include "sys/node-id.h"
#include "sys/platform.h"
#include "sys/energest.h"
#include "sys/stack-check.h"
@ -51,6 +52,7 @@
#include "services/rpl-border-router/rpl-border-router.h"
#include "services/orchestra/orchestra.h"
#include "services/shell/serial-shell.h"
#include "services/simple-energest/simple-energest.h"
#include <stdio.h>
#include <stdint.h>
@ -86,6 +88,9 @@ main(void)
platform_init_stage_two();
netstack_init();
node_id_init();
LOG_INFO("Starting " CONTIKI_VERSION_STRING "\n");
LOG_INFO("- Routing: %s\n", NETSTACK_ROUTING.name);
LOG_INFO("- Net: %s\n", NETSTACK_NETWORK.name);
@ -97,9 +102,8 @@ main(void)
LOG_INFO("- 802.15.4 Default channel: %u\n", IEEE802154_DEFAULT_CHANNEL);
#endif /* MAC_CONF_WITH_TSCH */
netstack_init();
LOG_INFO("Link-layer address ");
LOG_INFO("Node ID: %u\n", node_id);
LOG_INFO("Link-layer address: ");
LOG_INFO_LLADDR(&linkaddr_node_addr);
LOG_INFO_("\n");
@ -110,7 +114,7 @@ main(void)
process_start(&tcpip_process, NULL);
lladdr = uip_ds6_get_link_local(-1);
LOG_INFO("Tentative link-local IPv6 address ");
LOG_INFO("Tentative link-local IPv6 address: ");
LOG_INFO_6ADDR(lladdr != NULL ? &lladdr->ipaddr : NULL);
LOG_INFO_("\n");
}
@ -138,6 +142,10 @@ main(void)
LOG_DBG("With CoAP\n");
#endif /* BUILD_WITH_SHELL */
#if BUILD_WITH_SIMPLE_ENERGEST
simple_energest_init();
#endif /* BUILD_WITH_SIMPLE_ENERGEST */
autostart_start(autostart_processes);
watchdog_start();

View File

@ -324,4 +324,26 @@ list_item_next(void *item)
return item == NULL ? NULL : ((struct list *)item)->next;
}
/*---------------------------------------------------------------------------*/
/**
* \brief Check if the list contains an item
* \param list The list that is checked
* \param item An item to look for in the list
* \returns 0 if the list does not contains the item, and 1 otherwise
*
* This function searches for an item in the list and returns
* 0 if the list does not contain the item, and 1 if the item
* is present in the list.
*/
bool
list_contains(list_t list, void *item)
{
struct list *l;
for(l = *list; l != NULL; l = l->next) {
if(item == l) {
return true;
}
}
return false;
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -66,6 +66,8 @@
#ifndef LIST_H_
#define LIST_H_
#include <stdbool.h>
#define LIST_CONCAT2(s1, s2) s1##s2
#define LIST_CONCAT(s1, s2) LIST_CONCAT2(s1, s2)
@ -151,6 +153,8 @@ void list_insert(list_t list, void *previtem, void *newitem);
void * list_item_next(void *item);
bool list_contains(list_t list, void *item);
#endif /* LIST_H_ */
/** @} */

View File

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

View File

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

View File

@ -54,19 +54,13 @@
#define LOG_MODULE "coap"
#define LOG_LEVEL LOG_LEVEL_COAP
/* These should go into the state struct so that we can have multiple
requests */
static uint32_t res_block;
static uint8_t more;
static uint8_t block_error;
static void coap_request_callback(void *callback_data, coap_message_t *response);
/*---------------------------------------------------------------------------*/
static void
progress_request(coap_request_state_t *state) {
static int
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 =
@ -83,7 +77,9 @@ progress_request(coap_request_state_t *state) {
coap_send_transaction(state->transaction);
LOG_DBG("Requested #%"PRIu32" (MID %u)\n", state->block_num, request->mid);
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
@ -91,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;
@ -100,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);
}
}
/*---------------------------------------------------------------------------*/
void
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))
{
/* 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;
progress_request(state);
return progress_request(callback_state);
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -47,27 +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);
};
void coap_send_request(coap_request_state_t *state, coap_endpoint_t *endpoint,
/**
* \brief Send a CoAP request to a remote endpoint
* \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_callback_request_state_t *callback_state, coap_endpoint_t *endpoint,
coap_message_t *request,
void (*callback)(coap_request_state_t *state));
void (*callback)(coap_callback_request_state_t *callback_state));
#endif /* COAP_CALLBACK_API_H_ */
/** @} */

View File

@ -353,4 +353,18 @@ coap_observe_handler(coap_resource_t *resource, coap_message_t *coap_req,
}
}
/*---------------------------------------------------------------------------*/
uint8_t
coap_has_observers(char *path)
{
coap_observer_t *obs = NULL;
for(obs = (coap_observer_t *)list_head(observers_list); obs;
obs = obs->next) {
if((strncmp(obs->url, path, strlen(path))) == 0) {
return 1;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -80,5 +80,7 @@ void coap_notify_observers_sub(coap_resource_t *resource, const char *subpath);
void coap_observe_handler(coap_resource_t *resource, coap_message_t *request,
coap_message_t *response);
uint8_t coap_has_observers(char *path);
#endif /* COAP_OBSERVE_H_ */
/** @} */

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2018, RISE SICS AB.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \addtogroup coap
* @{
*/
/**
* \file
* Common request state for all the APIs
* \author
* Carlos Gonzalo Peces <carlosgp143@gmail.com>
*/
#ifndef COAP_REQUEST_STATE_H_
#define COAP_REQUEST_STATE_H_
typedef enum {
COAP_REQUEST_STATUS_RESPONSE, /* Response received and no more blocks */
COAP_REQUEST_STATUS_MORE, /* Response received and there are more blocks */
COAP_REQUEST_STATUS_FINISHED, /* Request finished */
COAP_REQUEST_STATUS_TIMEOUT, /* Request Timeout after all retransmissions */
COAP_REQUEST_STATUS_BLOCK_ERROR /* Blocks in wrong order */
} coap_request_status_t;
typedef struct coap_request_state {
coap_transaction_t *transaction;
coap_message_t *response;
coap_message_t *request;
coap_endpoint_t *remote_endpoint;
uint32_t block_num;
uint32_t res_block;
uint8_t more;
uint8_t block_error;
void *user_data;
coap_request_status_t status;
} coap_request_state_t;
#endif /* COAP_REQUEST_STATE_H_ */
/** @} */

View File

@ -211,30 +211,27 @@ coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
/* Only IPv6 supported */
int start = index_of(text, 0, size, '[');
int end = index_of(text, start, size, ']');
int secure = strncmp((const char *)text, "coaps:", 6) == 0;
uint32_t port;
if(start > 0 && end > start &&
uiplib_ipaddrconv((const char *)&text[start], &ep->ipaddr)) {
ep->secure = strncmp(text, "coaps:", 6) == 0;
if(start >= 0 && end > start &&
uiplib_ipaddrconv(&text[start], &ep->ipaddr)) {
if(text[end + 1] == ':' &&
get_port(text + end + 2, size - end - 2, &port)) {
ep->port = UIP_HTONS(port);
} else if(secure) {
/**
* Secure CoAP should use a different port but for now
* the same port is used.
*/
LOG_DBG("Using secure port (coaps)\n");
} else if(ep->secure) {
/* Use secure CoAP port by default for secure endpoints. */
ep->port = SERVER_LISTEN_SECURE_PORT;
ep->secure = 1;
} else {
ep->port = SERVER_LISTEN_PORT;
ep->secure = 0;
}
return 1;
} else {
if(uiplib_ipaddrconv((const char *)&text, &ep->ipaddr)) {
} else if(size < UIPLIB_IPV6_MAX_STR_LEN) {
char buf[UIPLIB_IPV6_MAX_STR_LEN];
memcpy(buf, text, size);
buf[size] = '\0';
if(uiplib_ipaddrconv(buf, &ep->ipaddr)) {
ep->port = SERVER_LISTEN_PORT;
ep->secure = 0;
return 1;
}
}

View File

@ -140,13 +140,13 @@
#define MAC_MAX_PAYLOAD (127 - 2)
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
/** \brief Fixed size of a frame header. This value is
* used in case framer returns an error or if SICSLOWPAN_USE_FIXED_HDRLEN
* is defined.
*/
#ifndef SICSLOWPAN_FIXED_HDRLEN
#define SICSLOWPAN_FIXED_HDRLEN 21
#endif
/** \brief Maximum size of a frame header. This value is
* used in case framer returns an error */
#ifdef SICSLOWPAN_CONF_MAC_MAX_HEADER
#define MAC_MAX_HEADER SICSLOWPAN_CONF_MAC_MAX_HEADER
#else /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
#define MAC_MAX_HEADER 21
#endif /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
/* set this to zero if not compressing EXT_HDR - for backwards compatibility */
#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
@ -336,8 +336,6 @@ store_fragment(uint8_t index, uint8_t offset)
frag_buf[i].index = index;
memcpy(frag_buf[i].data, packetbuf_ptr + packetbuf_hdr_len,
packetbuf_datalen() - packetbuf_hdr_len);
LOG_INFO("Fragsize: %d\n", frag_buf[i].len);
/* return the length of the stored fragment */
return frag_buf[i].len;
}
@ -371,7 +369,7 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
}
if(found < 0) {
LOG_WARN("*** Failed to store new fragment session - tag: %d\n", tag);
LOG_WARN("reassembly: failed to store new fragment session - tag: %d\n", tag);
return -1;
}
@ -398,7 +396,7 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
if(found < 0) {
/* no entry found for storing the new fragment */
LOG_WARN("*** Failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
LOG_WARN("reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
return -1;
}
@ -413,7 +411,7 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
} else {
/* should we also clear all fragments since we failed to store
this fragment? */
LOG_WARN("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
LOG_WARN("reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
return -1;
}
}
@ -610,7 +608,7 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
prefcount = prefcount == 15 ? 16 : prefcount;
postcount = postcount == 15 ? 16 : postcount;
LOG_INFO("Uncompressing %d + %d => ", prefcount, postcount);
LOG_DBG("uncompression: address %d %d", prefcount, postcount);
if(prefcount > 0) {
memcpy(ipaddr, prefix, prefcount);
@ -631,8 +629,8 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
uip_ds6_set_addr_iid(ipaddr, lladdr);
}
LOG_INFO_6ADDR(ipaddr);
LOG_INFO_("\n");
LOG_DBG_6ADDR(ipaddr);
LOG_DBG_("\n");
}
/*--------------------------------------------------------------------*/
@ -680,7 +678,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(LOG_DBG_ENABLED) {
uint16_t ndx;
LOG_DBG("before compression (%d): ", UIP_IP_BUF->len[1]);
LOG_DBG("compression: before (%d): ", UIP_IP_BUF->len[1]);
for(ndx = 0; ndx < UIP_IP_BUF->len[1] + 40; ndx++) {
uint8_t data = ((uint8_t *) (UIP_IP_BUF))[ndx];
LOG_DBG_("%02x", data);
@ -729,7 +727,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(addr_context_lookup_by_prefix(&UIP_IP_BUF->destipaddr) != NULL ||
addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr) != NULL) {
/* set context flag and increase hc06_ptr */
LOG_INFO("IPHC: compressing dest or src ipaddr - setting CID\n");
LOG_DBG("compression: dest or src ipaddr - setting CID\n");
iphc1 |= SICSLOWPAN_IPHC_CID;
hc06_ptr++;
}
@ -816,13 +814,13 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
/* source address - cannot be multicast */
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
LOG_INFO("IPHC: compressing unspecified - setting SAC\n");
LOG_DBG("compression: addr unspecified - setting SAC\n");
iphc1 |= SICSLOWPAN_IPHC_SAC;
iphc1 |= SICSLOWPAN_IPHC_SAM_00;
} else if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr))
!= NULL) {
/* elide the prefix - indicate by CID and set context + SAC */
LOG_INFO("IPHC: compressing src with context - setting CID & SAC ctx: %d\n",
LOG_DBG("compression: src with context - setting CID & SAC ctx: %d\n",
context->number);
iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
PACKETBUF_IPHC_BUF[2] |= context->number << 4;
@ -905,9 +903,9 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
next_nhc = hc06_ptr; /* here we set the next header is compressed. */
ext_hdr_len = 0;
/* reserve the write place of this next header position */
LOG_INFO("Compressing first header: %d\n", *next_hdr);
LOG_DBG("compression: first header: %d\n", *next_hdr);
while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
LOG_INFO("Compressing next header: %d\n", *next_hdr);
LOG_DBG("compression: next header: %d\n", *next_hdr);
int proto = -1; /* used for the specific ext hdr */
/* UDP and EXT header compression */
switch(*next_hdr) {
@ -926,7 +924,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
/* Len is defined to be in octets from the length byte */
len = (ext_hdr->len << 3) + 8;
LOG_INFO("Handling next header: %d (len:%d)\n", *next_hdr, len);
LOG_DBG("compression: next header %d (len:%d)\n", *next_hdr, len);
/* pick up the next header */
next_hdr = &ext_hdr->next;
/* If the next header is not compressable we need to reserve the
@ -935,7 +933,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
CHECK_BUFFER_SPACE(1);
hc06_ptr++;
LOG_INFO("Keeping the next header in this ext hdr: %d\n",
LOG_DBG("compression: keeping the next header in this ext hdr: %d\n",
ext_hdr->next);
}
/* copy the ext-hdr into the hc06 buffer */
@ -961,14 +959,14 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
/* allocate a byte for the next header posision as UDP has no next */
hc06_ptr++;
udp_buf = UIP_UDP_BUF(ext_hdr_len);
LOG_INFO("IPHC: Uncompressed UDP ports on send side: %x, %x\n",
LOG_DBG("compression: inlined UDP ports on send side: %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
/* Mask out the last 4 bits can be used as a mask */
if(((UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
((UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
/* we can compress 12 bits of both source and dest */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
LOG_INFO("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
LOG_DBG("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
CHECK_BUFFER_SPACE(1);
*hc06_ptr =
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
@ -979,7 +977,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
} else if((UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
/* we can compress 8 bits of dest, leave source. */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
LOG_INFO("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
LOG_DBG("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
CHECK_BUFFER_SPACE(3);
memcpy(hc06_ptr, &udp_buf->srcport, 2);
*(hc06_ptr + 2) =
@ -989,7 +987,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
} else if((UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
/* we can compress 8 bits of src, leave dest. Copy compressed port */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
LOG_INFO("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
LOG_DBG("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
CHECK_BUFFER_SPACE(3);
*hc06_ptr =
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
@ -999,7 +997,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
} else {
/* we cannot compress. Copy uncompressed ports, full checksum */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
LOG_INFO("IPHC: cannot compress UDP headers\n");
LOG_DBG("IPHC: cannot compress UDP headers\n");
CHECK_BUFFER_SPACE(4);
memcpy(hc06_ptr, &udp_buf->srcport, 4);
hc06_ptr += 4;
@ -1009,17 +1007,17 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
memcpy(hc06_ptr, &udp_buf->udpchksum, 2);
hc06_ptr += 2;
uncomp_hdr_len += UIP_UDPH_LEN;
/* this is the final header... */
/* this is the final header. */
next_hdr = NULL;
break;
default:
LOG_ERR("IPHC: could not handle compression of header");
LOG_ERR("compression: could not handle compression of header");
}
}
if(next_hdr != NULL) {
/* Last header could not be compressed - we assume that this is then OK!*/
/* as the last EXT_HDR should be "uncompressed" and have the next there */
LOG_INFO("IPHC: last header could is not compressed: %d\n", *next_hdr);
LOG_DBG("compression: last header could is not compressed: %d\n", *next_hdr);
}
/* before the packetbuf_hdr_len operation */
PACKETBUF_IPHC_BUF[0] = iphc0;
@ -1027,7 +1025,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(LOG_DBG_ENABLED) {
uint16_t ndx;
LOG_DBG("after compression %d: ", (int)(hc06_ptr - packetbuf_ptr));
LOG_DBG("compression: after (%d): ", (int)(hc06_ptr - packetbuf_ptr));
for(ndx = 0; ndx < hc06_ptr - packetbuf_ptr; ndx++) {
uint8_t data = ((uint8_t *) packetbuf_ptr)[ndx];
LOG_DBG_("%02x", data);
@ -1074,7 +1072,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
/* another if the CID flag is set */
if(iphc1 & SICSLOWPAN_IPHC_CID) {
LOG_INFO("IPHC: CID flag set - increase header with one\n");
LOG_DBG("uncompression: CID flag set - increase header with one\n");
hc06_ptr++;
}
@ -1122,7 +1120,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
/* Next header is carried inline */
SICSLOWPAN_IP_BUF(buf)->proto = *hc06_ptr;
LOG_INFO("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
LOG_DBG("uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
hc06_ptr += 1;
}
@ -1146,7 +1144,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
if (tmp != 0) {
context = addr_context_lookup_by_number(sci);
if(context == NULL) {
LOG_ERR("uncompress_hdr: error context not found\n");
LOG_ERR("uncompression: error context not found\n");
return;
}
}
@ -1193,7 +1191,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
/* all valid cases below need the context! */
if(context == NULL) {
LOG_ERR("uncompress_hdr: error context not found\n");
LOG_ERR("uncompression: error context not found\n");
return;
}
uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix,
@ -1228,12 +1226,12 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
if(!nh) {
next = *hc06_ptr;
hc06_ptr++;
LOG_INFO("Next header is not compressed... next: %d\n", next);
LOG_DBG("uncompression: next header is inlined. Next: %d\n", next);
}
len = *hc06_ptr;
hc06_ptr++;
LOG_INFO("IPHC: Found extension-header id=%d next=%d len=%d\n", eid, next, len);
LOG_DBG("uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
switch(eid) {
case SICSLOWPAN_NHC_ETX_HDR_HBHO:
proto = UIP_PROTO_HBHO;
@ -1248,7 +1246,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
proto = UIP_PROTO_DESTO;
break;
default:
LOG_INFO("IPHC: error unsupported extension-header\n");
LOG_DBG("uncompression: error unsupported ext header\n");
return;
}
*last_nextheader = proto;
@ -1263,7 +1261,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
ip_payload += (exthdr->len + 1) * 8;
ext_hdr_len += (exthdr->len + 1) * 8;
LOG_INFO("Uncompressed EXT hdr: %d len:%d exhdrlen:%d (calc: %d)\n",
LOG_DBG("uncompression: %d len: %d exhdrlen: %d (calc: %d)\n",
proto, len, exthdr->len, (exthdr->len + 1) * 8);
}
@ -1274,13 +1272,13 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
uint8_t checksum_compressed;
*last_nextheader = UIP_PROTO_UDP;
checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
LOG_INFO("IPHC: Incoming header value: %i\n", *hc06_ptr);
LOG_DBG("uncompression: incoming header value: %i\n", *hc06_ptr);
switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
case SICSLOWPAN_NHC_UDP_CS_P_00:
/* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */
memcpy(&udp_buf->srcport, hc06_ptr + 1, 2);
memcpy(&udp_buf->destport, hc06_ptr + 3, 2);
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+5): %x, %x\n",
UIP_HTONS(udp_buf->srcport),
UIP_HTONS(udp_buf->destport));
hc06_ptr += 5;
@ -1288,21 +1286,21 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
case SICSLOWPAN_NHC_UDP_CS_P_01:
/* 1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit inline */
LOG_INFO("IPHC: Decompressing destination\n");
LOG_DBG("uncompression: destination address\n");
memcpy(&udp_buf->srcport, hc06_ptr + 1, 2);
udp_buf->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3)));
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+4): %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
hc06_ptr += 4;
break;
case SICSLOWPAN_NHC_UDP_CS_P_10:
/* 1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit inline*/
LOG_INFO("IPHC: Decompressing source\n");
LOG_DBG("uncompression: source address\n");
udp_buf->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
(*(hc06_ptr + 1)));
memcpy(&udp_buf->destport, hc06_ptr + 2, 2);
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+4): %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
hc06_ptr += 4;
break;
@ -1313,27 +1311,27 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
(*(hc06_ptr + 1) >> 4));
udp_buf->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
((*(hc06_ptr + 1)) & 0x0F));
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+2): %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
hc06_ptr += 2;
break;
default:
LOG_INFO("sicslowpan uncompress_hdr: error unsupported UDP compression\n");
LOG_DBG("uncompression: error unsupported UDP compression\n");
return;
}
if(!checksum_compressed) { /* has_checksum, default */
memcpy(&udp_buf->udpchksum, hc06_ptr, 2);
hc06_ptr += 2;
LOG_INFO("IPHC: sicslowpan uncompress_hdr: checksum included\n");
LOG_DBG("uncompression: checksum included\n");
} else {
LOG_INFO("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n");
LOG_DBG("uncompression: checksum *NOT* included\n");
}
/* length field in UDP header (8 byte header + payload) */
udp_len = 8 + packetbuf_datalen() - (hc06_ptr - packetbuf_ptr);
udp_buf->udplen = UIP_HTONS(ip_len == 0 ? udp_len :
ip_len - UIP_IPH_LEN - ext_hdr_len);
LOG_INFO("Setting UDP length: %u (ext: %u) ip_len: %d udp_len:%d\n",
LOG_DBG("uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
uncomp_hdr_len += UIP_UDPH_LEN;
@ -1344,7 +1342,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
/* IP length field. */
if(ip_len == 0) {
int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN;
LOG_INFO("IP payload length: %d. %u - %u + %u - %u\n", len,
LOG_DBG("uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
packetbuf_datalen(), packetbuf_hdr_len, uncomp_hdr_len, UIP_IPH_LEN);
/* This is not a fragmented packet */
@ -1495,6 +1493,48 @@ send_packet(linkaddr_t *dest)
watchdog know that we are still alive. */
watchdog_periodic();
}
#if SICSLOWPAN_CONF_FRAG
/*--------------------------------------------------------------------*/
/**
* \brief This function is called by the 6lowpan code to copy a fragment's
* payload from uIP and send it down the stack.
* \param uip_offset the offset in the uIP buffer where to copy the payload from
* \param dest the link layer destination address of the packet
* \return 1 if success, 0 otherwise
*/
static int
fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) {
struct queuebuf *q;
/* Now copy fragment payload from uip_buf */
memcpy(packetbuf_ptr + packetbuf_hdr_len,
(uint8_t *)UIP_IP_BUF + uip_offset, packetbuf_payload_len);
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
/* Backup packetbuf to queuebuf. Enables preserving attributes for all framgnets */
q = queuebuf_new_from_packetbuf();
if(q == NULL) {
LOG_WARN("output: could not allocate queuebuf, dropping fragment\n");
return 0;
}
/* Send fragment */
send_packet(dest);
/* Restore packetbuf from queuebuf */
queuebuf_to_packetbuf(q);
queuebuf_free(q);
/* Check tx result. */
if((last_tx_status == MAC_TX_COLLISION) ||
(last_tx_status == MAC_TX_ERR) ||
(last_tx_status == MAC_TX_ERR_FATAL)) {
LOG_ERR("output: error in fragment tx, dropping subsequent fragments.\n");
return 0;
}
return 1;
}
#endif /* SICSLOWPAN_CONF_FRAG */
/*--------------------------------------------------------------------*/
/** \brief Take an IP packet and format it to be sent on an 802.15.4
* network using 6lowpan.
@ -1509,6 +1549,8 @@ static uint8_t
output(const linkaddr_t *localdest)
{
int framer_hdrlen;
int max_payload;
int frag_needed;
/* The MAC address of the destination of the packet */
linkaddr_t dest;
@ -1538,23 +1580,19 @@ output(const linkaddr_t *localdest)
linkaddr_copy(&dest, localdest);
}
LOG_INFO("output: sending packet len %d\n", uip_len);
LOG_INFO("output: sending IPv6 packet with len %d\n", uip_len);
/* copy over the retransmission count from uipbuf attributes */
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC */
#ifndef SICSLOWPAN_USE_FIXED_HDRLEN
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
framer_hdrlen = NETSTACK_FRAMER.length();
if(framer_hdrlen < 0) {
/* Framing failed, we assume the maximum header length */
framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN;
framer_hdrlen = MAC_MAX_HEADER;
}
#else /* USE_FRAMER_HDRLEN */
framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN;
#endif /* USE_FRAMER_HDRLEN */
mac_max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
@ -1576,131 +1614,134 @@ output(const linkaddr_t *localdest)
return 0;
}
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */
LOG_INFO("output: header of len %d\n", packetbuf_hdr_len);
if((int)uip_len - (int)uncomp_hdr_len > mac_max_payload - (int)packetbuf_hdr_len) {
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC.
* We calculate it here only to make a better decision of whether the outgoing packet
* needs to be fragmented or not. */
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
framer_hdrlen = NETSTACK_FRAMER.length();
if(framer_hdrlen < 0) {
/* Framing failed, we assume the maximum header length */
framer_hdrlen = MAC_MAX_HEADER;
}
max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > max_payload;
LOG_INFO("output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
uncomp_hdr_len, packetbuf_hdr_len,
uip_len, uip_len - uncomp_hdr_len + packetbuf_hdr_len,
max_payload, frag_needed);
if(frag_needed) {
#if SICSLOWPAN_CONF_FRAG
/* Number of bytes processed. */
uint16_t processed_ip_out_len;
struct queuebuf *q;
uint16_t frag_tag;
int curr_frag = 0;
/*
* The outbound IPv6 packet is too large to fit into a single 15.4
* packet, so we fragment it into multiple packets and send them.
* The first fragment contains frag1 dispatch, then
* IPv6/IPHC/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch.
* The first fragment contains frag1 dispatch, then IPv6/IPHC/HC_UDP
* dispatchs/headers and IPv6 payload (with len multiple of 8 bytes).
* The subsequent fragments contain the FRAGN dispatch and more of the
* IPv6 payload (still multiple of 8 bytes, except for the last fragment)
*/
int estimated_fragments = ((int)uip_len) / (mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
/* Total IPv6 payload */
int total_payload = (uip_len - uncomp_hdr_len);
/* IPv6 payload that goes to first fragment */
int frag1_payload = (max_payload - packetbuf_hdr_len - SICSLOWPAN_FRAG1_HDR_LEN) & 0xfffffff8;
/* max IPv6 payload in each FRAGN. Must be multiple of 8 bytes */
int fragn_max_payload = (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
/* max IPv6 payload in the last fragment. Needs not be multiple of 8 bytes */
int last_fragn_max_payload = max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
/* sum of all IPv6 payload that goes to non-first and non-last fragments */
int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
/* Ceiling of: 2 + middle_fragn_total_payload / fragn_max_payload */
int fragment_count = 2;
if(middle_fragn_total_payload > 0) {
fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
}
int freebuf = queuebuf_numfree() - 1;
LOG_INFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
if(freebuf < estimated_fragments) {
LOG_WARN("Dropping packet, not enough free bufs\n");
LOG_INFO("output: fragmentation needed, fragments: %u, free queuebufs: %u\n",
fragment_count, freebuf);
if(freebuf < fragment_count) {
LOG_WARN("output: dropping packet, not enough free bufs (needed: %u, free: %u)\n",
fragment_count, freebuf);
return 0;
}
LOG_INFO("Fragmentation sending packet len %d\n", uip_len);
/* Create 1st Fragment */
LOG_INFO("output: 1st fragment ");
/* Reset last tx status to ok in case the fragment transmissions are deferred */
last_tx_status = MAC_TX_OK;
/* move IPHC/IPv6 header */
memmove(packetbuf_ptr + SICSLOWPAN_FRAG1_HDR_LEN, packetbuf_ptr, packetbuf_hdr_len);
/*
* FRAG1 dispatch + header
* Note that the length is in units of 8 bytes
*/
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len));
frag_tag = my_tag++;
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
/* Copy payload and send */
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
packetbuf_payload_len = (mac_max_payload - packetbuf_hdr_len) & 0xfffffff8;
LOG_INFO_("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag);
if(packetbuf_payload_len < 0) {
if(frag1_payload < 0) {
/* The current implementation requires that all headers fit in the first
* fragment. Here is a corner case where the header did fit packetbuf
* but do no longer fit after truncating for a length multiple of 8. */
LOG_WARN("compressed header does not fit first fragment\n");
LOG_WARN("output: compressed header does not fit first fragment\n");
return 0;
}
memcpy(packetbuf_ptr + packetbuf_hdr_len,
(uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len);
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
q = queuebuf_new_from_packetbuf();
if(q == NULL) {
LOG_WARN("could not allocate queuebuf for first fragment, dropping packet\n");
return 0;
}
send_packet(&dest);
queuebuf_to_packetbuf(q);
queuebuf_free(q);
q = NULL;
/* Reset last tx status -- MAC layers most often call packet_sent asynchrously */
last_tx_status = MAC_TX_OK;
/* Update fragment tag */
frag_tag = my_tag++;
/* Check tx result. */
if((last_tx_status == MAC_TX_COLLISION) ||
(last_tx_status == MAC_TX_ERR) ||
(last_tx_status == MAC_TX_ERR_FATAL)) {
LOG_ERR("error in fragment tx, dropping subsequent fragments.\n");
/* Move IPHC/IPv6 header to make room for FRAG1 header */
memmove(packetbuf_ptr + SICSLOWPAN_FRAG1_HDR_LEN, packetbuf_ptr, packetbuf_hdr_len);
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
/* Set FRAG1 header */
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len));
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
/* Set frag1 payload len. Was already caulcated earlier as frag1_payload */
packetbuf_payload_len = frag1_payload;
/* Copy payload from uIP and send fragment */
/* Send fragment */
LOG_INFO("output: fragment %d/%d (tag %d, payload %d)\n",
curr_frag + 1, fragment_count,
frag_tag, packetbuf_payload_len);
if(fragment_copy_payload_and_send(uncomp_hdr_len, &dest) == 0) {
return 0;
}
/* set processed_ip_out_len to what we already sent from the IP payload*/
processed_ip_out_len = packetbuf_payload_len + uncomp_hdr_len;
/* Now prepare for subsequent fragments. */
/*
* Create following fragments
* Datagram tag is already in the buffer, we need to set the
* FRAGN dispatch and for each fragment, the offset
*/
/* FRAGN header: tag was already set at FRAG1. Now set dispatch for all FRAGN */
packetbuf_hdr_len = SICSLOWPAN_FRAGN_HDR_LEN;
/* PACKETBUF_FRAG_BUF->dispatch_size = */
/* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
packetbuf_payload_len = (mac_max_payload - packetbuf_hdr_len) & 0xfffffff8;
/* Keep track of the total length of data sent */
processed_ip_out_len = uncomp_hdr_len + packetbuf_payload_len;
/* Create and send subsequent fragments. */
while(processed_ip_out_len < uip_len) {
LOG_INFO("output: fragment ");
curr_frag++;
/* FRAGN header: set offset for this fragment */
PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
/* Copy payload and send */
if(uip_len - processed_ip_out_len < packetbuf_payload_len) {
/* Calculate fragment len */
if(uip_len - processed_ip_out_len > last_fragn_max_payload) {
/* Not last fragment, send max FRAGN payload */
packetbuf_payload_len = fragn_max_payload;
} else {
/* last fragment */
packetbuf_payload_len = uip_len - processed_ip_out_len;
}
LOG_INFO_("(offset %d, len %d, tag %d)\n",
processed_ip_out_len >> 3, packetbuf_payload_len, frag_tag);
memcpy(packetbuf_ptr + packetbuf_hdr_len,
(uint8_t *)UIP_IP_BUF + processed_ip_out_len, packetbuf_payload_len);
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
q = queuebuf_new_from_packetbuf();
if(q == NULL) {
LOG_WARN("could not allocate queuebuf, dropping fragment\n");
return 0;
}
send_packet(&dest);
queuebuf_to_packetbuf(q);
queuebuf_free(q);
q = NULL;
processed_ip_out_len += packetbuf_payload_len;
/* Check tx result. */
if((last_tx_status == MAC_TX_COLLISION) ||
(last_tx_status == MAC_TX_ERR) ||
(last_tx_status == MAC_TX_ERR_FATAL)) {
LOG_ERR("error in fragment tx, dropping subsequent fragments.\n");
/* Copy payload from uIP and send fragment */
/* Send fragment */
LOG_INFO("output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
curr_frag + 1, fragment_count,
frag_tag, packetbuf_payload_len, processed_ip_out_len);
if(fragment_copy_payload_and_send(processed_ip_out_len, &dest) == 0) {
return 0;
}
processed_ip_out_len += packetbuf_payload_len;
}
#else /* SICSLOWPAN_CONF_FRAG */
LOG_ERR("output: Packet too large to be sent without fragmentation support; dropping packet\n");
@ -1761,7 +1802,7 @@ input(void)
packetbuf_ptr = packetbuf_dataptr();
if(packetbuf_datalen() == 0) {
LOG_WARN("empty packet\n");
LOG_WARN("input: empty packet\n");
return;
}
@ -1780,20 +1821,21 @@ input(void)
*/
switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
case SICSLOWPAN_DISPATCH_FRAG1:
LOG_INFO("input: FRAG1 ");
frag_offset = 0;
frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
LOG_INFO_ ("size %d, tag %d, offset %d)\n",
frag_size, frag_tag, frag_offset);
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
first_fragment = 1;
is_fragment = 1;
LOG_INFO("input: received first element of a fragmented packet (tag %d, len %d)\n",
frag_tag, frag_size);
/* Add the fragment to the fragmentation context */
frag_context = add_fragment(frag_tag, frag_size, frag_offset);
if(frag_context == -1) {
LOG_ERR("input: failed to allocate new reassembly context\n");
return;
}
@ -1805,24 +1847,17 @@ input(void)
* set offset, tag, size
* Offset is in units of 8 bytes
*/
LOG_INFO("input: FRAGN ");
frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
LOG_INFO_("size %d, tag %d, offset %d)\n",
frag_size, frag_tag, frag_offset);
packetbuf_hdr_len += SICSLOWPAN_FRAGN_HDR_LEN;
/* If this is the last fragment, we may shave off any extrenous
bytes at the end. We must be liberal in what we accept. */
LOG_INFO_("last_fragment?: packetbuf_payload_len %d frag_size %d\n",
packetbuf_datalen() - packetbuf_hdr_len, frag_size);
/* Add the fragment to the fragmentation context (this will also
copy the payload) */
frag_context = add_fragment(frag_tag, frag_size, frag_offset);
if(frag_context == -1) {
LOG_ERR("input: reassembly context not found (tag %d)\n", frag_tag);
return;
}
@ -1858,10 +1893,10 @@ input(void)
/* Process next dispatch and headers */
if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
LOG_INFO("input: IPHC\n");
LOG_DBG("uncompression: IPHC dispatch\n");
uncompress_hdr_iphc(buffer, frag_size);
} else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
LOG_INFO("input: IPV6\n");
LOG_DBG("uncompression: IPV6 dispatch\n");
packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
/* Put uncompressed IP header in sicslowpan_buf. */
@ -1871,8 +1906,8 @@ input(void)
packetbuf_hdr_len += UIP_IPH_LEN;
uncomp_hdr_len += UIP_IPH_LEN;
} else {
LOG_ERR("input: unknown dispatch: 0x%02x\n",
PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH]);
LOG_ERR("uncompression: unknown dispatch: 0x%02x\n",
PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
return;
}
@ -1887,18 +1922,25 @@ input(void)
* If this is a subsequent fragment, this is the contrary.
*/
if(packetbuf_datalen() < packetbuf_hdr_len) {
LOG_ERR("packet dropped due to header > total packet\n");
LOG_ERR("input: packet dropped due to header > total packet\n");
return;
}
packetbuf_payload_len = packetbuf_datalen() - packetbuf_hdr_len;
#if SICSLOWPAN_CONF_FRAG
if(is_fragment) {
LOG_INFO("input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
frag_tag, packetbuf_payload_len, frag_offset << 3, packetbuf_datalen(), packetbuf_hdr_len);
}
#endif /*SICSLOWPAN_CONF_FRAG*/
/* Sanity-check size of incoming packet to avoid buffer overflow */
{
int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3)
+ packetbuf_payload_len;
if(req_size > sizeof(uip_buf)) {
LOG_ERR(
"packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n",
"input: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n",
UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3),
packetbuf_payload_len, req_size, (unsigned)sizeof(uip_buf));
return;
@ -1943,12 +1985,12 @@ input(void)
#else
uip_len = packetbuf_payload_len + uncomp_hdr_len;
#endif /* SICSLOWPAN_CONF_FRAG */
LOG_INFO("input: IP packet ready (length %d)\n",
LOG_INFO("input: received IPv6 packet with len %d\n",
uip_len);
if(LOG_DBG_ENABLED) {
uint16_t ndx;
LOG_DBG("after decompression %u:", UIP_IP_BUF->len[1]);
LOG_DBG("uncompression: after (%u):", UIP_IP_BUF->len[1]);
for (ndx = 0; ndx < UIP_IP_BUF->len[1] + 40; ndx++) {
uint8_t data = ((uint8_t *) (UIP_IP_BUF))[ndx];
LOG_DBG_("%02x", data);

View File

@ -91,7 +91,9 @@ static uip_ds6_maddr_t *locmaddr;
static uip_ds6_aaddr_t *locaaddr;
#endif /* UIP_DS6_AADDR_NB */
static uip_ds6_prefix_t *locprefix;
#if (UIP_LLADDR_LEN == 2)
static const uint8_t iid_prefix[] = { 0x00, 0x00 , 0x00 , 0xff , 0xfe , 0x00 };
#endif /* (UIP_LLADDR_LEN == 2) */
/*---------------------------------------------------------------------------*/
void

View File

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

View File

@ -530,7 +530,7 @@ na_input(void)
if(nd6_opt_llao != NULL) {
is_llchange =
memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET], lladdr,
UIP_LLADDR_LEN);
UIP_LLADDR_LEN) == 0 ? 0 : 1;
}
if(nbr->state == NBR_INCOMPLETE) {
if(nd6_opt_llao == NULL || !extract_lladdr_from_llao_aligned(&lladdr_aligned)) {

View File

@ -41,6 +41,7 @@
#include "contiki.h"
#include "net/ipv6/uip-sr.h"
#include "net/ipv6/uiplib.h"
#include "net/routing/routing.h"
#include "lib/list.h"
#include "lib/memb.h"
@ -246,4 +247,57 @@ uip_sr_free_all(void)
num_nodes--;
}
}
/*---------------------------------------------------------------------------*/
int
uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link)
{
int index = 0;
uip_ipaddr_t child_ipaddr;
uip_ipaddr_t parent_ipaddr;
NETSTACK_ROUTING.get_sr_node_ipaddr(&child_ipaddr, link);
NETSTACK_ROUTING.get_sr_node_ipaddr(&parent_ipaddr, link->parent);
if(LOG_WITH_COMPACT_ADDR) {
index += log_6addr_compact_snprint(buf+index, buflen-index, &child_ipaddr);
} else {
index += uiplib_ipaddr_snprint(buf+index, buflen-index, &child_ipaddr);
}
if(index >= buflen) {
return index;
}
if(link->parent == NULL) {
index += snprintf(buf+index, buflen-index, " (DODAG root)");
if(index >= buflen) {
return index;
}
} else {
index += snprintf(buf+index, buflen-index, " to ");
if(index >= buflen) {
return index;
}
if(LOG_WITH_COMPACT_ADDR) {
index += log_6addr_compact_snprint(buf+index, buflen-index, &parent_ipaddr);
} else {
index += uiplib_ipaddr_snprint(buf+index, buflen-index, &parent_ipaddr);
}
if(index >= buflen) {
return index;
}
}
if(link->lifetime != UIP_SR_INFINITE_LIFETIME) {
index += snprintf(buf+index, buflen-index,
" (lifetime: %lu seconds)", (unsigned long)link->lifetime);
if(index >= buflen) {
return index;
}
} else {
index += snprintf(buf+index, buflen-index, " (lifetime: infinite)");
if(index >= buflen) {
return index;
}
}
return index;
}
/** @} */

View File

@ -180,6 +180,17 @@ void uip_sr_init(void);
*/
void uip_sr_free_all(void);
/**
* Print a textual description of a source routing link
*
* \param buf The buffer where to write content
* \param buflen The buffer len
* \param link A pointer to the source routing link
* \return Identical to snprintf: number of bytes written excluding ending null
* byte. A value >= buflen if the buffer was too small.
*/
int uip_sr_link_snprint(char *buf, int buflen, uip_sr_node_t *link);
/** @} */
#endif /* UIP_SR_H */

View File

@ -1089,7 +1089,7 @@ uip_process(uint8_t flag)
if((UIP_IP_BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.vhlerr);
LOG_ERR("invalid version.");
LOG_ERR("invalid version\n");
goto drop;
}
/*

View File

@ -3,17 +3,17 @@
* 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.
* 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -25,7 +25,7 @@
* 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.
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack and the Contiki operating system.
*
@ -33,8 +33,11 @@
*/
/**
* \addtogroup uip-addr-lib
* @{
*
* \file
* Various uIP library functions.
* Implementation of the IP address manipulation library
* \author
* Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
@ -117,7 +120,7 @@ uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
/* Parse a IPv4-address from a string. Returns the number of characters read
/* Parse a IPv4-address from a string. Returns the number of characters read
* for the address. */
int
uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr)
@ -156,48 +159,9 @@ uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr)
void
uiplib_ipaddr_print(const uip_ipaddr_t *addr)
{
uint16_t a;
unsigned int i;
int f;
if(addr == NULL) {
printf("(NULL IP addr)");
return;
}
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
/*
* Printing IPv4-mapped addresses is done according to RFC 4291 [1]
*
* "An alternative form that is sometimes more
* convenient when dealing with a mixed environment
* of IPv4 and IPv6 nodes is x:x:x:x:x:x:d.d.d.d,
* where the 'x's are the hexadecimal values of the
* six high-order 16-bit pieces of the address, and
* the 'd's are the decimal values of the four
* low-order 8-bit pieces of the address (standard
* IPv4 representation)."
*
* [1] https://tools.ietf.org/html/rfc4291#page-4
*/
printf("::FFFF:%u.%u.%u.%u", addr->u8[12], addr->u8[13], addr->u8[14], addr->u8[15]);
} else {
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) {
printf("::");
}
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
printf(":");
}
printf("%x", a);
}
}
}
char buf[UIPLIB_IPV6_MAX_STR_LEN];
uiplib_ipaddr_snprint(buf, sizeof(buf), addr);
printf("%s", buf);
}
/*---------------------------------------------------------------------------*/
int
@ -205,15 +169,16 @@ uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr)
{
uint16_t a;
unsigned int i;
int f, n;
int f;
int n = 0;
if(size == 0) {
return 0;
}
if(addr == NULL) {
n = snprintf(buf, size - 1, "(NULL IP addr)");
n = snprintf(buf, size, "(NULL IP addr)");
return n;
} else if(ip64_addr_is_ipv4_mapped_addr(addr)) {
/*
* Printing IPv4-mapped addresses is done according to RFC 4291 [1]
@ -229,32 +194,38 @@ uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr)
*
* [1] https://tools.ietf.org/html/rfc4291#page-4
*/
n = snprintf(buf, size - 1, "::FFFF:%u.%u.%u.%u", addr->u8[12],
n = snprintf(buf, size, "::FFFF:%u.%u.%u.%u", addr->u8[12],
addr->u8[13], addr->u8[14], addr->u8[15]);
return n;
} else {
for(n = 0, i = 0, f = 0; i < sizeof(uip_ipaddr_t) && n < size - 1; i += 2) {
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) {
buf[n++] = ':';
buf[n++] = ':';
n += snprintf(buf+n, size-n, "::");
if(n >= size) {
return n;
}
}
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
buf[n++] = ':';
n += snprintf(buf+n, size-n, ":");
if(n >= size) {
return n;
}
}
n += snprintf(buf+n, size-n, "%x", a);
if(n >= size) {
return n;
}
n += snprintf(&buf[n], size - n - 1, "%x", a);
}
}
}
/*
* Make sure the output string is always null-terminated.
*/
buf[MIN(n, size - 1)] = '\0';
return n;
}
/*---------------------------------------------------------------------------*/
/**
* @}
*/

View File

@ -1,19 +1,19 @@
/*
* Copyright (c) 2002, Adam Dunkels.
* All rights reserved.
* 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.
* 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.
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@ -25,29 +25,30 @@
* 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.
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the Contiki desktop environment for the C64.
*
*
*/
/**
* \file
* Various uIP library functions.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef UIPLIB_H_
#define UIPLIB_H_
#include "net/ipv6/uip.h"
/**
* \addtogroup uipconvfunc
* \addtogroup uip
* @{
*
* \defgroup uip-addr-lib uIP address manipulation library
*
* A library with various IP address manipulation functions
* @{
*
* \file
* Header file for the IP address manipulation library
* \author
* Adam Dunkels <adam@sics.se>
*/
/**
@ -65,7 +66,7 @@
* the numerical representation of the address.
*
* \retval 0 If the IP address could not be parsed.
* \retval Non-zero If the IP address was parsed.
* \retval Non-zero If the IP address was parsed.
*/
#if NETSTACK_CONF_WITH_IPV6
#define uiplib_ipaddrconv uiplib_ip6addrconv
@ -77,10 +78,10 @@ int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr);
int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr);
/** @} */
/**
* \addtogroup uiplib
* @{
*/
/* The maxium length of an IPv6 string, including terminating null bytes
* fd01:0002:0003:0004:0005:0006:0007:0008 => 39 + 1 bytes */
#define UIPLIB_IPV6_MAX_STR_LEN 40
/**
* Print an IP address using printf().
@ -99,6 +100,8 @@ void uiplib_ipaddr_print(const uip_ipaddr_t *addr);
*/
int uiplib_ipaddr_snprint(char *buffer, size_t size, const uip_ipaddr_t *addr);
/** @} */
#endif /* UIPLIB_H_ */
/**
* @}
* @}
*/

View File

@ -63,8 +63,8 @@
/* ETX fixed point divisor. 128 is the value used by RPL (RFC 6551 and RFC 6719) */
#define ETX_DIVISOR LINK_STATS_ETX_DIVISOR
/* Number of Tx used to update the ETX EWMA in case of no-ACK */
#define ETX_NOACK_PENALTY 20
/* In case of no-ACK, add ETX_NOACK_PENALTY to the real Tx count, as a penalty */
#define ETX_NOACK_PENALTY 12
/* Initial ETX value */
#define ETX_DEFAULT 2
@ -156,9 +156,13 @@ link_stats_packet_sent(const linkaddr_t *lladdr, int status, int numtx)
stats->last_tx_time = clock_time();
stats->freshness = MIN(stats->freshness + numtx, FRESHNESS_MAX);
/* Add penalty in case of no-ACK */
if(status == MAC_TX_NOACK) {
numtx += ETX_NOACK_PENALTY;
}
#if LINK_STATS_ETX_FROM_PACKET_COUNT
/* Compute ETX from packet and ACK count */
numtx = (status == MAC_TX_NOACK) ? ETX_NOACK_PENALTY : numtx;
/* Halve both counter after TX_COUNT_MAX */
if(stats->tx_count + numtx > TX_COUNT_MAX) {
stats->tx_count /= 2;
@ -179,7 +183,7 @@ link_stats_packet_sent(const linkaddr_t *lladdr, int status, int numtx)
/* Compute ETX using an EWMA */
/* ETX used for this update */
packet_etx = ((status == MAC_TX_NOACK) ? ETX_NOACK_PENALTY : numtx) * ETX_DIVISOR;
packet_etx = numtx * ETX_DIVISOR;
/* ETX alpha used for this update */
ewma_alpha = link_stats_is_fresh(stats) ? EWMA_ALPHA : EWMA_BOOTSTRAP_ALPHA;

View File

@ -512,7 +512,6 @@ const struct mac_driver ble_l2cap_driver = {
input,
on,
off,
NULL,
};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ble_l2cap_tx_process, ev, data)

View File

@ -317,6 +317,15 @@
#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL (!(BUILD_WITH_ORCHESTRA))
#endif
/* Set an upper bound on burst length. Set to 0 to never set the frame pending
* bit, i.e., never trigger a burst. Note that receiver-side support for burst
* is always enabled, as it is part of IEEE 802.1.5.4-2015 (Section 7.2.1.3)*/
#ifdef TSCH_CONF_BURST_MAX_LEN
#define TSCH_BURST_MAX_LEN TSCH_CONF_BURST_MAX_LEN
#else
#define TSCH_BURST_MAX_LEN 32
#endif
/* 6TiSCH Minimal schedule slotframe length */
#ifdef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH
#define TSCH_SCHEDULE_DEFAULT_LENGTH TSCH_SCHEDULE_CONF_DEFAULT_LENGTH

View File

@ -82,10 +82,11 @@ tsch_log_process_pending(void)
printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link-NULL} ", log->asn.ms1b, log->asn.ls4b);
} else {
struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle);
printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link %2u %3u %3u %2u ch %2u} ",
printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link %2u %3u %3u %2u %2u ch %2u} ",
log->asn.ms1b, log->asn.ls4b,
log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset,
tsch_calculate_channel(&log->asn, log->link->channel_offset));
log->link->slotframe_handle, sf ? sf->size.val : 0,
log->burst_count, log->link->timeslot + log->burst_count, log->link->channel_offset,
log->channel);
}
switch(log->type) {
case tsch_log_tx:
@ -135,6 +136,8 @@ tsch_log_prepare_add(void)
struct tsch_log_t *log = &log_array[log_index];
log->asn = tsch_current_asn;
log->link = current_link;
log->burst_count = tsch_current_burst_count;
log->channel = tsch_current_channel;
return log;
} else {
log_dropped++;

View File

@ -80,6 +80,8 @@ struct tsch_log_t {
} type;
struct tsch_asn_t asn;
struct tsch_link *link;
uint8_t burst_count;
uint8_t channel;
union {
char message[48];
struct {

View File

@ -70,6 +70,9 @@
*/
static struct packetbuf_attr eackbuf_attrs[PACKETBUF_NUM_ATTRS];
/* The offset of the frame pending bit flag within the first byte of FCF */
#define IEEE802154_FRAME_PENDING_BIT_OFFSET 4
/*---------------------------------------------------------------------------*/
static int
tsch_packet_eackbuf_set_attr(uint8_t type, const packetbuf_attr_t val)
@ -459,4 +462,18 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
return curr_len;
}
/*---------------------------------------------------------------------------*/
/* Set frame pending bit in a packet (whose header was already build) */
void
tsch_packet_set_frame_pending(uint8_t *buf, int buf_size)
{
buf[0] |= (1 << IEEE802154_FRAME_PENDING_BIT_OFFSET);
}
/*---------------------------------------------------------------------------*/
/* Get frame pending bit from a packet */
int
tsch_packet_get_frame_pending(uint8_t *buf, int buf_size)
{
return (buf[0] >> IEEE802154_FRAME_PENDING_BIT_OFFSET) & 1;
}
/*---------------------------------------------------------------------------*/
/** @} */

View File

@ -101,6 +101,19 @@ int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offse
int tsch_packet_parse_eb(const uint8_t *buf, int buf_size,
frame802154_t *frame, struct ieee802154_ies *ies,
uint8_t *hdrlen, int frame_without_mic);
/**
* \brief Set frame pending bit in a packet (whose header was already build)
* \param buf The buffer where the packet resides
* \param buf_size The buffer size
*/
void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size);
/**
* \brief Get frame pending bit from a packet
* \param buf The buffer where the packet resides
* \param buf_size The buffer size
* \return The value of the frame pending bit, 1 or 0
*/
int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size);
#endif /* __TSCH_PACKET_H__ */
/** @} */

View File

@ -423,7 +423,7 @@ tsch_schedule_create_minimal(void)
* but is required according to 802.15.4e if also used for EB transmission.
* Timeslot: 0, channel offset: 0. */
tsch_schedule_add_link(sf_min,
LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING,
(LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING),
LINK_TYPE_ADVERTISING, &tsch_broadcast_address,
0, 0);
}

View File

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

View File

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

View File

@ -155,7 +155,7 @@ static rtimer_clock_t volatile current_slot_start;
static volatile int tsch_in_slot_operation = 0;
/* If we are inside a slot, this tells the current channel */
static uint8_t current_channel;
uint8_t tsch_current_channel;
/* Info about the link, packet and neighbor of
* the current (or next) slot */
@ -167,6 +167,11 @@ static struct tsch_link *backup_link = NULL;
static struct tsch_packet *current_packet = NULL;
static struct tsch_neighbor *current_neighbor = NULL;
/* Indicates whether an extra link is needed to handle the current burst */
static int burst_link_scheduled = 0;
/* Counts the length of the current burst */
int tsch_current_burst_count = 0;
/* Protothread for association */
PT_THREAD(tsch_scan(struct pt *pt));
/* Protothread for slot operation, called from rtimer interrupt
@ -456,6 +461,8 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
/* is this a broadcast packet? (wait for ack?) */
static uint8_t is_broadcast;
static rtimer_clock_t tx_start_time;
/* Did we set the frame pending bit to request an extra burst link? */
static int burst_link_requested;
#if CCA_ENABLED
static uint8_t cca_status;
@ -466,6 +473,14 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
packet_len = queuebuf_datalen(current_packet->qb);
/* is this a broadcast packet? (wait for ack?) */
is_broadcast = current_neighbor->is_broadcast;
/* Unicast. More packets in queue for the neighbor? */
burst_link_requested = 0;
if(!is_broadcast
&& tsch_current_burst_count + 1 < TSCH_BURST_MAX_LEN
&& tsch_queue_packet_count(&current_neighbor->addr) > 1) {
burst_link_requested = 1;
tsch_packet_set_frame_pending(packet, packet_len);
}
/* read seqno from payload */
seqno = ((uint8_t *)(packet))[2];
/* if this is an EB, then update its Sync-IE */
@ -618,6 +633,12 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
tsch_schedule_keepalive();
}
mac_tx_status = MAC_TX_OK;
/* We requested an extra slot and got an ack. This means
the extra slot will be scheduled at the received */
if(burst_link_requested) {
burst_link_scheduled = 1;
}
} else {
mac_tx_status = MAC_TX_NOACK;
}
@ -749,7 +770,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi);
current_input->rx_asn = tsch_current_asn;
current_input->rssi = (signed)radio_last_rssi;
current_input->channel = current_channel;
current_input->channel = tsch_current_channel;
header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame);
frame_valid = header_len > 0 &&
frame802154_check_dest_panid(&frame) &&
@ -844,6 +865,9 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
TSCH_DEBUG_RX_EVENT();
NETSTACK_RADIO.transmit(ack_len);
tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT);
/* Schedule a burst link iff the frame pending bit was set */
burst_link_scheduled = tsch_packet_get_frame_pending(current_input->payload, current_input->len);
}
}
@ -940,9 +964,16 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
}
is_active_slot = current_packet != NULL || (current_link->link_options & LINK_OPTION_RX);
if(is_active_slot) {
/* Hop channel */
current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset);
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel);
/* If we are in a burst, we stick to current channel instead of
* doing channel hopping, as per IEEE 802.15.4-2015 */
if(burst_link_scheduled) {
/* Reset burst_link_scheduled flag. Will be set again if burst continue. */
burst_link_scheduled = 0;
} else {
/* Hop channel */
tsch_current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset);
}
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, tsch_current_channel);
/* Turn the radio on already here if configured so; necessary for radios with slow startup */
tsch_radio_on(TSCH_RADIO_CMD_ON_START_OF_TIMESLOT);
/* Decide whether it is a TX/RX/IDLE or OFF slot */
@ -960,6 +991,10 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
static struct pt slot_rx_pt;
PT_SPAWN(&slot_operation_pt, &slot_rx_pt, tsch_rx_slot(&slot_rx_pt, t));
}
} else {
/* Make sure to end the burst in cast, for some reason, we were
* in a burst but now without any more packet to send. */
burst_link_scheduled = 0;
}
TSCH_DEBUG_SLOT_END();
}
@ -993,13 +1028,27 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
tsch_queue_update_all_backoff_windows(&current_link->addr);
}
/* Get next active link */
current_link = tsch_schedule_get_next_active_link(&tsch_current_asn, &timeslot_diff, &backup_link);
if(current_link == NULL) {
/* There is no next link. Fall back to default
* behavior: wake up at the next slot. */
/* A burst link was scheduled. Replay the current link at the
next time offset */
if(burst_link_scheduled) {
timeslot_diff = 1;
backup_link = NULL;
/* Keep track of the number of repetitions */
tsch_current_burst_count++;
} else {
/* Get next active link */
current_link = tsch_schedule_get_next_active_link(&tsch_current_asn, &timeslot_diff, &backup_link);
if(current_link == NULL) {
/* There is no next link. Fall back to default
* behavior: wake up at the next slot. */
timeslot_diff = 1;
} else {
/* Reset burst index now that the link was scheduled from
normal schedule (as opposed to from ongoing burst) */
tsch_current_burst_count = 0;
}
}
/* Update ASN */
TSCH_ASN_INC(tsch_current_asn, timeslot_diff);
/* Time to next wake up */

View File

@ -57,6 +57,8 @@ extern struct ringbufindex input_ringbuf;
extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
/* Last clock_time_t where synchronization happened */
extern clock_time_t last_sync_time;
/* Counts the length of the current burst */
extern int tsch_current_burst_count;
/********** Functions *********/

View File

@ -164,6 +164,8 @@ extern const linkaddr_t tsch_eb_address;
extern struct tsch_asn_t tsch_current_asn;
extern uint8_t tsch_join_priority;
extern struct tsch_link *current_link;
/* If we are inside a slot, this tells the current channel */
extern uint8_t tsch_current_channel;
/* TSCH channel hopping sequence */
extern uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN];
extern struct tsch_asn_divisor_t tsch_hopping_sequence_length;

View File

@ -42,12 +42,35 @@
#include "net/routing/rpl-lite/rpl.h"
#include "net/ipv6/uip-ds6-route.h"
#include "net/ipv6/uip-sr.h"
/* Log configuration */
#include "sys/log.h"
#define LOG_MODULE "RPL"
#define LOG_LEVEL LOG_LEVEL_RPL
/*---------------------------------------------------------------------------*/
void
rpl_dag_root_print_links(const char *str)
{
if(rpl_dag_root_is_root()) {
if(uip_sr_num_nodes() > 0) {
uip_sr_node_t *link;
/* Our routing links */
LOG_INFO("links: %u routing links in total (%s)\n", uip_sr_num_nodes(), str);
link = uip_sr_node_head();
while(link != NULL) {
char buf[100];
uip_sr_link_snprint(buf, sizeof(buf), link);
LOG_INFO("links: %s\n", buf);
link = uip_sr_node_next(link);
}
LOG_INFO("links: end of list\n");
} else {
LOG_INFO("No routing links\n");
}
}
}
/*---------------------------------------------------------------------------*/
static void
set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
@ -71,11 +94,12 @@ set_global_address(uip_ipaddr_t *prefix, uip_ipaddr_t *iid)
uip_ds6_addr_add(&root_ipaddr, 0, ADDR_AUTOCONF);
LOG_INFO("IPv6 addresses: ");
LOG_INFO("IPv6 addresses:\n");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(uip_ds6_if.addr_list[i].isused &&
(state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
LOG_INFO("-- ");
LOG_INFO_6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
LOG_INFO_("\n");
}

View File

@ -63,6 +63,12 @@ int rpl_dag_root_start(void);
* \return 1 if we are dag root, 0 otherwise
*/
int rpl_dag_root_is_root(void);
/**
* Prints a summary of all routing links
*
* \param str A descriptive text on the caller
*/
void rpl_dag_root_print_links(const char *str);
/** @} */

View File

@ -104,7 +104,7 @@ update_state(void)
/* how many more IP neighbors can be have? */
num_free = NBR_TABLE_MAX_NEIGHBORS - num_used;
LOG_INFO("nbr-policy: free: %d, parents: %d\n", num_free, num_parents);
LOG_DBG("nbr-policy: free: %d, parents: %d\n", num_free, num_parents);
}
/*---------------------------------------------------------------------------*/
static const linkaddr_t *
@ -127,12 +127,12 @@ find_removable_dio(uip_ipaddr_t *from, rpl_dio_t *dio)
/* Add the new neighbor only if it is better than the current worst. */
if(dio->rank + curr_instance.min_hoprankinc < worst_rank - curr_instance.min_hoprankinc / 2) {
/* Found *great* neighbor - add! */
LOG_INFO("nbr-policy: DIO rank %u, worse_rank %u -- add to cache\n",
LOG_DBG("nbr-policy: DIO rank %u, worst_rank %u -- add to cache\n",
dio->rank, worst_rank);
return worst_rank_nbr_lladdr;
}
LOG_INFO("nbr-policy: DIO rank %u, worse_rank %u -- do not add to cache\n",
LOG_DBG("nbr-policy: DIO rank %u, worst_rank %u -- do not add to cache\n",
dio->rank, worst_rank);
return NULL;
}

View File

@ -46,6 +46,7 @@
#include "net/routing/rpl-lite/rpl.h"
#include "net/link-stats.h"
#include "net/nbr-table.h"
#include "net/ipv6/uiplib.h"
/* Log configuration */
#include "sys/log.h"
@ -85,6 +86,59 @@ acceptable_rank(rpl_rank_t rank)
&& rank <= max_acceptable_rank();
}
/*---------------------------------------------------------------------------*/
int
rpl_neighbor_snprint(char *buf, int buflen, rpl_nbr_t *nbr)
{
int index = 0;
rpl_nbr_t *best = best_parent(0);
const struct link_stats *stats = rpl_neighbor_get_link_stats(nbr);
clock_time_t clock_now = clock_time();
if(LOG_WITH_COMPACT_ADDR) {
index += log_6addr_compact_snprint(buf+index, buflen-index, rpl_neighbor_get_ipaddr(nbr));
} else {
index += uiplib_ipaddr_snprint(buf+index, buflen-index, rpl_neighbor_get_ipaddr(nbr));
}
if(index >= buflen) {
return index;
}
index += snprintf(buf+index, buflen-index,
"%5u, %5u => %5u -- %2u %c%c%c%c%c",
nbr->rank,
rpl_neighbor_get_link_metric(nbr),
rpl_neighbor_rank_via_nbr(nbr),
stats != NULL ? stats->freshness : 0,
(nbr->rank == ROOT_RANK) ? 'r' : ' ',
nbr == best ? 'b' : ' ',
(acceptable_rank(rpl_neighbor_rank_via_nbr(nbr)) && rpl_neighbor_is_acceptable_parent(nbr)) ? 'a' : ' ',
link_stats_is_fresh(stats) ? 'f' : ' ',
nbr == curr_instance.dag.preferred_parent ? 'p' : ' '
);
if(index >= buflen) {
return index;
}
if(stats->last_tx_time > 0) {
index += snprintf(buf+index, buflen-index,
" (last tx %u min ago",
(unsigned)((clock_now - stats->last_tx_time) / (60 * CLOCK_SECOND)));
} else {
index += snprintf(buf+index, buflen-index,
" (no tx");
}
if(index >= buflen) {
return index;
}
if(nbr->better_parent_since > 0) {
index += snprintf(buf+index, buflen-index,
", better since %u min)",
(unsigned)((clock_now - nbr->better_parent_since) / (60 * CLOCK_SECOND)));
} else {
index += snprintf(buf+index, buflen-index,
")");
}
return index;
}
/*---------------------------------------------------------------------------*/
void
rpl_neighbor_print_list(const char *str)
{
@ -92,8 +146,6 @@ rpl_neighbor_print_list(const char *str)
int curr_dio_interval = curr_instance.dag.dio_intcurrent;
int curr_rank = curr_instance.dag.rank;
rpl_nbr_t *nbr = nbr_table_head(rpl_neighbors);
rpl_nbr_t *best = best_parent(0);
clock_time_t clock_now = clock_time();
LOG_INFO("nbr: own state, addr ");
LOG_INFO_6ADDR(rpl_get_global_address());
@ -103,30 +155,9 @@ rpl_neighbor_print_list(const char *str)
max_acceptable_rank(),
curr_dio_interval, rpl_neighbor_count(), str);
while(nbr != NULL) {
const struct link_stats *stats = rpl_neighbor_get_link_stats(nbr);
LOG_INFO("nbr: ");
LOG_INFO_6ADDR(rpl_neighbor_get_ipaddr(nbr));
LOG_INFO_(" %5u, %5u => %5u -- %2u %c%c%c%c%c",
nbr->rank,
rpl_neighbor_get_link_metric(nbr),
rpl_neighbor_rank_via_nbr(nbr),
stats != NULL ? stats->freshness : 0,
(nbr->rank == ROOT_RANK) ? 'r' : ' ',
nbr == best ? 'b' : ' ',
(acceptable_rank(rpl_neighbor_rank_via_nbr(nbr)) && rpl_neighbor_is_acceptable_parent(nbr)) ? 'a' : ' ',
link_stats_is_fresh(stats) ? 'f' : ' ',
nbr == curr_instance.dag.preferred_parent ? 'p' : ' '
);
if(stats->last_tx_time > 0) {
LOG_INFO_(" (last tx %u min ago", (unsigned)((clock_now - stats->last_tx_time) / (60 * CLOCK_SECOND)));
} else {
LOG_INFO_(" (no tx");
}
if(nbr->better_parent_since > 0) {
LOG_INFO_(", better since %u min)\n", (unsigned)((clock_now - nbr->better_parent_since) / (60 * CLOCK_SECOND)));
} else {
LOG_INFO_(")\n");
}
char buf[120];
rpl_neighbor_snprint(buf, sizeof(buf), nbr);
LOG_INFO("nbr: %s\n", buf);
nbr = nbr_table_next(rpl_neighbors, nbr);
}
LOG_INFO("nbr: end of list\n");
@ -378,9 +409,9 @@ rpl_neighbor_select_best(void)
/* The best is not fresh. Probe it (unless there is already an urgent
probing target). We will be called back after the probing anyway. */
if(curr_instance.dag.urgent_probing_target == NULL) {
LOG_WARN("best parent is not fresh, schedule urgent probing to ");
LOG_WARN_6ADDR(rpl_neighbor_get_ipaddr(best));
LOG_WARN_("\n");
LOG_INFO("best parent is not fresh, schedule urgent probing to ");
LOG_INFO_6ADDR(rpl_neighbor_get_ipaddr(best));
LOG_INFO_("\n");
curr_instance.dag.urgent_probing_target = best;
rpl_schedule_probing_now();
}

View File

@ -192,6 +192,17 @@ void rpl_neighbor_remove_all(void);
*/
rpl_nbr_t *rpl_neighbor_select_best(void);
/**
* Print a textual description of RPL neighbor into a string
*
* \param buf The buffer where to write content
* \param buflen The buffer len
* \param nbr A pointer to a RPL neighbor that will be written to the buffer
* \return Identical to snprintf: number of bytes written excluding ending null
* byte. A value >= buflen if the buffer was too small.
*/
int rpl_neighbor_snprint(char *buf, int buflen, rpl_nbr_t *nbr);
typedef rpl_nbr_t rpl_parent_t;
#define rpl_parent_get_from_ipaddr(addr) rpl_neighbor_get_from_ipaddr(addr)
#define rpl_parent_get_ipaddr(nbr) rpl_neighbor_get_ipaddr(nbr)

View File

@ -521,6 +521,7 @@ handle_periodic_timer(void *ptr)
if(LOG_INFO_ENABLED) {
rpl_neighbor_print_list("Periodic");
rpl_dag_root_print_links("Periodic");
}
ctimer_reset(&periodic_timer);

View File

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

View File

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

View File

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

View File

@ -94,7 +94,6 @@ struct arp_entry {
static const struct ip64_eth_addr broadcast_ethaddr =
{{0xff,0xff,0xff,0xff,0xff,0xff}};
static const uint16_t broadcast_ipaddr[2] = {0xffff,0xffff};
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];

View File

@ -39,6 +39,7 @@
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
* Carlos Gonzalo Peces <carlosgp143@gmail.com>
*/
#include "lwm2m-engine.h"
@ -56,7 +57,6 @@
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_NAME
#include "net/ipv6/uip-ds6.h"
#endif /* LWM2M_ENGINE_CLIENT_ENDPOINT_NAME */
@ -68,9 +68,9 @@
#ifndef LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX
#ifdef LWM2M_DEVICE_MODEL_NUMBER
#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX LWM2M_DEVICE_MODEL_NUMBER
#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX "Contiki-NG-"LWM2M_DEVICE_MODEL_NUMBER
#else /* LWM2M_DEVICE_MODEL_NUMBER */
#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX "Contiki-"
#define LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX "Contiki-NG"
#endif /* LWM2M_DEVICE_MODEL_NUMBER */
#endif /* LWM2M_ENGINE_CLIENT_ENDPOINT_PREFIX */
@ -80,10 +80,24 @@
#define USE_RD_CLIENT 1
#endif /* LWM2M_ENGINE_CONF_USE_RD_CLIENT */
#if LWM2M_QUEUE_MODE_ENABLED
/* Queue Mode is handled using the RD Client and the Q-Mode object */
#define USE_RD_CLIENT 1
#endif
#if USE_RD_CLIENT
#include "lwm2m-rd-client.h"
#endif
#if LWM2M_QUEUE_MODE_ENABLED
#include "lwm2m-queue-mode.h"
#include "lwm2m-notification-queue.h"
#if LWM2M_QUEUE_MODE_OBJECT_ENABLED
#include "lwm2m-queue-mode-object.h"
#endif /* LWM2M_QUEUE_MODE_OBJECT_ENABLED */
#endif /* LWM2M_QUEUE_MODE_ENABLED */
/* MACRO for getting out resource ID from resource array ID + flags */
#define RSC_ID(x) ((uint16_t)(x & 0xffff))
#define RSC_READABLE(x) ((x & LWM2M_RESOURCE_READ) > 0)
@ -129,7 +143,6 @@ static struct {
/* in the future also a timeout */
} created;
COAP_HANDLER(lwm2m_handler, lwm2m_handler_callback);
LIST(object_list);
LIST(generic_object_list);
@ -554,6 +567,10 @@ lwm2m_engine_init(void)
#if USE_RD_CLIENT
lwm2m_rd_client_init(endpoint);
#endif
#if LWM2M_QUEUE_MODE_ENABLED && LWM2M_QUEUE_MODE_OBJECT_ENABLED
lwm2m_queue_mode_object_init();
#endif
}
/*---------------------------------------------------------------------------*/
/*
@ -746,7 +763,7 @@ perform_multi_resource_read_op(lwm2m_object_t *object,
}
/* ---------- Read operation ------------- */
} else if(ctx->operation == LWM2M_OP_READ) {
lwm2m_status_t success;
lwm2m_status_t success = 0;
uint8_t lv;
lv = ctx->level;
@ -1373,6 +1390,10 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response,
context.inbuf->size = coap_get_payload(request, (const uint8_t **)&context.inbuf->buffer);
context.inbuf->pos = 0;
#if LWM2M_QUEUE_MODE_ENABLED
lwm2m_queue_mode_request_received();
#endif /* LWM2M_QUEUE_MODE_ENABLED */
/* Maybe this should be part of CoAP itself - this seems not to be working
with the leshan server */
#define LWM2M_CONF_ENTITY_TOO_LARGE_BLOCK1 0
@ -1632,14 +1653,46 @@ lwm2m_handler_callback(coap_message_t *request, coap_message_t *response,
return COAP_HANDLER_STATUS_PROCESSED;
}
/*---------------------------------------------------------------------------*/
void lwm2m_notify_object_observers(lwm2m_object_instance_t *obj,
static void
lwm2m_send_notification(char* path)
{
#if LWM2M_QUEUE_MODE_ENABLED && LWM2M_QUEUE_MODE_INCLUDE_DYNAMIC_ADAPTATION
if(lwm2m_queue_mode_get_dynamic_adaptation_flag()) {
lwm2m_queue_mode_set_handler_from_notification();
}
#endif
coap_notify_observers_sub(NULL, path);
}
/*---------------------------------------------------------------------------*/
void
lwm2m_notify_object_observers(lwm2m_object_instance_t *obj,
uint16_t resource)
{
char path[20]; /* 60000/60000/60000 */
if(obj != NULL) {
snprintf(path, 20, "%d/%d/%d", obj->object_id, obj->instance_id, resource);
coap_notify_observers_sub(NULL, path);
}
#if LWM2M_QUEUE_MODE_ENABLED
if(coap_has_observers(path)) {
/* Client is sleeping -> add the notification to the list */
if(!lwm2m_rd_client_is_client_awake()) {
lwm2m_notification_queue_add_notification_path(obj->object_id, obj->instance_id, resource);
/* if it is the first notification -> wake up and send update */
if(!lwm2m_queue_mode_is_waked_up_by_notification()) {
lwm2m_queue_mode_set_waked_up_by_notification();
lwm2m_rd_client_fsm_execute_queue_mode_update();
}
/* Client is awake -> send the notification */
} else {
lwm2m_send_notification(path);
}
}
#else
lwm2m_send_notification(path);
#endif
}
/*---------------------------------------------------------------------------*/
/** @} */

Some files were not shown because too many files have changed in this diff Show More