diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..9a0a6ea --- /dev/null +++ b/.clang-format @@ -0,0 +1,112 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: InlineOnly +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + BeforeCatch: false + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^/ot-esp32.git + +# Configure upstream alias +git remote add upstream git@github.com:openthread/ot-esp32.git +``` + +### Contributor License Agreement (CLA) + +Contributions to this project must be accompanied by a Contributor License Agreement. You (or your employer) retain the copyright to your contribution; this simply gives us permission to use and redistribute your contributions as part of the project. Head over to to see your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one (even if it was for a different project), you probably don't need to do it again. + +### Submitting a Pull Request + +#### Branch + +For each new feature, create a working branch: + +```bash +# Create a working branch for your new feature +git branch --track origin/master + +# Checkout the branch +git checkout +``` + +#### Create Commits + +```bash +# Add each modified file you'd like to include in the commit +git add + +# Create a commit +git commit +``` + +This will open up a text editor where you can craft your commit message. + +#### Upstream Sync and Clean Up + +Prior to submitting your pull request, you might want to do a few things to clean up your branch and make it as simple as possible for the original repo's maintainer to test, accept, and merge your work. + +If any commits have been made to the upstream master branch, you should rebase your development branch so that merging it will be a simple fast-forward that won't require any conflict resolution work. + +```bash +# Fetch upstream master and merge with your repo's master branch +git checkout master +git pull upstream master + +# If there were any new commits, rebase your development branch +git checkout +git rebase master +``` + +Now, it may be desirable to squash some of your smaller commits down into a small number of larger more cohesive commits. You can do this with an interactive rebase: + +```bash +# Rebase all commits on your development branch +git checkout +git rebase -i master +``` + +This will open up a text editor where you can specify which commits to squash. + +#### Coding Conventions and Style + +ot-esp32 uses and enforces the [OpenThread Coding Conventions and Style](https://github.com/openthread/openthread/blob/master/STYLE_GUIDE.md) on all code, except for code located in [third_party](third_party). Use `script/make-pretty` and `script/make-pretty check` to automatically reformat code and check for code-style compliance, respectively. ot-esp32 currently requires [clang-format v6.0.0](http://releases.llvm.org/download.html#6.0.0) for C/C++ and [yapf v0.29.0](https://github.com/google/yapf) for Python. + +As part of the cleanup process, you should also run `script/make-pretty check` to ensure that your code passes the baseline code style checks. + +#### Push and Test + +```bash +# Checkout your branch +git checkout + +# Push to your GitHub fork: +git push origin +``` + +This will trigger continuous-integration checks using GitHub Actions. You can view the status and logs via the "Actions" tab in your fork. + +#### Submit Pull Request + +Once you've validated that all continuous-integration checks have passed, go to the page for your fork on GitHub, select your development branch, and click the pull request button. If you need to make any adjustments to your pull request, just push the updates to GitHub. Your pull request will automatically track the changes on your development branch and update. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d63767e --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2020, 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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8b91704 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# OpenThread on ESP32 + +**ot-esp32** is a port of OpenThread for the [Espressif ESP32 platform](https://www.espressif.com/en/products/socs/esp32/overview), where OpenThread uses a [Radio Co-Processor (RCP) design](https://openthread.io/platforms#radio-co-processor-rcp), transmitting and receiving radio using an 802.15.4-capable SoC. + +For more information on OpenThread, see [openthread.io](https://openthread.io). + +## Getting started + +Get started with the [example CLI application](example/README.md). + +## Contributing + +We would love for you to contribute to OpenThread ESP32 and help make it even better than it is today! See our [Contributing Guidelines](https://github.com/openthread/ot-esp32/blob/master/CONTRIBUTING.md) for more information. + +Contributors are required to abide by our [Code of Conduct](https://github.com/openthread/ot-esp32/blob/master/CODE_OF_CONDUCT.md) and [Coding Conventions and Style Guide](https://github.com/openthread/openthread/blob/master/STYLE_GUIDE.md). + +## Versioning + +OpenThread ESP32 follows the [Semantic Versioning guidelines](http://semver.org/) for release cycle transparency and to maintain backwards compatibility. + +## License + +OpenThread ESP32 is released under the [BSD 3-Clause license](https://github.com/openthread/ot-esp32/blob/master/LICENSE). See the [`LICENSE`](https://github.com/openthread/ot-esp32/blob/master/LICENSE) file for more information. + +Please only use the OpenThread ESP32 name and marks when accurately referencing this software distribution. Do not use the marks in a way that suggests you are endorsed by or otherwise affiliated with Nest, Google, or The Thread Group. diff --git a/component.mk b/component.mk new file mode 100644 index 0000000..d13cc7e --- /dev/null +++ b/component.mk @@ -0,0 +1,79 @@ +# +# Copyright (c) 2020, 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. +# +# Description: +# This file is the component file builds ot-esp32 project as an esp-idf component. +# + +COMPONENT_ADD_INCLUDEDIRS := \ + include \ + third_party/openthread/include + +COMPONENT_PRIV_INCLUDEDIRS := \ + src \ + third_party/openthread/src \ + third_party/openthread/src/core \ + third_party/openthread/src/lib/hdlc \ + third_party/openthread/src/lib/spinel \ + third_party/openthread/src/ncp \ + third_party/openthread/third_party/jlink/SEGGER_RTT_V640/RTT + +COMPONENT_SRCDIRS := \ + src \ + third_party/openthread/src/cli \ + third_party/openthread/src/core \ + third_party/openthread/src/core/api \ + third_party/openthread/src/core/coap \ + third_party/openthread/src/core/common \ + third_party/openthread/src/core/crypto \ + third_party/openthread/src/core/mac \ + third_party/openthread/src/core/meshcop \ + third_party/openthread/src/core/net \ + third_party/openthread/src/core/radio \ + third_party/openthread/src/core/thread \ + third_party/openthread/src/core/utils \ + third_party/openthread/src/lib/hdlc \ + third_party/openthread/src/lib/spinel \ + third_party/openthread/src/ncp + +COMPONENT_OBJEXCLUDE := \ + third_party/openthread/src/core/common/extension_example.o + +COMMON_FLAGS := \ + -D_GNU_SOURCE \ + -DOPENTHREAD_CONFIG_FILE=\ \ + -DOPENTHREAD_FTD=1 \ + -DOPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1 \ + -DOPENTHREAD_PROJECT_CORE_CONFIG_FILE=\"openthread-core-esp32-config.h\" \ + -DSPINEL_PLATFORM_HEADER=\"spinel_platform.h\" \ + -Wno-error=non-virtual-dtor + +CFLAGS += $(COMMON_FLAGS) + +CXXFLAGS += $(COMMON_FLAGS) + +CPPFLAGS += $(COMMON_FLAGS) diff --git a/doc/images/connect-devices.jpg b/doc/images/connect-devices.jpg new file mode 100644 index 0000000..43511e2 Binary files /dev/null and b/doc/images/connect-devices.jpg differ diff --git a/example/Makefile b/example/Makefile new file mode 100644 index 0000000..71ffc65 --- /dev/null +++ b/example/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (c) 2020, 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. +# +# Description: +# Make file of the example CLI application. +# + +PROJECT_NAME := ot-cli + +EXTRA_COMPONENT_DIRS += $(PROJECT_PATH)/.. + +COMMON_FLAGS := \ + -DMBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED \ + -DOPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=0 \ + -DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=0 \ + -DOPENTHREAD_ENABLE_BUILTIN_MBEDTLS=0 \ + -DOT_RADIO_UART_TXD=GPIO_NUM_4 \ + -DMBEDTLS_ECJPAKE_C \ + -Wno-deprecated-declarations + +EXTRA_CFLAGS=$(COMMON_FLAGS) + +EXTRA_CXXFLAGS=$(COMMON_FLAGS) + +EXTRA_CPPFLAGS=$(COMMON_FLAGS) + +include $(IDF_PATH)/make/project.mk diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..f9bd814 --- /dev/null +++ b/example/README.md @@ -0,0 +1,95 @@ +# Example CLI Application + +The example CLI application runs the OpenThread stack on the [Espressif ESP32](https://www.espressif.com/en/products/socs/esp32/overview) and controls it with CLI commands through UART. OpenThread transmits and receives radio using a UART-connected [nRF52840 DK](https://www.nordicsemi.com/Products/Low-power-short-range-wireless/nRF52840). + +## Platform + +This example runs on Linux. + +## Setup + +### Setup ESP-IDF + +Clone the [Espressif IoT Development Framework](https://github.com/espressif/esp-idf): + +```shell +git clone --branch release/v3.3 git@github.com:espressif/esp-idf.git +``` + +Set up the environment: + +```shell +export IDF_PATH=$HOME/esp-idf +source $IDF_PATH/export.sh +``` + +### Build and flash the CLI application + +Connect the ESP32 board to the Linux host and execute: + +```shell +cd example +make -j6 +make flash +``` + +### Build and flash nRF52840 image + +Connect the nRF52840 DK to the Linux host and execute: + +```shell +cd third_party/openthread +./bootstrap +make -f example/Makefile-nrf52840 CFLAGS="-DUART_HWFC_ENABLED=0" + +cd output/nrf52840/bin +arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex + +nrfjprog -f nrf52 -s 683704924 --chiperase --program ot-rcp.hex +``` + +Note: The Serial Number (for example, 683704924) is located in the center of the nRF52840 DK, as shown in the picture below. + +### Connect devices + +Connect the ESP32 board and the nRF52840 DK: + +- ESP32.IO5 <---> nRF52840.P0.06 +- ESP32.IO4 <---> nRF52840.P0.08 + +![Connect-Devices](../doc/images/connect-devices.jpg) + +## Run the CLI application + +Connect to the ESP32 board from the Linux host: + +```shell +make monitor +``` + +_Note: Dependending on your Linux distribution, the new line characters ('\r', '\n') may cause commands display issues. To have good look of the CLI, Connect the ESP32 board with advanced command `picocom -b 115200 /dev/ttyUSB0 --imap lfcrlf` (install `picocom` with `sudo apt-get install picocom`)._ + +The CLI application is now in interactive mode and waiting for commands, start the OpenThread stack to verify your setup: + +```shell +> dataset init new +Done +> dataset +Active Timestamp: 1 +Channel: 13 +Channel Mask: 07fff800 +Ext PAN ID: d63e8e3e495ebbc3 +Mesh Local Prefix: fd3d:b50b:f96d:722d/64 +Master Key: dfd34f0f05cad978ec4e32b0413038ff +Network Name: OpenThread-8f28 +PAN ID: 0x8f28 +PSKc: c23a76e98f1a6483639b1ac1271e2e27 +Security Policy: 0, onrcb +Done +> dataset commit active +Done +> ifconfig up +Done +> thread start +Done +``` diff --git a/example/main/cli.c b/example/main/cli.c new file mode 100644 index 0000000..13a45e2 --- /dev/null +++ b/example/main/cli.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2020, 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 an example OpenThread CLI application. + * + * This file is just for example, but not for production. + * + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define CLI_LOG_TAG "OT_CLI" + +static void run_cli(void *aContext) +{ + OT_UNUSED_VARIABLE(aContext); + +pseudo_reset: + + otSysInit(0, NULL); + + otSysApiLock(); + + size_t instanceSize = 0; + + // Get the instance size. + otInstanceInit(NULL, &instanceSize); + void *instanceBuffer = malloc(instanceSize); + + otInstance *instance = otInstanceInit(instanceBuffer, &instanceSize); + + assert(instance != NULL); + + otCliUartInit(instance); + otSysApiUnlock(); + + if (!heap_caps_check_integrity_all(true)) + { + ESP_LOGE(CLI_LOG_TAG, "heap corrupted"); + abort(); + } + + while (!otSysPseudoResetWasRequested()) + { + otSysMainloopContext mainloop; + + otSysMainloopInit(&mainloop); + + otSysApiLock(); + otTaskletsProcess(instance); + otSysMainloopUpdate(instance, &mainloop); + otSysApiUnlock(); + + if (otSysMainloopPoll(&mainloop) >= 0) + { + otSysApiLock(); + otSysMainloopProcess(instance, &mainloop); + otSysApiUnlock(); + } + else + { + ESP_LOGE(CLI_LOG_TAG, "OpenThread system polling failed"); + abort(); + } + } + + otInstanceFinalize(instance); + otSysDeinit(); + + goto pseudo_reset; + + vTaskDelete(NULL); +} + +void app_main() +{ + xTaskCreate(run_cli, "cli", 10 * 1024, NULL, 5, NULL); +} diff --git a/example/main/component.mk b/example/main/component.mk new file mode 100644 index 0000000..42861ed --- /dev/null +++ b/example/main/component.mk @@ -0,0 +1,30 @@ +# +# Copyright (c) 2020, 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. +# +# Description: +# Dummy component file. +# diff --git a/example/partitions.csv b/example/partitions.csv new file mode 100644 index 0000000..3581674 --- /dev/null +++ b/example/partitions.csv @@ -0,0 +1,35 @@ +# +# Copyright (c) 2020, 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. +# +# Description: +# Espressif ESP32 Partition Table for openthread-esp32-cli demo App. +# +# Name, Type, SubType, Offset, Size + nvs, data, nvs, 0x9000, 0x6000 + phy_init, data, phy, 0xf000, 0x1000 + factory, app, factory, 0x10000, 1M + ot_storage, data, fat, , 512K, diff --git a/example/sdkconfig.defaults b/example/sdkconfig.defaults new file mode 100644 index 0000000..26cf12b --- /dev/null +++ b/example/sdkconfig.defaults @@ -0,0 +1,34 @@ +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC= +CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC= +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN= +CONFIG_MBEDTLS_DEBUG= +CONFIG_MBEDTLS_ECP_RESTARTABLE= +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI= +CONFIG_MBEDTLS_HARDWARE_SHA= +CONFIG_MBEDTLS_HAVE_TIME=y +CONFIG_MBEDTLS_HAVE_TIME_DATE= +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +CONFIG_MBEDTLS_TLS_SERVER_ONLY= +CONFIG_MBEDTLS_TLS_CLIENT_ONLY= +CONFIG_MBEDTLS_TLS_DISABLED= +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP= +CONFIG_PARTITION_TABLE_TWO_OTA= +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y diff --git a/include/openthread/openthread-esp32.h b/include/openthread/openthread-esp32.h new file mode 100644 index 0000000..fb3fbd3 --- /dev/null +++ b/include/openthread/openthread-esp32.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2020, 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 functions needed by OpenThread's example applications. + */ + +#ifndef OT_ESP32_OPENTHREAD_ESP32_H_ +#define OT_ESP32_OPENTHREAD_ESP32_H_ + +#include +#include +#include + +#include +#include + +/** + * The minimum FreeRTOS stack size required by the OT stack. + * + * It is not recommended to run the OT stack in tasks with + * stack size smaller than this value. + * + */ +#define OT_MIN_RTOS_STACK_SIZE (10 * 1024) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This structure represents a context for a select() based mainloop. + * + */ +typedef struct otSysMainloopContext +{ + fd_set mReadFdSet; ///< The read file descriptors. + fd_set mWriteFdSet; ///< The write file descriptors. + fd_set mErrorFdSet; ///< The error file descriptors. + int mMaxFd; ///< The max file descriptor. + struct timeval mTimeout; ///< The timeout. +} otSysMainloopContext; + +/** + * This function performs all platform-specific initialization of OpenThread's drivers. + * + * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function + * when initialization of OpenThread's drivers is most appropriate. + * + * @param[in] argc Number of arguments in @p argv. + * @param[in] argv Argument vector. + * + */ +void otSysInit(int argc, char *argv[]); + +/** + * This function performs all platform-specific deinitialization for OpenThread's drivers. + * + * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function + * when deinitialization of OpenThread's drivers is most appropriate. + * + */ +void otSysDeinit(void); + +/** + * This function returns true if a pseudo-reset was requested. + * + * In such a case, the main loop should shut down and re-initialize the OpenThread instance. + * + * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function + * in the main loop to determine when to shut down and re-initialize the OpenThread instance. + * + */ +bool otSysPseudoResetWasRequested(void); + +/** + * This function initialize a mainloop context. + * + * @param[inout] aMainloop A pointer to the mainloop to be initialized. + * + */ +void otSysMainloopInit(otSysMainloopContext *aMainloop); + +/** + * This function updates the mainloop context. + * + * @param[in] aInstance The OpenThread instance structure. + * @param[inout] aMainloop A pointer to the mainloop context. + * + */ +void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop); + +/** + * This function polls OpenThread's mainloop. + * + * @param[inout] aMainloop A pointer to the mainloop context. + * + * @returns value returned from select(). + * + */ +int otSysMainloopPoll(otSysMainloopContext *aMainloop); + +/** + * This function performs all platform-specific processing for OpenThread's example applications. + * + * @note This function is not called by the OpenThread library. Instead, the system/RTOS should call this function + * in the main loop when processing OpenThread's drivers is most appropriate. + * + * @param[in] aInstance The OpenThread instance structure. + * @param[in] aMainloop A pointer to the mainloop context. + * + */ +void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop); + +/** + * This functions locks the OpenThread API lock. + * + * Every OT APIs that takes an otInstance argument + * MUST be protected with this API lock except that + * the call site is in OT callbacks. + * + */ +void otSysApiLock(void); + +/** + * This function unlocks the OpenThread API lock. + * + */ +void otSysApiUnlock(void); + +#ifdef __cplusplus +} // end of extern "C" +#endif + +#endif // OT_ESP32_OPENTHREAD_ESP32_H_ diff --git a/script/bootstrap b/script/bootstrap new file mode 100755 index 0000000..dcc7339 --- /dev/null +++ b/script/bootstrap @@ -0,0 +1,34 @@ +#!/bin/sh +# +# Copyright (c) 2020, 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. +# +# Description: +# This file installs all needed dependencies and toolchains needed for +# example compilation and programming. +# + +third_party/openthread/script/bootstrap diff --git a/script/check-esp32-build b/script/check-esp32-build new file mode 100755 index 0000000..35f5675 --- /dev/null +++ b/script/check-esp32-build @@ -0,0 +1,57 @@ +#!/bin/bash +# +# Copyright (c) 2020, 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. +# + +set -euxo pipefail + +setup_esp_idf() +{ + git clone --branch release/v3.3 --recursive https://github.com/espressif/esp-idf.git + export IDF_PATH="$(pwd)"/esp-idf + + pip3 install wheel setuptools + "${IDF_PATH}"/install.sh + python3 -m pip install --user -r "${IDF_PATH}"/requirements.txt + + source ${IDF_PATH}/export.sh +} + +build_cli_app() +{ + cd example + VERBOSE=1 make defconfig + VERBOSE=1 make -j4 +} + +main() +{ + setup_esp_idf + build_cli_app +} + +main diff --git a/script/clang-format b/script/clang-format new file mode 100755 index 0000000..8cbcc0d --- /dev/null +++ b/script/clang-format @@ -0,0 +1,30 @@ +#!/bin/bash +# +# 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. +# + +third_party/openthread/script/clang-format "$@" diff --git a/script/clang-format-check b/script/clang-format-check new file mode 100755 index 0000000..470e95d --- /dev/null +++ b/script/clang-format-check @@ -0,0 +1,30 @@ +#!/bin/bash +# +# 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. +# + +third_party/openthread/script/clang-format-check "$@" diff --git a/script/make-pretty b/script/make-pretty new file mode 100755 index 0000000..dc32c12 --- /dev/null +++ b/script/make-pretty @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Copyright (c) 2019, 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. +# + +third_party/openthread/script/make-pretty "$@" diff --git a/src/alarm.c b/src/alarm.c new file mode 100644 index 0000000..4f36327 --- /dev/null +++ b/src/alarm.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "error_handling.h" + +static uint64_t sAlarmT0 = 0; +static uint64_t sAlarmDt = 0; +static bool sIsRunning = false; + +void otPlatAlarmMilliStartAt(otInstance *aInstance, uint32_t aT0, uint32_t aDt) +{ + OT_UNUSED_VARIABLE(aInstance); + + sAlarmT0 = aT0; + sAlarmDt = aDt; + sIsRunning = true; + + ESP_LOGD(OT_PLAT_LOG_TAG, "alarm start running, t0=%llu, dt=%llu", sAlarmT0, sAlarmDt); +} + +void otPlatAlarmMilliStop(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + sIsRunning = false; +} + +uint32_t otPlatAlarmMilliGetNow(void) +{ + return esp_timer_get_time() / OT_US_PER_MS; +} + +void platformAlarmUpdate(otSysMainloopContext *aMainloop) +{ + struct timeval *timeout = &aMainloop->mTimeout; + uint32_t now = otPlatAlarmMilliGetNow(); + + if (!sIsRunning) + { + timeout->tv_sec = INT32_MAX; + timeout->tv_usec = 0; + } + else if (sAlarmDt + sAlarmT0 > now) + { + uint64_t remaining = sAlarmDt + sAlarmT0 - now; + timeout->tv_sec = remaining / OT_MS_PER_S; + timeout->tv_usec = (remaining % OT_MS_PER_S) * OT_US_PER_MS; + } + else + { + timeout->tv_sec = 0; + timeout->tv_usec = 0; + } +} + +void platformAlarmProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop) +{ + OT_UNUSED_VARIABLE(aMainloop); + + if (sIsRunning) + { + if (sAlarmT0 + sAlarmDt <= otPlatAlarmMilliGetNow()) + { + sIsRunning = false; + +#if OPENTHREAD_CONFIG_DIAG_ENABLE + + if (otPlatDiagModeGet()) + { + otPlatDiagAlarmFired(aInstance); + } + else +#endif + { + otPlatAlarmMilliFired(aInstance); + } + + ESP_LOGD(OT_PLAT_LOG_TAG, "alarm fired"); + } + } +} diff --git a/src/api_lock.c b/src/api_lock.c new file mode 100644 index 0000000..14cd4b8 --- /dev/null +++ b/src/api_lock.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include +#include +#include +#include + +#include + +#include "error_handling.h" + +static SemaphoreHandle_t sApiMutex = NULL; + +void otSysApiLock(void) +{ + BaseType_t ret = xSemaphoreTake(sApiMutex, portMAX_DELAY); + VerifyOrDie(ret == pdTRUE, OT_EXIT_FAILURE); +} + +void otSysApiUnlock(void) +{ + xSemaphoreGive(sApiMutex); +} + +void platformApiLockInit(void) +{ + sApiMutex = xSemaphoreCreateMutex(); + VerifyOrDie(sApiMutex != NULL, OT_EXIT_FAILURE); +} + +void platformApiLockDeinit(void) +{ + vSemaphoreDelete(sApiMutex); + sApiMutex = NULL; +} diff --git a/src/error_handling.h b/src/error_handling.h new file mode 100644 index 0000000..4dd0ab1 --- /dev/null +++ b/src/error_handling.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020, 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. + */ + +#ifndef OT_ESP32_ERROR_HANDLING_H_ +#define OT_ESP32_ERROR_HANDLING_H_ + +#include "core/common/code_utils.hpp" +#include "core/common/logging.hpp" +#include "lib/platform/exit_code.h" + +#endif // OT_ESP32_ERROR_HANDLING_H_ diff --git a/src/flash.c b/src/flash.c new file mode 100644 index 0000000..fb2d939 --- /dev/null +++ b/src/flash.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "error_handling.h" + +static const esp_partition_t *sSettingsPartition = NULL; + +/** + * Dummy otPlatSettings APIs implementation. + */ +void otPlatSettingsInit(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); +} + +void otPlatSettingsDeinit(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); +} + +otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aKey); + OT_UNUSED_VARIABLE(aIndex); + OT_UNUSED_VARIABLE(aValue); + OT_UNUSED_VARIABLE(aValueLength); + return OT_ERROR_NOT_FOUND; +} + +otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aKey); + OT_UNUSED_VARIABLE(aValue); + OT_UNUSED_VARIABLE(aValueLength); + return OT_ERROR_NONE; +} + +otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aKey); + OT_UNUSED_VARIABLE(aValue); + OT_UNUSED_VARIABLE(aValueLength); + return OT_ERROR_NONE; +} + +otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aKey); + OT_UNUSED_VARIABLE(aIndex); + return OT_ERROR_NONE; +} + +void otPlatFlashInit(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + // esp32 startup code automatically call spi_flash_init(); + + sSettingsPartition = + esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, OT_FLASH_PARTITION_NAME); + + VerifyOrDie(sSettingsPartition != NULL, OT_EXIT_FAILURE); +} + +uint32_t otPlatFlashGetSwapSize(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return SETTINGS_CONFIG_PAGE_NUM * SETTINGS_CONFIG_PAGE_SIZE; +} + +void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex) +{ + const esp_partition_t *partition; + uint32_t address; + uint32_t size; + + OT_UNUSED_VARIABLE(aInstance); + + assert(sSettingsPartition != NULL); + + partition = sSettingsPartition; + address = SETTINGS_CONFIG_PAGE_SIZE * (aSwapIndex != 0); + size = SETTINGS_CONFIG_PAGE_SIZE; + + esp_err_t error = esp_partition_erase_range(partition, address, size); + VerifyOrDie(error == ESP_OK, OT_EXIT_FAILURE); +} + +void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize) +{ + OT_UNUSED_VARIABLE(aInstance); + + esp_err_t error = ESP_FAIL; + + VerifyOrExit(sSettingsPartition != NULL, OT_NOOP); + + aOffset += SETTINGS_CONFIG_PAGE_SIZE * (aSwapIndex != 0); + + SuccessOrExit(error = esp_partition_read(sSettingsPartition, aOffset, aData, aSize)); + +exit: + VerifyOrDie(error == ESP_OK, OT_EXIT_FAILURE); +} + +void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize) +{ + OT_UNUSED_VARIABLE(aInstance); + + esp_err_t error = ESP_FAIL; + + VerifyOrExit(sSettingsPartition != NULL, OT_NOOP); + + aOffset += SETTINGS_CONFIG_PAGE_SIZE * (aSwapIndex != 0); + + SuccessOrExit(error = esp_partition_write(sSettingsPartition, aOffset, aData, aSize)); + +exit: + VerifyOrDie(error == ESP_OK, OT_EXIT_FAILURE); +} diff --git a/src/logging.c b/src/logging.c new file mode 100644 index 0000000..79824f2 --- /dev/null +++ b/src/logging.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include + +#include + +#include +#include + +#include "error_handling.h" + +#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[256]; + int charsWritten; + va_list args; + + OT_UNUSED_VARIABLE(aLogRegion); + + va_start(args, aFormat); + charsWritten = vsnprintf(logString, sizeof(logString), aFormat, args); + if (charsWritten < 0) + { + logString[0] = '\0'; + } + + switch (aLogLevel) + { + case OT_LOG_LEVEL_CRIT: + ESP_LOGE(OT_PLAT_LOG_TAG, "%s", logString); + break; + case OT_LOG_LEVEL_WARN: + ESP_LOGW(OT_PLAT_LOG_TAG, "%s", logString); + break; + case OT_LOG_LEVEL_NOTE: + case OT_LOG_LEVEL_INFO: + ESP_LOGI(OT_PLAT_LOG_TAG, "%s", logString); + break; + default: + ESP_LOGD(OT_PLAT_LOG_TAG, "%s", logString); + break; + } + va_end(args); +} +#endif diff --git a/src/memory.c b/src/memory.c new file mode 100644 index 0000000..bba3bc0 --- /dev/null +++ b/src/memory.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +void *otPlatCAlloc(size_t aNum, size_t aSize) +{ + return calloc(aNum, aSize); +} + +void otPlatFree(void *aPtr) +{ + free(aPtr); +} diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..322a7e0 --- /dev/null +++ b/src/misc.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include + +#include + +#include + +static otPlatResetReason sPlatResetReason = OT_PLAT_RESET_REASON_POWER_ON; +bool gPlatformPseudoResetWasRequested; +static otPlatMcuPowerState gPlatMcuPowerState = OT_PLAT_MCU_POWER_STATE_ON; + +void otPlatReset(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + gPlatformPseudoResetWasRequested = true; +} + +otPlatResetReason otPlatGetResetReason(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sPlatResetReason; +} + +void otPlatWakeHost(void) +{ + // Not Implemented. +} + +otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState) +{ + otError error = OT_ERROR_NONE; + + OT_UNUSED_VARIABLE(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) +{ + OT_UNUSED_VARIABLE(aInstance); + return gPlatMcuPowerState; +} + +void otPlatAssertFail(const char *aFilename, int aLineNumber) +{ + OT_UNUSED_VARIABLE(aFilename); + OT_UNUSED_VARIABLE(aLineNumber); + assert(false); +} diff --git a/src/openthread-core-esp32-config.h b/src/openthread-core-esp32-config.h new file mode 100644 index 0000000..f7d8da1 --- /dev/null +++ b/src/openthread-core-esp32-config.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2020, 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. + */ + +#ifndef OT_ESP32_OPENTHREAD_CORE_ESP32_CONFIG_H_ +#define OT_ESP32_OPENTHREAD_CORE_ESP32_CONFIG_H_ + +/** + * @def OPENTHREAD_CONFIG_PLATFORM_INFO + * + * The platform-specific string to insert into the OpenThread version string. + * + */ +#define OPENTHREAD_CONFIG_PLATFORM_INFO "ESP32" + +/** + * @def OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT + * + * The assert is managed by platform defined logic when this flag is set. + * + */ +#define OPENTHREAD_CONFIG_PLATFORM_ASSERT_MANAGEMENT 1 + +/** + * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE + * + * Define to 1 to enable otPlatFlash* APIs to support non-volatile storage. + * + * When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs. + * + */ +#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1 + +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT + * + * The ESP32 platform provides an otPlatLog() function. + */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED + +/** + * @def OPENTHREAD_CONFIG_LOG_LEVEL + * + * The log level (used at compile time). If `OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE` is set, this defines the most + * verbose log level possible. See `OPENTHREAD_CONFIG_LOG_LEVEL_INIT` to set the initial log level. + * + */ +#ifndef OPENTHREAD_CONFIG_LOG_LEVEL +#define OPENTHREAD_CONFIG_LOG_LEVEL OT_LOG_LEVEL_INFO +#endif + +/** + * @def OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS + * + * The number of message buffers in buffer pool + */ +#define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 50 + +/** + * @def OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE + * + * Enable setting steering data out of band. + * + */ +#ifndef OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE +#define OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_COAP_API_ENABLE + * + * Define to 1 to enable the CoAP API. + * + */ +#define OPENTHREAD_CONFIG_COAP_API_ENABLE 1 + +/** + * @def OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE + * + * Define to 1 to enable Border Router support. + * + */ +#ifndef OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE +#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE + * + * Define to 1 to enable Thread Test Harness reference device support. + * + */ +#ifndef OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE +#define OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE + * + * Define to 1 to enable Child Supervision support. + * + */ +#ifndef OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE +#define OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE + * + * Define to 1 to enable DHCPv6 Client support. + * + */ +#ifndef OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE +#define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE + * + * Define to 1 to enable DHCPv6 Server support. + * + */ +#ifndef OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE +#define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE + * + * Define to 1 to enable DNS Client support. + * + */ +#ifndef OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE +#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE + * + * Define to 1 to enable multiple instance support. + * + */ +#define OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE 1 + +/** + * @def OPENTHREAD_CONFIG_NCP_SPI_ENABLE + * + * Define to 1 to enable NCP SPI support. + * + */ +#define OPENTHREAD_CONFIG_NCP_SPI_ENABLE 0 + +/** + * @def OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER + * + * Define to 1 to enable NCP Spinel Encrypter. + * + */ +#define OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER 0 + +/** + * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE + * + * Define to 1 to enable NCP UART support. + * + */ +#define OPENTHREAD_CONFIG_NCP_UART_ENABLE 1 + +/** + * @def OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE + * + * Define to 1 to support injecting Service entries into the Thread Network Data. + * + */ +#define OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE 1 + +/** + * @def PACKAGE + * + * Name of package. + * + */ +#define PACKAGE "openthread" + +/** + * @def PACKAGE_BUGREPORT + * + * Define to the address where bug reports for this package should be sent. + * + */ +#define PACKAGE_BUGREPORT "openthread-devel@googlegroups.com" + +/** + * @def PACKAGE_NAME + * + * Define to the full name of this package. + * + */ +#define PACKAGE_NAME "ot-esp32" + +/** + * @def PACKAGE_VERSION + * + * The package version. + * + */ +#define PACKAGE_VERSION "1.0.0" + +/** + * @def PACKAGE_STRING + * + * Define to the full name and version of this package. + * + */ +#define PACKAGE_STRING (PACKAGE_NAME " - " PACKAGE_VERSION) + +/** + * @def PACKAGE_TARNAME + * + * Define to the one symbol short name of this package. + * + */ +#define PACKAGE_TARNAME PACKAGE_NAME + +/** + * @def PACKAGE_URL + * + * Define to the home page for this package. + * + */ +#define PACKAGE_URL "https://github.com/openthread/ot-esp32" + +#endif // OT_ESP32_OPENTHREAD_CORE_ESP32_CONFIG_H_ diff --git a/src/platform-esp32.h b/src/platform-esp32.h new file mode 100644 index 0000000..862b280 --- /dev/null +++ b/src/platform-esp32.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2020, 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. + */ + +#ifndef OT_ESP32_PLATFORM_ESP32_H_ +#define OT_ESP32_PLATFORM_ESP32_H_ + +#include +#include + +#include + +#include + +#include + +#include "openthread-core-esp32-config.h" + +/** + * The default SPI flash partition used by OpenThread settings. + * + */ +#define OT_FLASH_PARTITION_NAME "ot_storage" + +/** + * The default page number of SPI flash partition used by OpenThread settings. + * + */ +#define SETTINGS_CONFIG_PAGE_NUM 2 + +/** + * The default page size of SPI flash partition used by OpenThread settings. + * + */ +#define SETTINGS_CONFIG_PAGE_SIZE 4096 + +/** + * The default platform logging tag. + * + */ +#define OT_PLAT_LOG_TAG "OT_ESP32_PLAT" + +/** + * The default TXD pin of the radio uart. + * + */ +#ifndef OT_RADIO_UART_TXD +#define OT_RADIO_UART_TXD (GPIO_NUM_2) +#endif + +/** + * The default RXD pin of the radio uart. + * + */ +#ifndef OT_RADIO_UART_RXD +#define OT_RADIO_UART_RXD (GPIO_NUM_5) +#endif + +/** + * The uart used by radio spinel. + * + */ +#ifndef OT_RADIO_UART_NUM +#define OT_RADIO_UART_NUM (UART_NUM_1) +#endif + +/** + * The uart used by OpenThread CLI. + * + */ +#define OT_CLI_UART_NUM (UART_NUM_0) + +/** + * The uart receive buffer size for both CLI uart and radio uart. + * + */ +#define OT_UART_RX_BUF_SIZE (UART_FIFO_LEN * 2) + +/** + * Milliseconds per Second. + * + */ +#ifndef OT_MS_PER_S +#define OT_MS_PER_S 1000 +#endif + +/** + * Microseconds per Millisecond. + * + */ +#ifndef OT_US_PER_MS +#define OT_US_PER_MS 1000 +#endif + +/** + * Microseconds per Second. + * + */ +#ifndef OT_US_PER_S +#define OT_US_PER_S (OT_MS_PER_S * OT_US_PER_MS) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This function updates OpenThread alarm events to the mainloop context. + * + * @param[inout] aMainloop The mainloop context; + * + */ +void platformAlarmUpdate(otSysMainloopContext *aMainloop); + +/** + * This function process alarm events. + * + * @param[in] aInstance The OpenThread instance. + * @param[in] aMainloop The mainloop context. + * + */ +void platformAlarmProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop); + +/** + * This function initialize the CLI UART driver. + * + */ +void platformCliUartInit(void); + +/** + * This function deinitialize the CLI UART driver. + * + */ +void platformCliUartDeinit(void); + +/** + * This function updates CLI UART events to the mainloop context. + * + * param[inout] aMainloop The mainloop context. + * + */ +void platformCliUartUpdate(otSysMainloopContext *aMainloop); + +/** + * This function process CLI UART events. + * + * @param[in] aInstance The OpenThread instance. + * @param[in] aMainloop The mainloop context. + * + */ +void platformCliUartProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop); + +/** + * This function initializes the radio transceiver. + * + * @param[in] aResetRadio TRUE to reset on init, FALSE to not reset on init. + * @param[in] aRestoreDatasetFromNcp TRUE to restore dataset to host from non-volatile memory + * (only used when attempts to upgrade from NCP to RCP mode), + * FALSE otherwise. + * + */ +void platformRadioInit(bool aResetRadio, bool aRestoreDataSetFromNcp); + +/** + * This function deinitialize the radio driver. + * + */ +void platformRadioDeinit(void); + +/** + * This function updates spinel radio events to the mainloop context. + * + * param[inout] aMainloop The mainloop context. + * + */ +void platformRadioUpdate(otSysMainloopContext *aMainloop); + +/** + * This function process radio events. + * + * @param[in] aInstance The OpenThread instance. + * @param[in] aMainloop The mainloop context. + * + */ +void platformRadioProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop); + +/** + * This function initializes the API lock. + * + */ +void platformApiLockInit(void); + +/** + * This function deinitialize the API lock. + * + */ +void platformApiLockDeinit(void); + +#ifdef __cplusplus +} +#endif + +#endif // OT_ESP32_PLATFORM_ESP32_H_ diff --git a/src/radio.cpp b/src/radio.cpp new file mode 100644 index 0000000..3f17025 --- /dev/null +++ b/src/radio.cpp @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2020, 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 OpenThread platform driver API in openthread/platform/radio.h. + * + */ + +#include "platform-esp32.h" + +#include + +#include "radio_spinel.hpp" +#include "spinel_hdlc.hpp" + +static ot::Spinel::RadioSpinel sRadioSpinel; + +void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) +{ + OT_UNUSED_VARIABLE(aInstance); + SuccessOrDie(sRadioSpinel.GetIeeeEui64(aIeeeEui64)); +} + +void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid) +{ + OT_UNUSED_VARIABLE(aInstance); + SuccessOrDie(sRadioSpinel.SetPanId(panid)); +} + +void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aAddress) +{ + OT_UNUSED_VARIABLE(aInstance); + otExtAddress addr; + + for (size_t i = 0; i < sizeof(addr); i++) + { + addr.m8[i] = aAddress->m8[sizeof(addr) - 1 - i]; + } + + SuccessOrDie(sRadioSpinel.SetExtendedAddress(addr)); +} + +void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t aAddress) +{ + OT_UNUSED_VARIABLE(aInstance); + SuccessOrDie(sRadioSpinel.SetShortAddress(aAddress)); +} + +void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable) +{ + OT_UNUSED_VARIABLE(aInstance); + SuccessOrDie(sRadioSpinel.SetPromiscuous(aEnable)); +} + +bool otPlatRadioIsEnabled(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.IsEnabled(); +} + +otError otPlatRadioEnable(otInstance *aInstance) +{ + return sRadioSpinel.Enable(aInstance); +} + +otError otPlatRadioDisable(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.Disable(); +} + +otError otPlatRadioSleep(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.Sleep(); +} + +otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.Receive(aChannel); +} + +otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.Transmit(*aFrame); +} + +otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return &sRadioSpinel.GetTransmitFrame(); +} + +int8_t otPlatRadioGetRssi(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.GetRssi(); +} + +otRadioCaps otPlatRadioGetCaps(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.GetRadioCaps(); +} + +const char *otPlatRadioGetVersionString(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.GetVersion(); +} + +bool otPlatRadioGetPromiscuous(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.IsPromiscuous(); +} + +void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable) +{ + OT_UNUSED_VARIABLE(aInstance); + SuccessOrDie(sRadioSpinel.EnableSrcMatch(aEnable)); +} + +otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.AddSrcMatchShortEntry(aShortAddress); +} + +otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress) +{ + OT_UNUSED_VARIABLE(aInstance); + otExtAddress addr; + + for (size_t i = 0; i < sizeof(addr); i++) + { + addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i]; + } + + return sRadioSpinel.AddSrcMatchExtEntry(addr); +} + +otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.ClearSrcMatchShortEntry(aShortAddress); +} + +otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress) +{ + OT_UNUSED_VARIABLE(aInstance); + otExtAddress addr; + + for (size_t i = 0; i < sizeof(addr); i++) + { + addr.m8[i] = aExtAddress->m8[sizeof(addr) - 1 - i]; + } + + return sRadioSpinel.ClearSrcMatchExtEntry(addr); +} + +void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + SuccessOrDie(sRadioSpinel.ClearSrcMatchShortEntries()); +} + +void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + SuccessOrDie(sRadioSpinel.ClearSrcMatchExtEntries()); +} + +otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.EnergyScan(aScanChannel, aScanDuration); +} + +otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower) +{ + otError error; + + OT_UNUSED_VARIABLE(aInstance); + VerifyOrExit(aPower != NULL, error = OT_ERROR_INVALID_ARGS); + error = sRadioSpinel.GetTransmitPower(*aPower); + +exit: + return error; +} + +otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.SetTransmitPower(aPower); +} + +otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold) +{ + otError error; + + OT_UNUSED_VARIABLE(aInstance); + VerifyOrExit(aThreshold != NULL, error = OT_ERROR_INVALID_ARGS); + error = sRadioSpinel.GetCcaEnergyDetectThreshold(*aThreshold); + +exit: + return error; +} + +otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.SetCcaEnergyDetectThreshold(aThreshold); +} + +int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.GetReceiveSensitivity(); +} + +#if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE +otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.SetCoexEnabled(aEnabled); +} + +bool otPlatRadioIsCoexEnabled(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.IsCoexEnabled(); +} + +otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics) +{ + OT_UNUSED_VARIABLE(aInstance); + + otError error = OT_ERROR_NONE; + + VerifyOrExit(aCoexMetrics != NULL, error = OT_ERROR_INVALID_ARGS); + + error = sRadioSpinel.GetCoexMetrics(*aCoexMetrics); + +exit: + return error; +} +#endif + +#if OPENTHREAD_CONFIG_DIAG_ENABLE +otError otPlatDiagProcess(otInstance *aInstance, int argc, char *argv[], char *aOutput, size_t aOutputMaxLen) +{ + // deliver the platform specific diags commands to radio only ncp. + OT_UNUSED_VARIABLE(aInstance); + char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE] = {'\0'}; + char *cur = cmd; + char *end = cmd + sizeof(cmd); + + for (int index = 0; index < argc; index++) + { + cur += snprintf(cur, static_cast(end - cur), "%s ", argv[index]); + } + + return sRadioSpinel.PlatDiagProcess(cmd, aOutput, aOutputMaxLen); +} + +void otPlatDiagModeSet(bool aMode) +{ + SuccessOrExit(sRadioSpinel.PlatDiagProcess(aMode ? "start" : "stop", NULL, 0)); + sRadioSpinel.SetDiagEnabled(aMode); + +exit: + return; +} + +bool otPlatDiagModeGet(void) +{ + return sRadioSpinel.IsDiagEnabled(); +} + +void otPlatDiagTxPowerSet(int8_t aTxPower) +{ + char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; + + snprintf(cmd, sizeof(cmd), "power %d", aTxPower); + SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, NULL, 0)); + +exit: + return; +} + +void otPlatDiagChannelSet(uint8_t aChannel) +{ + char cmd[OPENTHREAD_CONFIG_DIAG_CMD_LINE_BUFFER_SIZE]; + + snprintf(cmd, sizeof(cmd), "channel %d", aChannel); + SuccessOrExit(sRadioSpinel.PlatDiagProcess(cmd, NULL, 0)); + +exit: + return; +} + +void otPlatDiagRadioReceived(otInstance *aInstance, otRadioFrame *aFrame, otError aError) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aFrame); + OT_UNUSED_VARIABLE(aError); +} + +void otPlatDiagAlarmCallback(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); +} +#endif // OPENTHREAD_CONFIG_DIAG_ENABLE + +uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.GetRadioChannelMask(false); +} + +uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.GetRadioChannelMask(true); +} + +otRadioState otPlatRadioGetState(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + return sRadioSpinel.GetState(); +} + +void platformRadioInit(bool aResetRadio, bool aRestoreDataSetFromNcp) +{ + sRadioSpinel.GetSpinelInterface().Init(); + sRadioSpinel.Init(aResetRadio, aRestoreDataSetFromNcp); +} + +void platformRadioDeinit(void) +{ + sRadioSpinel.Deinit(); +} + +void platformRadioProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop) +{ + (void)aInstance; + sRadioSpinel.Process(*aMainloop); +} + +void platformRadioUpdate(otSysMainloopContext *aMainloop) +{ + sRadioSpinel.GetSpinelInterface().Update(*aMainloop); +} diff --git a/src/spinel_hdlc.cpp b/src/spinel_hdlc.cpp new file mode 100644 index 0000000..0f29efa --- /dev/null +++ b/src/spinel_hdlc.cpp @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2020, 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 "spinel_hdlc.hpp" + +#include "platform-esp32.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +#include "error_handling.h" + +namespace ot { + +namespace Esp32 { + +HdlcInterface::HdlcInterface(ot::Spinel::SpinelInterface::ReceiveFrameCallback aCallback, + void * aCallbackContext, + ot::Spinel::SpinelInterface::RxFrameBuffer & aFrameBuffer) + : mReceiveFrameCallback(aCallback) + , mReceiveFrameContext(aCallbackContext) + , mReceiveFrameBuffer(aFrameBuffer) + , mHdlcDecoder(aFrameBuffer, HandleHdlcFrame, this) +{ +} + +HdlcInterface::~HdlcInterface(void) +{ +} + +void HdlcInterface::Init(void) +{ + mUartRxBuffer = static_cast(heap_caps_malloc(kMaxFrameSize, MALLOC_CAP_8BIT)); + VerifyOrDie(mUartRxBuffer != NULL, OT_EXIT_FAILURE); + + InitUart(); +} + +void HdlcInterface::Deinit(void) +{ + DeinitUart(); + + heap_caps_free(mUartRxBuffer); + mUartRxBuffer = NULL; +} + +otError HdlcInterface::SendFrame(const uint8_t *aFrame, uint16_t aLength) +{ + otError error = OT_ERROR_NONE; + ot::Hdlc::FrameBuffer encoderBuffer; + ot::Hdlc::Encoder hdlcEncoder(encoderBuffer); + + SuccessOrExit(error = hdlcEncoder.BeginFrame()); + SuccessOrExit(error = hdlcEncoder.Encode(aFrame, aLength)); + SuccessOrExit(error = hdlcEncoder.EndFrame()); + + SuccessOrExit(error = Write(encoderBuffer.GetFrame(), encoderBuffer.GetLength())); + +exit: + if (error != OT_ERROR_NONE) + { + ESP_LOGE(OT_PLAT_LOG_TAG, "send radio frame failed"); + } + else + { + ESP_LOGD(OT_PLAT_LOG_TAG, "sent radio frame\n"); + } + + return error; +} + +void HdlcInterface::Process(const otSysMainloopContext &aMainloop) +{ + if (FD_ISSET(mUartFd, &aMainloop.mReadFdSet)) + { + ESP_LOGD(OT_PLAT_LOG_TAG, "radio uart read event"); + TryReadAndDecode(); + } +} + +void HdlcInterface::Update(otSysMainloopContext &aMainloop) +{ + // Register only READ events for radio UART and always wait + // for a radio WRITE to complete. + FD_SET(mUartFd, &aMainloop.mReadFdSet); + if (mUartFd > aMainloop.mMaxFd) + { + aMainloop.mMaxFd = mUartFd; + } +} + +int HdlcInterface::TryReadAndDecode(void) +{ + uint8_t buffer[kMaxFrameSize]; + ssize_t rval; + + rval = read(mUartFd, buffer, sizeof(buffer)); + + if (rval > 0) + { + mHdlcDecoder.Decode(buffer, static_cast(rval)); + } + else if ((rval < 0) && (errno != EAGAIN) && (errno != EINTR)) + { + abort(); + } + + return rval; +} + +otError HdlcInterface::WaitForWritable(void) +{ + otError error = OT_ERROR_NONE; + struct timeval timeout = {kMaxWaitTime / OT_MS_PER_S, (kMaxWaitTime % OT_MS_PER_S) * OT_US_PER_MS}; + uint64_t now = otPlatTimeGet(); + uint64_t end = now + kMaxWaitTime * OT_US_PER_MS; + fd_set writeFds; + fd_set errorFds; + int rval; + + while (true) + { + FD_ZERO(&writeFds); + FD_ZERO(&errorFds); + FD_SET(mUartFd, &writeFds); + FD_SET(mUartFd, &errorFds); + + rval = select(mUartFd + 1, NULL, &writeFds, &errorFds, &timeout); + + if (rval > 0) + { + if (FD_ISSET(mUartFd, &writeFds)) + { + ExitNow(); + } + else if (FD_ISSET(mUartFd, &errorFds)) + { + VerifyOrDie(false, OT_EXIT_FAILURE); + } + else + { + assert(false); + } + } + else if ((rval < 0) && (errno != EINTR)) + { + VerifyOrDie(false, OT_EXIT_FAILURE); + } + + now = otPlatTimeGet(); + + if (end > now) + { + uint64_t remain = end - now; + + timeout.tv_sec = static_cast(remain / 1000000); + timeout.tv_usec = static_cast(remain % 1000000); + } + else + { + break; + } + } + + error = OT_ERROR_FAILED; + +exit: + return error; +} + +otError HdlcInterface::Write(const uint8_t *aFrame, uint16_t aLength) +{ + otError error = OT_ERROR_NONE; + + while (aLength) + { + ssize_t rval = write(mUartFd, aFrame, aLength); + + if (rval > 0) + { + assert(rval <= aLength); + aLength -= static_cast(rval); + aFrame += static_cast(rval); + continue; + } + + if ((rval < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR)) + { + abort(); + } + + SuccessOrExit(error = WaitForWritable()); + } + +exit: + return error; +} + +otError HdlcInterface::WaitForFrame(uint64_t aTimeoutUs) +{ + otError error = OT_ERROR_NONE; + struct timeval timeout; + fd_set read_fds; + fd_set error_fds; + int rval; + + FD_ZERO(&read_fds); + FD_ZERO(&error_fds); + FD_SET(mUartFd, &read_fds); + FD_SET(mUartFd, &error_fds); + + timeout.tv_sec = static_cast(aTimeoutUs / OT_US_PER_S); + timeout.tv_usec = static_cast(aTimeoutUs % OT_US_PER_S); + + rval = select(mUartFd + 1, &read_fds, NULL, &error_fds, &timeout); + + if (rval > 0) + { + if (FD_ISSET(mUartFd, &read_fds)) + { + TryReadAndDecode(); + } + else if (FD_ISSET(mUartFd, &error_fds)) + { + abort(); + } + else + { + abort(); + } + } + else if (rval == 0) + { + ExitNow(error = OT_ERROR_RESPONSE_TIMEOUT); + } + else if (errno != EINTR) + { + abort(); + } + +exit: + return error; +} + +void HdlcInterface::HandleHdlcFrame(void *aContext, otError aError) +{ + static_cast(aContext)->HandleHdlcFrame(aError); +} + +void HdlcInterface::HandleHdlcFrame(otError aError) +{ + if (aError == OT_ERROR_NONE) + { + ESP_LOGD(OT_PLAT_LOG_TAG, "received hdlc radio frame\n"); + mReceiveFrameCallback(mReceiveFrameContext); + } + else + { + ESP_LOGE(OT_PLAT_LOG_TAG, "dropping radio frame: %s\n", otThreadErrorToString(aError)); + mReceiveFrameBuffer.DiscardFrame(); + } +} + +void HdlcInterface::InitUart(void) +{ + char uartPath[16]; + uart_config_t uart_config = {.baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 0, + .use_ref_tick = false}; + + ESP_ERROR_CHECK(uart_param_config(OT_RADIO_UART_NUM, &uart_config)); + ESP_ERROR_CHECK( + uart_set_pin(OT_RADIO_UART_NUM, OT_RADIO_UART_TXD, OT_RADIO_UART_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_driver_install(OT_RADIO_UART_NUM, OT_UART_RX_BUF_SIZE, 0, 0, NULL, 0)); + + // We have a driver now installed so set up the read/write functions to use driver also. + esp_vfs_dev_uart_use_driver(OT_RADIO_UART_NUM); + + sprintf(uartPath, "/dev/uart/%d", OT_RADIO_UART_NUM); + mUartFd = open(uartPath, O_RDWR | O_NONBLOCK); + + VerifyOrDie(mUartFd != -1, OT_EXIT_FAILURE); +} + +void HdlcInterface::DeinitUart(void) +{ + if (mUartFd != -1) + { + close(mUartFd); + mUartFd = -1; + } + ESP_ERROR_CHECK(uart_driver_delete(OT_RADIO_UART_NUM)); +} + +} // namespace Esp32 + +} // namespace ot diff --git a/src/spinel_hdlc.hpp b/src/spinel_hdlc.hpp new file mode 100644 index 0000000..7a944e0 --- /dev/null +++ b/src/spinel_hdlc.hpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2020, 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. + */ + +#ifndef OT_ESP32_SPINEL_HDLC_HPP_ +#define OT_ESP32_SPINEL_HDLC_HPP_ + +#include "openthread-core-esp32-config.h" + +#include + +#include "lib/spinel/spinel_interface.hpp" + +namespace ot { + +namespace Esp32 { + +typedef uint8_t HdlcSpinelContext; + +/** + * This class defines an HDLC spinel interface to the Radio Co-processor (RCP). + * + */ +class HdlcInterface +{ +public: + /** + * This constructor initializes the object. + * + * @param[in] aCallback Callback on frame received + * @param[in] aCallbackContext Callback context + * @param[in] aFrameBuffer A reference to a `RxFrameBuffer` object. + * + */ + HdlcInterface(ot::Spinel::SpinelInterface::ReceiveFrameCallback aCallback, + void * aCallbackContext, + ot::Spinel::SpinelInterface::RxFrameBuffer & aFrameBuffer); + + /** + * This destructor deinitializes the object. + * + */ + ~HdlcInterface(void); + + /** + * This method initializes the HDLC interface. + * + */ + void Init(void); + + /** + * This method deinitializes the HDLC interface. + * + */ + void Deinit(void); + + /** + * This method encodes and sends a spinel frame to Radio Co-processor (RCP) over the socket. + * + * This is blocking call, i.e., if the socket is not writable, this method waits for it to become writable for + * up to `kMaxWaitTime` interval. + * + * @param[in] aFrame A pointer to buffer containing the spinel frame to send. + * @param[in] aLength The length (number of bytes) in the frame. + * + * @retval OT_ERROR_NONE Successfully encoded and sent the spinel frame. + * @retval OT_ERROR_NO_BUFS Insufficient buffer space available to encode the frame. + * @retval OT_ERROR_FAILED Failed to send due to socket not becoming writable within `kMaxWaitTime`. + * + */ + otError SendFrame(const uint8_t *aFrame, uint16_t aLength); + + /** + * This method waits for receiving part or all of spinel frame within specified timeout. + * + * @param[in] aTimeoutUs The timeout value in microseconds. + * + * @retval OT_ERROR_NONE Part or all of spinel frame is received. + * @retval OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p aTimeoutUs. + * + */ + otError WaitForFrame(uint64_t aTimeoutUs); + + /** + * This method performs radio driver processing. + * + * @param[in] aContext The context containing no thing, never used. + * + */ + void Process(const otSysMainloopContext &aMainloop); + + /** + * This methods updates the mainloop context. + * + * @param[in] aMainloop A mainloop context. + * + */ + void Update(otSysMainloopContext &aMainloop); + +private: + enum + { + /** + * Maximum spinel frame size. + * + */ + kMaxFrameSize = ot::Spinel::SpinelInterface::kMaxFrameSize, + + /** + * Maximum wait time in Milliseconds for socket to become writable (see `SendFrame`). + * + */ + kMaxWaitTime = 2000, + }; + + void InitUart(void); + void DeinitUart(void); + + int TryReadAndDecode(void); + + /** + * This method waits for the UART file descriptor associated with the HDLC interface to become writable within + * `kMaxWaitTime` interval. + * + * @retval OT_ERROR_NONE Socket is writable. + * @retval OT_ERROR_FAILED Socket did not become writable within `kMaxWaitTime`. + * + */ + otError WaitForWritable(void); + + /** + * This method writes a given frame to the socket. + * + * This is blocking call, i.e., if the UART is not writable, this method waits for it to become writable for + * up to `kMaxWaitTime` interval. + * + * @param[in] aFrame A pointer to buffer containing the frame to write. + * @param[in] aLength The length (number of bytes) in the frame. + * + * @retval OT_ERROR_NONE Frame was written successfully. + * @retval OT_ERROR_FAILED Failed to write due to UART not becoming writable within `kMaxWaitTime`. + * + */ + otError Write(const uint8_t *aFrame, uint16_t aLength); + + static void HandleHdlcFrame(void *aContext, otError aError); + void HandleHdlcFrame(otError aError); + + ot::Spinel::SpinelInterface::ReceiveFrameCallback mReceiveFrameCallback; + void * mReceiveFrameContext; + ot::Spinel::SpinelInterface::RxFrameBuffer & mReceiveFrameBuffer; + + ot::Hdlc::Decoder mHdlcDecoder; + uint8_t * mUartRxBuffer; + + int mUartFd; + + // Non-copyable, intentionally not implemented. + HdlcInterface(const HdlcInterface &); + HdlcInterface &operator=(const HdlcInterface &); +}; + +} // namespace Esp32 + +} // namespace ot + +#endif // OT_ESP32_SPINEL_HDLC_HPP_ diff --git a/src/system.c b/src/system.c new file mode 100644 index 0000000..b8289d0 --- /dev/null +++ b/src/system.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +extern bool gPlatformPseudoResetWasRequested; + +void otSysInit(int argc, char *argv[]) +{ + OT_UNUSED_VARIABLE(argc); + OT_UNUSED_VARIABLE(argv); + + if (gPlatformPseudoResetWasRequested) + { + gPlatformPseudoResetWasRequested = false; + } + + platformApiLockInit(); + platformCliUartInit(); + platformRadioInit(/* aResetRadio */ true, /* aRestoreDataSetFromNcp */ false); + + ESP_LOGI(OT_PLAT_LOG_TAG, "init radio done"); +} + +void otSysDeinit(void) +{ + platformRadioDeinit(); + platformCliUartDeinit(); + platformApiLockDeinit(); +} + +bool otSysPseudoResetWasRequested(void) +{ + return gPlatformPseudoResetWasRequested; +} + +void otSysMainloopInit(otSysMainloopContext *aMainloop) +{ + FD_ZERO(&aMainloop->mReadFdSet); + FD_ZERO(&aMainloop->mWriteFdSet); + FD_ZERO(&aMainloop->mErrorFdSet); + + aMainloop->mMaxFd = -1; + aMainloop->mTimeout.tv_sec = 10; + aMainloop->mTimeout.tv_usec = 0; +} + +void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop) +{ + platformAlarmUpdate(aMainloop); + + platformCliUartUpdate(aMainloop); + + platformRadioUpdate(aMainloop); + + if (otTaskletsArePending(aInstance)) + { + aMainloop->mTimeout.tv_sec = 0; + aMainloop->mTimeout.tv_usec = 0; + } +} + +int otSysMainloopPoll(otSysMainloopContext *aMainloop) +{ + return select(aMainloop->mMaxFd + 1, &aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet, + &aMainloop->mTimeout); +} + +void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop) +{ + platformCliUartProcess(aInstance, aMainloop); + platformRadioProcess(aInstance, aMainloop); + platformAlarmProcess(aInstance, aMainloop); +} diff --git a/src/time.c b/src/time.c new file mode 100644 index 0000000..0b35a65 --- /dev/null +++ b/src/time.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include +#include +#include + +#include +#include + +#include "error_handling.h" + +/** + * Get the current time (64bits width). + * + * @returns The current time in microseconds. + * + */ +uint64_t otPlatTimeGet(void) +{ + struct timeval tv_now; + + int err = gettimeofday(&tv_now, NULL); + VerifyOrDie(err == 0, OT_EXIT_FAILURE); + + return (uint64_t)tv_now.tv_sec * OT_US_PER_S + tv_now.tv_usec; +} diff --git a/src/uart.c b/src/uart.c new file mode 100644 index 0000000..e52a57b --- /dev/null +++ b/src/uart.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2020, 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-esp32.h" + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "error_handling.h" + +static int sCliUartFd; + +otError otPlatUartEnable(void) +{ + return OT_ERROR_NONE; +} + +otError otPlatUartDisable(void) +{ + return OT_ERROR_NONE; +} + +otError otPlatUartFlush(void) +{ + return OT_ERROR_NONE; +} + +otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength) +{ + otError error = OT_ERROR_NONE; + + int rval = write(sCliUartFd, aBuf, aBufLength); + + VerifyOrExit(rval == (int)aBufLength, error = OT_ERROR_FAILED); + + otPlatUartSendDone(); + +exit: + return error; +} + +void platformCliUartInit() +{ + char uartPath[16]; + uart_config_t uart_config = {.baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 0, + .use_ref_tick = false}; + ESP_ERROR_CHECK(uart_param_config(OT_CLI_UART_NUM, &uart_config)); + + // Disable IO buffer. + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + + // Install UART driver for interrupt-driven reads and writes. + ESP_ERROR_CHECK(uart_driver_install(OT_CLI_UART_NUM, OT_UART_RX_BUF_SIZE, 0, 0, NULL, 0)); + + // Tell VFS to use UART driver. + esp_vfs_dev_uart_use_driver(OT_CLI_UART_NUM); + + esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_LF); + esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_LF); + + sprintf(uartPath, "/dev/uart/%d", OT_CLI_UART_NUM); + sCliUartFd = open(uartPath, O_RDWR | O_NONBLOCK); + + VerifyOrDie(sCliUartFd != -1, OT_EXIT_FAILURE); +} + +void platformCliUartDeinit(void) +{ + if (sCliUartFd != -1) + { + close(sCliUartFd); + sCliUartFd = -1; + } + uart_driver_delete(OT_CLI_UART_NUM); +} + +void platformCliUartUpdate(otSysMainloopContext *aMainloop) +{ + FD_SET(sCliUartFd, &aMainloop->mReadFdSet); + if (sCliUartFd > aMainloop->mMaxFd) + { + aMainloop->mMaxFd = sCliUartFd; + } +} + +void platformCliUartProcess(otInstance *aInstance, const otSysMainloopContext *aMainloop) +{ + (void)aInstance; + + if (FD_ISSET(sCliUartFd, &aMainloop->mReadFdSet)) + { + uint8_t buffer[256]; + + int rval = read(sCliUartFd, buffer, sizeof(buffer)); + + if (rval > 0) + { + otPlatUartReceived(buffer, (uint16_t)rval); + } + else if (rval > 0) + { + VerifyOrDie(errno == EAGAIN || errno == EINTR, OT_EXIT_FAILURE); + } + } +} diff --git a/third_party/openthread b/third_party/openthread new file mode 160000 index 0000000..aa1b292 --- /dev/null +++ b/third_party/openthread @@ -0,0 +1 @@ +Subproject commit aa1b2927c8898f46583b427ee3293133dd2e7f2c