Merge branch 'release-4.1' into contrib/example-lwm2m
This commit is contained in:
commit
42c2bba036
|
@ -1,6 +1,7 @@
|
||||||
CONTIKI_CPU_DIRS = . net dev
|
CONTIKI_CPU_DIRS = . net dev
|
||||||
|
|
||||||
CONTIKI_SOURCEFILES += rtimer-arch.c watchdog.c eeprom.c int-master.c
|
CONTIKI_SOURCEFILES += rtimer-arch.c watchdog.c eeprom.c int-master.c
|
||||||
|
CONTIKI_SOURCEFILES += gpio-hal-arch.c
|
||||||
|
|
||||||
### Compiler definitions
|
### Compiler definitions
|
||||||
CC ?= gcc
|
CC ?= gcc
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, George Oikonomou - http://www.spd.gr
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "dev/gpio-hal.h"
|
||||||
|
#include "sys/log.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Log configuration */
|
||||||
|
#define LOG_MODULE "GPIO arch"
|
||||||
|
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static gpio_hal_pin_cfg_t pin_cfg[GPIO_HAL_PIN_COUNT];
|
||||||
|
static uint8_t pin_state[GPIO_HAL_PIN_COUNT];
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_interrupt_enable(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Pin %u: Enabled interrupt\n", pin);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_interrupt_disable(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Pin %u: Disabled interrupt\n", pin);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_pin_cfg_set(gpio_hal_pin_t pin, gpio_hal_pin_cfg_t cfg)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_cfg[pin] = cfg;
|
||||||
|
LOG_DBG("Pin %u: Set config=0x%02x\n", pin, pin_cfg[pin]);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
gpio_hal_pin_cfg_t
|
||||||
|
gpio_hal_arch_pin_cfg_get(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Pin %u: Config=0x%02x\n", pin, pin_cfg[pin]);
|
||||||
|
return pin_cfg[pin];
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_pin_set_input(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Pin %u: Set input\n", pin);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_pin_set_output(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Pin %u: Set output\n", pin);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_set_pin(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_state[pin] = 1;
|
||||||
|
LOG_DBG("Pin %u: Set\n", pin);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_clear_pin(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_state[pin] = 0;
|
||||||
|
LOG_DBG("Pin %u: Clear\n", pin);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
uint8_t
|
||||||
|
gpio_hal_arch_read_pin(gpio_hal_pin_t pin)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Pin %u: Read=%u\n", pin, pin_state[pin]);
|
||||||
|
return pin_state[pin];
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_write_pin(gpio_hal_pin_t pin, uint8_t value)
|
||||||
|
{
|
||||||
|
if(pin >= GPIO_HAL_PIN_COUNT) {
|
||||||
|
LOG_ERR("Pin %u out of bounds\n", pin);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pin_state[pin] = value;
|
||||||
|
LOG_DBG("Pin %u: Write=%u\n", pin, pin_state[pin]);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_set_pins(gpio_hal_pin_mask_t pins)
|
||||||
|
{
|
||||||
|
gpio_hal_pin_t pin;
|
||||||
|
|
||||||
|
for(pin = 0; pin < GPIO_HAL_PIN_COUNT; pin++) {
|
||||||
|
if(pins & (1 << pin)) {
|
||||||
|
pin_state[pin] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Set pins 0x%08" PRIx32 "\n", pins);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_clear_pins(gpio_hal_pin_mask_t pins)
|
||||||
|
{
|
||||||
|
gpio_hal_pin_t pin;
|
||||||
|
|
||||||
|
for(pin = 0; pin < GPIO_HAL_PIN_COUNT; pin++) {
|
||||||
|
if(pins & (1 << pin)) {
|
||||||
|
pin_state[pin] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Clear pins 0x%08" PRIx32 "\n", pins);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
gpio_hal_pin_mask_t
|
||||||
|
gpio_hal_arch_read_pins(gpio_hal_pin_mask_t pins)
|
||||||
|
{
|
||||||
|
gpio_hal_pin_t pin;
|
||||||
|
gpio_hal_pin_mask_t state = 0;
|
||||||
|
|
||||||
|
for(pin = 0; pin < GPIO_HAL_PIN_COUNT; pin++) {
|
||||||
|
state |= (pin_state[pin] << pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Read pins 0x%08" PRIx32 "\n", state);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
gpio_hal_arch_write_pins(gpio_hal_pin_mask_t pins, gpio_hal_pin_mask_t value)
|
||||||
|
{
|
||||||
|
gpio_hal_pin_t pin;
|
||||||
|
|
||||||
|
for(pin = 0; pin < GPIO_HAL_PIN_COUNT; pin++) {
|
||||||
|
if(pins & (1 << pin)) {
|
||||||
|
pin_state[pin] = (value & (1 << pin)) == 0 ? 0 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("Write pins 0x%08" PRIx32 "->0x%08" PRIx32 "\n", pins, value);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, George Oikonomou - http://www.spd.gr
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef NATIVE_DEF_H_
|
||||||
|
#define NATIVE_DEF_H_
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#define GPIO_HAL_CONF_ARCH_SW_TOGGLE 1
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#endif /* NATIVE_DEF_H_ */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
|
@ -6,8 +6,8 @@ endif
|
||||||
CONTIKI_TARGET_DIRS = . dev
|
CONTIKI_TARGET_DIRS = . dev
|
||||||
CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o}
|
CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o}
|
||||||
|
|
||||||
CONTIKI_TARGET_SOURCEFILES += platform.c clock.c xmem.c leds-arch.c
|
CONTIKI_TARGET_SOURCEFILES += platform.c clock.c xmem.c
|
||||||
CONTIKI_TARGET_SOURCEFILES += cfs-posix.c cfs-posix-dir.c
|
CONTIKI_TARGET_SOURCEFILES += cfs-posix.c cfs-posix-dir.c buttons.c
|
||||||
|
|
||||||
ifeq ($(HOST_OS),Windows)
|
ifeq ($(HOST_OS),Windows)
|
||||||
CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c
|
CONTIKI_TARGET_SOURCEFILES += wpcap-drv.c wpcap.c
|
||||||
|
|
|
@ -37,7 +37,9 @@
|
||||||
#ifdef PROJECT_CONF_PATH
|
#ifdef PROJECT_CONF_PATH
|
||||||
#include PROJECT_CONF_PATH
|
#include PROJECT_CONF_PATH
|
||||||
#endif /* PROJECT_CONF_PATH */
|
#endif /* PROJECT_CONF_PATH */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "native-def.h"
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
@ -60,8 +62,6 @@ int select_set_callback(int fd, const struct select_callback *callback);
|
||||||
|
|
||||||
typedef unsigned int uip_stats_t;
|
typedef unsigned int uip_stats_t;
|
||||||
|
|
||||||
#define LEDS_CONF_LEGACY_API 1
|
|
||||||
|
|
||||||
#ifndef UIP_CONF_BYTE_ORDER
|
#ifndef UIP_CONF_BYTE_ORDER
|
||||||
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,6 +91,8 @@ typedef unsigned long clock_time_t;
|
||||||
|
|
||||||
#define LOG_CONF_ENABLED 1
|
#define LOG_CONF_ENABLED 1
|
||||||
|
|
||||||
|
#define PLATFORM_SUPPORTS_BUTTON_HAL 1
|
||||||
|
|
||||||
/* Not part of C99 but actually present */
|
/* Not part of C99 but actually present */
|
||||||
int strcasecmp(const char*, const char*);
|
int strcasecmp(const char*, const char*);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, George Oikonomou - http://www.spd.gr
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "dev/button-hal.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
button_hal_button_t *button_hal_buttons[] = { NULL };
|
||||||
|
const uint8_t button_hal_button_count = 0;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2005, Swedish Institute of Computer Science.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. Neither the name of the Institute nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* This file is part of the Contiki operating system.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* A brief description of what this file is.
|
|
||||||
* \author
|
|
||||||
* Adam Dunkels <adam@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dev/leds.h"
|
|
||||||
static leds_mask_t leds;
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
leds_arch_init(void)
|
|
||||||
{
|
|
||||||
leds = 0;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
leds_mask_t
|
|
||||||
leds_arch_get(void)
|
|
||||||
{
|
|
||||||
return leds;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
leds_arch_set(leds_mask_t l)
|
|
||||||
{
|
|
||||||
leds = l;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -56,6 +56,9 @@
|
||||||
#include "net/netstack.h"
|
#include "net/netstack.h"
|
||||||
|
|
||||||
#include "dev/serial-line.h"
|
#include "dev/serial-line.h"
|
||||||
|
#include "dev/button-hal.h"
|
||||||
|
#include "dev/gpio-hal.h"
|
||||||
|
#include "dev/leds.h"
|
||||||
|
|
||||||
#include "net/ipv6/uip.h"
|
#include "net/ipv6/uip.h"
|
||||||
#include "net/ipv6/uip-debug.h"
|
#include "net/ipv6/uip-debug.h"
|
||||||
|
@ -251,6 +254,9 @@ platform_process_args(int argc, char**argv)
|
||||||
void
|
void
|
||||||
platform_init_stage_one()
|
platform_init_stage_one()
|
||||||
{
|
{
|
||||||
|
gpio_hal_init();
|
||||||
|
button_hal_init();
|
||||||
|
leds_init();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -3,6 +3,6 @@ CONTIKI = ../../..
|
||||||
|
|
||||||
all: $(CONTIKI_PROJECT)
|
all: $(CONTIKI_PROJECT)
|
||||||
|
|
||||||
PLATFORMS_ONLY = srf06-cc26xx cc2538dk openmote-cc2538 zoul
|
PLATFORMS_ONLY = srf06-cc26xx cc2538dk openmote-cc2538 zoul native
|
||||||
|
|
||||||
include $(CONTIKI)/Makefile.include
|
include $(CONTIKI)/Makefile.include
|
||||||
|
|
|
@ -47,10 +47,13 @@ PROCESS_THREAD(button_hal_example, ev, data)
|
||||||
|
|
||||||
printf("Button HAL example.\n");
|
printf("Button HAL example.\n");
|
||||||
printf("Device button count: %u.\n", button_hal_button_count);
|
printf("Device button count: %u.\n", button_hal_button_count);
|
||||||
printf("%s on pin %u with ID=0, Logic=%s, Pull=%s\n",
|
|
||||||
BUTTON_HAL_GET_DESCRIPTION(btn), btn->pin,
|
if(btn) {
|
||||||
btn->negative_logic ? "Negative" : "Positive",
|
printf("%s on pin %u with ID=0, Logic=%s, Pull=%s\n",
|
||||||
btn->pull == GPIO_HAL_PIN_CFG_PULL_UP ? "Pull Up" : "Pull Down");
|
BUTTON_HAL_GET_DESCRIPTION(btn), btn->pin,
|
||||||
|
btn->negative_logic ? "Negative" : "Positive",
|
||||||
|
btn->pull == GPIO_HAL_PIN_CFG_PULL_UP ? "Pull Up" : "Pull Down");
|
||||||
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
CONTIKI_PROJECT = gpio-hal-example
|
CONTIKI_PROJECT = gpio-hal-example
|
||||||
CONTIKI = ../../..
|
CONTIKI = ../../..
|
||||||
|
|
||||||
PLATFORMS_ONLY = srf06-cc26xx cc2538dk openmote-cc2538 zoul
|
PLATFORMS_ONLY = srf06-cc26xx cc2538dk openmote-cc2538 zoul native
|
||||||
|
|
||||||
include $(CONTIKI)/Makefile.identify-target
|
include $(CONTIKI)/Makefile.identify-target
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "dev/button-hal.h"
|
#include "dev/button-hal.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
extern gpio_hal_pin_t out_pin1, out_pin2, out_pin3;
|
extern gpio_hal_pin_t out_pin1, out_pin2, out_pin3;
|
||||||
extern gpio_hal_pin_t btn_pin;
|
extern gpio_hal_pin_t btn_pin;
|
||||||
|
@ -43,6 +44,13 @@ extern gpio_hal_pin_t btn_pin;
|
||||||
static struct etimer et;
|
static struct etimer et;
|
||||||
static uint8_t counter;
|
static uint8_t counter;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* Print gpio_hal_pin_mask_t using the correct format */
|
||||||
|
#if GPIO_HAL_PIN_COUNT > 32
|
||||||
|
#define PIN_MASK_FMT PRIx64
|
||||||
|
#else
|
||||||
|
#define PIN_MASK_FMT PRIx32
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
PROCESS(gpio_hal_example, "GPIO HAL Example");
|
PROCESS(gpio_hal_example, "GPIO HAL Example");
|
||||||
AUTOSTART_PROCESSES(&gpio_hal_example);
|
AUTOSTART_PROCESSES(&gpio_hal_example);
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -119,7 +127,8 @@ PROCESS_THREAD(gpio_hal_example, ev, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test read */
|
/* Test read */
|
||||||
printf("%u: Pins are 1-%u, 2=%u, 3=%u, mask=0x%08lx\n", counter & 7,
|
printf("%u: Pins are 1-%u, 2=%u, 3=%u, mask=0x%08" PIN_MASK_FMT "\n",
|
||||||
|
counter & 7,
|
||||||
gpio_hal_arch_read_pin(out_pin1),
|
gpio_hal_arch_read_pin(out_pin1),
|
||||||
gpio_hal_arch_read_pin(out_pin2),
|
gpio_hal_arch_read_pin(out_pin2),
|
||||||
gpio_hal_arch_read_pin(out_pin3),
|
gpio_hal_arch_read_pin(out_pin3),
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, George Oikonomou - http://www.spd.gr
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "dev/gpio-hal.h"
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
gpio_hal_pin_t out_pin1 = 0;
|
||||||
|
gpio_hal_pin_t out_pin2 = 1;
|
||||||
|
gpio_hal_pin_t out_pin3 = 2;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
gpio_hal_pin_t btn_pin = 4;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
|
@ -8,6 +8,6 @@ CONTIKI = ../..
|
||||||
|
|
||||||
MODULES_REL += arch/platform/$(TARGET)
|
MODULES_REL += arch/platform/$(TARGET)
|
||||||
|
|
||||||
PLATFORMS_ONLY = srf06-cc26xx cc2538dk openmote-cc2538 zoul
|
PLATFORMS_ONLY = srf06-cc26xx cc2538dk openmote-cc2538 zoul native
|
||||||
|
|
||||||
include $(CONTIKI)/Makefile.include
|
include $(CONTIKI)/Makefile.include
|
||||||
|
|
|
@ -199,10 +199,18 @@ coap_receive(const coap_endpoint_t *src,
|
||||||
new_offset = block_offset;
|
new_offset = block_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call CoAP framework and check if found and allowed */
|
if(new_offset < 0) {
|
||||||
status = call_service(message, response,
|
LOG_DBG("Blockwise: block request offset overflow\n");
|
||||||
transaction->message + COAP_MAX_HEADER_SIZE,
|
coap_status_code = BAD_OPTION_4_02;
|
||||||
block_size, &new_offset);
|
coap_error_message = "BlockOutOfScope";
|
||||||
|
status = COAP_HANDLER_STATUS_CONTINUE;
|
||||||
|
} else {
|
||||||
|
/* call CoAP framework and check if found and allowed */
|
||||||
|
status = call_service(message, response,
|
||||||
|
transaction->message + COAP_MAX_HEADER_SIZE,
|
||||||
|
block_size, &new_offset);
|
||||||
|
}
|
||||||
|
|
||||||
if(status != COAP_HANDLER_STATUS_CONTINUE) {
|
if(status != COAP_HANDLER_STATUS_CONTINUE) {
|
||||||
|
|
||||||
if(coap_status_code == NO_ERROR) {
|
if(coap_status_code == NO_ERROR) {
|
||||||
|
|
|
@ -1115,13 +1115,10 @@ coap_set_header_size1(coap_message_t *coap_pkt, uint32_t size)
|
||||||
int
|
int
|
||||||
coap_get_payload(coap_message_t *coap_pkt, const uint8_t **payload)
|
coap_get_payload(coap_message_t *coap_pkt, const uint8_t **payload)
|
||||||
{
|
{
|
||||||
if(coap_pkt->payload) {
|
if(payload != NULL) {
|
||||||
*payload = coap_pkt->payload;
|
*payload = coap_pkt->payload;
|
||||||
return coap_pkt->payload_len;
|
|
||||||
} else {
|
|
||||||
*payload = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return coap_pkt->payload != NULL ? coap_pkt->payload_len : 0;
|
||||||
}
|
}
|
||||||
int
|
int
|
||||||
coap_set_payload(coap_message_t *coap_pkt, const void *payload, size_t length)
|
coap_set_payload(coap_message_t *coap_pkt, const void *payload, size_t length)
|
||||||
|
|
|
@ -97,6 +97,7 @@
|
||||||
|
|
||||||
/* define the buffer as a byte array */
|
/* define the buffer as a byte array */
|
||||||
#define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
|
#define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
|
||||||
|
#define PACKETBUF_PAYLOAD_END ((uint8_t *)(packetbuf_ptr + mac_max_payload))
|
||||||
|
|
||||||
#define PACKETBUF_6LO_PTR (packetbuf_ptr + packetbuf_hdr_len)
|
#define PACKETBUF_6LO_PTR (packetbuf_ptr + packetbuf_hdr_len)
|
||||||
#define PACKETBUF_6LO_DISPATCH 0 /* 8 bit */
|
#define PACKETBUF_6LO_DISPATCH 0 /* 8 bit */
|
||||||
|
@ -197,6 +198,11 @@ static int packetbuf_payload_len;
|
||||||
*/
|
*/
|
||||||
static uint8_t uncomp_hdr_len;
|
static uint8_t uncomp_hdr_len;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mac_max_payload is the maimum payload space on the MAC frame.
|
||||||
|
*/
|
||||||
|
static int mac_max_payload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current page (RFC 4944)
|
* The current page (RFC 4944)
|
||||||
*/
|
*/
|
||||||
|
@ -663,8 +669,9 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
|
||||||
* compress the IID.
|
* compress the IID.
|
||||||
* \param link_destaddr L2 destination address, needed to compress IP
|
* \param link_destaddr L2 destination address, needed to compress IP
|
||||||
* dest
|
* dest
|
||||||
|
* \return 1 if success, else 0
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
compress_hdr_iphc(linkaddr_t *link_destaddr)
|
compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
{
|
{
|
||||||
uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
|
uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
|
||||||
|
@ -681,7 +688,23 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
LOG_DBG_("\n");
|
LOG_DBG_("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Macro used only internally, during header compression. Checks if there
|
||||||
|
* is sufficient space in packetbuf before writing any further. */
|
||||||
|
#define CHECK_BUFFER_SPACE(writelen) do { \
|
||||||
|
if(hc06_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \
|
||||||
|
LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \
|
||||||
|
(unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - hc06_ptr)); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
hc06_ptr = PACKETBUF_IPHC_BUF + 2;
|
hc06_ptr = PACKETBUF_IPHC_BUF + 2;
|
||||||
|
|
||||||
|
/* Check if there is enough space for the compressed IPv6 header, in the
|
||||||
|
* worst case (least compressed case). Extension headers and transport
|
||||||
|
* layer will be checked when they are compressed. */
|
||||||
|
CHECK_BUFFER_SPACE(38);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As we copy some bit-length fields, in the IPHC encoding bytes,
|
* As we copy some bit-length fields, in the IPHC encoding bytes,
|
||||||
* we sometimes use |=
|
* we sometimes use |=
|
||||||
|
@ -910,11 +933,13 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
NHC byte extra - before the next header here. This is due to
|
NHC byte extra - before the next header here. This is due to
|
||||||
next not being elided in that case. */
|
next not being elided in that case. */
|
||||||
if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
|
if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
|
||||||
|
CHECK_BUFFER_SPACE(1);
|
||||||
hc06_ptr++;
|
hc06_ptr++;
|
||||||
LOG_INFO("Keeping the next header in this ext hdr: %d\n",
|
LOG_INFO("Keeping the next header in this ext hdr: %d\n",
|
||||||
ext_hdr->next);
|
ext_hdr->next);
|
||||||
}
|
}
|
||||||
/* copy the ext-hdr into the hc06 buffer */
|
/* copy the ext-hdr into the hc06 buffer */
|
||||||
|
CHECK_BUFFER_SPACE(len);
|
||||||
memcpy(hc06_ptr, ext_hdr, len);
|
memcpy(hc06_ptr, ext_hdr, len);
|
||||||
/* modify the len to octets */
|
/* modify the len to octets */
|
||||||
ext_hdr = (struct uip_ext_hdr *) hc06_ptr;
|
ext_hdr = (struct uip_ext_hdr *) hc06_ptr;
|
||||||
|
@ -944,6 +969,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
/* we can compress 12 bits of both source and dest */
|
/* we can compress 12 bits of both source and dest */
|
||||||
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
|
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
|
||||||
LOG_INFO("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
|
LOG_INFO("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
|
||||||
|
CHECK_BUFFER_SPACE(1);
|
||||||
*hc06_ptr =
|
*hc06_ptr =
|
||||||
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
|
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
|
||||||
SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
|
SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
|
||||||
|
@ -954,6 +980,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
/* we can compress 8 bits of dest, leave source. */
|
/* we can compress 8 bits of dest, leave source. */
|
||||||
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
|
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
|
||||||
LOG_INFO("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
|
LOG_INFO("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
|
||||||
|
CHECK_BUFFER_SPACE(3);
|
||||||
memcpy(hc06_ptr, &udp_buf->srcport, 2);
|
memcpy(hc06_ptr, &udp_buf->srcport, 2);
|
||||||
*(hc06_ptr + 2) =
|
*(hc06_ptr + 2) =
|
||||||
(uint8_t)((UIP_HTONS(udp_buf->destport) -
|
(uint8_t)((UIP_HTONS(udp_buf->destport) -
|
||||||
|
@ -963,6 +990,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
/* we can compress 8 bits of src, leave dest. Copy compressed port */
|
/* we can compress 8 bits of src, leave dest. Copy compressed port */
|
||||||
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
|
*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_INFO("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
|
||||||
|
CHECK_BUFFER_SPACE(3);
|
||||||
*hc06_ptr =
|
*hc06_ptr =
|
||||||
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
|
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
|
||||||
SICSLOWPAN_UDP_8_BIT_PORT_MIN));
|
SICSLOWPAN_UDP_8_BIT_PORT_MIN));
|
||||||
|
@ -972,10 +1000,12 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
/* we cannot compress. Copy uncompressed ports, full checksum */
|
/* we cannot compress. Copy uncompressed ports, full checksum */
|
||||||
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
|
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
|
||||||
LOG_INFO("IPHC: cannot compress UDP headers\n");
|
LOG_INFO("IPHC: cannot compress UDP headers\n");
|
||||||
|
CHECK_BUFFER_SPACE(4);
|
||||||
memcpy(hc06_ptr, &udp_buf->srcport, 4);
|
memcpy(hc06_ptr, &udp_buf->srcport, 4);
|
||||||
hc06_ptr += 4;
|
hc06_ptr += 4;
|
||||||
}
|
}
|
||||||
/* always inline the checksum */
|
/* always inline the checksum */
|
||||||
|
CHECK_BUFFER_SPACE(2);
|
||||||
memcpy(hc06_ptr, &udp_buf->udpchksum, 2);
|
memcpy(hc06_ptr, &udp_buf->udpchksum, 2);
|
||||||
hc06_ptr += 2;
|
hc06_ptr += 2;
|
||||||
uncomp_hdr_len += UIP_UDPH_LEN;
|
uncomp_hdr_len += UIP_UDPH_LEN;
|
||||||
|
@ -1006,6 +1036,8 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
packetbuf_hdr_len = hc06_ptr - packetbuf_ptr;
|
packetbuf_hdr_len = hc06_ptr - packetbuf_ptr;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
|
@ -1477,7 +1509,6 @@ static uint8_t
|
||||||
output(const linkaddr_t *localdest)
|
output(const linkaddr_t *localdest)
|
||||||
{
|
{
|
||||||
int framer_hdrlen;
|
int framer_hdrlen;
|
||||||
int max_payload;
|
|
||||||
|
|
||||||
/* The MAC address of the destination of the packet */
|
/* The MAC address of the destination of the packet */
|
||||||
linkaddr_t dest;
|
linkaddr_t dest;
|
||||||
|
@ -1513,6 +1544,20 @@ output(const linkaddr_t *localdest)
|
||||||
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
|
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
|
||||||
uipbuf_get_attr(UIPBUF_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;
|
||||||
|
}
|
||||||
|
#else /* USE_FRAMER_HDRLEN */
|
||||||
|
framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN;
|
||||||
|
#endif /* USE_FRAMER_HDRLEN */
|
||||||
|
|
||||||
|
mac_max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
|
||||||
|
|
||||||
/* Try to compress the headers */
|
/* Try to compress the headers */
|
||||||
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
|
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
|
||||||
compress_hdr_ipv6(&dest);
|
compress_hdr_ipv6(&dest);
|
||||||
|
@ -1526,26 +1571,14 @@ output(const linkaddr_t *localdest)
|
||||||
}
|
}
|
||||||
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH */
|
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH */
|
||||||
#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
|
#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
|
||||||
compress_hdr_iphc(&dest);
|
if(compress_hdr_iphc(&dest) == 0) {
|
||||||
|
/* Warning should already be issued by function above */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */
|
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */
|
||||||
LOG_INFO("output: header of len %d\n", packetbuf_hdr_len);
|
LOG_INFO("output: header of len %d\n", packetbuf_hdr_len);
|
||||||
|
|
||||||
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC.
|
if((int)uip_len - (int)uncomp_hdr_len > mac_max_payload - (int)packetbuf_hdr_len) {
|
||||||
* We calculate it here only to make a better decision of whether the outgoing packet
|
|
||||||
* needs to be fragmented or not. */
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
#else /* USE_FRAMER_HDRLEN */
|
|
||||||
framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN;
|
|
||||||
#endif /* USE_FRAMER_HDRLEN */
|
|
||||||
|
|
||||||
max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
|
|
||||||
if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) {
|
|
||||||
#if SICSLOWPAN_CONF_FRAG
|
#if SICSLOWPAN_CONF_FRAG
|
||||||
/* Number of bytes processed. */
|
/* Number of bytes processed. */
|
||||||
uint16_t processed_ip_out_len;
|
uint16_t processed_ip_out_len;
|
||||||
|
@ -1560,7 +1593,7 @@ output(const linkaddr_t *localdest)
|
||||||
* IPv6/IPHC/HC_UDP dispatchs/headers.
|
* IPv6/IPHC/HC_UDP dispatchs/headers.
|
||||||
* The following fragments contain only the fragn dispatch.
|
* The following fragments contain only the fragn dispatch.
|
||||||
*/
|
*/
|
||||||
int estimated_fragments = ((int)uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
|
int estimated_fragments = ((int)uip_len) / (mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
|
||||||
int freebuf = queuebuf_numfree() - 1;
|
int freebuf = queuebuf_numfree() - 1;
|
||||||
LOG_INFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
|
LOG_INFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
|
||||||
if(freebuf < estimated_fragments) {
|
if(freebuf < estimated_fragments) {
|
||||||
|
@ -1590,8 +1623,17 @@ output(const linkaddr_t *localdest)
|
||||||
|
|
||||||
/* Copy payload and send */
|
/* Copy payload and send */
|
||||||
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
|
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
|
||||||
packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8;
|
packetbuf_payload_len = (mac_max_payload - packetbuf_hdr_len) & 0xfffffff8;
|
||||||
LOG_INFO_("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag);
|
LOG_INFO_("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag);
|
||||||
|
|
||||||
|
if(packetbuf_payload_len < 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");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(packetbuf_ptr + packetbuf_hdr_len,
|
memcpy(packetbuf_ptr + packetbuf_hdr_len,
|
||||||
(uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len);
|
(uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len);
|
||||||
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
|
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
|
||||||
|
@ -1626,7 +1668,7 @@ output(const linkaddr_t *localdest)
|
||||||
/* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */
|
/* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */
|
||||||
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
|
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
|
||||||
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
|
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
|
||||||
packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8;
|
packetbuf_payload_len = (mac_max_payload - packetbuf_hdr_len) & 0xfffffff8;
|
||||||
while(processed_ip_out_len < uip_len) {
|
while(processed_ip_out_len < uip_len) {
|
||||||
LOG_INFO("output: fragment ");
|
LOG_INFO("output: fragment ");
|
||||||
PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
|
PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
|
||||||
|
|
|
@ -183,14 +183,14 @@ void
|
||||||
rpl_refresh_routes(const char *str)
|
rpl_refresh_routes(const char *str)
|
||||||
{
|
{
|
||||||
if(rpl_dag_root_is_root()) {
|
if(rpl_dag_root_is_root()) {
|
||||||
LOG_WARN("incrementing DTSN (%s), current %u)\n",
|
/* Increment DTSN */
|
||||||
|
RPL_LOLLIPOP_INCREMENT(curr_instance.dtsn_out);
|
||||||
|
|
||||||
|
LOG_WARN("incremented DTSN (%s), current %u\n",
|
||||||
str, curr_instance.dtsn_out);
|
str, curr_instance.dtsn_out);
|
||||||
if(LOG_INFO_ENABLED) {
|
if(LOG_INFO_ENABLED) {
|
||||||
rpl_neighbor_print_list("Refresh routes (before)");
|
rpl_neighbor_print_list("Refresh routes (before)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Increment DTSN */
|
|
||||||
RPL_LOLLIPOP_INCREMENT(curr_instance.dtsn_out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -198,15 +198,16 @@ void
|
||||||
rpl_global_repair(const char *str)
|
rpl_global_repair(const char *str)
|
||||||
{
|
{
|
||||||
if(rpl_dag_root_is_root()) {
|
if(rpl_dag_root_is_root()) {
|
||||||
LOG_WARN("initiating global repair (%s), version %u, rank %u)\n",
|
RPL_LOLLIPOP_INCREMENT(curr_instance.dag.version); /* New DAG version */
|
||||||
|
curr_instance.dtsn_out = RPL_LOLLIPOP_INIT; /* Re-initialize DTSN */
|
||||||
|
|
||||||
|
LOG_WARN("initiating global repair (%s), version %u, rank %u\n",
|
||||||
str, curr_instance.dag.version, curr_instance.dag.rank);
|
str, curr_instance.dag.version, curr_instance.dag.rank);
|
||||||
if(LOG_INFO_ENABLED) {
|
if(LOG_INFO_ENABLED) {
|
||||||
rpl_neighbor_print_list("Global repair (before)");
|
rpl_neighbor_print_list("Global repair (before)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initiate global repair */
|
/* Now do a local repair to disseminate the new version */
|
||||||
RPL_LOLLIPOP_INCREMENT(curr_instance.dag.version); /* New DAG version */
|
|
||||||
RPL_LOLLIPOP_INCREMENT(curr_instance.dtsn_out); /* Request new DAOs */
|
|
||||||
rpl_local_repair("Global repair");
|
rpl_local_repair("Global repair");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,12 +216,13 @@ static void
|
||||||
global_repair_non_root(rpl_dio_t *dio)
|
global_repair_non_root(rpl_dio_t *dio)
|
||||||
{
|
{
|
||||||
if(!rpl_dag_root_is_root()) {
|
if(!rpl_dag_root_is_root()) {
|
||||||
LOG_WARN("participating in global repair, version %u, rank %u)\n",
|
LOG_WARN("participating in global repair, version %u, rank %u\n",
|
||||||
curr_instance.dag.version, curr_instance.dag.rank);
|
dio->version, curr_instance.dag.rank);
|
||||||
if(LOG_INFO_ENABLED) {
|
if(LOG_INFO_ENABLED) {
|
||||||
rpl_neighbor_print_list("Global repair (before)");
|
rpl_neighbor_print_list("Global repair (before)");
|
||||||
}
|
}
|
||||||
/* Re-initialize configuration from DIO */
|
/* Re-initialize configuration from DIO */
|
||||||
|
rpl_timers_stop_dag_timers();
|
||||||
init_dag_from_dio(dio);
|
init_dag_from_dio(dio);
|
||||||
rpl_local_repair("Global repair");
|
rpl_local_repair("Global repair");
|
||||||
}
|
}
|
||||||
|
@ -395,9 +397,15 @@ process_dio_from_current_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the DIO sender is on an older version of the DAG, ignore it. The node
|
/* If the DIO sender is on an older version of the DAG, do not process it
|
||||||
will eventually hear the global repair and catch up. */
|
* further. The sender will eventually hear the global repair and catch up. */
|
||||||
if(rpl_lollipop_greater_than(curr_instance.dag.version, dio->version)) {
|
if(rpl_lollipop_greater_than(curr_instance.dag.version, dio->version)) {
|
||||||
|
if(dio->rank == ROOT_RANK) {
|
||||||
|
/* Before returning, if the DIO was from the root, an old DAG versions
|
||||||
|
* likely incidates a root reboot. Reset our DIO timer to make sure the
|
||||||
|
* root hears our version ASAP, and in turn triggers a global repair. */
|
||||||
|
rpl_timers_dio_reset("Heard old version from root");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,10 +420,12 @@ process_dio_from_current_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
* Must come first, as it might remove all neighbors, and we then need
|
* Must come first, as it might remove all neighbors, and we then need
|
||||||
* to re-add this source of the DIO to the neighbor table */
|
* to re-add this source of the DIO to the neighbor table */
|
||||||
if(rpl_lollipop_greater_than(dio->version, curr_instance.dag.version)) {
|
if(rpl_lollipop_greater_than(dio->version, curr_instance.dag.version)) {
|
||||||
if(curr_instance.dag.rank == ROOT_RANK) { /* The root should not hear newer versions */
|
if(curr_instance.dag.rank == ROOT_RANK) {
|
||||||
|
/* The root should not hear newer versions unless it just rebooted */
|
||||||
LOG_ERR("inconsistent DIO version (current: %u, received: %u), initiate global repair\n",
|
LOG_ERR("inconsistent DIO version (current: %u, received: %u), initiate global repair\n",
|
||||||
curr_instance.dag.version, dio->version);
|
curr_instance.dag.version, dio->version);
|
||||||
curr_instance.dag.version = dio->version; /* Update version and trigger global repair */
|
/* Update version and trigger global repair */
|
||||||
|
curr_instance.dag.version = dio->version;
|
||||||
rpl_global_repair("Inconsistent DIO version");
|
rpl_global_repair("Inconsistent DIO version");
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("new DIO version (current: %u, received: %u), apply global repair\n",
|
LOG_WARN("new DIO version (current: %u, received: %u), apply global repair\n",
|
||||||
|
@ -451,7 +461,7 @@ process_dio_from_current_dag(uip_ipaddr_t *from, rpl_dio_t *dio)
|
||||||
if(curr_instance.mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
|
if(curr_instance.mop != RPL_MOP_NO_DOWNWARD_ROUTES) {
|
||||||
if(nbr != NULL && nbr == curr_instance.dag.preferred_parent && rpl_lollipop_greater_than(dio->dtsn, last_dtsn)) {
|
if(nbr != NULL && nbr == curr_instance.dag.preferred_parent && rpl_lollipop_greater_than(dio->dtsn, last_dtsn)) {
|
||||||
RPL_LOLLIPOP_INCREMENT(curr_instance.dtsn_out);
|
RPL_LOLLIPOP_INCREMENT(curr_instance.dtsn_out);
|
||||||
LOG_INFO("DTSN increment %u->%u, schedule new DAO with DTSN %u",
|
LOG_WARN("DTSN increment %u->%u, schedule new DAO with DTSN %u\n",
|
||||||
last_dtsn, dio->dtsn, curr_instance.dtsn_out);
|
last_dtsn, dio->dtsn, curr_instance.dtsn_out);
|
||||||
rpl_timers_schedule_dao();
|
rpl_timers_schedule_dao();
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,18 @@ static rpl_nbr_t * best_parent(int fresh_only);
|
||||||
/* Per-neighbor RPL information */
|
/* Per-neighbor RPL information */
|
||||||
NBR_TABLE_GLOBAL(rpl_nbr_t, rpl_neighbors);
|
NBR_TABLE_GLOBAL(rpl_nbr_t, rpl_neighbors);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int
|
||||||
|
max_acceptable_rank(void)
|
||||||
|
{
|
||||||
|
if(curr_instance.max_rankinc == 0) {
|
||||||
|
/* There is no max rank increment */
|
||||||
|
return RPL_INFINITE_RANK;
|
||||||
|
} else {
|
||||||
|
/* Make sure not to exceed RPL_INFINITE_RANK */
|
||||||
|
return MIN((uint32_t)curr_instance.dag.lowest_rank + curr_instance.max_rankinc, RPL_INFINITE_RANK);
|
||||||
|
}
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* As per RFC 6550, section 8.2.2.4 */
|
/* As per RFC 6550, section 8.2.2.4 */
|
||||||
static int
|
static int
|
||||||
|
@ -70,8 +82,7 @@ acceptable_rank(rpl_rank_t rank)
|
||||||
{
|
{
|
||||||
return rank != RPL_INFINITE_RANK
|
return rank != RPL_INFINITE_RANK
|
||||||
&& rank >= ROOT_RANK
|
&& rank >= ROOT_RANK
|
||||||
&& ((curr_instance.max_rankinc == 0) ||
|
&& rank <= max_acceptable_rank();
|
||||||
rank <= curr_instance.dag.lowest_rank + curr_instance.max_rankinc);
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -89,7 +100,7 @@ rpl_neighbor_print_list(const char *str)
|
||||||
LOG_INFO_(", DAG state: %s, MOP %u OCP %u rank %u max-rank %u, dioint %u, nbr count %u (%s)\n",
|
LOG_INFO_(", DAG state: %s, MOP %u OCP %u rank %u max-rank %u, dioint %u, nbr count %u (%s)\n",
|
||||||
rpl_dag_state_to_str(curr_instance.dag.state),
|
rpl_dag_state_to_str(curr_instance.dag.state),
|
||||||
curr_instance.mop, curr_instance.of->ocp, curr_rank,
|
curr_instance.mop, curr_instance.of->ocp, curr_rank,
|
||||||
curr_instance.max_rankinc != 0 ? curr_instance.dag.lowest_rank + curr_instance.max_rankinc : 0xffff,
|
max_acceptable_rank(),
|
||||||
curr_dio_interval, rpl_neighbor_count(), str);
|
curr_dio_interval, rpl_neighbor_count(), str);
|
||||||
while(nbr != NULL) {
|
while(nbr != NULL) {
|
||||||
const struct link_stats *stats = rpl_neighbor_get_link_stats(nbr);
|
const struct link_stats *stats = rpl_neighbor_get_link_stats(nbr);
|
||||||
|
|
|
@ -435,7 +435,7 @@ handle_probing_timer(void *ptr)
|
||||||
LOG_INFO_6ADDR(target_ipaddr);
|
LOG_INFO_6ADDR(target_ipaddr);
|
||||||
LOG_INFO_(" %s last tx %u min ago\n",
|
LOG_INFO_(" %s last tx %u min ago\n",
|
||||||
curr_instance.dag.urgent_probing_target != NULL ? "(urgent)" : "",
|
curr_instance.dag.urgent_probing_target != NULL ? "(urgent)" : "",
|
||||||
probing_target != NULL ?
|
stats != NULL ?
|
||||||
(unsigned)((clock_time() - stats->last_tx_time) / (60 * CLOCK_SECOND)) : 0
|
(unsigned)((clock_time() - stats->last_tx_time) / (60 * CLOCK_SECOND)) : 0
|
||||||
);
|
);
|
||||||
/* Send probe, e.g. unicast DIO or DIS */
|
/* Send probe, e.g. unicast DIO or DIS */
|
||||||
|
|
|
@ -174,7 +174,7 @@ PT_THREAD(cmd_rpl_status(struct pt *pt, shell_output_func output, char *args))
|
||||||
SHELL_OUTPUT(output, "-- State: %s\n", rpl_state_to_str(curr_instance.dag.state));
|
SHELL_OUTPUT(output, "-- State: %s\n", rpl_state_to_str(curr_instance.dag.state));
|
||||||
SHELL_OUTPUT(output, "-- Preferred parent: ");
|
SHELL_OUTPUT(output, "-- Preferred parent: ");
|
||||||
shell_output_6addr(output, rpl_neighbor_get_ipaddr(curr_instance.dag.preferred_parent));
|
shell_output_6addr(output, rpl_neighbor_get_ipaddr(curr_instance.dag.preferred_parent));
|
||||||
SHELL_OUTPUT(output, "\n");
|
SHELL_OUTPUT(output, " (last DTSN: %u)\n", curr_instance.dag.preferred_parent->dtsn);
|
||||||
SHELL_OUTPUT(output, "-- Rank: %u\n", curr_instance.dag.rank);
|
SHELL_OUTPUT(output, "-- Rank: %u\n", curr_instance.dag.rank);
|
||||||
SHELL_OUTPUT(output, "-- Lowest rank: %u (%u)\n", curr_instance.dag.lowest_rank, curr_instance.max_rankinc);
|
SHELL_OUTPUT(output, "-- Lowest rank: %u (%u)\n", curr_instance.dag.lowest_rank, curr_instance.max_rankinc);
|
||||||
SHELL_OUTPUT(output, "-- DTSN out: %u\n", curr_instance.dtsn_out);
|
SHELL_OUTPUT(output, "-- DTSN out: %u\n", curr_instance.dtsn_out);
|
||||||
|
|
|
@ -22,6 +22,7 @@ rpl-border-router/sky \
|
||||||
slip-radio/sky \
|
slip-radio/sky \
|
||||||
libs/ipv6-hooks/sky \
|
libs/ipv6-hooks/sky \
|
||||||
nullnet/native \
|
nullnet/native \
|
||||||
|
mqtt-client/native \
|
||||||
|
|
||||||
TOOLS=
|
TOOLS=
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue