mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
pkg/openthread: add OpenThread core
This commit is contained in:
parent
8501a03cbc
commit
017280db13
@ -562,6 +562,11 @@ ifneq (,$(filter random,$(USEMODULE)))
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter openthread_contrib,$(USEMODULE)))
|
||||
USEMODULE += openthread_contrib_netdev
|
||||
FEATURES_REQUIRED += cpp
|
||||
endif
|
||||
|
||||
ifneq (,$(filter emcute,$(USEMODULE)))
|
||||
USEMODULE += core_thread_flags
|
||||
USEMODULE += sock_udp
|
||||
|
@ -565,11 +565,22 @@ static void _isr(netdev_t *netdev)
|
||||
|
||||
if (netdev->event_callback && (dev->netdev.flags & AT86RF2XX_OPT_TELL_TX_END)) {
|
||||
switch (trac_status) {
|
||||
#ifdef MODULE_OPENTHREAD
|
||||
case AT86RF2XX_TRX_STATE__TRAC_SUCCESS:
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
|
||||
DEBUG("[at86rf2xx] TX SUCCESS\n");
|
||||
break;
|
||||
case AT86RF2XX_TRX_STATE__TRAC_SUCCESS_DATA_PENDING:
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE_DATA_PENDING);
|
||||
DEBUG("[at86rf2xx] TX SUCCESS DATA PENDING\n");
|
||||
break;
|
||||
#else
|
||||
case AT86RF2XX_TRX_STATE__TRAC_SUCCESS:
|
||||
case AT86RF2XX_TRX_STATE__TRAC_SUCCESS_DATA_PENDING:
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
|
||||
DEBUG("[at86rf2xx] TX SUCCESS\n");
|
||||
break;
|
||||
#endif
|
||||
case AT86RF2XX_TRX_STATE__TRAC_NO_ACK:
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_NOACK);
|
||||
DEBUG("[at86rf2xx] TX NO_ACK\n");
|
||||
|
@ -70,15 +70,16 @@ enum {
|
||||
* upper layer
|
||||
*/
|
||||
typedef enum {
|
||||
NETDEV_EVENT_ISR, /**< driver needs it's ISR handled */
|
||||
NETDEV_EVENT_RX_STARTED, /**< started to receive a packet */
|
||||
NETDEV_EVENT_RX_COMPLETE, /**< finished receiving a packet */
|
||||
NETDEV_EVENT_TX_STARTED, /**< started to transfer a packet */
|
||||
NETDEV_EVENT_TX_COMPLETE, /**< finished transferring packet */
|
||||
NETDEV_EVENT_TX_NOACK, /**< ACK requested but not received */
|
||||
NETDEV_EVENT_TX_MEDIUM_BUSY, /**< couldn't transfer packet */
|
||||
NETDEV_EVENT_LINK_UP, /**< link established */
|
||||
NETDEV_EVENT_LINK_DOWN, /**< link gone */
|
||||
NETDEV_EVENT_ISR, /**< driver needs it's ISR handled */
|
||||
NETDEV_EVENT_RX_STARTED, /**< started to receive a packet */
|
||||
NETDEV_EVENT_RX_COMPLETE, /**< finished receiving a packet */
|
||||
NETDEV_EVENT_TX_STARTED, /**< started to transfer a packet */
|
||||
NETDEV_EVENT_TX_COMPLETE, /**< transfer packet complete */
|
||||
NETDEV_EVENT_TX_COMPLETE_DATA_PENDING, /**< transfer packet complete and data pending flag */
|
||||
NETDEV_EVENT_TX_NOACK, /**< ACK requested but not received */
|
||||
NETDEV_EVENT_TX_MEDIUM_BUSY, /**< couldn't transfer packet */
|
||||
NETDEV_EVENT_LINK_UP, /**< link established */
|
||||
NETDEV_EVENT_LINK_DOWN, /**< link gone */
|
||||
/* expand this list if needed */
|
||||
} netdev_event_t;
|
||||
|
||||
|
@ -41,6 +41,7 @@ PSEUDOMODULES += netstats_ipv6
|
||||
PSEUDOMODULES += netstats_rpl
|
||||
PSEUDOMODULES += newlib
|
||||
PSEUDOMODULES += newlib_nano
|
||||
PSEUDOMODULES += openthread
|
||||
PSEUDOMODULES += pktqueue
|
||||
PSEUDOMODULES += posix
|
||||
PSEUDOMODULES += printf_float
|
||||
|
32
pkg/openthread/Makefile
Normal file
32
pkg/openthread/Makefile
Normal file
@ -0,0 +1,32 @@
|
||||
PKG_NAME=openthread
|
||||
PKG_URL=https://github.com/openthread/openthread.git
|
||||
PKG_VERSION=fbfd76a990b81f007957e1bd774e51bce742e53e
|
||||
PKG_BUILDDIR ?= $(BINDIRBASE)/pkg/$(BOARD)/$(PKG_NAME)
|
||||
|
||||
$(info Compile OpenThread for FTD device)
|
||||
OPENTHREAD_ARGS+= --enable-cli-app=ftd --enable-application-coap
|
||||
|
||||
$(info $$OPENTHREAD_ARGS is [${OPENTHREAD_ARGS}])
|
||||
|
||||
.PHONY: all
|
||||
|
||||
OPENTHREAD_COMMON_FLAGS=-fdata-sections -ffunction-sections -Os
|
||||
all: git-download
|
||||
cd $(PKG_BUILDDIR) && PREFIX="/" ./bootstrap
|
||||
cd $(PKG_BUILDDIR) && CPP="$(CPP)" CC="$(CC)" CXX="$(CXX)"\
|
||||
OBJC="" OBJCXX="" AR="$(AR)" RANLIB="$(RANLIB)" NM="$(NM)" \
|
||||
STRIP="$(STRIP)" \
|
||||
CPPFLAGS="$(OPENTHREAD_COMMON_FLAGS) $(CFLAGS_CPU) " \
|
||||
CFLAGS="$(OPENTHREAD_COMMON_FLAGS) $(CFLAGS_CPU) " \
|
||||
CXXFLAGS="$(OPENTHREAD_COMMON_FLAGS) $(CFLAGS_CPU) -fno-exceptions -fno-rtti " \
|
||||
LDFLAGS="$(OPENTHREAD_COMMON_FLAGS) $(CFLAGS_CPU) -nostartfiles -specs=nano.specs \
|
||||
-specs=nosys.specs -Wl,--gc-sections -Wl,-Map=map.map " \
|
||||
./configure --disable-docs --host=$(TARGET_ARCH) --target=$(TARGET_ARCH) \
|
||||
--prefix=/ --enable-default-logging ${OPENTHREAD_ARGS}
|
||||
cd $(PKG_BUILDDIR) && DESTDIR=$(PKG_BUILDDIR)/output PREFIX=/ make -j4 --no-print-directory install
|
||||
|
||||
cp $(PKG_BUILDDIR)/output/lib/libmbedcrypto.a ${BINDIR}/libmbedcrypto.a
|
||||
cp $(PKG_BUILDDIR)/output/lib/libopenthread-ftd.a ${BINDIR}/libopenthread.a
|
||||
cp $(PKG_BUILDDIR)/output/lib/libopenthread-cli-ftd.a ${BINDIR}/libopenthread-cli.a
|
||||
sed -ie 's/BASE/_BASE/g' $(PKG_BUILDDIR)/output/include/openthread/types.h
|
||||
include $(RIOTBASE)/pkg/pkg.mk
|
11
pkg/openthread/Makefile.include
Normal file
11
pkg/openthread/Makefile.include
Normal file
@ -0,0 +1,11 @@
|
||||
OPENTHREAD_DIR = $(RIOTBASE)/pkg/openthread
|
||||
|
||||
INCLUDES += -I$(OPENTHREAD_DIR)/include \
|
||||
-I$(OPENTHREAD_DIR)/include/openthread \
|
||||
-I$(BINDIRBASE)/pkg/$(BOARD)/openthread/output/include \
|
||||
-I$(BINDIRBASE)/pkg/$(BOARD)/openthread/include/openthread \
|
||||
|
||||
ifneq (,$(filter openthread_contrib,$(USEMODULE)))
|
||||
DIRS += $(OPENTHREAD_DIR)/contrib
|
||||
DIRS += $(OPENTHREAD_DIR)/contrib/netdev
|
||||
endif
|
3
pkg/openthread/contrib/Makefile
Normal file
3
pkg/openthread/contrib/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE := openthread_contrib
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
3
pkg/openthread/contrib/netdev/Makefile
Normal file
3
pkg/openthread/contrib/netdev/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE := openthread_contrib_netdev
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
186
pkg/openthread/contrib/netdev/openthread_netdev.c
Normal file
186
pkg/openthread/contrib/netdev/openthread_netdev.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Netdev adoption for OpenThread
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "msg.h"
|
||||
#include "openthread/cli.h"
|
||||
#include "openthread/instance.h"
|
||||
#include "openthread/ip6.h"
|
||||
#include "openthread/platform/alarm.h"
|
||||
#include "openthread/platform/uart.h"
|
||||
#include "openthread/tasklet.h"
|
||||
#include "openthread/thread.h"
|
||||
#include "random.h"
|
||||
#include "ot.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define OPENTHREAD_QUEUE_LEN (8)
|
||||
static msg_t _queue[OPENTHREAD_QUEUE_LEN];
|
||||
|
||||
static kernel_pid_t _pid;
|
||||
static otInstance *sInstance;
|
||||
|
||||
/**
|
||||
* @name Default configuration for OpenThread network
|
||||
* @{
|
||||
*/
|
||||
#ifndef OPENTHREAD_PANID
|
||||
#define OPENTHREAD_PANID 0x1234
|
||||
#endif
|
||||
#ifndef OPENTHREAD_CHANNEL
|
||||
#define OPENTHREAD_CHANNEL (26U)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
uint8_t ot_call_command(char* command, void *arg, void* answer) {
|
||||
ot_job_t job;
|
||||
|
||||
job.command = command;
|
||||
job.arg = arg;
|
||||
job.answer = answer;
|
||||
|
||||
msg_t msg, reply;
|
||||
msg.type = OPENTHREAD_JOB_MSG_TYPE_EVENT;
|
||||
msg.content.ptr = &job;
|
||||
msg_send_receive(&msg, &reply, openthread_get_pid());
|
||||
return (uint8_t)reply.content.value;
|
||||
}
|
||||
|
||||
/* OpenThread will call this when switching state from empty tasklet to non-empty tasklet. */
|
||||
void otTaskletsSignalPending(otInstance *aInstance) {
|
||||
otTaskletsProcess(aInstance);
|
||||
}
|
||||
|
||||
static void *_openthread_event_loop(void *arg) {
|
||||
_pid = thread_getpid();
|
||||
|
||||
/* enable OpenThread UART */
|
||||
otPlatUartEnable();
|
||||
|
||||
/* init OpenThread */
|
||||
sInstance = otInstanceInit();
|
||||
|
||||
msg_init_queue(_queue, OPENTHREAD_QUEUE_LEN);
|
||||
netdev_t *dev;
|
||||
msg_t msg, reply;
|
||||
|
||||
otCliUartInit(sInstance);
|
||||
|
||||
#if OPENTHREAD_ENABLE_DIAG
|
||||
diagInit(sInstance);
|
||||
#endif
|
||||
|
||||
/* Init default parameters */
|
||||
otPanId panid = OPENTHREAD_PANID;
|
||||
uint8_t channel = OPENTHREAD_CHANNEL;
|
||||
otLinkSetPanId(sInstance, panid);
|
||||
otLinkSetChannel(sInstance, channel);
|
||||
/* Bring up the IPv6 interface */
|
||||
otIp6SetEnabled(sInstance, true);
|
||||
/* Start Thread protocol operation */
|
||||
otThreadSetEnabled(sInstance, true);
|
||||
|
||||
uint8_t *buf;
|
||||
ot_job_t *job;
|
||||
while (1) {
|
||||
msg_receive(&msg);
|
||||
switch (msg.type) {
|
||||
case OPENTHREAD_XTIMER_MSG_TYPE_EVENT:
|
||||
/* Tell OpenThread a time event was received */
|
||||
otPlatAlarmFired(sInstance);
|
||||
break;
|
||||
case OPENTHREAD_NETDEV_MSG_TYPE_EVENT:
|
||||
/* Received an event from driver */
|
||||
dev = msg.content.ptr;
|
||||
dev->driver->isr(dev);
|
||||
break;
|
||||
case OPENTHREAD_SERIAL_MSG_TYPE_EVENT:
|
||||
/* Tell OpenThread about the reception of a CLI command */
|
||||
buf = msg.content.ptr;
|
||||
otPlatUartReceived(buf, strlen((char *) buf));
|
||||
break;
|
||||
case OPENTHREAD_JOB_MSG_TYPE_EVENT:
|
||||
job = msg.content.ptr;
|
||||
reply.content.value = ot_exec_command(sInstance, job->command, job->arg, job->answer);
|
||||
msg_reply(&msg, &reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _event_cb(netdev_t *dev, netdev_event_t event) {
|
||||
switch (event) {
|
||||
case NETDEV_EVENT_ISR:
|
||||
{
|
||||
msg_t msg;
|
||||
assert(_pid != KERNEL_PID_UNDEF);
|
||||
|
||||
msg.type = OPENTHREAD_NETDEV_MSG_TYPE_EVENT;
|
||||
msg.content.ptr = dev;
|
||||
|
||||
if (msg_send(&msg, _pid) <= 0) {
|
||||
DEBUG("openthread_netdev: possibly lost interrupt.\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NETDEV_EVENT_RX_COMPLETE:
|
||||
DEBUG("openthread_netdev: Reception of a packet\n");
|
||||
recv_pkt(sInstance, dev);
|
||||
break;
|
||||
case NETDEV_EVENT_TX_COMPLETE:
|
||||
case NETDEV_EVENT_TX_NOACK:
|
||||
case NETDEV_EVENT_TX_MEDIUM_BUSY:
|
||||
DEBUG("openthread_netdev: Transmission of a packet\n");
|
||||
send_pkt(sInstance, dev, event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* get OpenThread thread pid */
|
||||
kernel_pid_t openthread_get_pid(void) {
|
||||
return _pid;
|
||||
}
|
||||
|
||||
/* starts OpenThread thread */
|
||||
int openthread_netdev_init(char *stack, int stacksize, char priority,
|
||||
const char *name, netdev_t *netdev) {
|
||||
netdev->driver->init(netdev);
|
||||
netdev->event_callback = _event_cb;
|
||||
|
||||
netopt_enable_t enable = NETOPT_ENABLE;
|
||||
netdev->driver->set(netdev, NETOPT_TX_END_IRQ, &enable, sizeof(enable));
|
||||
|
||||
_pid = thread_create(stack, stacksize,
|
||||
priority, THREAD_CREATE_STACKTEST,
|
||||
_openthread_event_loop, NULL, name);
|
||||
|
||||
if (_pid <= 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return _pid;
|
||||
}
|
80
pkg/openthread/contrib/openthread.c
Normal file
80
pkg/openthread/contrib/openthread.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread main functions
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "openthread/platform/alarm.h"
|
||||
#include "openthread/platform/uart.h"
|
||||
#include "ot.h"
|
||||
#include "random.h"
|
||||
#include "thread.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#ifdef MODULE_AT86RF2XX
|
||||
#include "at86rf2xx.h"
|
||||
#include "at86rf2xx_params.h"
|
||||
#endif
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef MODULE_AT86RF2XX /* is mutual exclusive with above ifdef */
|
||||
#define OPENTHREAD_NETIF_NUMOF (sizeof(at86rf2xx_params) / sizeof(at86rf2xx_params[0]))
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_AT86RF2XX
|
||||
static at86rf2xx_t at86rf2xx_dev;
|
||||
#endif
|
||||
|
||||
#define OPENTHREAD_NETDEV_BUFLEN (ETHERNET_MAX_LEN)
|
||||
|
||||
static uint8_t rx_buf[OPENTHREAD_NETDEV_BUFLEN];
|
||||
static uint8_t tx_buf[OPENTHREAD_NETDEV_BUFLEN];
|
||||
static char ot_thread_stack[2 * THREAD_STACKSIZE_MAIN];
|
||||
|
||||
/* init and run OpeanThread's UART simulation (stdio) */
|
||||
void openthread_uart_run(void)
|
||||
{
|
||||
char buf[256];
|
||||
msg_t msg;
|
||||
|
||||
msg.type = OPENTHREAD_SERIAL_MSG_TYPE_EVENT;
|
||||
msg.content.ptr = buf;
|
||||
|
||||
buf[1] = 0;
|
||||
while (1) {
|
||||
char c = getchar();
|
||||
buf[0] = c;
|
||||
msg_send(&msg, openthread_get_pid());
|
||||
}
|
||||
}
|
||||
|
||||
void openthread_bootstrap(void)
|
||||
{
|
||||
/* init random */
|
||||
ot_random_init();
|
||||
|
||||
/* setup netdev modules */
|
||||
#ifdef MODULE_AT86RF2XX
|
||||
at86rf2xx_setup(&at86rf2xx_dev, &at86rf2xx_params[0]);
|
||||
netdev_t *netdev = (netdev_t *) &at86rf2xx_dev;
|
||||
#endif
|
||||
|
||||
openthread_radio_init(netdev, tx_buf, rx_buf);
|
||||
openthread_netdev_init(ot_thread_stack, sizeof(ot_thread_stack), THREAD_PRIORITY_MAIN - 5, "openthread", netdev);
|
||||
}
|
68
pkg/openthread/contrib/platform_alarm.c
Normal file
68
pkg/openthread/contrib/platform_alarm.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread alarm platform abstraction
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "msg.h"
|
||||
#include "openthread/platform/alarm.h"
|
||||
#include "ot.h"
|
||||
#include "thread.h"
|
||||
#include "xtimer.h"
|
||||
#include "timex.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
static xtimer_t ot_timer;
|
||||
static msg_t ot_alarm_msg;
|
||||
|
||||
/**
|
||||
* Set the alarm to fire at @p aDt milliseconds after @p aT0.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aT0 The reference time.
|
||||
* @param[in] aDt The time delay in milliseconds from @p aT0.
|
||||
*/
|
||||
void otPlatAlarmStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
|
||||
{
|
||||
DEBUG("openthread: otPlatAlarmStartAt: aT0: %" PRIu32 ", aDT: %" PRIu32 "\n", aT0, aDt);
|
||||
ot_alarm_msg.type = OPENTHREAD_XTIMER_MSG_TYPE_EVENT;
|
||||
|
||||
if (aDt == 0) {
|
||||
msg_send(&ot_alarm_msg, thread_getpid());
|
||||
}
|
||||
else {
|
||||
int dt = aDt * US_PER_MS;
|
||||
xtimer_set_msg(&ot_timer, dt, &ot_alarm_msg, thread_getpid());
|
||||
}
|
||||
}
|
||||
|
||||
/* OpenThread will call this to stop alarms */
|
||||
void otPlatAlarmStop(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("openthread: otPlatAlarmStop\n");
|
||||
xtimer_remove(&ot_timer);
|
||||
}
|
||||
|
||||
/* OpenThread will call this for getting running time in millisecs */
|
||||
uint32_t otPlatAlarmGetNow(void)
|
||||
{
|
||||
uint32_t now = xtimer_now_usec() / US_PER_MS;
|
||||
DEBUG("openthread: otPlatAlarmGetNow: %" PRIu32 "\n", now);
|
||||
return now;
|
||||
}
|
38
pkg/openthread/contrib/platform_diag.c
Normal file
38
pkg/openthread/contrib/platform_diag.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread diagnostics platform abstraction
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static bool sDiagMode = false;
|
||||
|
||||
void otPlatDiagProcess(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
|
||||
{
|
||||
/* add more plarform specific diagnostics features here */
|
||||
(void)argc;
|
||||
}
|
||||
|
||||
void otPlatDiagModeSet(bool aMode)
|
||||
{
|
||||
sDiagMode = aMode;
|
||||
}
|
||||
|
||||
bool otPlatDiagModeGet(void)
|
||||
{
|
||||
return sDiagMode;
|
||||
}
|
297
pkg/openthread/contrib/platform_functions_wrapper.c
Normal file
297
pkg/openthread/contrib/platform_functions_wrapper.c
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (C)
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread functions wrapper. They are used to call OT functions from OT thread
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@inria.cl>
|
||||
* @author Baptiste CLENET <bapclenet@gmail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "thread.h"
|
||||
#include "openthread/ip6.h"
|
||||
#include "openthread/thread.h"
|
||||
#include "openthread/udp.h"
|
||||
#include "ot.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
typedef uint8_t OT_COMMAND;
|
||||
|
||||
OT_COMMAND ot_channel(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_eui64(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_extaddr(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_ipaddr(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_masterkey(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_networkname(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_mode(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_panid(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_parent(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_state(otInstance* ot_instance, void* arg, void* answer);
|
||||
OT_COMMAND ot_thread(otInstance* ot_instance, void* arg, void* answer);
|
||||
|
||||
/**
|
||||
* @brief Struct containing an OpenThread job command
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name; /**< A pointer to the job name string. */
|
||||
OT_COMMAND (*function)(otInstance*, void*, void*); /**< function to be called */
|
||||
} ot_command_t;
|
||||
|
||||
const ot_command_t otCommands[] =
|
||||
{
|
||||
/* channel: arg NULL: get channel in answer | arg not NULL: set channel */
|
||||
{ "channel", &ot_channel },
|
||||
/* eui64 : arg NULL: get eui64 in answer | arg not NULL: set eui64 */
|
||||
{ "eui64", &ot_eui64 },
|
||||
/* extaddr: arg NULL: get extaddr in answer | arg not NULL: set extaddr */
|
||||
{ "extaddr", &ot_extaddr },
|
||||
/* ipaddr: arg NULL: get nb ipaddr in answer | arg not NULL: get ipaddr[arg] */
|
||||
{ "ipaddr", &ot_ipaddr },
|
||||
/* masterkey: arg NULL: get masterkey in answer | arg not NULL: set masterkey */
|
||||
{ "masterkey", &ot_masterkey },
|
||||
/* mode: arg NULL: get mode in answer | arg not NULL: set mode */
|
||||
{ "mode", ot_mode },
|
||||
/* networkname: arg NULL: get networkname in answer | arg not NULL: set networkname */
|
||||
{ "networkname", &ot_networkname },
|
||||
/* panid: arg NULL: get panid in answer | arg not NULL: set panid */
|
||||
{ "panid", &ot_panid },
|
||||
/* parent: arg NULL: get parent in answer */
|
||||
{ "parent", &ot_parent },
|
||||
/* state: arg NULL: get state in answer */
|
||||
{ "state", &ot_state },
|
||||
/* thread: arg "start"/"stop": start/stop thread operation */
|
||||
{ "thread", &ot_thread },
|
||||
};
|
||||
|
||||
uint8_t ot_exec_command(otInstance *ot_instance, const char* command, void *arg, void* answer) {
|
||||
uint8_t res = 0xFF;
|
||||
/* Check running thread */
|
||||
if (openthread_get_pid() == thread_getpid()) {
|
||||
for (uint8_t i = 0; i < sizeof(otCommands) / sizeof(otCommands[0]); i++) {
|
||||
if (strcmp(command, otCommands[i].name) == 0) {
|
||||
res = (*otCommands[i].function)(ot_instance, arg, answer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (res == 0xFF) {
|
||||
DEBUG("Wrong ot_COMMAND name\n");
|
||||
res = 1;
|
||||
}
|
||||
} else {
|
||||
DEBUG("ERROR: ot_exec_job needs to run in OpenThread thread\n");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void output_bytes(const char* name, const uint8_t *aBytes, uint8_t aLength)
|
||||
{
|
||||
DEBUG("%s: ", name);
|
||||
for (int i = 0; i < aLength; i++) {
|
||||
DEBUG("%02x", aBytes[i]);
|
||||
}
|
||||
DEBUG("\n");
|
||||
}
|
||||
|
||||
OT_COMMAND ot_channel(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
*((uint8_t *) answer) = otLinkGetChannel(ot_instance);
|
||||
DEBUG("Channel: %04x\n", *((uint8_t *) answer));
|
||||
} else if (arg != NULL) {
|
||||
uint8_t channel = *((uint8_t *) arg);
|
||||
otLinkSetChannel(ot_instance, channel);
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_eui64(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
otExtAddress address;
|
||||
otLinkGetFactoryAssignedIeeeEui64(ot_instance, &address);
|
||||
output_bytes("eui64", address.m8, OT_EXT_ADDRESS_SIZE);
|
||||
*((otExtAddress *) answer) = address;
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
OT_COMMAND ot_extaddr(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
answer = (void*)otLinkGetExtendedAddress(ot_instance);
|
||||
output_bytes("extaddr", (const uint8_t *)answer, OT_EXT_ADDRESS_SIZE);
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_ipaddr(otInstance* ot_instance, void* arg, void* answer) {
|
||||
uint8_t cnt = 0;
|
||||
for (const otNetifAddress *addr = otIp6GetUnicastAddresses(ot_instance); addr; addr = addr->mNext) {
|
||||
if (arg != NULL && answer != NULL && cnt == *((uint8_t *) arg)) {
|
||||
*((otNetifAddress *) answer) = *addr;
|
||||
return 0;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
if (answer != NULL) {
|
||||
*((uint8_t *) answer) = cnt;
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_masterkey(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
const otMasterKey* masterkey = otThreadGetMasterKey(ot_instance);
|
||||
*((otMasterKey *) answer) = *masterkey;
|
||||
output_bytes("masterkey", (const uint8_t *)answer, OT_MASTER_KEY_SIZE);
|
||||
} else if (arg != NULL) {
|
||||
otThreadSetMasterKey(ot_instance, (otMasterKey*)arg);
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_mode(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (arg != NULL) {
|
||||
otLinkModeConfig link_mode;
|
||||
memset(&link_mode, 0, sizeof(otLinkModeConfig));
|
||||
char mode[6];
|
||||
memcpy(mode, (char*)arg, 5);
|
||||
mode[5] = '\0';
|
||||
for (char *arg = &mode[0]; *arg != '\0'; arg++) {
|
||||
switch (*arg) {
|
||||
case 'r':
|
||||
link_mode.mRxOnWhenIdle = 1;
|
||||
break;
|
||||
case 's':
|
||||
link_mode.mSecureDataRequests = 1;
|
||||
break;
|
||||
case 'd':
|
||||
link_mode.mDeviceType = 1;
|
||||
break;
|
||||
case 'n':
|
||||
link_mode.mNetworkData = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
otThreadSetLinkMode(ot_instance, link_mode);
|
||||
DEBUG("OT mode changed to %s\n", (char*)arg);
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_networkname(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
const char* networkName = otThreadGetNetworkName(ot_instance);
|
||||
strcpy((char*) answer, networkName);
|
||||
DEBUG("networkname: %.*s\n", OT_NETWORK_NAME_MAX_SIZE, networkName);
|
||||
} else if (arg != NULL) {
|
||||
otThreadSetNetworkName(ot_instance, (char*) arg);
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
OT_COMMAND ot_panid(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
*((uint16_t *) answer) = otLinkGetPanId(ot_instance);
|
||||
DEBUG("PanID: %04x\n", *((uint16_t *) answer));
|
||||
} else if (arg != NULL) {
|
||||
/* Thread operation needs to be stopped before setting panid */
|
||||
otThreadSetEnabled(ot_instance, false);
|
||||
uint16_t panid = *((uint16_t *) arg);
|
||||
otLinkSetPanId(ot_instance, panid);
|
||||
otThreadSetEnabled(ot_instance, true);
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_parent(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
otRouterInfo parentInfo;
|
||||
otThreadGetParentInfo(ot_instance, &parentInfo);
|
||||
output_bytes("parent", (const uint8_t *)parentInfo.mExtAddress.m8, sizeof(parentInfo.mExtAddress));
|
||||
DEBUG("Rloc: %x\n", parentInfo.mRloc16);
|
||||
*((otRouterInfo *) answer) = parentInfo;
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_state(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (answer != NULL) {
|
||||
uint8_t state = otThreadGetDeviceRole(ot_instance);
|
||||
*((uint8_t *) answer) = state;
|
||||
DEBUG("state: ");
|
||||
switch (state) {
|
||||
case kDeviceRoleOffline:
|
||||
puts("offline");
|
||||
break;
|
||||
case kDeviceRoleDisabled:
|
||||
puts("disabled");
|
||||
break;
|
||||
case kDeviceRoleDetached:
|
||||
puts("detached");
|
||||
break;
|
||||
case kDeviceRoleChild:
|
||||
puts("child");
|
||||
break;
|
||||
case kDeviceRoleRouter:
|
||||
puts("router");
|
||||
break;
|
||||
case kDeviceRoleLeader:
|
||||
puts("leader");
|
||||
break;
|
||||
default:
|
||||
puts("invalid state");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OT_COMMAND ot_thread(otInstance* ot_instance, void* arg, void* answer) {
|
||||
if (arg != NULL) {
|
||||
if (strcmp((char*)arg, "start") == 0) {
|
||||
otThreadSetEnabled(ot_instance, true);
|
||||
DEBUG("Thread start\n");
|
||||
} else if (strcmp((char*)arg, "stop") == 0) {
|
||||
otThreadSetEnabled(ot_instance, false);
|
||||
DEBUG("Thread stop\n");
|
||||
} else {
|
||||
DEBUG("ERROR: thread available args: start/stop\n");
|
||||
}
|
||||
} else {
|
||||
DEBUG("ERROR: wrong argument\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
97
pkg/openthread/contrib/platform_logging.c
Normal file
97
pkg/openthread/contrib/platform_logging.c
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread logging platform abstraction
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "openthread/platform/logging.h"
|
||||
|
||||
/* adapted from OpenThread posix example:
|
||||
* See: https://github.com/openthread/openthread/blob/master/examples/platforms/posix/logging.c */
|
||||
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
switch (aLogLevel) {
|
||||
case kLogLevelNone:
|
||||
fprintf(stderr, "NONE ");
|
||||
break;
|
||||
|
||||
case kLogLevelCrit:
|
||||
fprintf(stderr, "CRIT ");
|
||||
break;
|
||||
|
||||
case kLogLevelWarn:
|
||||
fprintf(stderr, "WARN ");
|
||||
break;
|
||||
|
||||
case kLogLevelInfo:
|
||||
fprintf(stderr, "INFO ");
|
||||
break;
|
||||
|
||||
case kLogLevelDebg:
|
||||
fprintf(stderr, "DEBG ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (aLogRegion) {
|
||||
case kLogRegionApi:
|
||||
fprintf(stderr, "API ");
|
||||
break;
|
||||
|
||||
case kLogRegionMle:
|
||||
fprintf(stderr, "MLE ");
|
||||
break;
|
||||
|
||||
case kLogRegionArp:
|
||||
fprintf(stderr, "ARP ");
|
||||
break;
|
||||
|
||||
case kLogRegionNetData:
|
||||
fprintf(stderr, "NETD ");
|
||||
break;
|
||||
|
||||
case kLogRegionIp6:
|
||||
fprintf(stderr, "IPV6 ");
|
||||
break;
|
||||
|
||||
case kLogRegionIcmp:
|
||||
fprintf(stderr, "ICMP ");
|
||||
break;
|
||||
|
||||
case kLogRegionMac:
|
||||
fprintf(stderr, "MAC ");
|
||||
break;
|
||||
|
||||
case kLogRegionMem:
|
||||
fprintf(stderr, "MEM ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
va_start(args, aFormat);
|
||||
vfprintf(stderr, aFormat, args);
|
||||
fprintf(stderr, "\r");
|
||||
va_end(args);
|
||||
}
|
36
pkg/openthread/contrib/platform_misc.c
Normal file
36
pkg/openthread/contrib/platform_misc.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) Baptiste Clenet
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread misc platform abstraction
|
||||
*
|
||||
* @author Baptiste Clenet <bapclenet@gmail.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#include "openthread/types.h"
|
||||
#include "openthread/platform/misc.h"
|
||||
#include "periph/pm.h"
|
||||
|
||||
void otPlatReset(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
printf("reboot...\n");
|
||||
pm_reboot();
|
||||
}
|
||||
|
||||
otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
/* TODO: Write me! */
|
||||
return kPlatResetReason_PowerOn;
|
||||
}
|
422
pkg/openthread/contrib/platform_radio.c
Normal file
422
pkg/openthread/contrib/platform_radio.c
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread radio platform abstraction
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "errno.h"
|
||||
#include "net/ethernet/hdr.h"
|
||||
#include "net/ethertype.h"
|
||||
#include "net/ieee802154.h"
|
||||
#include "net/netdev/ieee802154.h"
|
||||
#include "openthread/platform/radio.h"
|
||||
#include "ot.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define RADIO_IEEE802154_FCS_LEN (2U)
|
||||
|
||||
static RadioPacket sTransmitFrame;
|
||||
static RadioPacket sReceiveFrame;
|
||||
static int8_t Rssi;
|
||||
|
||||
static netdev_t *_dev;
|
||||
|
||||
static bool sDisabled;
|
||||
|
||||
/* set 15.4 channel */
|
||||
static int _set_channel(uint16_t channel)
|
||||
{
|
||||
return _dev->driver->set(_dev, NETOPT_CHANNEL, &channel, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
/*get transmission power from driver */
|
||||
static int16_t _get_power(void)
|
||||
{
|
||||
int16_t power;
|
||||
|
||||
_dev->driver->get(_dev, NETOPT_TX_POWER, &power, sizeof(int16_t));
|
||||
return power;
|
||||
}
|
||||
|
||||
/* set transmission power */
|
||||
static int _set_power(int16_t power)
|
||||
{
|
||||
return _dev->driver->set(_dev, NETOPT_TX_POWER, &power, sizeof(int16_t));
|
||||
}
|
||||
|
||||
/* set IEEE802.15.4 PAN ID */
|
||||
static int _set_panid(uint16_t panid)
|
||||
{
|
||||
return _dev->driver->set(_dev, NETOPT_NID, &panid, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
/* set extended HW address */
|
||||
static int _set_long_addr(uint8_t *ext_addr)
|
||||
{
|
||||
return _dev->driver->set(_dev, NETOPT_ADDRESS_LONG, ext_addr, IEEE802154_LONG_ADDRESS_LEN);
|
||||
}
|
||||
|
||||
/* set short address */
|
||||
static int _set_addr(uint16_t addr)
|
||||
{
|
||||
return _dev->driver->set(_dev, NETOPT_ADDRESS, &addr, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
/* check the state of promiscuous mode */
|
||||
static netopt_enable_t _is_promiscuous(void)
|
||||
{
|
||||
netopt_enable_t en;
|
||||
|
||||
_dev->driver->get(_dev, NETOPT_PROMISCUOUSMODE, &en, sizeof(en));
|
||||
return en == NETOPT_ENABLE ? true : false;;
|
||||
}
|
||||
|
||||
/* set the state of promiscuous mode */
|
||||
static int _set_promiscuous(netopt_enable_t enable)
|
||||
{
|
||||
return _dev->driver->set(_dev, NETOPT_PROMISCUOUSMODE, &enable, sizeof(enable));
|
||||
}
|
||||
|
||||
/* wrapper for setting device state */
|
||||
static void _set_state(netopt_state_t state)
|
||||
{
|
||||
_dev->driver->set(_dev, NETOPT_STATE, &state, sizeof(netopt_state_t));
|
||||
}
|
||||
|
||||
/* wrapper for getting device state */
|
||||
static netopt_state_t _get_state(void)
|
||||
{
|
||||
netopt_state_t state;
|
||||
_dev->driver->get(_dev, NETOPT_STATE, &state, sizeof(netopt_state_t));
|
||||
return state;
|
||||
}
|
||||
|
||||
/* sets device state to SLEEP */
|
||||
static void _set_sleep(void)
|
||||
{
|
||||
_set_state(NETOPT_STATE_SLEEP);
|
||||
}
|
||||
|
||||
/* set device state to IDLE */
|
||||
static void _set_idle(void)
|
||||
{
|
||||
_set_state(NETOPT_STATE_IDLE);
|
||||
}
|
||||
|
||||
/* init framebuffers and initial state */
|
||||
void openthread_radio_init(netdev_t *dev, uint8_t *tb, uint8_t *rb)
|
||||
{
|
||||
sTransmitFrame.mPsdu = tb;
|
||||
sTransmitFrame.mLength = 0;
|
||||
sReceiveFrame.mPsdu = rb;
|
||||
sReceiveFrame.mLength = 0;
|
||||
_dev = dev;
|
||||
}
|
||||
|
||||
/* Called upon NETDEV_EVENT_RX_COMPLETE event */
|
||||
void recv_pkt(otInstance *aInstance, netdev_t *dev)
|
||||
{
|
||||
DEBUG("Openthread: Received pkt\n");
|
||||
netdev_ieee802154_rx_info_t rx_info;
|
||||
/* Read frame length from driver */
|
||||
int len = dev->driver->recv(dev, NULL, 0, &rx_info);
|
||||
Rssi = rx_info.rssi;
|
||||
|
||||
/* very unlikely */
|
||||
if ((len > (unsigned) UINT16_MAX)) {
|
||||
DEBUG("Len too high: %d\n", len);
|
||||
otPlatRadioReceiveDone(aInstance, NULL, kThreadError_Abort);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fill OpenThread receive frame */
|
||||
/* Openthread needs a packet length with FCS included,
|
||||
* OpenThread do not use the data so we don't need to calculate FCS */
|
||||
sReceiveFrame.mLength = len + RADIO_IEEE802154_FCS_LEN;
|
||||
sReceiveFrame.mPower = _get_power();
|
||||
|
||||
/* Read received frame */
|
||||
int res = dev->driver->recv(dev, (char *) sReceiveFrame.mPsdu, len, NULL);
|
||||
|
||||
DEBUG("Received message: len %d\n", (int) sReceiveFrame.mLength);
|
||||
for (int i = 0; i < sReceiveFrame.mLength; ++i) {
|
||||
DEBUG("%x ", sReceiveFrame.mPsdu[i]);
|
||||
}
|
||||
DEBUG("\n");
|
||||
|
||||
/* Tell OpenThread that receive has finished */
|
||||
otPlatRadioReceiveDone(aInstance, res > 0 ? &sReceiveFrame : NULL, res > 0 ? kThreadError_None : kThreadError_Abort);
|
||||
}
|
||||
|
||||
/* Called upon TX event */
|
||||
void send_pkt(otInstance *aInstance, netdev_t *dev, netdev_event_t event)
|
||||
{
|
||||
/* Tell OpenThread transmission is done depending on the NETDEV event */
|
||||
switch (event) {
|
||||
case NETDEV_EVENT_TX_COMPLETE:
|
||||
DEBUG("openthread: NETDEV_EVENT_TX_COMPLETE\n");
|
||||
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, kThreadError_None);
|
||||
break;
|
||||
case NETDEV_EVENT_TX_COMPLETE_DATA_PENDING:
|
||||
DEBUG("openthread: NETDEV_EVENT_TX_COMPLETE_DATA_PENDING\n");
|
||||
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, true, kThreadError_None);
|
||||
break;
|
||||
case NETDEV_EVENT_TX_NOACK:
|
||||
DEBUG("openthread: NETDEV_EVENT_TX_NOACK\n");
|
||||
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, kThreadError_NoAck);
|
||||
break;
|
||||
case NETDEV_EVENT_TX_MEDIUM_BUSY:
|
||||
DEBUG("openthread: NETDEV_EVENT_TX_MEDIUM_BUSY\n");
|
||||
otPlatRadioTransmitDone(aInstance, &sTransmitFrame, false, kThreadError_ChannelAccessFailure);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* OpenThread will call this for setting PAN ID */
|
||||
void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioSetPanId: setting PAN ID to %04x\n", panid);
|
||||
_set_panid(panid);
|
||||
}
|
||||
|
||||
/* OpenThread will call this for setting extended address */
|
||||
void otPlatRadioSetExtendedAddress(otInstance *aInstance, uint8_t *aExtendedAddress)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioSetExtendedAddress\n");
|
||||
uint8_t reversed_addr[IEEE802154_LONG_ADDRESS_LEN];
|
||||
for (int i = 0; i < IEEE802154_LONG_ADDRESS_LEN; i++) {
|
||||
reversed_addr[i] = aExtendedAddress[IEEE802154_LONG_ADDRESS_LEN - 1 - i];
|
||||
}
|
||||
_set_long_addr(reversed_addr);
|
||||
}
|
||||
|
||||
/* OpenThread will call this for setting short address */
|
||||
void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aShortAddress)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioSetShortAddress: setting address to %04x\n", aShortAddress);
|
||||
_set_addr(((aShortAddress & 0xff) << 8) | ((aShortAddress >> 8) & 0xff));
|
||||
}
|
||||
|
||||
/* OpenThread will call this for enabling the radio */
|
||||
ThreadError otPlatRadioEnable(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioEnable\n");
|
||||
(void) aInstance;
|
||||
|
||||
if (sDisabled) {
|
||||
sDisabled = false;
|
||||
_set_idle();
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
/* OpenThread will call this for disabling the radio */
|
||||
ThreadError otPlatRadioDisable(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioDisable\n");
|
||||
(void) aInstance;
|
||||
|
||||
if (!sDisabled) {
|
||||
sDisabled = true;
|
||||
_set_sleep();
|
||||
}
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
bool otPlatRadioIsEnabled(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("otPlatRadioIsEnabled\n");
|
||||
(void) aInstance;
|
||||
netopt_state_t state = _get_state();
|
||||
if (state == NETOPT_STATE_OFF || state == NETOPT_STATE_SLEEP) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* OpenThread will call this for setting device state to SLEEP */
|
||||
ThreadError otPlatRadioSleep(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("otPlatRadioSleep\n");
|
||||
(void) aInstance;
|
||||
|
||||
_set_sleep();
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
/*OpenThread will call this for waiting the reception of a packet */
|
||||
ThreadError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioReceive. Channel: %i\n", aChannel);
|
||||
(void) aInstance;
|
||||
|
||||
_set_idle();
|
||||
_set_channel(aChannel);
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
/* OpenThread will call this function to get the transmit buffer */
|
||||
RadioPacket *otPlatRadioGetTransmitBuffer(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioGetTransmitBuffer\n");
|
||||
return &sTransmitFrame;
|
||||
}
|
||||
|
||||
/* OpenThread will call this function to set the transmit power */
|
||||
void otPlatRadioSetDefaultTxPower(otInstance *aInstance, int8_t aPower)
|
||||
{
|
||||
(void)aInstance;
|
||||
|
||||
_set_power(aPower);
|
||||
}
|
||||
|
||||
/* OpenThread will call this for transmitting a packet*/
|
||||
ThreadError otPlatRadioTransmit(otInstance *aInstance, RadioPacket *aPacket)
|
||||
{
|
||||
(void) aInstance;
|
||||
struct iovec pkt;
|
||||
|
||||
/* Populate iovec with transmit data
|
||||
* Unlike RIOT, OpenThread includes two bytes FCS (0x00 0x00) so
|
||||
* these bytes are removed
|
||||
*/
|
||||
pkt.iov_base = aPacket->mPsdu;
|
||||
pkt.iov_len = aPacket->mLength - RADIO_IEEE802154_FCS_LEN;
|
||||
|
||||
/*Set channel and power based on transmit frame */
|
||||
DEBUG("otPlatRadioTransmit->channel: %i, length %d\n", (int) aPacket->mChannel, (int)aPacket->mLength);
|
||||
for (int i = 0; i < aPacket->mLength; ++i) {
|
||||
DEBUG("%x ", aPacket->mPsdu[i]);
|
||||
}
|
||||
DEBUG("\n");
|
||||
_set_channel(aPacket->mChannel);
|
||||
_set_power(aPacket->mPower);
|
||||
|
||||
/* send packet though netdev */
|
||||
_dev->driver->send(_dev, &pkt, 1);
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
/* OpenThread will call this for getting the radio caps */
|
||||
otRadioCaps otPlatRadioGetCaps(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioGetCaps\n");
|
||||
/* all drivers should handle ACK, including call of NETDEV_EVENT_TX_NOACK */
|
||||
return kRadioCapsNone;
|
||||
}
|
||||
|
||||
/* OpenThread will call this for getting the state of promiscuous mode */
|
||||
bool otPlatRadioGetPromiscuous(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioGetPromiscuous\n");
|
||||
return _is_promiscuous();
|
||||
}
|
||||
|
||||
/* OpenThread will call this for setting the state of promiscuous mode */
|
||||
void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
DEBUG("openthread: otPlatRadioSetPromiscuous\n");
|
||||
_set_promiscuous((aEnable) ? NETOPT_ENABLE : NETOPT_DISABLE);
|
||||
}
|
||||
|
||||
int8_t otPlatRadioGetRssi(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("otPlatRadioGetRssi\n");
|
||||
(void) aInstance;
|
||||
return Rssi;
|
||||
}
|
||||
|
||||
void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable)
|
||||
{
|
||||
DEBUG("otPlatRadioEnableSrcMatch\n");
|
||||
(void)aInstance;
|
||||
(void)aEnable;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
||||
{
|
||||
DEBUG("otPlatRadioAddSrcMatchShortEntry\n");
|
||||
(void)aInstance;
|
||||
(void)aShortAddress;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
||||
{
|
||||
DEBUG("otPlatRadioAddSrcMatchExtEntry\n");
|
||||
(void)aInstance;
|
||||
(void)aExtAddress;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, const uint16_t aShortAddress)
|
||||
{
|
||||
DEBUG("otPlatRadioClearSrcMatchShortEntry\n");
|
||||
(void)aInstance;
|
||||
(void)aShortAddress;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const uint8_t *aExtAddress)
|
||||
{
|
||||
DEBUG("otPlatRadioClearSrcMatchExtEntry\n");
|
||||
(void)aInstance;
|
||||
(void)aExtAddress;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("otPlatRadioClearSrcMatchShortEntries\n");
|
||||
(void)aInstance;
|
||||
}
|
||||
|
||||
void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("otPlatRadioClearSrcMatchExtEntries\n");
|
||||
(void)aInstance;
|
||||
}
|
||||
|
||||
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
|
||||
{
|
||||
DEBUG("otPlatRadioEnergyScan\n");
|
||||
(void)aInstance;
|
||||
(void)aScanChannel;
|
||||
(void)aScanDuration;
|
||||
return kThreadError_NotImplemented;
|
||||
}
|
||||
|
||||
void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeee64Eui64)
|
||||
{
|
||||
_dev->driver->get(_dev, NETOPT_IPV6_IID, aIeee64Eui64, sizeof(eui64_t));
|
||||
}
|
||||
|
||||
int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance)
|
||||
{
|
||||
return -100;
|
||||
}
|
51
pkg/openthread/contrib/platform_random.c
Normal file
51
pkg/openthread/contrib/platform_random.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread random platform abstraction
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "openthread/platform/random.h"
|
||||
#include "periph/cpuid.h"
|
||||
#include "random.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/* init random */
|
||||
void ot_random_init(void)
|
||||
{
|
||||
#ifdef CPUID_LEN
|
||||
char cpu_id[CPUID_LEN];
|
||||
cpuid_get(cpu_id);
|
||||
uint32_t seed = 0;
|
||||
for (unsigned i = 0; i < CPUID_LEN; i++) {
|
||||
seed += cpu_id[i];
|
||||
}
|
||||
random_init(seed);
|
||||
#else
|
||||
#error "CPU not supported (current CPU doesn't provide CPUID, required for entropy)"
|
||||
#endif
|
||||
}
|
||||
|
||||
/* OpenThread will call this to get a random number */
|
||||
uint32_t otPlatRandomGet(void)
|
||||
{
|
||||
uint32_t rand_val = random_uint32();
|
||||
|
||||
DEBUG("otPlatRandomGet: %i\n", (int) rand_val);
|
||||
return rand_val;
|
||||
}
|
72
pkg/openthread/contrib/platform_settings.c
Normal file
72
pkg/openthread/contrib/platform_settings.c
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread settings platform abstraction
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "assert.h"
|
||||
#include "openthread/types.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
void otPlatSettingsInit(otInstance *aInstance)
|
||||
{
|
||||
}
|
||||
|
||||
ThreadError otPlatSettingsBeginChange(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatSettingsCommitChange(otInstance *aInstance)
|
||||
{
|
||||
DEBUG("openthread: otPlatSettingsCommitChange\n");
|
||||
(void)aInstance;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatSettingsAbandonChange(otInstance *aInstance)
|
||||
{
|
||||
(void)aInstance;
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
|
||||
{
|
||||
DEBUG("openthread: otPlatSettingsGet\n");
|
||||
*aValueLength = 0;
|
||||
return kThreadError_NotImplemented;
|
||||
}
|
||||
|
||||
ThreadError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
|
||||
{
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
|
||||
{
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
ThreadError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
|
||||
{
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
void otPlatSettingsWipe(otInstance *aInstance)
|
||||
{
|
||||
}
|
46
pkg/openthread/contrib/platform_uart.c
Normal file
46
pkg/openthread/contrib/platform_uart.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @ingroup net
|
||||
* @file
|
||||
* @brief Implementation of OpenThread UART platform abstraction
|
||||
*
|
||||
* @author Jose Ignacio Alamos <jialamos@uc.cl>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "periph/uart.h"
|
||||
#include "openthread/platform/uart.h"
|
||||
|
||||
/* OpenThread will call this for enabling UART (required for OpenThread's CLI)*/
|
||||
ThreadError otPlatUartEnable(void)
|
||||
{
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
/* OpenThread will call this for disabling UART */
|
||||
ThreadError otPlatUartDisable(void)
|
||||
{
|
||||
return kThreadError_None;
|
||||
}
|
||||
|
||||
/* OpenThread will call this for sending data through UART */
|
||||
ThreadError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
uart_write(UART_DEV(0), aBuf, aBufLength);
|
||||
|
||||
/* Tell OpenThread the sending of UART is done */
|
||||
otPlatUartSendDone();
|
||||
|
||||
return kThreadError_None;
|
||||
}
|
153
pkg/openthread/include/ot.h
Normal file
153
pkg/openthread/include/ot.h
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Fundacion Inria Chile
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pkg_openthread_cli OpenThread
|
||||
* @ingroup pkg_openthread
|
||||
* @brief An open source implementation of Thread stack
|
||||
* @see https://github.com/openthread/openthread
|
||||
*
|
||||
* Thread if a mesh oriented network stack running for IEEE802.15.4 networks.
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @author José Ignacio Alamos <jialamos@uc.cl>
|
||||
*/
|
||||
|
||||
#ifndef OT_H
|
||||
#define OT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "net/netopt.h"
|
||||
#include "net/ieee802154.h"
|
||||
#include "net/ethernet.h"
|
||||
#include "net/gnrc/netdev.h"
|
||||
#include "thread.h"
|
||||
#include "openthread/types.h"
|
||||
|
||||
#define OPENTHREAD_XTIMER_MSG_TYPE_EVENT (0x2235) /**< xtimer message receiver event*/
|
||||
#define OPENTHREAD_NETDEV_MSG_TYPE_EVENT (0x2236) /**< message received from driver */
|
||||
#define OPENTHREAD_SERIAL_MSG_TYPE_EVENT (0x2237) /**< event indicating a serial (UART) message was sent to OpenThread */
|
||||
#define OPENTHREAD_MSG_TYPE_RECV (0x2238) /**< event for frame reception */
|
||||
#define OPENTHREAD_JOB_MSG_TYPE_EVENT (0x2240) /**< event indicating an OT_JOB message */
|
||||
|
||||
/**
|
||||
* @brief Struct containing a serial message
|
||||
*/
|
||||
typedef struct {
|
||||
void *buf; /**< buffer containing the message */
|
||||
size_t len; /**< length of the message */
|
||||
} serial_msg_t;
|
||||
|
||||
/**
|
||||
* @brief Struct containing an OpenThread job
|
||||
*/
|
||||
typedef struct {
|
||||
const char *command; /**< A pointer to the job name string. */
|
||||
void *arg; /**< arg for the job **/
|
||||
void *answer; /**< answer from the job **/
|
||||
} ot_job_t;
|
||||
|
||||
/**
|
||||
* @brief Gets packet from driver and tells OpenThread about the reception.
|
||||
*
|
||||
* @param[in] aInstance pointer to an OpenThread instance
|
||||
*/
|
||||
void recv_pkt(otInstance *aInstance, netdev_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Inform OpenThread when tx is finished
|
||||
*
|
||||
* @param[in] aInstance pointer to an OpenThread instance
|
||||
* @param[in] dev pointer to a netdev interface
|
||||
* @param[in] event just occurred netdev event
|
||||
*/
|
||||
void send_pkt(otInstance *aInstance, netdev_t *dev, netdev_event_t event);
|
||||
|
||||
/**
|
||||
* @brief Bootstrap OpenThread
|
||||
*/
|
||||
void openthread_bootstrap(void);
|
||||
|
||||
/**
|
||||
* @brief Init OpenThread radio
|
||||
*
|
||||
* @param[in] dev pointer to a netdev interface
|
||||
* @param[in] tb pointer to the TX buffer designed for OpenThread
|
||||
* @param[in] event pointer to the RX buffer designed for Open_Thread
|
||||
*/
|
||||
void openthread_radio_init(netdev_t *dev, uint8_t *tb, uint8_t *rb);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Starts OpenThread thread.
|
||||
*
|
||||
* @param[in] stack pointer to the stack designed for OpenThread
|
||||
* @param[in] stacksize size of the stack
|
||||
* @param[in] priority priority of the OpenThread stack
|
||||
* @param[in] name name of the OpenThread stack
|
||||
* @param[in] netdev pointer to the netdev interface
|
||||
*
|
||||
* @return PID of OpenThread thread
|
||||
* @return -EINVAL if there was an error creating the thread
|
||||
*/
|
||||
int openthread_netdev_init(char *stack, int stacksize, char priority, const char *name, netdev_t *netdev);
|
||||
|
||||
/**
|
||||
* @brief get PID of OpenThread thread.
|
||||
*
|
||||
* @return PID of OpenThread thread
|
||||
*/
|
||||
kernel_pid_t openthread_get_pid(void);
|
||||
|
||||
/**
|
||||
* @brief Init OpenThread random
|
||||
*/
|
||||
void ot_random_init(void);
|
||||
|
||||
/*
|
||||
* @brief Run OpenThread UART simulator (stdio)
|
||||
*/
|
||||
void openthread_uart_run(void);
|
||||
|
||||
/**
|
||||
* @brief Execute OpenThread command. Call this function only in OpenThread thread
|
||||
*
|
||||
* @param[in] ot_instance OpenThread instance
|
||||
* @param[in] command OpenThread command name
|
||||
* @param[in] arg arg for the command
|
||||
* @param[out] answer answer for the command
|
||||
*
|
||||
* @return 0 on success, 1 on error
|
||||
*/
|
||||
uint8_t ot_exec_command(otInstance *ot_instance, const char* command, void *arg, void* answer);
|
||||
|
||||
/**
|
||||
* @brief Call OpenThread command in same thread as OT core (due to concurrency).
|
||||
*
|
||||
* @note An OpenThread command allows direct calls to OpenThread API (otXXX functions) without worrying about concurrency
|
||||
* issues. All API calls should be made in OT_JOB type functions.
|
||||
*
|
||||
* @param[in] command name of the command to call
|
||||
* @param[in] arg arg for the command
|
||||
* @param[out] answer answer for the command
|
||||
*
|
||||
* @return 0 on success, 1 on error
|
||||
*/
|
||||
uint8_t ot_call_command(char* command, void *arg, void* answer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OT_H */
|
||||
/** @} */
|
@ -72,6 +72,10 @@
|
||||
#include "lwip.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_OPENTHREAD
|
||||
#include "ot.h"
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_FIB
|
||||
#include "net/fib.h"
|
||||
#endif
|
||||
@ -140,6 +144,10 @@ void auto_init(void)
|
||||
DEBUG("Bootstraping lwIP.\n");
|
||||
lwip_bootstrap();
|
||||
#endif
|
||||
#ifdef MODULE_OPENTHREAD
|
||||
extern void openthread_bootstrap(void);
|
||||
openthread_bootstrap();
|
||||
#endif
|
||||
#ifdef MODULE_GCOAP
|
||||
DEBUG("Auto init gcoap module.\n");
|
||||
gcoap_init();
|
||||
|
Loading…
Reference in New Issue
Block a user