[posix] radio only host side driver (#2690)

This commit is contained in:
Yakun Xu
2018-06-25 16:32:32 -07:00
committed by Jonathan Hui
parent 17eace65e2
commit 1b14a36a35
42 changed files with 5842 additions and 32 deletions
+6
View File
@@ -47,6 +47,12 @@ after_success:
matrix:
include:
- env: BUILD_TARGET="posix-app-cli" VERBOSE=1
os: linux
compiler: gcc
- env: BUILD_TARGET="posix-app-ncp" VERBOSE=1
os: linux
compiler: gcc
- env: BUILD_TARGET="posix-distcheck" CC=clang-5.0 CXX=clang++-5.0 VERBOSE=1 VIRTUAL_TIME=1
os: linux
addons:
+2 -2
View File
@@ -39,10 +39,10 @@ cd /tmp || die
[ $TRAVIS_OS_NAME != linux ] || {
sudo apt-get update || die
[ $BUILD_TARGET != posix-distcheck -a $BUILD_TARGET != posix-32-bit -a $BUILD_TARGET != posix-mtd -a $BUILD_TARGET != posix-ncp ] || {
[ $BUILD_TARGET != posix-distcheck -a $BUILD_TARGET != posix-32-bit -a $BUILD_TARGET != posix-app-cli -a $BUILD_TARGET != posix-mtd -a $BUILD_TARGET != posix-ncp -a $BUILD_TARGET != posix-app-ncp ] || {
pip install --user --upgrade pip || die
pip install --user -r $TRAVIS_BUILD_DIR/tests/scripts/thread-cert/requirements.txt || die
[ $BUILD_TARGET != posix-ncp ] || {
[ $BUILD_TARGET != posix-ncp -a $BUILD_TARGET != posix-app-ncp ] || {
# Packages used by ncp tools.
pip install --user git+https://github.com/openthread/pyspinel || die
}
+14
View File
@@ -432,6 +432,13 @@ set -x
COVERAGE=1 CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 make -f examples/Makefile-posix check || die
}
[ $BUILD_TARGET != posix-app-cli ] || {
./bootstrap || die
make -f examples/Makefile-posix || die
make -f src/posix/Makefile-posix || die
OT_CLI_PATH="$(pwd)/$(ls output/posix/*/bin/ot-cli)" RADIO_DEVICE="$(pwd)/$(ls output/*/bin/ot-ncp-radio)" COVERAGE=1 make -f src/posix/Makefile-posix check || die
}
[ $BUILD_TARGET != posix-mtd ] || {
./bootstrap || die
COVERAGE=1 CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32 USE_MTD=1 make -f examples/Makefile-posix check || die
@@ -442,6 +449,13 @@ set -x
make -f examples/Makefile-posix check configure_OPTIONS="--enable-ncp-app=ftd --with-ncp-bus=spi --with-examples=posix" || die
}
[ $BUILD_TARGET != posix-app-ncp ] || {
./bootstrap || die
make -f examples/Makefile-posix || die
make -f src/posix/Makefile-posix || die
OT_NCP_PATH="$(pwd)/$(ls output/posix/*/bin/ot-ncp)" RADIO_DEVICE="$(pwd)/$(ls output/*/bin/ot-ncp-radio)" COVERAGE=1 NODE_TYPE=ncp-sim make -f src/posix/Makefile-posix check || die
}
[ $BUILD_TARGET != posix-ncp ] || {
./bootstrap || die
NODE_TYPE=ncp-sim make -f examples/Makefile-posix check || die
+1 -1
View File
@@ -50,8 +50,8 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \
SUBDIRS = \
include \
src \
third_party \
src \
examples \
tests \
tools \
+67 -6
View File
@@ -373,6 +373,59 @@ NL_ENABLE_TESTS([yes])
AM_CONDITIONAL([OPENTHREAD_BUILD_TESTS], [test "${nl_cv_build_tests}" = "yes"])
#
# Posix App
#
AC_ARG_ENABLE(
[posix-app],
[AS_HELP_STRING([--enable-posix-app],[Enable POSIX app(no|ncp|cli|all) @<:@default=no@:>@.])],
[
case "${enableval}" in
all|both|yes)
enable_posix_app=yes
OPENTHREAD_ENABLE_POSIX_APP=1
OPENTHREAD_ENABLE_POSIX_APP_NCP=1
OPENTHREAD_ENABLE_POSIX_APP_CLI=1
;;
no)
enable_posix_app=no
OPENTHREAD_ENABLE_POSIX_APP=0
OPENTHREAD_ENABLE_POSIX_APP_NCP=0
OPENTHREAD_ENABLE_POSIX_APP_CLI=0
;;
ncp)
enable_posix_app=yes
OPENTHREAD_ENABLE_POSIX_APP=1
OPENTHREAD_ENABLE_POSIX_APP_NCP=1
OPENTHREAD_ENABLE_POSIX_APP_CLI=0
;;
cli)
enable_posix_app=yes
OPENTHREAD_ENABLE_POSIX_APP=1
OPENTHREAD_ENABLE_POSIX_APP_NCP=0
OPENTHREAD_ENABLE_POSIX_APP_CLI=1
;;
*)
AC_MSG_ERROR([Invalid value ${enableval} for --enable-posix-app])
;;
esac
],
[
enable_posix_app=no
OPENTHREAD_ENABLE_POSIX_APP=0
OPENTHREAD_ENABLE_POSIX_APP_NCP=0
OPENTHREAD_ENABLE_POSIX_APP_CLI=0])
AC_MSG_CHECKING([posix-app])
AC_MSG_RESULT(${enable_posix_app})
AM_CONDITIONAL([OPENTHREAD_ENABLE_POSIX_APP], [test "${OPENTHREAD_ENABLE_POSIX_APP}" == "1"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_POSIX_APP_NCP], [test "${OPENTHREAD_ENABLE_POSIX_APP_NCP}" == "1"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_POSIX_APP_CLI], [test "${OPENTHREAD_ENABLE_POSIX_APP_CLI}" == "1"])
AC_SUBST(OPENTHREAD_ENABLE_POSIX_APP)
AC_SUBST(OPENTHREAD_ENABLE_POSIX_APP_NCP)
AC_SUBST(OPENTHREAD_ENABLE_POSIX_APP_CLI)
#
# CLI Library
#
@@ -413,9 +466,9 @@ AC_ARG_ENABLE(cli-app,
AC_MSG_CHECKING([cli-app modes])
AC_MSG_RESULT(${enable_cli_app})
AM_CONDITIONAL([OPENTHREAD_ENABLE_CLI], [test "${enable_cli_app}" == "yes"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_CLI], [test "${enable_cli_app}" == "yes" -o "${OPENTHREAD_ENABLE_POSIX_APP_CLI}" == "1"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_CLI_MTD], [test "${enable_cli_app_mtd}" == "yes"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_CLI_FTD], [test "${enable_cli_app_ftd}" == "yes"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_CLI_FTD], [test "${enable_cli_app_ftd}" == "yes" -o "${OPENTHREAD_ENABLE_POSIX_APP_CLI}" == "1"])
AC_SUBST(OPENTHREAD_ENABLE_CLI)
AC_SUBST(OPENTHREAD_ENABLE_CLI_FTD)
AC_SUBST(OPENTHREAD_ENABLE_CLI_MTD)
@@ -496,9 +549,9 @@ AC_SUBST(OPENTHREAD_ENABLE_NCP_MTD)
AC_SUBST(OPENTHREAD_ENABLE_NCP_FTD)
AC_SUBST(OPENTHREAD_ENABLE_NCP_RADIO)
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP], [test "${enable_ncp_app}" == "yes"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP], [test "${enable_ncp_app}" == "yes" -o "${OPENTHREAD_ENABLE_POSIX_APP_NCP}" == "1"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP_MTD], [test "${enable_ncp_app_mtd}" == "yes"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP_FTD], [test "${enable_ncp_app_ftd}" == "yes"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP_FTD], [test "${enable_ncp_app_ftd}" == "yes" -o "${OPENTHREAD_ENABLE_POSIX_APP_NCP}" == "1"])
AM_CONDITIONAL([OPENTHREAD_ENABLE_NCP_RADIO], [test "${enable_ncp_app_radio}" == "yes"])
#
@@ -1299,8 +1352,12 @@ AC_ARG_WITH(examples,
[Specify the examples from one of: none, posix, cc2538, cc2650, cc2652, da15000, efr32, emsk, gp712, kw41z, nrf52840, samr21 @<:@default=none@:>@.])],
[
case "${with_examples}" in
none|posix|cc2538|cc2650|cc2652|da15000|efr32|emsk|gp712|kw41z|nrf52840|samr21)
none)
;;
posix|cc2538|cc2650|cc2652|da15000|efr32|emsk|gp712|kw41z|nrf52840|samr21)
if test ${enable_posix_app} = "yes"; then
AC_MSG_ERROR([--with-examples must be none when POSIX apps are enabled by --enable-posix-app])
fi
;;
*)
AC_MSG_ERROR([Invalid value ${with_examples} for --with-examples])
@@ -1446,6 +1503,8 @@ NL_ENABLE_DOCS([auto],[NO])
AM_CONDITIONAL(OPENTHREAD_BUILD_DOCS, [test "${nl_cv_build_docs}" = "yes"])
AM_CONDITIONAL(OPENTHREAD_POSIX, [test "${OPENTHREAD_ENABLE_POSIX_APP}" = "1" -o "${OPENTHREAD_EXAMPLES_POSIX}" = "1"])
#
# Checks for libraries and packages.
#
@@ -1541,6 +1600,8 @@ src/cli/Makefile
src/ncp/Makefile
src/core/Makefile
src/diag/Makefile
src/posix/Makefile
src/posix/platform/Makefile
third_party/Makefile
third_party/mbedtls/Makefile
examples/Makefile
+6
View File
@@ -35,6 +35,7 @@ DIST_SUBDIRS = \
cli \
ncp \
diag \
posix \
$(NULL)
# Always build (e.g. for 'make all') these subdirectories.
@@ -55,12 +56,17 @@ if OPENTHREAD_ENABLE_DIAG
SUBDIRS += diag
endif
if OPENTHREAD_ENABLE_POSIX_APP
SUBDIRS += posix
endif
# Always pretty (e.g. for 'make pretty') these subdirectories.
PRETTY_SUBDIRS = \
cli \
core \
ncp \
posix \
$(NULL)
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
+5
View File
@@ -120,6 +120,11 @@ CPPFLAGS_COMMON = \
$(OPENTHREAD_TARGET_DEFINES) \
$(NULL)
if OPENTHREAD_POSIX
CPPFLAGS_COMMON += \
-DOPENTHREAD_POSIX=1 \
$(NULL)
endif
libopenthread_cli_mtd_a_CPPFLAGS = \
-DOPENTHREAD_MTD=1 \
+5 -5
View File
@@ -77,7 +77,7 @@
#include "cli_coap.hpp"
#endif
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
#include <openthread/platform/debug_uart.h>
#endif
@@ -125,10 +125,10 @@ const struct Command Interpreter::sCommands[] = {
{"eidcache", &Interpreter::ProcessEidCache},
#endif
{"eui64", &Interpreter::ProcessEui64},
#ifdef OPENTHREAD_EXAMPLES_POSIX
#if OPENTHREAD_POSIX
{"exit", &Interpreter::ProcessExit},
#endif
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
{"logfilename", &Interpreter::ProcessLogFilename},
#endif
{"extaddr", &Interpreter::ProcessExtAddress},
@@ -919,7 +919,7 @@ exit:
AppendResult(error);
}
#ifdef OPENTHREAD_EXAMPLES_POSIX
#if OPENTHREAD_POSIX
void Interpreter::ProcessExit(int argc, char *argv[])
{
exit(EXIT_SUCCESS);
@@ -928,7 +928,7 @@ void Interpreter::ProcessExit(int argc, char *argv[])
}
#endif
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
void Interpreter::ProcessLogFilename(int argc, char *argv[])
{
+2 -2
View File
@@ -215,10 +215,10 @@ private:
void ProcessEidCache(int argc, char *argv[]);
#endif
void ProcessEui64(int argc, char *argv[]);
#ifdef OPENTHREAD_EXAMPLES_POSIX
#if OPENTHREAD_POSIX
void ProcessExit(int argc, char *argv[]);
#endif
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_POSIX
void ProcessLogFilename(int argc, char *argv[]);
#endif
void ProcessExtAddress(int argc, char *argv[]);
+1 -1
View File
@@ -132,7 +132,7 @@ void Uart::ReceiveTask(const uint8_t *aBuf, uint16_t aBufLength)
break;
#ifdef OPENTHREAD_EXAMPLES_POSIX
#if OPENTHREAD_POSIX
case 0x04: // ASCII for Ctrl-D
exit(EXIT_SUCCESS);
+294
View File
@@ -0,0 +1,294 @@
#
# Copyright (c) 2016, The OpenThread Authors.
# 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.
#
# Don't allow this top-level makefile's targets to be built in parallel.
.NOTPARALLEL:
COVERAGE ?= 0
DEBUG ?= 0
ECHO := @echo
MAKE := make
MKDIR_P := mkdir -p
LN_S := ln -s
RM_F := rm -f
BuildJobs ?= 10
# If the user has asserted COVERAGE, alter the configuration options
# accordingly.
configure_OPTIONS = \
--enable-application-coap \
--enable-border-router \
--enable-cert-log \
--enable-child-supervision \
--enable-commissioner \
--enable-dhcp6-client \
--enable-dhcp6-server \
--enable-diag \
--enable-dns-client \
--enable-jam-detection \
--enable-joiner \
--enable-legacy \
--enable-mac-filter \
--enable-posix-app=all \
--enable-service \
--enable-tmf-proxy \
--with-ncp-bus=uart \
$(NULL)
TopSourceDir := $(dir $(shell readlink $(firstword $(MAKEFILE_LIST))))../..
AbsTopSourceDir := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))../..
CONFIG_FILE = OPENTHREAD_PROJECT_CORE_CONFIG_FILE='\"openthread-core-posix-config.h\"'
CONFIG_FILE_PATH = $(AbsTopSourceDir)/src/posix/platform
COMMONCFLAGS := \
-O0 \
-g \
-D$(CONFIG_FILE) \
-I$(CONFIG_FILE_PATH) \
$(NULL)
CPPFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
CFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
CXXFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
LDFLAGS += \
$(COMMONCFLAGS) \
$(NULL)
INSTALL := /usr/bin/install
INSTALLFLAGS := -p
BuildPath = build/posix
TopBuildDir = $(BuildPath)
AbsTopBuildDir = $(PWD)/$(TopBuildDir)
ResultPath = output/posix
TopResultDir = $(ResultPath)
AbsTopResultDir = $(PWD)/$(TopResultDir)
TargetTuple = $(shell ${AbsTopSourceDir}/third_party/nlbuild-autotools/repo/third_party/autoconf/config.guess | sed -e 's/[[:digit:].]*$$//g')
ifndef BuildJobs
BuildJobs := $(shell getconf _NPROCESSORS_ONLN)
endif
JOBSFLAG := -j$(BuildJobs)
#
# configure-arch <target>
#
# Configure OpenThread for the specified target.
#
# target - The target to configure.
#
define configure-target
$(ECHO) " CONFIG $(1)..."
(cd $(BuildPath)/$(1) && $(AbsTopSourceDir)/configure \
INSTALL="$(INSTALL) $(INSTALLFLAGS)" \
CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" \
--prefix=/ \
--exec-prefix=/$(1) \
$(configure_OPTIONS))
endef # configure-target
#
# build-target <target>
#
# Build the OpenThread intermediate build products for the specified
# target.
#
# target - The target to build.
#
define build-target
$(ECHO) " BUILD $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
all
endef # build-target
#
# check-target <target>
#
# Check (run unit tests) OpenThread for the specified target.
#
# target - The target to check.
#
define check-target
$(ECHO) " CHECK $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
check
endef # check-target
#
# distcheck-target <target>
#
# Check (run unit tests) OpenThread for the specified target.
#
# target - The target to distcheck.
#
define distcheck-target
$(ECHO) " DISTCHECK $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
distcheck
endef # distcheck-target
#
# coverage-target <target>
#
# Generate code coverage from unit tests for OpenThread for the
# specified target.
#
# target - The target to generate code coverage for.
#
define coverage-target
$(ECHO) " COVERAGE $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
coverage
endef # coverage-target
#
# stage-target <target>
#
# Stage (install) the OpenThread final build products for the specified
# target.
#
# target - The target to stage.
#
define stage-target
$(ECHO) " STAGE $(1)"
$(MAKE) $(JOBSFLAG) -C $(BuildPath)/$(1) --no-print-directory \
DESTDIR=$(AbsTopResultDir) \
install
endef # stage-target
#
# TARGET_template <target>
#
# Define macros, targets and rules to configure, build, and stage
# OpenThread for a single target.
#
# target - The target to instantiate the template for.
#
define TARGET_template
CONFIGURE_TARGETS += configure-$(1)
BUILD_TARGETS += do-build-$(1)
CHECK_TARGETS += check-$(1)
DISTCHECK_TARGETS += distcheck-$(1)
COVERAGE_TARGETS += coverage-$(1)
STAGE_TARGETS += stage-$(1)
BUILD_DIRS += $(BuildPath)/$(1)
DIRECTORIES += $(BuildPath)/$(1)
configure-$(1): $(BuildPath)/$(1)/config.status
$(BuildPath)/$(1)/config.status: | $(BuildPath)/$(1)
$$(call configure-target,$(1))
do-build-$(1): configure-$(1)
do-build-$(1):
+$$(call build-target,$(1))
check-$(1): do-build-$(1)
check-$(1):
+$$(call check-target,$(1))
distcheck-$(1): do-build-$(1)
distcheck-$(1):
+$$(call distcheck-target,$(1))
coverage-$(1): do-build-$(1)
coverage-$(1):
+$$(call coverage-target,$(1))
stage-$(1): do-build-$(1)
stage-$(1): | $(TopResultDir)
$$(call stage-target,$(1))
$(1): stage-$(1)
endef # TARGET_template
.DEFAULT_GOAL := all
all: stage
# Instantiate an target-specific build template for the target.
$(eval $(call TARGET_template,$(TargetTuple)))
#
# Common / Finalization
#
configure: $(CONFIGURE_TARGETS)
build: $(BUILD_TARGETS)
check: $(CHECK_TARGETS)
distcheck: $(DISTCHECK_TARGETS)
coverage: $(COVERAGE_TARGETS)
stage: $(STAGE_TARGETS)
DIRECTORIES = $(TopResultDir) $(TopResultDir)/$(TargetTuple)/lib $(BUILD_DIRS)
CLEAN_DIRS = $(TopResultDir) $(BUILD_DIRS)
all: stage
$(DIRECTORIES):
$(ECHO) " MKDIR $@"
@$(MKDIR_P) "$@"
clean:
$(ECHO) " CLEAN"
@$(RM_F) -r $(CLEAN_DIRS)
help:
$(ECHO) "Simply type 'make -f $(firstword $(MAKEFILE_LIST))' to build OpenThread for the following "
$(ECHO) "target:"
$(ECHO) ""
$(ECHO) " $(TargetTuple)"
$(ECHO) ""
+150
View File
@@ -0,0 +1,150 @@
#
# Copyright (c) 2018, The OpenThread Authors.
# 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 $(abs_top_nlbuild_autotools_dir)/automake/pre.am
# Always package (e.g. for 'make dist') these subdirectories.
DIST_SUBDIRS = \
platform \
$(NULL)
# Always build (e.g. for 'make all') these subdirectories.
SUBDIRS = \
platform \
$(NULL)
# Always pretty (e.g. for 'make pretty') these subdirectories.
PRETTY_SUBDIRS = \
platform \
$(NULL)
CPPFLAGS_COMMON = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/src/posix/platform \
-D_GNU_SOURCE \
$(NULL)
LIBTOOLFLAGS_COMMON = --preserve-dup-deps
LDADD_COMMON = \
$(top_builddir)/src/posix/platform/libopenthread-posix.a \
-lstdc++ \
-lutil \
$(NULL)
if OPENTHREAD_ENABLE_BUILTIN_MBEDTLS
LDADD_COMMON += \
$(top_builddir)/third_party/mbedtls/libmbedcrypto.a \
$(NULL)
endif # OPENTHREAD_ENABLE_BUILTIN_MBEDTLS
if OPENTHREAD_ENABLE_DIAG
LDADD_COMMON += \
$(top_builddir)/src/diag/libopenthread-diag.a \
$(NULL)
endif # OPENTHREAD_ENABLE_DIAG
bin_PROGRAMS = \
$(NULL)
if OPENTHREAD_ENABLE_POSIX_APP_NCP
bin_PROGRAMS += \
ot-ncp \
$(NULL)
endif
ot_ncp_CPPFLAGS = \
$(CPPFLAGS_COMMON) \
-DOPENTHREAD_POSIX_APP=1 \
$(NULL)
ot_ncp_SOURCES = \
main.c \
$(NULL)
ot_ncp_LDADD = \
$(top_builddir)/src/ncp/libopenthread-ncp-ftd.a \
$(top_builddir)/src/core/libopenthread-ftd.a \
$(LDADD_COMMON) \
$(top_builddir)/src/core/libopenthread-ftd.a \
$(LDADD_COMMON) \
$(NULL)
ot_ncp_LDFLAGS = \
$(LDFLAGS_COMMON) \
$(NULL)
ot_ncp_LIBTOOLFLAGS = \
$(LIBTOOLFLAGS_COMMON) \
$(NULL)
if OPENTHREAD_ENABLE_POSIX_APP_CLI
bin_PROGRAMS += \
ot-cli \
$(NULL)
endif
ot_cli_CPPFLAGS = \
$(CPPFLAGS_COMMON) \
-DOPENTHREAD_POSIX_APP=2 \
$(NULL)
ot_cli_SOURCES = \
main.c \
$(NULL)
ot_cli_LDADD = \
$(top_builddir)/src/cli/libopenthread-cli-ftd.a \
$(top_builddir)/src/core/libopenthread-ftd.a \
$(LDADD_COMMON) \
$(top_builddir)/src/core/libopenthread-ftd.a \
$(LDADD_COMMON) \
$(NULL)
ot_cli_LDFLAGS = \
$(LDFLAGS_COMMON) \
$(NULL)
ot_cli_LIBTOOLFLAGS = \
$(LIBTOOLFLAGS_COMMON) \
$(NULL)
if OPENTHREAD_ENABLE_LINKER_MAP
ot_ncp_LDFLAGS += -Wl,-Map=ot-cli-ftd.map
ot_cli_LDFLAGS += -Wl,-Map=ot-cli-mtd.map
endif
if OPENTHREAD_BUILD_COVERAGE
CLEANFILES = $(wildcard *.gcda *.gcno)
endif # OPENTHREAD_BUILD_COVERAGE
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
+108
View File
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2018, The OpenThread Authors.
* 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 <assert.h>
#include <openthread-core-config.h>
#include <openthread/config.h>
#define OPENTHREAD_POSIX_APP_NCP 1
#define OPENTHREAD_POSIX_APP_CLI 2
#include <openthread/diag.h>
#if OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_NCP
#include <openthread/ncp.h>
#elif OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_CLI
#include <openthread/cli.h>
#else
#error "Unknown posix app mode!"
#endif
#include <openthread/openthread.h>
#include <openthread/platform/logging.h>
#include "platform.h"
void otTaskletsSignalPending(otInstance *aInstance)
{
(void)aInstance;
}
int main(int argc, char *argv[])
{
otInstance *sInstance;
pseudo_reset:
PlatformInit(argc, argv);
sInstance = otInstanceInitSingle();
assert(sInstance);
#if OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_NCP
otNcpInit(sInstance);
#elif OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_CLI
otCliUartInit(sInstance);
#endif
#if OPENTHREAD_ENABLE_DIAG
otDiagInit(sInstance);
#endif
while (!PlatformPseudoResetWasRequested())
{
otTaskletsProcess(sInstance);
PlatformProcessDrivers(sInstance);
}
otInstanceFinalize(sInstance);
goto pseudo_reset;
return 0;
}
/*
* Provide, if required an "otPlatLog()" function
*/
#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
OT_UNUSED_VARIABLE(aFormat);
va_list ap;
va_start(ap, aFormat);
#if OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_NCP
otCliPlatLogv(aLogLevel, aLogRegion, aFormat, ap);
#elif OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_CLI
otNcpPlatLogv(aLogLevel, aLogRegion, aFormat, ap);
#endif
va_end(ap);
}
#endif
+75
View File
@@ -0,0 +1,75 @@
#
# Copyright (c) 2016-2018, The OpenThread Authors.
# 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 $(abs_top_nlbuild_autotools_dir)/automake/pre.am
lib_LIBRARIES = libopenthread-posix.a
libopenthread_posix_a_CPPFLAGS = \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/core \
-I$(top_srcdir)/src/ncp \
-I$(top_srcdir)/src/posix/platform \
-D_GNU_SOURCE \
$(NULL)
libopenthread_posix_a_SOURCES = \
alarm.c \
diag.c \
flash.c \
frame_queue.cpp \
hdlc.cpp \
logging.c \
misc.c \
platform.c \
radio_spinel.cpp \
random.c \
settings.cpp \
spi-stubs.c \
spinel.c \
uart.c \
$(NULL)
noinst_HEADERS = \
flash.h \
frame_queue.hpp \
platform.h \
platform-posix.h \
radio_spinel.hpp \
$(NULL)
PRETTY_FILES = \
$(libopenthread_posix_a_SOURCES) \
$(noinst_HEADERS) \
$(NULL)
if OPENTHREAD_BUILD_COVERAGE
CLEANFILES = $(wildcard *.gcda *.gcno)
endif # OPENTHREAD_BUILD_COVERAGE
include $(abs_top_nlbuild_autotools_dir)/automake/post.am
+59
View File
@@ -0,0 +1,59 @@
# OpenThread on POSIX
This directory contains platform drivers for POSIX with an external radio tranceiver.
## Build
```bash
$ cd <path-to-openthread>
$ ./bootstrap
$ make -f src/posix/Makefile-posix
```
After a successful build, the `elf` files are found in
`<path-to-openthread>/output/posix/<platform>/bin`.
##
## Interact
1. Spawn the process:
`stty` is required.
```bash
$ cd <path-to-openthread>/output/<platform>/bin
$ ./ot-cli /dev/ttyUSB0 115200
```
2. Type `help` for list of commands.
```bash
> help
help
channel
childtimeout
contextreusedelay
extaddr
extpanid
ipaddr
keysequence
leaderweight
masterkey
mode
netdataregister
networkidtimeout
networkname
panid
ping
prefix
releaserouterid
rloc16
route
routerupgradethreshold
scan
start
state
stop
whitelist
```
+195
View File
@@ -0,0 +1,195 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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 "platform-posix.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <openthread/platform/alarm-micro.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/diag.h>
#define MS_PER_S 1000
#define US_PER_MS 1000
#define US_PER_S 1000000
#define DEFAULT_TIMEOUT 10 // seconds
static bool sIsMsRunning = false;
static uint32_t sMsAlarm = 0;
static bool sIsUsRunning = false;
static uint32_t sUsAlarm = 0;
static uint32_t sSpeedUpFactor = 1;
static struct timeval sStart;
void platformAlarmInit(uint32_t aSpeedUpFactor)
{
sSpeedUpFactor = aSpeedUpFactor;
gettimeofday(&sStart, NULL);
}
uint32_t otPlatAlarmMilliGetNow(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
timersub(&tv, &sStart, &tv);
return (uint32_t)(((uint64_t)tv.tv_sec * sSpeedUpFactor * MS_PER_S) +
((uint64_t)tv.tv_usec * sSpeedUpFactor / US_PER_MS));
}
void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
(void)aInstance;
sMsAlarm = aT0 + aDt;
sIsMsRunning = true;
}
void otPlatAlarmMilliStop(otInstance *aInstance)
{
(void)aInstance;
sIsMsRunning = false;
}
uint32_t otPlatAlarmMicroGetNow(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
timersub(&tv, &sStart, &tv);
return (uint32_t)(tv.tv_sec * US_PER_S + tv.tv_usec) * sSpeedUpFactor;
}
void otPlatAlarmMicroStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt)
{
(void)aInstance;
sUsAlarm = aT0 + aDt;
sIsUsRunning = true;
}
void otPlatAlarmMicroStop(otInstance *aInstance)
{
(void)aInstance;
sIsUsRunning = false;
}
void platformAlarmUpdateTimeout(struct timeval *aTimeout)
{
int32_t usRemaining = DEFAULT_TIMEOUT * US_PER_S;
int32_t msRemaining = DEFAULT_TIMEOUT * MS_PER_S;
if (aTimeout == NULL)
{
return;
}
if (sIsUsRunning)
{
usRemaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
}
if (sIsMsRunning)
{
msRemaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
}
if (usRemaining <= 0 || msRemaining <= 0)
{
aTimeout->tv_sec = 0;
aTimeout->tv_usec = 0;
}
else
{
int64_t remaining = ((int64_t)msRemaining) * US_PER_MS;
if (usRemaining < remaining)
{
remaining = usRemaining;
}
remaining /= sSpeedUpFactor;
if (remaining == 0)
{
remaining = 1;
}
aTimeout->tv_sec = (time_t)remaining / US_PER_S;
aTimeout->tv_usec = remaining % US_PER_S;
}
}
void platformAlarmProcess(otInstance *aInstance)
{
int32_t remaining;
if (sIsMsRunning)
{
remaining = (int32_t)(sMsAlarm - otPlatAlarmMilliGetNow());
if (remaining <= 0)
{
sIsMsRunning = false;
#if OPENTHREAD_ENABLE_DIAG
if (otPlatDiagModeGet())
{
otPlatDiagAlarmFired(aInstance);
}
else
#endif
{
otPlatAlarmMilliFired(aInstance);
}
}
}
#if OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
if (sIsUsRunning)
{
remaining = (int32_t)(sUsAlarm - otPlatAlarmMicroGetNow());
if (remaining <= 0)
{
sIsUsRunning = false;
otPlatAlarmMicroFired(aInstance);
}
}
#endif // OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
}
+92
View File
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file includes macros for validating runtime conditions.
*/
#ifndef CODE_UTILS_H
#define CODE_UTILS_H
/**
* This checks for the specified condition, which is expected to
* commonly be true, and branches to the local label 'exit' if the
* condition is false.
*
* @param[in] aCondition A Boolean expression to be evaluated.
*
*/
#define otEXPECT(aCondition) \
do \
{ \
if (!(aCondition)) \
{ \
goto exit; \
} \
} while (0)
/**
* This checks for the specified condition, which is expected to
* commonly be true, and both executes @p anAction and branches to
* the local label 'exit' if the condition is false.
*
* @param[in] aCondition A Boolean expression to be evaluated.
* @param[in] aAction An expression or block to execute when the
* assertion fails.
*
*/
#define otEXPECT_ACTION(aCondition, aAction) \
do \
{ \
if (!(aCondition)) \
{ \
aAction; \
goto exit; \
} \
} while (0)
/**
* This unconditionally executes @aAction and branches to the local
* label 'exit'.
*
* @note The use of this interface implies neither success nor
* failure for the overall exit status of the enclosing
* function body.
*
* @param[in] aAction An expression or block to execute.
*
*/
#define otEXIT_NOW(aAction) \
do \
{ \
aAction; \
goto exit; \
} while (0)
#endif // CODE_UTILS_H
+149
View File
@@ -0,0 +1,149 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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 <openthread-core-config.h>
#include <stdarg.h>
#include <stdio.h>
#include <openthread/config.h>
#include <openthread/types.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/debug_uart.h>
#include <openthread/platform/toolchain.h>
/*
* Implementation note:
* These are all "weak" so that a platform may if it chooses override the instance.
*/
OT_TOOL_WEAK
void otPlatDebugUart_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
otPlatDebugUart_vprintf(fmt, ap);
va_end(ap);
}
OT_TOOL_WEAK
void otPlatDebugUart_vprintf(const char *fmt, va_list ap)
{
char buf[128];
/* by standard ...
* vsnprintf() always null terminates
*/
vsnprintf(buf, sizeof(buf), fmt, ap);
/* however ... some platforms have bugs */
buf[sizeof(buf) - 1] = 0;
otPlatDebugUart_puts_no_nl(buf);
}
OT_TOOL_WEAK
void otPlatDebugUart_write_bytes(const uint8_t *pBytes, int nBytes)
{
while (nBytes > 0)
{
otPlatDebugUart_putchar((int)(*pBytes));
pBytes++;
nBytes--;
}
}
OT_TOOL_WEAK
void otPlatDebugUart_puts_no_nl(const char *s)
{
while (*s)
{
otPlatDebugUart_putchar(*s);
s++;
}
}
OT_TOOL_WEAK
void otPlatDebugUart_puts(const char *s)
{
otPlatDebugUart_puts_no_nl(s);
otPlatDebugUart_putchar('\n');
}
OT_TOOL_WEAK
void otPlatDebugUart_putchar(int c)
{
/* map lf to crlf as needed */
if (c == '\n')
{
otPlatDebugUart_putchar_raw('\r');
}
otPlatDebugUart_putchar_raw(c);
}
/* provide WEAK stubs for platforms that do not implement all functions */
OT_TOOL_WEAK
void otPlatDebugUart_putchar_raw(int c)
{
OT_UNUSED_VARIABLE(c);
}
OT_TOOL_WEAK
int otPlatDebugUart_kbhit(void)
{
return 0; /* nothing */
}
OT_TOOL_WEAK
int otPlatDebugUart_getc(void)
{
return -1; /* nothing */
}
OT_TOOL_WEAK
otError otPlatDebugUart_logfile(const char *filename)
{
OT_UNUSED_VARIABLE(filename);
return OT_ERROR_FAILED;
}
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART)
/* this should not be a WEAK function */
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
va_list ap;
uint32_t now;
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
now = otPlatAlarmMilliGetNow();
otPlatDebugUart_printf("%3d.%03d | ", (int)(now / 1000), (int)(now % 1000));
va_start(ap, aFormat);
otPlatDebugUart_vprintf(aFormat, ap);
va_end(ap);
otPlatDebugUart_putchar('\n');
}
#endif
+89
View File
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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 "platform-posix.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <openthread/config.h>
#include <openthread/openthread.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>
#if OPENTHREAD_ENABLE_DIAG
/**
* Diagnostics mode variables.
*
*/
static bool sDiagMode = false;
void otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
// Add more plarform specific diagnostics features here.
snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
(void)argc;
(void)aInstance;
}
void otPlatDiagModeSet(bool aMode)
{
sDiagMode = aMode;
}
bool otPlatDiagModeGet()
{
return sDiagMode;
}
void otPlatDiagChannelSet(uint8_t aChannel)
{
(void)aChannel;
}
void otPlatDiagTxPowerSet(int8_t aTxPower)
{
(void)aTxPower;
}
void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
{
(void)aInstance;
(void)aFrame;
(void)aError;
}
void otPlatDiagAlarmCallback(otInstance *aInstance)
{
(void)aInstance;
}
#endif // OPENTHREAD_ENABLE_DIAG
+163
View File
@@ -0,0 +1,163 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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 "platform-posix.h"
#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <openthread/config.h>
#include "code_utils.h"
#include "flash.h"
static int sFlashFd = -1;
uint32_t sEraseAddress;
enum
{
FLASH_SIZE = 0x40000,
FLASH_PAGE_SIZE = 0x800,
FLASH_PAGE_NUM = 128,
};
otError utilsFlashInit(void)
{
otError error = OT_ERROR_NONE;
char fileName[32];
struct stat st;
bool create = false;
const char *offset = getenv("PORT_OFFSET");
memset(&st, 0, sizeof(st));
if (stat("tmp", &st) == -1)
{
mkdir("tmp", 0777);
}
if (offset == NULL)
{
offset = "0";
}
snprintf(fileName, sizeof(fileName), "tmp/%s_%" PRIx64 ".flash", offset, NODE_ID);
if (access(fileName, 0))
{
create = true;
}
sFlashFd = open(fileName, O_RDWR | O_CREAT, 0666);
lseek(sFlashFd, 0, SEEK_SET);
otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED);
if (create)
{
for (uint16_t index = 0; index < FLASH_PAGE_NUM; index++)
{
error = utilsFlashErasePage(index * FLASH_PAGE_SIZE);
otEXPECT(error == OT_ERROR_NONE);
}
}
exit:
return error;
}
uint32_t utilsFlashGetSize(void)
{
return FLASH_SIZE;
}
otError utilsFlashErasePage(uint32_t aAddress)
{
otError error = OT_ERROR_NONE;
uint32_t address;
uint8_t dummyPage[FLASH_SIZE];
otEXPECT_ACTION(sFlashFd >= 0, error = OT_ERROR_FAILED);
otEXPECT_ACTION(aAddress < FLASH_SIZE, error = OT_ERROR_INVALID_ARGS);
// Get start address of the flash page that includes aAddress
address = aAddress & (~(uint32_t)(FLASH_PAGE_SIZE - 1));
// set the page to the erased state.
memset((void *)(&dummyPage[0]), 0xff, FLASH_PAGE_SIZE);
// Write the page
ssize_t r;
r = pwrite(sFlashFd, &(dummyPage[0]), FLASH_PAGE_SIZE, (off_t)address);
otEXPECT_ACTION(((int)r) == ((int)(FLASH_PAGE_SIZE)), error = OT_ERROR_FAILED);
exit:
return error;
}
otError utilsFlashStatusWait(uint32_t aTimeout)
{
(void)aTimeout;
return OT_ERROR_NONE;
}
uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t ret = 0;
uint32_t index = 0;
uint8_t byte;
otEXPECT(sFlashFd >= 0 && aAddress < FLASH_SIZE);
for (index = 0; index < aSize; index++)
{
otEXPECT((ret = utilsFlashRead(aAddress + index, &byte, 1)) == 1);
// Use bitwise AND to emulate the behavior of flash memory
byte &= aData[index];
otEXPECT((ret = (uint32_t)pwrite(sFlashFd, &byte, 1, (off_t)(aAddress + index))) == 1);
}
exit:
return index;
}
uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t ret = 0;
otEXPECT(sFlashFd >= 0 && aAddress < FLASH_SIZE);
ret = (uint32_t)pread(sFlashFd, aData, aSize, (off_t)aAddress);
exit:
return ret;
}
+129
View File
@@ -0,0 +1,129 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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.
*/
/**
* @file
* @brief
* This file defines the flash interface used by settings.cpp.
*/
#ifndef UTILS_FLASH_H
#define UTILS_FLASH_H
#include <stdint.h>
#include <openthread/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Perform any initialization for flash driver.
*
* @retval ::OT_ERROR_NONE Initialize flash driver success.
* @retval ::OT_ERROR_FAILED Initialize flash driver fail.
*/
otError utilsFlashInit(void);
/**
* Get the size of flash that can be read/write by the caller.
* The usable flash size is always the multiple of flash page size.
*
* @returns The size of the flash.
*/
uint32_t utilsFlashGetSize(void);
/**
* Erase one flash page that include the input address.
* This is a non-blocking function. It can work with utilsFlashStatusWait to check when erase is done.
*
* The flash address starts from 0, and this function maps the input address to the physical address of flash for
* erasing. 0 is always mapped to the beginning of one flash page. The input address should never be mapped to the
* firmware space or any other protected flash space.
*
* @param[in] aAddress The start address of the flash to erase.
*
* @retval OT_ERROR_NONE Erase flash operation is started.
* @retval OT_ERROR_FAILED Erase flash operation is not started.
* @retval OT_ERROR_INVALID_ARGS aAddress is out of range of flash or not aligend.
*/
otError utilsFlashErasePage(uint32_t aAddress);
/**
* Check whether flash is ready or busy.
*
* @param[in] aTimeout The interval in milliseconds waiting for the flash operation to be done and become ready again.
* zero indicates that it is a polling function, and returns current status of flash immediately.
* non-zero indicates that it is blocking there until the operation is done and become ready, or
* timeout expires.
*
* @retval OT_ERROR_NONE Flash is ready for any operation.
* @retval OT_ERROR_BUSY Flash is busy.
*/
otError utilsFlashStatusWait(uint32_t aTimeout);
/**
* Write flash. The write operation only clears bits, but never set bits.
*
* The flash address starts from 0, and this function maps the input address to the physical address of flash for
* writing. 0 is always mapped to the beginning of one flash page. The input address should never be mapped to the
* firmware space or any other protected flash space.
*
* @param[in] aAddress The start address of the flash to write.
* @param[in] aData The pointer of the data to write.
* @param[in] aSize The size of the data to write.
*
* @returns The actual size of octets write to flash.
* It is expected the same as aSize, and may be less than aSize.
* 0 indicates that something wrong happens when writing.
*/
uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize);
/**
* Read flash.
*
* The flash address starts from 0, and this function maps the input address to the physical address of flash for
* reading. 0 is always mapped to the beginning of one flash page. The input address should never be mapped to the
* firmware space or any other protected flash space.
*
* @param[in] aAddress The start address of the flash to read.
* @param[Out] aData The pointer of buffer for reading.
* @param[in] aSize The size of the data to read.
*
* @returns The actual size of octets read to buffer.
* It is expected the same as aSize, and may be less than aSize.
* 0 indicates that something wrong happens when reading.
*/
uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // UTILS_FLASH_H
+239
View File
@@ -0,0 +1,239 @@
/*
* Copyright (c) 2018, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file includes implementation of frame queue.
*/
#include "platform-posix.h"
#include "frame_queue.hpp"
#include <assert.h>
#include <string.h>
#include "code_utils.h"
namespace ot {
otError FrameQueue::Push(const uint8_t *aFrame, uint8_t aLength)
{
otError error = OT_ERROR_NONE;
uint16_t newTail = mTail + aLength + 1;
assert(aFrame != NULL);
otEXPECT_ACTION(aFrame != NULL, error = OT_ERROR_INVALID_ARGS);
if (mHead > mTail)
{
otEXPECT_ACTION(newTail < mHead, error = OT_ERROR_NO_BUFS);
}
else if (newTail >= sizeof(mBuffer))
{
newTail -= sizeof(mBuffer);
otEXPECT_ACTION(newTail < mHead, error = OT_ERROR_NO_BUFS);
}
mBuffer[mTail] = aLength;
if (newTail > mTail)
{
memcpy(mBuffer + mTail + 1, aFrame, aLength);
}
else
{
uint16_t half = (sizeof(mBuffer) - mTail - 1);
memcpy(mBuffer + mTail + 1, aFrame, half);
memcpy(mBuffer, aFrame + half, (aLength - half));
}
mTail = newTail;
exit:
return error;
}
void FrameQueue::Shift(void)
{
if (mHead != mTail)
{
mHead += 1 + mBuffer[mHead];
mHead %= sizeof(mBuffer);
}
}
const uint8_t *FrameQueue::Peek(uint8_t *aFrame, uint8_t &aLength)
{
const uint8_t *frame = NULL;
uint16_t next;
otEXPECT(mHead != mTail);
aLength = mBuffer[mHead];
next = mHead + 1 + aLength;
if (next >= sizeof(mBuffer))
{
uint16_t half = sizeof(mBuffer) - mHead - 1;
memcpy(aFrame, mBuffer + mHead + 1, half);
memcpy(aFrame + half, mBuffer, aLength - half);
frame = aFrame;
}
else
{
frame = mBuffer + mHead + 1;
}
exit:
return frame;
}
} // namespace ot
#if SELF_TEST
#include <stdlib.h>
void TestSingle()
{
otError error;
ot::FrameQueue frameQueue;
uint8_t length;
uint8_t frame[255];
for (size_t i = 0; i < sizeof(frame); ++i)
{
frame[i] = i;
}
for (size_t i = 0; i < sizeof(frame); ++i)
{
uint8_t outFrame[255];
const uint8_t *retFrame = NULL;
error = frameQueue.Push(frame, i);
assert(OT_ERROR_NONE == error);
assert(!frameQueue.IsEmpty());
retFrame = frameQueue.Peek(outFrame, length);
assert(retFrame != NULL);
assert(length == i);
for (size_t j = 0; j < i; ++j)
{
assert(retFrame[j] == frame[j]);
}
frameQueue.Shift();
assert(frameQueue.IsEmpty());
}
}
void TestMultiple()
{
otError error;
ot::FrameQueue frameQueue;
uint8_t length;
uint8_t frame[255];
for (size_t i = 0; i < sizeof(frame); ++i)
{
frame[i] = i;
}
srand(0);
for (size_t i = 0; i < sizeof(frame); ++i)
{
uint8_t outFrame[255];
const uint8_t *retFrame = NULL;
int action = rand();
if (action & 0x01) // push when odd
{
error = frameQueue.Push(frame, i);
if (error == OT_ERROR_NO_BUFS)
continue;
assert(OT_ERROR_NONE == error);
assert(!frameQueue.IsEmpty());
retFrame = frameQueue.Peek(outFrame, length);
assert(retFrame != NULL);
for (size_t j = 0; j < length; ++j)
{
assert(retFrame[j] == frame[j]);
}
}
else
{
frameQueue.Shift();
}
}
}
void TestRing()
{
ot::FrameQueue frameQueue;
uint8_t length;
uint8_t frame[255];
for (size_t i = 0; i < sizeof(frame); ++i)
{
frame[i] = i;
}
for (size_t i = 0; i < OPENTHREAD_CONFIG_FRAME_CACHE_SIZE + 255; i += sizeof(frame))
{
uint8_t outFrame[255];
const uint8_t *retFrame = NULL;
frameQueue.Push(frame, sizeof(frame));
retFrame = frameQueue.Peek(outFrame, length);
for (size_t j = 0; j < sizeof(frame); ++j)
{
assert(retFrame[j] == frame[j]);
}
frameQueue.Shift();
};
}
void RunAllTests()
{
TestSingle();
TestMultiple();
TestRing();
}
int main(void)
{
RunAllTests();
printf("All tests passed\n");
return 0;
}
#endif
+117
View File
@@ -0,0 +1,117 @@
/*
* Copyright (c) 2018, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file includes definitions for frame queue.
*/
#ifndef OT_FRAME_QUEUE_HPP_
#define OT_FRAME_QUEUE_HPP_
#include <stdint.h>
/**
* @def OPENTHREAD_CONFIG_FRAME_QUEUE_SIZE
*
* The size of a frame queue in bytes.
*
*/
#ifndef OPENTHREAD_CONFIG_FRAME_QUEUE_SIZE
#define OPENTHREAD_CONFIG_FRAME_QUEUE_SIZE 4096
#endif
namespace ot {
class FrameQueue
{
public:
/**
* This constructor initializes a frame queue based on ring buffer.
*
*/
FrameQueue(void)
: mHead(0)
, mTail(0)
{
}
/**
* This method checks if the cache is empty.
*
* @retval true No frames are queued.
* @retval false At least one frame is queued.
*
*/
bool IsEmpty(void) const { return mHead == mTail; }
/**
* This method removes one frame from the head.
*
*/
void Shift(void);
/**
* This method pushes one frame into the queue.
*
* @param[in] aFrame A pointer to a spinel frame to be queued.
* @param[in] aLength Frame length in bytes.
*
* @retval OT_ERROR_NONE Successfully queued this frame.
* @retval OT_ERROR_NO_BUFS Insufficient memory for this frame.
*
*/
otError Push(const uint8_t *aFrame, uint8_t aLength);
/**
* This method gets one frame at head.
*
* @note aFrame is only used when necessary, always use the returned pointer to access frame data.
*
* @param[out] aFrame A pointer to the frame to receive the data.
* @param[out] aLength A reference to receive the frame length.
*
* @return A pointer to the frame.
*
*/
const uint8_t *Peek(uint8_t *aFrame, uint8_t &aLength);
private:
enum
{
kQueueSize = OPENTHREAD_CONFIG_FRAME_QUEUE_SIZE,
};
uint8_t mBuffer[kQueueSize];
uint16_t mHead;
uint16_t mTail;
};
} // namespace ot
#endif // OT_FRAME_CACHE_HPP_
+1
View File
@@ -0,0 +1 @@
../../ncp/hdlc.cpp
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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 "platform-posix.h"
#include <openthread-core-config.h>
#include <openthread/config.h>
#include <ctype.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <openthread/platform/logging.h>
#include "code_utils.h"
// Macro to append content to end of the log string.
#define LOG_PRINTF(...) \
charsWritten = snprintf(&logString[offset], sizeof(logString) - offset, __VA_ARGS__); \
otEXPECT_ACTION(charsWritten >= 0, logString[offset] = 0); \
offset += (unsigned int)charsWritten; \
otEXPECT_ACTION(offset < sizeof(logString), logString[sizeof(logString) - 1] = 0)
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) || \
(OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NCP_SPINEL)
OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
char logString[512];
unsigned int offset;
int charsWritten;
va_list args;
offset = 0;
LOG_PRINTF("[%" PRIx64 "] ", NODE_ID);
va_start(args, aFormat);
charsWritten = vsnprintf(&logString[offset], sizeof(logString) - offset, aFormat, args);
va_end(args);
otEXPECT_ACTION(charsWritten >= 0, logString[offset] = 0);
exit:
#ifndef _WIN32
syslog(LOG_CRIT, "%s", logString);
#else
printf("%s\r\n", logString);
#endif
(void)aLogLevel;
(void)aLogRegion;
}
#endif // #if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
+112
View File
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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 "platform-posix.h"
#include <unistd.h>
#include <openthread/types.h>
#include <openthread/platform/misc.h>
#include "platform.h"
extern int gArgumentsCount;
extern char **gArguments;
static otPlatResetReason sPlatResetReason = OT_PLAT_RESET_REASON_POWER_ON;
bool gPlatformPseudoResetWasRequested;
static otPlatMcuPowerState gPlatMcuPowerState = OT_PLAT_MCU_POWER_STATE_ON;
void otPlatReset(otInstance *aInstance)
{
#if OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
gPlatformPseudoResetWasRequested = true;
sPlatResetReason = OT_PLAT_RESET_REASON_SOFTWARE;
#else // elif OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
// Restart the process using execvp.
char *argv[gArgumentsCount + 1];
for (int i = 0; i < gArgumentsCount; ++i)
{
argv[i] = gArguments[i];
}
argv[gArgumentsCount] = NULL;
PlatformDeinit();
platformUartRestore();
alarm(0);
execvp(argv[0], argv);
perror("reset failed");
exit(EXIT_FAILURE);
#endif // else OPENTHREAD_PLATFORM_USE_PSEUDO_RESET
(void)aInstance;
}
otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
{
(void)aInstance;
return sPlatResetReason;
}
void otPlatWakeHost(void)
{
// TODO: implement an operation to wake the host from sleep state.
}
otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState)
{
otError error = OT_ERROR_NONE;
(void)aInstance;
switch (aState)
{
case OT_PLAT_MCU_POWER_STATE_ON:
case OT_PLAT_MCU_POWER_STATE_LOW_POWER:
gPlatMcuPowerState = aState;
break;
default:
error = OT_ERROR_FAILED;
break;
}
return error;
}
otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance)
{
(void)aInstance;
return gPlatMcuPowerState;
}
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2017, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file includes posix compile-time configuration constants
* for OpenThread.
*/
#ifndef OPENTHREAD_CORE_POSIX_CONFIG_H_
#define OPENTHREAD_CORE_POSIX_CONFIG_H_
/**
* @def OPENTHREAD_CONFIG_PLATFORM_INFO
*
* The platform-specific string to insert into the OpenThread version string.
*
*/
#define OPENTHREAD_CONFIG_PLATFORM_INFO "POSIX"
/**
* @def OPENTHREAD_CONFIG_LOG_OUTPUT
*
* Specify where the log output should go.
*
*/
#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */
#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
#endif
#if OPENTHREAD_RADIO
/**
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT
*
* Define to 1 if you want to enable software ACK timeout logic.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT 1
/**
* @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT
*
* Define to 1 if you want to enable software retransmission logic.
*
* Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_ENABLE_RAW_LINK_API` is set).
*
*/
#define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT 1
#endif // OPENTHREAD_RADIO
/**
* @def OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER
*
* Define to 1 if you want to support microsecond timer in platform.
*
*/
#define OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER 1
#endif // OPENTHREAD_CORE_POSIX_CONFIG_H_
+213
View File
@@ -0,0 +1,213 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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.
*/
/**
* @file
* @brief
* This file includes the (posix or windows) platform-specific initializers.
*/
#ifndef PLATFORM_POSIX_H_
#define PLATFORM_POSIX_H_
#include <openthread-core-config.h>
#include <openthread/config.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <poll.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <openthread/openthread.h>
#include "openthread-core-config.h"
enum
{
OT_SIM_EVENT_ALARM_FIRED = 0,
OT_SIM_EVENT_RADIO_RECEIVED = 1,
OT_EVENT_DATA_MAX_SIZE = 1024,
};
OT_TOOL_PACKED_BEGIN
struct Event
{
uint64_t mDelay;
uint8_t mEvent;
uint16_t mDataLength;
uint8_t mData[OT_EVENT_DATA_MAX_SIZE];
} OT_TOOL_PACKED_END;
/**
* Unique node ID.
*
*/
extern uint64_t NODE_ID;
/**
* Well-known Unique ID used by a simulated radio that supports promiscuous mode.
*
*/
#define WELLKNOWN_NODE_ID 34
/**
* This function initializes the alarm service used by OpenThread.
*
*/
void platformAlarmInit(uint32_t aSpeedUpFactor);
/**
* This function retrieves the time remaining until the alarm fires.
*
* @param[out] aTimeval A pointer to the timeval struct.
*
*/
void platformAlarmUpdateTimeout(struct timeval *tv);
/**
* This function performs alarm driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void platformAlarmProcess(otInstance *aInstance);
/**
* This function returns the next alarm event time.
*
* @returns The next alarm fire time.
*
*/
int32_t platformAlarmGetNext(void);
/**
* This function returns the current alarm time.
*
* @returns The current alarm time.
*
*/
uint64_t platformAlarmGetNow(void);
/**
* This function advances the alarm time by @p aDelta.
*
* @param[in] aDelta The amount of time to advance.
*
*/
void platformAlarmAdvanceNow(uint64_t aDelta);
/**
* This function initializes the radio service used by OpenThread.
*
* @param[in] aRadioFile A pointer to the radio file.
* @param[in] aRadioConfig A pointer to the radio config.
*
*/
void platformRadioInit(const char *aRadioFile, const char *aRadioConfig);
/**
* This function shuts down the radio service used by OpenThread.
*
*/
void platformRadioDeinit(void);
/**
* This function inputs a received radio frame.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aBuf A pointer to the received radio frame.
* @param[in] aBufLength The size of the received radio frame.
*
*/
void platformRadioReceive(otInstance *aInstance, uint8_t *aBuf, uint16_t aBufLength);
/**
* This function updates the file descriptor sets with file descriptors used by the radio driver.
*
* @param[inout] aReadFdSet A pointer to the read file descriptors.
* @param[inout] aWriteFdSet A pointer to the write file descriptors.
* @param[inout] aMaxFd A pointer to the max file descriptor.
* @param[inout] aTimeout A pointer to the timeout.
*
*/
void platformRadioUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, int *aMaxFd, struct timeval *aTimeout);
/**
* This function performs radio driver processing.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aReadFdSet A pointer to the read file descriptors.
* @param[in] aWriteFdSet A pointer to the write file descriptors.
*
*/
void platformRadioProcess(otInstance *aInstance, fd_set *aReadFdSet, fd_set *aWriteFdSet);
/**
* This function initializes the random number service used by OpenThread.
*
*/
void platformRandomInit(void);
/**
* This function updates the file descriptor sets with file descriptors used by the UART driver.
*
* @param[inout] aReadFdSet A pointer to the read file descriptors.
* @param[inout] aWriteFdSet A pointer to the write file descriptors.
* @param[inout] aMaxFd A pointer to the max file descriptor.
*
*/
void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd);
/**
* This function performs radio driver processing.
*
* @param[in] aReadFdSet A pointer to the read file descriptors.
* @param[in] aWriteFdSet A pointer to the write file descriptors.
* @param[in] aErrorFdSet A pointer to the error file descriptors.
*
*/
void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet);
/**
* This function restores the Uart.
*
*/
void platformUartRestore(void);
#endif // PLATFORM_POSIX_H_
+162
View File
@@ -0,0 +1,162 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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.
*/
/**
* @file
* @brief
* This file includes the platform-specific initializers.
*/
#include "platform-posix.h"
#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <openthread/openthread.h>
#include <openthread/tasklet.h>
#include <openthread/platform/alarm-milli.h>
uint64_t NODE_ID = 0;
extern bool gPlatformPseudoResetWasRequested;
int gArgumentsCount = 0;
char **gArguments = NULL;
void PrintUsage(const char *aArg0)
{
fprintf(stderr, "Syntax:\n %s [-s TimeSpeedUpFactor] {NodeId|Device DeviceConfig|Command CommandArgs}\n", aArg0);
exit(EXIT_FAILURE);
}
void PlatformInit(int aArgCount, char *aArgVector[])
{
int i;
uint32_t speedUpFactor = 1;
char * endptr;
const char *radioFile = NULL;
const char *radioConfig = "";
if (gPlatformPseudoResetWasRequested)
{
gPlatformPseudoResetWasRequested = false;
return;
}
if (aArgCount < 2)
{
PrintUsage(aArgVector[0]);
}
i = 1;
if (!strcmp(aArgVector[i], "-s"))
{
++i;
speedUpFactor = (uint32_t)strtol(aArgVector[i], &endptr, 0);
if (*endptr != '\0' || speedUpFactor == 0)
{
fprintf(stderr, "Invalid value for TimerSpeedUpFactor: %s\n", aArgVector[i]);
exit(EXIT_FAILURE);
}
++i;
}
if (i >= aArgCount)
{
PrintUsage(aArgVector[0]);
}
radioFile = aArgVector[i];
if (i + 1 < aArgCount)
{
radioConfig = aArgVector[i + 1];
}
openlog(basename(aArgVector[0]), LOG_PID, LOG_USER);
setlogmask(setlogmask(0) & LOG_UPTO(LOG_NOTICE));
gArgumentsCount = aArgCount;
gArguments = aArgVector;
platformAlarmInit(speedUpFactor);
platformRadioInit(radioFile, radioConfig);
platformRandomInit();
}
bool PlatformPseudoResetWasRequested(void)
{
return gPlatformPseudoResetWasRequested;
}
void PlatformDeinit(void)
{
platformRadioDeinit();
}
void PlatformProcessDrivers(otInstance *aInstance)
{
fd_set read_fds;
fd_set write_fds;
fd_set error_fds;
struct timeval timeout;
int max_fd = -1;
int rval;
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&error_fds);
platformAlarmUpdateTimeout(&timeout);
platformUartUpdateFdSet(&read_fds, &write_fds, &error_fds, &max_fd);
platformRadioUpdateFdSet(&read_fds, &write_fds, &max_fd, &timeout);
if (otTaskletsArePending(aInstance))
{
timeout.tv_sec = 0;
timeout.tv_usec = 0;
}
rval = select(max_fd + 1, &read_fds, &write_fds, &error_fds, &timeout);
if ((rval < 0) && (errno != EINTR))
{
perror("select");
exit(EXIT_FAILURE);
}
platformUartProcess(&read_fds, &write_fds, &error_fds);
platformRadioProcess(aInstance, &read_fds, &write_fds);
platformAlarmProcess(aInstance);
}
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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.
*/
/**
* @file
* @brief
* This file defines the platform-specific initializers.
*/
#ifndef PLATFORM_H_
#define PLATFORM_H_
#include <openthread/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* This function performs all platform-specific initialization.
*
*/
void PlatformInit(int argc, char *argv[]);
/**
* This function performs all platform-specific deinitialization.
*
*/
void PlatformDeinit(void);
/**
* This function returns true is a pseudo-reset was requested.
* In such a case, the main loop should shut down and re-initialize
* the OpenThread instance.
*
*/
bool PlatformPseudoResetWasRequested(void);
/**
* This function performs all platform-specific processing.
*
* @param[in] aInstance The OpenThread instance structure.
*
*/
void PlatformProcessDrivers(otInstance *aInstance);
/**
* This function is called whenever platform drivers needs processing.
*
*/
extern void PlatformEventSignalPending(void);
#ifdef __cplusplus
} // end of extern "C"
#endif
#endif // PLATFORM_H_
File diff suppressed because it is too large Load Diff
+492
View File
@@ -0,0 +1,492 @@
/*
* Copyright (c) 2018, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file includes definitions for the spinel based radio transceiver.
*/
#ifndef RADIO_SPINEL_HPP_
#define RADIO_SPINEL_HPP_
#include "frame_queue.hpp"
#include "hdlc.hpp"
#include "spinel.h"
namespace ot {
class RadioSpinel
{
public:
/**
* This constructor initializes the spinel based OpenThread transceiver.
*
*/
RadioSpinel(void);
/**
* Initialize this radio transceiver.
*
* @param[in] aRadioFile The path to either a uart device or an executable.
* @param[in] aRadioConfig Parameters given to the device or executable.
*
*/
void Init(const char *aRadioFile, const char *aRadioConfig);
/**
* Deinitialize this radio transceiver.
*
*/
void Deinit(void);
/**
* This method gets the status of promiscuous mode.
*
* @retval true Promiscuous mode is enabled.
* @retval false Promiscuous mode is disabled.
*
*/
bool GetPromiscuous(void) const { return mPromiscuous; }
/**
* This method sets the status of promiscuous mode.
*
* @param[in] aEnable Whether to enable or disable promiscuous mode.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetPromiscuous(bool aEnable);
/**
* This method sets the Short Address for address filtering.
*
* @param[in] aShortAddress The IEEE 802.15.4 Short Address.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetShortAddress(uint16_t aAddress);
/**
* This method gets the factory-assigned IEEE EUI-64 for this transceiver.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[out] aIeeeEui64 A pointer to the factory-assigned IEEE EUI-64.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetIeeeEui64(uint8_t *aIeeeEui64);
/**
* This method sets the Extended Address for address filtering.
*
* @param[in] aExtAddress A pointer to the IEEE 802.15.4 Extended Address stored in little-endian byte order.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetExtendedAddress(const otExtAddress &aAddress);
/**
* This method sets the PAN ID for address filtering.
*
* @param[in] aPanId The IEEE 802.15.4 PAN ID.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetPanId(uint16_t aPanId);
/**
* This method gets the radio's transmit power in dBm.
*
* @param[out] aPower The transmit power in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError GetTransmitPower(int8_t &aPower);
/**
* This method sets the radio's transmit power in dBm.
*
* @param[in] aPower The transmit power in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError SetTransmitPower(int8_t aPower);
/**
* This method returns the radio receive sensitivity value.
*
* @returns The radio receive sensitivity value in dBm.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
uint8_t GetReceiveSensitivity(void) const { return mRxSensitivity; }
/**
* This method returns a reference to the transmit buffer.
*
* The caller forms the IEEE 802.15.4 frame in this buffer then calls otPlatRadioTransmit() to request transmission.
*
* @returns A reference to the transmit buffer.
*
*/
otRadioFrame &GetTransmitFrame(void) { return mTxRadioFrame; }
/**
* This method enables or disables source address match feature.
*
* @param[in] aEnable Enable/disable source address match feature.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError EnableSrcMatch(bool aEnable);
/**
* This method adds a short address to the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aShortAddress The short address to be added.
*
* @retval OT_ERROR_NONE Successfully added short address to the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_BUFS No available entry in the source match table.
*/
otError AddSrcMatchShortEntry(const uint16_t aShortAddress);
/**
* This method removes a short address from the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aShortAddress The short address to be removed.
*
* @retval OT_ERROR_NONE Successfully removed short address from the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_ADDRESS The short address is not in source address match table.
*/
otError ClearSrcMatchShortEntry(const uint16_t aShortAddress);
/**
* Clear all short addresses from the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError ClearSrcMatchShortEntries(void);
/**
* Add an extended address to the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aExtAddress The extended address to be added stored in little-endian byte order.
*
* @retval OT_ERROR_NONE Successfully added extended address to the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_BUFS No available entry in the source match table.
*/
otError AddSrcMatchExtEntry(const otExtAddress &aExtAddress);
/**
* Remove an extended address from the source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aExtAddress The extended address to be removed stored in little-endian byte order.
*
* @retval OT_ERROR_NONE Successfully removed the extended address from the source match table.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
* @retval OT_ERROR_NO_ADDRESS The extended address is not in source address match table.
*/
otError ClearSrcMatchExtEntry(const otExtAddress &aExtAddress);
/**
* Clear all the extended/long addresses from source address match table.
*
* @param[in] aInstance The OpenThread instance structure.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError ClearSrcMatchExtEntries(void);
/**
* This method switches the radio state from Receive to Transmit.
*
* @param[in] aFrame A reference to the transmitted frame.
*
* @retval OT_ERROR_NONE Successfully transitioned to Transmit.
* @retval OT_ERROR_BUSY Failed due to another transmission is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
* @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state.
*/
otError Transmit(otRadioFrame &aFrame);
/**
* This method swithes the radio state from Sleep to Receive.
*
* @param[in] aChannel The channel to use for receiving.
*
* @retval OT_ERROR_NONE Successfully transitioned to Receive.
* @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
*
*/
otError Receive(uint8_t aChannel);
/**
* This method switches the radio state from Receive to Sleep.
*
* @retval OT_ERROR_NONE Successfully transitioned to Sleep.
* @retval OT_ERROR_BUSY The radio was transmitting
* @retval OT_ERROR_INVALID_STATE The radio was disabled
*
*/
otError Sleep(void);
/**
* Enable the radio.
*
* @param[in] aInstance A pointer to the OpenThread instance.
*
* @retval OT_ERROR_NONE Successfully enabled.
* @retval OT_ERROR_FAILED The radio could not be enabled.
*
*/
otError Enable(otInstance *aInstance);
/**
* Disable the radio.
*
* @retval OT_ERROR_NONE Successfully transitioned to Disabled.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Disable(void);
/**
* This method checks whether radio is enabled or not.
*
* @returns TRUE if the radio is enabled, FALSE otherwise.
*
*/
bool IsEnabled(void) const { return mState != OT_RADIO_STATE_DISABLED; }
/**
* This method updates the file descriptor sets with file descriptors used by the radio driver.
*
* @param[inout] aReadFdSet A reference to the read file descriptors.
* @param[inout] aWriteFdSet A reference to the write file descriptors.
* @param[inout] aMaxFd A reference to the max file descriptor.
* @param[inout] aTimeout A reference to the timeout.
*
*/
void UpdateFdSet(fd_set &aReadFdSet, fd_set &aWriteFdSet, int &aMaxFd, struct timeval &aTimeout);
/**
* This method performs radio driver processing.
*
* @param[in] aReadFdSet A reference to the read file descriptors.
* @param[in] aWriteFdSet A reference to the write file descriptors.
*
*/
void Process(const fd_set &aReadFdSet, const fd_set &aWriteFdSet);
private:
enum
{
kMaxSpinelFrame = 2048, ///< Max size in bytes for transfering spinel frames.
kMaxWaitTime = 2000, ///< Max time to wait for response in milliseconds.
};
void ReadAll(void);
otError WriteAll(const uint8_t *aBuffer, uint16_t aLength);
void ProcessFrameQueue(void);
/**
* This method tries to retrieve a spinel property from OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to unpack property value.
* @param[out] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully got the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Get(spinel_prop_key_t aKey, const char *aFormat, ...);
/**
* This method tries to update a spinel property of OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to pack property value.
* @param[in] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully set the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Set(spinel_prop_key_t aKey, const char *aFormat, ...);
/**
* This method tries to insert a item into a spinel list property of OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to pack the item.
* @param[in] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully insert item into the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Insert(spinel_prop_key_t aKey, const char *aFormat, ...);
/**
* This method tries to remove a item from a spinel list property of OpenThread transceiver.
*
* @param[in] aKey Spinel property key.
* @param[in] aFormat Spinel formatter to pack the item.
* @param[in] ... Variable arguments list.
*
* @retval OT_ERROR_NONE Successfully removed item from the property.
* @retval OT_ERROR_BUSY Failed due to another operation is on going.
* @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver.
*
*/
otError Remove(spinel_prop_key_t aKey, const char *aFormat, ...);
spinel_tid_t GetNextTid(void);
void FreeTid(spinel_tid_t tid) { mCmdTidsInUse &= ~(1 << tid); }
otError RequestV(bool aWait, uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, va_list aArgs);
otError Request(bool aWait, uint32_t aCommand, spinel_prop_key_t aKey, const char *aFormat, ...);
otError WaitResponse(void);
otError SendReset(void);
otError SendCommand(uint32_t command,
spinel_prop_key_t key,
spinel_tid_t tid,
const char * pack_format,
va_list args);
otError ParseRadioFrame(otRadioFrame &aFrame, const uint8_t *aBuffer, uint16_t aLength);
static void HandleHdlcError(void *aContext, otError aError, uint8_t *aBuffer, uint16_t aLength);
static void HandleSpinelFrame(void *aContext, uint8_t *aBuffer, uint16_t aLength)
{
static_cast<RadioSpinel *>(aContext)->HandleSpinelFrame(aBuffer, aLength);
}
void HandleSpinelFrame(const uint8_t *aBuffer, uint16_t aLength);
void HandleNotification(const uint8_t *aBuffer, uint16_t aLength);
void HandleValueIs(spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
void HandleResponse(const uint8_t *aBuffer, uint16_t aLength);
void HandleTransmitDone(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
void HandleWaitingResponse(uint32_t aCommand, spinel_prop_key_t aKey, const uint8_t *aBuffer, uint16_t aLength);
void RadioReceive(void);
void RadioTransmit(void);
otInstance *mInstance;
uint16_t mCmdTidsInUse; ///< Used transaction ids.
spinel_tid_t mCmdNextTid; ///< Next available transaction id.
spinel_tid_t mTxRadioTid; ///< The transaction id used to send a radio frame.
spinel_tid_t mWaitingTid; ///< The transaction id of current transaction.
spinel_prop_key_t mWaitingKey; ///< The property key of current transaction.
const char * mPropertyFormat; ///< The spinel property format of current transaction.
va_list mPropertyArgs; ///< The arguments pack or unpack spinel property of current transcation.
uint32_t mExpectedCommand; ///< Expected response command of current transaction.
otError mError; ///< The result of current transaction.
uint8_t mHdlcBuffer[kMaxSpinelFrame];
Hdlc::Decoder mHdlcDecoder;
Hdlc::Encoder mHdlcEncoder;
FrameQueue mFrameQueue;
uint8_t mRxPsdu[OT_RADIO_FRAME_MAX_SIZE];
uint8_t mTxPsdu[OT_RADIO_FRAME_MAX_SIZE];
otRadioFrame mRxRadioFrame;
otRadioFrame mTxRadioFrame;
otRadioFrame *mTransmitFrame; ///< Points to the frame to send
otExtAddress mExtendedAddress;
uint16_t mShortAddress;
uint16_t mPanid;
uint8_t mChannel;
int8_t mRxSensitivity;
uint8_t mTxState;
otError mTxError;
int mSockFd;
otRadioState mState;
bool mAckWait;
bool mPromiscuous;
bool mIsReady;
};
} // namespace ot
#endif // RADIO_SPINEL_HPP_
+132
View File
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file implements a pseudo-random number generator.
*
*/
#include <assert.h>
#include <stdio.h>
#include "platform-posix.h"
#include <openthread/types.h>
#include <openthread/platform/random.h>
#include "code_utils.h"
static uint32_t sState = 1;
void platformRandomInit(void)
{
#if __SANITIZE_ADDRESS__ == 0
otError error;
error = otPlatRandomGetTrue((uint8_t *)&sState, sizeof(sState));
assert(error == OT_ERROR_NONE);
#else // __SANITIZE_ADDRESS__
// Multiplying NODE_ID assures that no two nodes gets the same seed within an hour.
sState = (uint32_t)time(NULL) + (3600 * NODE_ID);
#endif // __SANITIZE_ADDRESS__
}
uint32_t otPlatRandomGet(void)
{
uint32_t mlcg, p, q;
uint64_t tmpstate;
tmpstate = (uint64_t)33614 * (uint64_t)sState;
q = tmpstate & 0xffffffff;
q = q >> 1;
p = tmpstate >> 32;
mlcg = p + q;
if (mlcg & 0x80000000)
{
mlcg &= 0x7fffffff;
mlcg++;
}
sState = mlcg;
return mlcg;
}
otError otPlatRandomGetTrue(uint8_t *aOutput, uint16_t aOutputLength)
{
otError error = OT_ERROR_NONE;
#if __SANITIZE_ADDRESS__ == 0
FILE * file = NULL;
size_t readLength;
otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
file = fopen("/dev/urandom", "rb");
otEXPECT_ACTION(file != NULL, error = OT_ERROR_FAILED);
readLength = fread(aOutput, 1, aOutputLength, file);
otEXPECT_ACTION(readLength == aOutputLength, error = OT_ERROR_FAILED);
exit:
if (file != NULL)
{
fclose(file);
}
#else // __SANITIZE_ADDRESS__
/*
* THE IMPLEMENTATION BELOW IS NOT COMPLIANT WITH THE THREAD SPECIFICATION.
*
* Address Sanitizer triggers test failures when reading random
* values from /dev/urandom. The pseudo-random number generator
* implementation below is only used to enable continuous
* integration checks with Address Sanitizer enabled.
*/
otEXPECT_ACTION(aOutput && aOutputLength, error = OT_ERROR_INVALID_ARGS);
for (uint16_t length = 0; length < aOutputLength; length++)
{
aOutput[length] = (uint8_t)otPlatRandomGet();
}
exit:
#endif // __SANITIZE_ADDRESS__
return error;
}
+461
View File
@@ -0,0 +1,461 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file implements the OpenThread platform abstraction for non-volatile storage of settings.
*
*/
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "utils/wrap_string.h"
#include <openthread-core-config.h>
#include "openthread/platform/settings.h"
#include "openthread/types.h"
#include <code_utils.h>
#include "flash.h"
#ifdef __cplusplus
extern "C" {
#endif
enum
{
kBlockAddBeginFlag = 0x1,
kBlockAddCompleteFlag = 0x02,
kBlockDeleteFlag = 0x04,
kBlockIndex0Flag = 0x08,
};
enum
{
kSettingsFlagSize = 4,
kSettingsBlockDataSize = 255,
kSettingsInSwap = 0xbe5cc5ef,
kSettingsInUse = 0xbe5cc5ee,
kSettingsNotUse = 0xbe5cc5ec,
};
OT_TOOL_PACKED_BEGIN
struct settingsBlock
{
uint16_t key;
uint16_t flag;
uint16_t length;
uint16_t reserved;
} OT_TOOL_PACKED_END;
/**
* @def SETTINGS_CONFIG_BASE_ADDRESS
*
* The base address of settings.
*
*/
#ifndef SETTINGS_CONFIG_BASE_ADDRESS
#define SETTINGS_CONFIG_BASE_ADDRESS 0x39000
#endif // SETTINGS_CONFIG_BASE_ADDRESS
/**
* @def SETTINGS_CONFIG_PAGE_SIZE
*
* The page size of settings.
*
*/
#ifndef SETTINGS_CONFIG_PAGE_SIZE
#define SETTINGS_CONFIG_PAGE_SIZE 0x800
#endif // SETTINGS_CONFIG_PAGE_SIZE
/**
* @def SETTINGS_CONFIG_PAGE_NUM
*
* The page number of settings.
*
*/
#ifndef SETTINGS_CONFIG_PAGE_NUM
#define SETTINGS_CONFIG_PAGE_NUM 2
#endif // SETTINGS_CONFIG_PAGE_NUM
static uint32_t sSettingsBaseAddress;
static uint32_t sSettingsUsedSize;
static uint16_t getAlignLength(uint16_t length)
{
return (length + 3) & 0xfffc;
}
static void setSettingsFlag(uint32_t aBase, uint32_t aFlag)
{
utilsFlashWrite(aBase, reinterpret_cast<uint8_t *>(&aFlag), sizeof(aFlag));
}
static void initSettings(uint32_t aBase, uint32_t aFlag)
{
uint32_t address = aBase;
uint32_t settingsSize = SETTINGS_CONFIG_PAGE_NUM > 1 ? SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM / 2
: SETTINGS_CONFIG_PAGE_SIZE;
while (address < (aBase + settingsSize))
{
utilsFlashErasePage(address);
utilsFlashStatusWait(1000);
address += SETTINGS_CONFIG_PAGE_SIZE;
}
setSettingsFlag(aBase, aFlag);
}
static uint32_t swapSettingsBlock(otInstance *aInstance)
{
uint32_t oldBase = sSettingsBaseAddress;
uint32_t swapAddress = oldBase;
uint32_t usedSize = sSettingsUsedSize;
uint8_t pageNum = SETTINGS_CONFIG_PAGE_NUM;
uint32_t settingsSize = pageNum > 1 ? SETTINGS_CONFIG_PAGE_SIZE * pageNum / 2 : SETTINGS_CONFIG_PAGE_SIZE;
(void)aInstance;
otEXPECT(pageNum > 1);
sSettingsBaseAddress =
(swapAddress == SETTINGS_CONFIG_BASE_ADDRESS) ? (swapAddress + settingsSize) : SETTINGS_CONFIG_BASE_ADDRESS;
initSettings(sSettingsBaseAddress, static_cast<uint32_t>(kSettingsInSwap));
sSettingsUsedSize = kSettingsFlagSize;
swapAddress += kSettingsFlagSize;
while (swapAddress < (oldBase + usedSize))
{
OT_TOOL_PACKED_BEGIN
struct addSettingsBlock
{
struct settingsBlock block;
uint8_t data[kSettingsBlockDataSize];
} OT_TOOL_PACKED_END addBlock;
bool valid = true;
utilsFlashRead(swapAddress, reinterpret_cast<uint8_t *>(&addBlock.block), sizeof(struct settingsBlock));
swapAddress += sizeof(struct settingsBlock);
if (!(addBlock.block.flag & kBlockAddCompleteFlag) && (addBlock.block.flag & kBlockDeleteFlag))
{
uint32_t address = swapAddress + getAlignLength(addBlock.block.length);
while (address < (oldBase + usedSize))
{
struct settingsBlock block;
utilsFlashRead(address, reinterpret_cast<uint8_t *>(&block), sizeof(block));
if (!(block.flag & kBlockAddCompleteFlag) && (block.flag & kBlockDeleteFlag) &&
!(block.flag & kBlockIndex0Flag) && (block.key == addBlock.block.key))
{
valid = false;
break;
}
address += (getAlignLength(block.length) + sizeof(struct settingsBlock));
}
if (valid)
{
utilsFlashRead(swapAddress, addBlock.data, getAlignLength(addBlock.block.length));
utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize, reinterpret_cast<uint8_t *>(&addBlock),
getAlignLength(addBlock.block.length) + sizeof(struct settingsBlock));
sSettingsUsedSize += (sizeof(struct settingsBlock) + getAlignLength(addBlock.block.length));
}
}
else if (addBlock.block.flag == 0xff)
{
break;
}
swapAddress += getAlignLength(addBlock.block.length);
}
setSettingsFlag(sSettingsBaseAddress, static_cast<uint32_t>(kSettingsInUse));
setSettingsFlag(oldBase, static_cast<uint32_t>(kSettingsNotUse));
exit:
return settingsSize - sSettingsUsedSize;
}
static otError addSetting(otInstance * aInstance,
uint16_t aKey,
bool aIndex0,
const uint8_t *aValue,
uint16_t aValueLength)
{
otError error = OT_ERROR_NONE;
OT_TOOL_PACKED_BEGIN
struct addSettingsBlock
{
struct settingsBlock block;
uint8_t data[kSettingsBlockDataSize];
} OT_TOOL_PACKED_END addBlock;
uint32_t settingsSize = SETTINGS_CONFIG_PAGE_NUM > 1 ? SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM / 2
: SETTINGS_CONFIG_PAGE_SIZE;
addBlock.block.flag = 0xff;
addBlock.block.key = aKey;
if (aIndex0)
{
addBlock.block.flag &= (~kBlockIndex0Flag);
}
addBlock.block.flag &= (~kBlockAddBeginFlag);
addBlock.block.length = aValueLength;
if ((sSettingsUsedSize + getAlignLength(addBlock.block.length) + sizeof(struct settingsBlock)) >= settingsSize)
{
otEXPECT_ACTION(swapSettingsBlock(aInstance) >=
(getAlignLength(addBlock.block.length) + sizeof(struct settingsBlock)),
error = OT_ERROR_NO_BUFS);
}
utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize, reinterpret_cast<uint8_t *>(&addBlock.block),
sizeof(struct settingsBlock));
memset(addBlock.data, 0xff, kSettingsBlockDataSize);
memcpy(addBlock.data, aValue, addBlock.block.length);
utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize + sizeof(struct settingsBlock),
reinterpret_cast<uint8_t *>(addBlock.data), getAlignLength(addBlock.block.length));
addBlock.block.flag &= (~kBlockAddCompleteFlag);
utilsFlashWrite(sSettingsBaseAddress + sSettingsUsedSize, reinterpret_cast<uint8_t *>(&addBlock.block),
sizeof(struct settingsBlock));
sSettingsUsedSize += (sizeof(struct settingsBlock) + getAlignLength(addBlock.block.length));
exit:
return error;
}
// settings API
void otPlatSettingsInit(otInstance *aInstance)
{
uint8_t index;
uint32_t settingsSize = SETTINGS_CONFIG_PAGE_NUM > 1 ? SETTINGS_CONFIG_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM / 2
: SETTINGS_CONFIG_PAGE_SIZE;
(void)aInstance;
sSettingsBaseAddress = SETTINGS_CONFIG_BASE_ADDRESS;
utilsFlashInit();
for (index = 0; index < 2; index++)
{
uint32_t blockFlag;
sSettingsBaseAddress += settingsSize * index;
utilsFlashRead(sSettingsBaseAddress, reinterpret_cast<uint8_t *>(&blockFlag), sizeof(blockFlag));
if (blockFlag == kSettingsInUse)
{
break;
}
}
if (index == 2)
{
initSettings(sSettingsBaseAddress, static_cast<uint32_t>(kSettingsInUse));
}
sSettingsUsedSize = kSettingsFlagSize;
while (sSettingsUsedSize < settingsSize)
{
struct settingsBlock block;
utilsFlashRead(sSettingsBaseAddress + sSettingsUsedSize, reinterpret_cast<uint8_t *>(&block), sizeof(block));
if (!(block.flag & kBlockAddBeginFlag))
{
sSettingsUsedSize += (getAlignLength(block.length) + sizeof(struct settingsBlock));
}
else
{
break;
}
}
}
otError otPlatSettingsBeginChange(otInstance *aInstance)
{
(void)aInstance;
return OT_ERROR_NONE;
}
otError otPlatSettingsCommitChange(otInstance *aInstance)
{
(void)aInstance;
return OT_ERROR_NONE;
}
otError otPlatSettingsAbandonChange(otInstance *aInstance)
{
(void)aInstance;
return OT_ERROR_NONE;
}
otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
{
otError error = OT_ERROR_NOT_FOUND;
uint32_t address = sSettingsBaseAddress + kSettingsFlagSize;
uint16_t valueLength = 0;
int index = 0;
(void)aInstance;
while (address < (sSettingsBaseAddress + sSettingsUsedSize))
{
struct settingsBlock block;
utilsFlashRead(address, reinterpret_cast<uint8_t *>(&block), sizeof(block));
if (block.key == aKey)
{
if (!(block.flag & kBlockIndex0Flag))
{
index = 0;
}
if (!(block.flag & kBlockAddCompleteFlag) && (block.flag & kBlockDeleteFlag))
{
if (index == aIndex)
{
uint16_t readLength = block.length;
// only perform read if an input buffer was passed in
if (aValue != NULL && aValueLength != NULL)
{
// adjust read length if input buffer length is smaller
if (readLength > *aValueLength)
{
readLength = *aValueLength;
}
utilsFlashRead(address + sizeof(struct settingsBlock), aValue, readLength);
}
valueLength = block.length;
error = OT_ERROR_NONE;
}
index++;
}
}
address += (getAlignLength(block.length) + sizeof(struct settingsBlock));
}
if (aValueLength != NULL)
{
*aValueLength = valueLength;
}
return error;
}
otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
return addSetting(aInstance, aKey, true, aValue, aValueLength);
}
otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
{
uint16_t length;
bool index0;
index0 = (otPlatSettingsGet(aInstance, aKey, 0, NULL, &length) == OT_ERROR_NOT_FOUND ? true : false);
return addSetting(aInstance, aKey, index0, aValue, aValueLength);
}
otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
{
otError error = OT_ERROR_NOT_FOUND;
uint32_t address = sSettingsBaseAddress + kSettingsFlagSize;
int index = 0;
(void)aInstance;
while (address < (sSettingsBaseAddress + sSettingsUsedSize))
{
struct settingsBlock block;
utilsFlashRead(address, reinterpret_cast<uint8_t *>(&block), sizeof(block));
if (block.key == aKey)
{
if (!(block.flag & kBlockIndex0Flag))
{
index = 0;
}
if (!(block.flag & kBlockAddCompleteFlag) && (block.flag & kBlockDeleteFlag))
{
if (aIndex == index || aIndex == -1)
{
error = OT_ERROR_NONE;
block.flag &= (~kBlockDeleteFlag);
utilsFlashWrite(address, reinterpret_cast<uint8_t *>(&block), sizeof(block));
}
if (index == 1 && aIndex == 0)
{
block.flag &= (~kBlockIndex0Flag);
utilsFlashWrite(address, reinterpret_cast<uint8_t *>(&block), sizeof(block));
}
index++;
}
}
address += (getAlignLength(block.length) + sizeof(struct settingsBlock));
}
return error;
}
void otPlatSettingsWipe(otInstance *aInstance)
{
initSettings(sSettingsBaseAddress, static_cast<uint32_t>(kSettingsInUse));
otPlatSettingsInit(aInstance);
}
#ifdef __cplusplus
};
#endif
+93
View File
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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.
*/
/**
* @file
* This file implements the spi stubs.
*
*/
#include "platform-posix.h"
#include <stdio.h>
#include <stdlib.h>
#include <openthread/config.h>
#include <openthread/platform/spi-slave.h>
#include <openthread/platform/uart.h>
#if OPENTHREAD_ENABLE_NCP_SPI
// Spi-slave stubs
otError otPlatSpiSlaveEnable(otPlatSpiSlaveTransactionCompleteCallback aCompleteCallback,
otPlatSpiSlaveTransactionProcessCallback aProcessCallback,
void * aContext)
{
(void)aCompleteCallback;
(void)aProcessCallback;
(void)aContext;
fprintf(stderr, "\nNo SPI support for posix platform.");
exit(0);
return OT_ERROR_NOT_IMPLEMENTED;
}
void otPlatSpiSlaveDisable(void)
{
}
otError otPlatSpiSlavePrepareTransaction(uint8_t *aOutputBuf,
uint16_t aOutputBufLen,
uint8_t *aInputBuf,
uint16_t aInputBufLen,
bool aRequestTransactionFlag)
{
(void)aOutputBuf;
(void)aOutputBufLen;
(void)aInputBuf;
(void)aInputBufLen;
(void)aRequestTransactionFlag;
return OT_ERROR_NOT_IMPLEMENTED;
}
// Uart
void otPlatUartSendDone(void)
{
}
void otPlatUartReceived(const uint8_t *aBuf, uint16_t aBufLength)
{
(void)aBuf;
(void)aBufLength;
}
#endif // OPENTHREAD_ENABLE_NCP_SPI
+1
View File
@@ -0,0 +1 @@
../../ncp/spinel.c
+314
View File
@@ -0,0 +1,314 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* 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 "platform-posix.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <termios.h>
#include <unistd.h>
#include <openthread/platform/debug_uart.h>
#include <openthread/platform/uart.h>
#include "code_utils.h"
int posix_openpt(int oflag);
int grantpt(int fildes);
int unlockpt(int fd);
char *ptsname(int fd);
static uint8_t s_receive_buffer[128];
static const uint8_t *s_write_buffer;
static uint16_t s_write_length;
static int s_in_fd;
static int s_out_fd;
static struct termios original_stdin_termios;
static struct termios original_stdout_termios;
static void restore_stdin_termios(void)
{
tcsetattr(s_in_fd, TCSAFLUSH, &original_stdin_termios);
}
static void restore_stdout_termios(void)
{
tcsetattr(s_out_fd, TCSAFLUSH, &original_stdout_termios);
}
void platformUartRestore(void)
{
restore_stdin_termios();
restore_stdout_termios();
dup2(s_out_fd, STDOUT_FILENO);
}
otError otPlatUartEnable(void)
{
otError error = OT_ERROR_NONE;
struct termios termios;
#ifdef OPENTHREAD_TARGET_LINUX
// Ensure we terminate this process if the
// parent process dies.
prctl(PR_SET_PDEATHSIG, SIGHUP);
#endif
s_in_fd = dup(STDIN_FILENO);
s_out_fd = dup(STDOUT_FILENO);
dup2(STDERR_FILENO, STDOUT_FILENO);
// We need this signal to make sure that this
// process terminates properly.
signal(SIGPIPE, SIG_DFL);
if (isatty(s_in_fd))
{
tcgetattr(s_in_fd, &original_stdin_termios);
atexit(&restore_stdin_termios);
}
if (isatty(s_out_fd))
{
tcgetattr(s_out_fd, &original_stdout_termios);
atexit(&restore_stdout_termios);
}
if (isatty(s_in_fd))
{
// get current configuration
otEXPECT_ACTION(tcgetattr(s_in_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
// Set up the termios settings for raw mode. This turns
// off input/output processing, line processing, and character processing.
cfmakeraw(&termios);
// Set up our cflags for local use. Turn on hangup-on-close.
termios.c_cflag |= HUPCL | CREAD | CLOCAL;
// "Minimum number of characters for noncanonical read"
termios.c_cc[VMIN] = 1;
// "Timeout in deciseconds for noncanonical read"
termios.c_cc[VTIME] = 0;
// configure baud rate
otEXPECT_ACTION(cfsetispeed(&termios, B115200) == 0, perror("cfsetispeed"); error = OT_ERROR_GENERIC);
// set configuration
otEXPECT_ACTION(tcsetattr(s_in_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
}
if (isatty(s_out_fd))
{
// get current configuration
otEXPECT_ACTION(tcgetattr(s_out_fd, &termios) == 0, perror("tcgetattr"); error = OT_ERROR_GENERIC);
// Set up the termios settings for raw mode. This turns
// off input/output processing, line processing, and character processing.
cfmakeraw(&termios);
// Absolutely obliterate all output processing.
termios.c_oflag = 0;
// Set up our cflags for local use. Turn on hangup-on-close.
termios.c_cflag |= HUPCL | CREAD | CLOCAL;
// configure baud rate
otEXPECT_ACTION(cfsetospeed(&termios, B115200) == 0, perror("cfsetospeed"); error = OT_ERROR_GENERIC);
// set configuration
otEXPECT_ACTION(tcsetattr(s_out_fd, TCSANOW, &termios) == 0, perror("tcsetattr"); error = OT_ERROR_GENERIC);
}
return error;
exit:
close(s_in_fd);
close(s_out_fd);
return error;
}
otError otPlatUartDisable(void)
{
otError error = OT_ERROR_NONE;
close(s_in_fd);
close(s_out_fd);
return error;
}
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
{
otError error = OT_ERROR_NONE;
otEXPECT_ACTION(s_write_length == 0, error = OT_ERROR_BUSY);
s_write_buffer = aBuf;
s_write_length = aBufLength;
exit:
return error;
}
void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
{
if (aReadFdSet != NULL)
{
FD_SET(s_in_fd, aReadFdSet);
if (aErrorFdSet != NULL)
{
FD_SET(s_in_fd, aErrorFdSet);
}
if (aMaxFd != NULL && *aMaxFd < s_in_fd)
{
*aMaxFd = s_in_fd;
}
}
if ((aWriteFdSet != NULL) && (s_write_length > 0))
{
FD_SET(s_out_fd, aWriteFdSet);
if (aErrorFdSet != NULL)
{
FD_SET(s_out_fd, aErrorFdSet);
}
if (aMaxFd != NULL && *aMaxFd < s_out_fd)
{
*aMaxFd = s_out_fd;
}
}
}
void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet)
{
ssize_t rval;
errno = 0;
if (FD_ISSET(s_in_fd, aErrorFdSet))
{
perror("s_in_fd");
exit(EXIT_FAILURE);
}
if (FD_ISSET(s_out_fd, aErrorFdSet))
{
perror("s_out_fd");
exit(EXIT_FAILURE);
}
if (FD_ISSET(s_in_fd, aReadFdSet))
{
rval = read(s_in_fd, s_receive_buffer, sizeof(s_receive_buffer));
if (rval < 0)
{
perror("read");
exit(EXIT_FAILURE);
}
else if (rval > 0)
{
otPlatUartReceived(s_receive_buffer, (uint16_t)rval);
}
}
if ((s_write_length > 0) && (FD_ISSET(s_out_fd, aWriteFdSet)))
{
rval = write(s_out_fd, s_write_buffer, s_write_length);
if (rval <= 0)
{
perror("write");
exit(EXIT_FAILURE);
}
s_write_buffer += (uint16_t)rval;
s_write_length -= (uint16_t)rval;
if (s_write_length == 0)
{
otPlatUartSendDone();
}
}
}
#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART && (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART)
static FILE *posix_logfile;
otError otPlatDebugUart_logfile(const char *filename)
{
posix_logfile = fopen(filename, "wt");
return posix_logfile ? OT_ERROR_NONE : OT_ERROR_FAILED;
}
void otPlatDebugUart_putchar_raw(int c)
{
FILE *fp;
/* note: log file will have a mix of cr/lf and
* in some/many cases duplicate cr because in
* some cases the log function {ie: Mbed} already
* includes the CR or LF... but other log functions
* do not include cr/lf and expect it appened
*/
fp = posix_logfile;
if (fp != NULL)
{
/* log is lost ... until a file is setup */
fputc(c, fp);
/* we could "fflush" but will not */
}
}
int otPlatDebugUart_kbhit(void)
{
/* not supported */
return 0;
}
int otPlatDebugUart_getc(void)
{
/* not supported */
return -1;
}
#endif
+1 -1
View File
@@ -48,7 +48,7 @@ PRETTY_SUBDIRS = \
unit \
$(NULL)
if OPENTHREAD_EXAMPLES_POSIX
if OPENTHREAD_POSIX
if OPENTHREAD_ENABLE_CLI
SUBDIRS += \
unit \
+1 -1
View File
@@ -39,7 +39,7 @@ DIST_SUBDIRS = \
SUBDIRS = \
$(NULL)
if OPENTHREAD_EXAMPLES_POSIX
if OPENTHREAD_POSIX
if OPENTHREAD_ENABLE_CLI
SUBDIRS += \
thread-cert \
+18 -6
View File
@@ -59,13 +59,17 @@ class otCli:
def __init_sim(self, nodeid, mode):
""" Initialize a simulation node. """
if "OT_CLI_PATH" in os.environ.keys():
if 'OT_CLI_PATH' in os.environ.keys():
cmd = os.environ['OT_CLI_PATH']
elif "top_builddir" in os.environ.keys():
elif 'top_builddir' in os.environ.keys():
srcdir = os.environ['top_builddir']
cmd = '%s/examples/apps/cli/ot-cli-%s' % (srcdir, mode)
else:
cmd = './ot-cli-%s' % mode
if 'RADIO_DEVICE' in os.environ:
cmd += ' %s' % os.environ['RADIO_DEVICE']
cmd += ' %d' % nodeid
print ("%s" % cmd)
@@ -77,11 +81,18 @@ class otCli:
def __init_ncp_sim(self, nodeid, mode):
""" Initialize an NCP simulation node. """
if "top_builddir" in os.environ.keys():
builddir = os.environ['top_builddir']
cmd = 'spinel-cli.py -p %s/examples/apps/ncp/ot-ncp-%s -n' % (builddir, mode)
if 'RADIO_DEVICE' in os.environ:
args = ' %s' % os.environ['RADIO_DEVICE']
else:
cmd = './ot-ncp-%s' % mode
args = ''
if 'OT_NCP_PATH' in os.environ.keys():
cmd = 'spinel-cli.py -p "%s%s" -n' % (os.environ['OT_NCP_PATH'], args)
elif "top_builddir" in os.environ.keys():
builddir = os.environ['top_builddir']
cmd = 'spinel-cli.py -p "%s/examples/apps/ncp/ot-ncp-%s%s" -n' % (builddir, mode, args)
else:
cmd = 'spinel-cli.py -p "./ot-ncp-%s%s" -n' % (mode, args)
cmd += ' %d' % nodeid
print ("%s" % cmd)
@@ -106,6 +117,7 @@ class otCli:
def send_command(self, cmd):
print("%d: %s" % (self.nodeid, cmd))
self.pexpect.send(cmd + '\n')
sys.stdout.flush()
if isinstance(self.simulator, simulator.VirtualTime):
self.simulator.receive_events()
+28 -4
View File
@@ -51,12 +51,24 @@ if OPENTHREAD_BUILD_TESTS
AM_CPPFLAGS = \
-DOPENTHREAD_FTD=1 \
-I$(top_srcdir)/examples/platforms \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/core \
$(NULL)
if OPENTHREAD_EXAMPLES_POSIX
AM_CPPFLAGS += \
-I$(top_srcdir)/examples/platforms \
$(NULL)
endif
if OPENTHREAD_ENABLE_POSIX_APP
AM_CPPFLAGS += \
-DOPENTHREAD_ENABLE_POSIX_APP=1 \
-I$(top_srcdir)/src/posix/platform \
$(NULL)
endif
if OPENTHREAD_ENABLE_NCP
COMMON_LDADD = \
@@ -80,6 +92,12 @@ COMMON_LDADD += \
$(NULL)
endif # OPENTHREAD_ENABLE_BUILTIN_MBEDTLS
if OPENTHREAD_ENABLE_POSIX_APP
COMMON_LDADD += \
-lutil
$(NULL)
endif
# Test applications that should be run when the 'check' target is run.
check_PROGRAMS = \
@@ -210,10 +228,16 @@ test_toolchain_LDADD = $(COMMON_LDADD)
test_toolchain_SOURCES = test_platform.cpp test_toolchain.cpp test_toolchain_c.c
if OPENTHREAD_ENABLE_DIAG
test_diag_LDADD = $(top_builddir)/src/diag/libopenthread-diag.a \
$(top_builddir)/examples/platforms/posix/libopenthread-posix.a \
$(NULL)
test_diag_LDADD = $(top_builddir)/src/diag/libopenthread-diag.a
test_diag_SOURCES = test_diag.cpp
if OPENTHREAD_ENABLE_POSIX_APP
test_diag_LDADD += $(top_builddir)/src/posix/platform/libopenthread-posix.a \
-lutil \
$(NULL)
endif
if OPENTHREAD_EXAMPLES_POSIX
test_diag_LDADD += $(top_builddir)/examples/platforms/posix/libopenthread-posix.a
endif
endif
PRETTY_FILES = \
+8 -3
View File
@@ -29,6 +29,8 @@
#include <openthread/diag.h>
#include <openthread/platform/radio.h>
#include <stdlib.h>
#include "utils/wrap_string.h"
#include "platform.h"
@@ -227,9 +229,12 @@ void TestDiag(void)
}};
// initialize platform layer
int argc = 2;
char *argv[8] = {(char *)"test_diag", (char *)"1"};
PlatformInit(argc, argv);
#if OPENTHREAD_ENABLE_POSIX_APP
char *argv[] = {(char *)"test_diag", getenv("RADIO_DEVICE"), (char *)"1"};
#else
char *argv[] = {(char *)"test_diag", (char *)"1"};
#endif
PlatformInit(sizeof(argv) / sizeof(char *), argv);
// initialize diagnostics module
otDiagInit(NULL);