├── .github ├── dependabot.yml └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.txt ├── LICENSE ├── README.md ├── config └── ncs │ ├── overlay-common.conf │ ├── overlay-ot-cli-ftd-1.1.conf │ ├── overlay-ot-cli-ftd-1.2.conf │ ├── overlay-ot-cli-ftd-1.3.conf │ ├── overlay-ot-cli-ftd-1.4.conf │ ├── overlay-ot-cli-ftd-common.conf │ ├── overlay-ot-rcp-1.2.conf │ ├── overlay-ot-rcp-1.3.conf │ ├── overlay-ot-rcp-1.4.conf │ ├── overlay-ot-rcp-common.conf │ ├── requirements-nrfutil.txt │ └── sdk-nrf-commit ├── doc ├── OpenThread 1.2 Reference Release QSG.pdf └── nRF52840 Dongle Programming Guide_v4.pdf ├── requirements.txt ├── script ├── bootstrap.bash ├── make-commissioner.bash ├── make-firmware.bash ├── make-pretty ├── make-raspbian.bash ├── make-reference-release.bash ├── make-thci.bash ├── mount.bash ├── otbr-cleanup.bash └── otbr-setup.bash └── thci ├── OTNCS.py └── OTNCS_BR.py /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2025, The OpenThread Authors. 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # 1. Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # 2. Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # 3. Neither the name of the copyright holder nor the 13 | # names of its contributors may be used to endorse or promote products 14 | # derived from this software without specific prior written permission. 15 | # 16 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | # POSSIBILITY OF SUCH DAMAGE. 27 | # 28 | 29 | version: 2 30 | updates: 31 | - package-ecosystem: "github-actions" 32 | directory: "/" 33 | schedule: 34 | interval: "weekly" 35 | commit-message: 36 | prefix: "github-actions" 37 | labels: 38 | - "dependencies" 39 | rebase-strategy: "disabled" 40 | open-pull-requests-limit: 1 41 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2023, The OpenThread Authors. 3 | # All rights reserved. 4 | # 5 | # Redistribution and use in source and binary forms, with or without 6 | # modification, are permitted provided that the following conditions are met: 7 | # 1. Redistributions of source code must retain the above copyright 8 | # notice, this list of conditions and the following disclaimer. 9 | # 2. Redistributions in binary form must reproduce the above copyright 10 | # notice, this list of conditions and the following disclaimer in the 11 | # documentation and/or other materials provided with the distribution. 12 | # 3. Neither the name of the copyright holder nor the 13 | # names of its contributors may be used to endorse or promote products 14 | # derived from this software without specific prior written permission. 15 | # 16 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | # POSSIBILITY OF SUCH DAMAGE. 27 | # 28 | name: Build 29 | 30 | on: 31 | push: 32 | pull_request: 33 | branches: 34 | - 'main' 35 | 36 | jobs: 37 | build: 38 | runs-on: ubuntu-latest 39 | steps: 40 | - name: Free Disk Space (Ubuntu) 41 | uses: jlumbroso/free-disk-space@main 42 | - name: Bootstrap 43 | run: | 44 | cd /tmp 45 | sudo apt-get update 46 | sudo apt-get --no-install-recommends install -y ninja-build gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf 47 | wget --tries 4 --no-check-certificate --quiet https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/RC2.1/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2 -O gcc-arm.tar.bz2 48 | tar xjf gcc-arm.tar.bz2 49 | echo "PATH=/tmp/gcc-arm-none-eabi-9-2019-q4-major/bin:$PATH" >> "$GITHUB_ENV" 50 | wget --tries 4 --no-check-certificate --quiet https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz -O gcc-arm 51 | tar xf gcc-arm 52 | - name: Checkout 53 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 54 | with: 55 | submodules: recursive 56 | - name: Build nrf52840 reference release for 1.2 57 | run: | 58 | REFERENCE_PLATFORM=nrf52840 REFERENCE_RELEASE_TYPE=1.2 ./script/make-reference-release.bash 59 | - name: Build nrf52840 reference release for 1.3 60 | run: | 61 | REFERENCE_PLATFORM=nrf52840 REFERENCE_RELEASE_TYPE=1.3 ./script/make-reference-release.bash 62 | - name: Build ncs reference release for 1.4 63 | run: | 64 | git submodule status 65 | export ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb 66 | export GNUARMEMB_TOOLCHAIN_PATH=/tmp/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/ 67 | REFERENCE_PLATFORM=ncs REFERENCE_RELEASE_TYPE=1.4 ./script/make-reference-release.bash 68 | - uses: actions/upload-artifact@v4 69 | with: 70 | name: reference-releases 71 | path: | 72 | build/ot-1.4* 73 | retention-days: 1 74 | if-no-files-found: error 75 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build*/ 2 | output/ 3 | .idea 4 | ncs/* 5 | mnt-rpi/* 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ot-br-posix"] 2 | path = ot-br-posix 3 | url = https://github.com/openthread/ot-br-posix 4 | [submodule "ot-nrf528xx"] 5 | path = ot-nrf528xx 6 | url = https://github.com/openthread/ot-nrf528xx 7 | [submodule "ot-commissioner"] 8 | path = ot-commissioner 9 | url = https://github.com/openthread/ot-commissioner 10 | branch = cert 11 | [submodule "openthread"] 12 | path = openthread 13 | url = https://github.com/openthread/openthread 14 | [submodule "docker-rpi-emu"] 15 | path = docker-rpi-emu 16 | url = https://github.com/ryankurte/docker-rpi-emu.git 17 | [submodule "openthread-1.1"] 18 | path = openthread-1.1 19 | url = https://github.com/openthread/openthread.git 20 | [submodule "ot-efr32"] 21 | path = ot-efr32 22 | url = https://github.com/openthread/ot-efr32 23 | -------------------------------------------------------------------------------- /CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | NOTES: 2 | 3 | * Refer to OpenThread 1.2 Reference Release QSG.pdf for setup guide. 4 | * Verified that THCI works with Thread 1.2 Test Harness 1.2, without assurance to pass certification regression tests. 5 | * Two APIs (`mdns_query()` and `mldv2_query()`) are missing for Host Role. Recommend using Host Device from the other vendors during certification. 6 | 7 | FEATURES 8 | 9 | * Low Power 10 | * Multicast across Thread Networks 11 | * Domain Unicast Address 12 | * OT-Commissioner, Host 13 | 14 | CHANGELOG 15 | ========== 16 | * 06/03/2025 17 | * Support of RDNSS link-local server address 18 | * Updated submodules 19 | * openthread commitid: ea3a3da 20 | * ot-br-posix commitid: 153e800 21 | * ot-nrf528xx commitid: 4966f65 22 | 23 | * 05/21/2025 24 | * New OT API to signal upstream DNS unavailability 25 | * Updated submodules 26 | * openthread commitid: 4071e32 27 | * ot-br-posix commitid: a204b9e 28 | * ot-nrf528xx commitid: 5d54f48 29 | 30 | * 05/16/2025 31 | * Update mDNSResponder to latest 2600.100.147 32 | * Updated submodules 33 | * openthread commitid: fb0446f 34 | * ot-br-posix commitid: e4e1d0c 35 | 36 | * 05/15/2025 37 | * Updated submodules 38 | * ot-commissioner commitid: f31a98a 39 | 40 | * 04/08/2025 41 | * Support of RA RDNSS 42 | * Updated submodules 43 | * openthread commitid: c9c19aa 44 | * ot-br-posix commitid: a5f8e53 45 | * ot-nrf528xx commitid: 8ef210b 46 | 47 | * 04/01/2025 48 | * Remove the python2 occurrences 49 | * Updated submodules 50 | * ot-commissioner 06adb26 51 | 52 | * 03/05/2025 53 | * Fix for deprecation of expired DHCPv6 lease prefixes 54 | * Updated submodules 55 | * openthread commitid: b1ca77a 56 | * ot-br-posix commitid: 6b9a12e 57 | * ot-nrf528xx commitid: b1b8548 58 | 59 | * 01/21/2025 60 | * Disable PD daemon to fix mDNS disruption 61 | * Updated submodules 62 | * openthread commitid: f6cee79 63 | * ot-br-posix commitid: b574b6c 64 | * ot-nrf528xx commitid: 6586034 65 | 66 | * 11/26/2024 67 | * Updated submodules 68 | * openthread commitid: 147de7e 69 | * ot-br-posix commitid: 7fd5bd1 70 | * ot-nrf528xx commitid: c3b8222 71 | 72 | * 11/15/2024 73 | * Updated submodules 74 | * openthread commitid: 0551005 75 | * ot-br-posix commitid: b041fa5 76 | * ot-nrf528xx commitid: 39ac3d1 77 | 78 | * 11/08/2024 79 | * Updated submodules 80 | * openthread commitid: 0fb1c22 81 | * ot-br-posix commitid: 6934ff0 82 | * ot-nrf528xx commitid: e3ea7ae 83 | 84 | * 10/18/2024 85 | * Updated submodules 86 | * openthread commitid: deb35b0 87 | * ot-br-posix commitid: 7f04c18 88 | * ot-nrf528xx commitid: f485040 89 | 90 | * 09/14/2024 91 | * Updated submodules 92 | * openthread commitid: 97a3f76 93 | * ot-br-posix commitid: b9210e7 94 | * ot-nrf528xx commitid: e5eb822 95 | 96 | * 08/26/2024 97 | * Updated NCS to `887bdfc` 98 | 99 | * 08/15/2024 100 | * Updated submodules 101 | * openthread commitid: 5edc367 102 | * ot-br-posix commitid: b66cabf 103 | * ot-nrf528xx commitid: c9b9974 104 | 105 | * 08/13/2024 106 | * Updated NCS to `3203d13` 107 | 108 | * 08/08/2024 109 | * Updated submodules 110 | * ot-commissioner commitid: 639e627 111 | 112 | * 08/02/2024 113 | * Updated submodules 114 | * openthread commitid: 5493815 115 | * ot-br-posix commitid: f59b0f5 116 | * ot-nrf528xx commitid: 454310a 117 | 118 | * 06/17/2024 119 | * Updated submodules 120 | * openthread commitid: cb1220d 121 | * ot-br-posix commitid: 2071966 122 | * ot-nrf528xx commitid: f5665ee 123 | 124 | * 12/11/2023 125 | * Updated submodules 126 | * openthread commitid: ae6eff5 127 | * ot-br-posix commitid: 98db630 128 | * ot-nrf528xx commitid: cba66f2 129 | 130 | * 07/11/2023 131 | * Updated submodules 132 | * openthread commitid: 8bc2504 133 | * ot-br-posix commitid: 790dc77 134 | * ot-nrf528xx commitid: 982244f 135 | * ot-commisioner commitid: acb3371 136 | * Updated NCS to `4d1c577` 137 | 138 | * 05/26/2023 139 | * Updated submodules 140 | * openthread commitid: 6865b83d7 141 | * ot-br-posix commitid: d15b080045 142 | * ot-nrf528xx commitid: e801931 143 | 144 | * 05/10/2023 145 | * Added support for REFERENCE_RELEASE_TYPE 1.3.1 146 | * TREL and NAT64 are enabled in 1.3.1 147 | 148 | * 01/19/2023 149 | * Support for Thread 1.3.0 150 | * Updated submodules 151 | * openthread commitid: c6179c2 152 | * ot-br-posix commitid: 22d4f4e 153 | * ot-nrf528xx commitid: e6ee80b 154 | * ot-efr32 commitid: 38a4446 155 | * ot-commissioner commitid: 8287429 156 | 157 | * 08/18/2021 (commitid:95c5cb793, main) 158 | * Add efr32mg12 (brd4166a) support for Thread 1.3 builds 159 | 160 | * Build scripts 161 | * Refactor to allow new platforms to be added easily 162 | 163 | * 06/15/2021 (commitid:4b36e5115, main) 164 | 165 | * OpenThread Firmware Update 166 | * Use latest openthread/openthread main branch 167 | 168 | * OTBR Update 169 | * Use latest openthread/ot-br-posix main branch 170 | 171 | * THCI update - OpenThread.py (TD) 172 | * Support both Thread Dev Harness V1.2 and Thread Dev Harness V1.1 173 | 174 | * THCI update - OpenThread_BR.py (BBR) 175 | * Support TestHarness Discovery and SSH connection 176 | * Support BR_1/BR_2/Host/ExtComm capabilities 177 | 178 | * OT-Commissioner 179 | * Update to latest openthread/ot-commissioner cert branch 180 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021, The OpenThread Authors. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. Neither the name of the copyright holder nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ot-reference-release 2 | 3 | ## Usage 4 | 5 | Clone this repository: 6 | 7 | ``` 8 | $ git clone https://github.com/openthread/ot-reference-release 9 | ``` 10 | 11 | Initialize the submodules: 12 | 13 | ``` 14 | $ git submodule update --init --recursive 15 | ``` 16 | 17 | At the root of the repository: 18 | 19 | ``` 20 | $ REFERENCE_PLATFORM=(nrf52840|efr32mg12|ncs|none) REFERENCE_RELEASE_TYPE=(1.2|1.3|1.3.1) [SD_CARD=/dev/...] [OTBR_RCP_BUS=(UART|SPI)] [IN_CHINA=(0|1)] [OTBR_RADIO_URL='spinel+hdlc+uart:///dev/ttyUSB0'] [OPENTHREAD_COMMIT_HASH=c9c19aa9fa5877cf1532c35a584618900e5c99c7] ./script/make-reference-release.bash 21 | ``` 22 | 23 | This will produce a reference release folder in `./build/`. The folder will be 24 | named after the release type, date and the OpenThread commit id. 25 | 26 | `SD_CARD` is expected to be the device file path of an SD card inserted to 27 | the host. If this variable is specified, the script will flash the Raspberry Pi 28 | image containing OpenThread border router service to the SD card. 29 | 30 | If `IN_CHINA` is set to 1, the script will prefer to use apt sources based in 31 | China so that you can save time while installing software dependencies. 32 | 33 | `OTBR_RCP_BUS` sets the RCP hardware interface type of Spinel on otbr-agent. 34 | If this variable is not specified, the interface type is set to `UART` by default. 35 | 36 | `OTBR_RADIO_URL` sets the otbr-agent's radio URL. If this variable is not specified, 37 | the otbr-agent's argument is set to `spinel+hdlc+uart:///dev/ttyACM0` by default. 38 | 39 | `OPENTHREAD_COMMIT_HASH` sets custom openthread commit SHA for NCS builds. 40 | 41 | For example, if you are in China and want to flash the built image to an SD card: 42 | 43 | ``` 44 | $ REFERENCE_PLATFORM=nrf52840 REFERENCE_RELEASE_TYPE=1.2 IN_CHINA=1 SD_CARD=/dev/sda ./script/make-reference-release.bash 45 | ``` 46 | 47 | When `REFERENCE_RELEASE_TYPE` is `1.2`, reference release contains following components: 48 | - Raspberry Pi image containing OTBR service and OT Commissioner 49 | - Firmware 50 | - THCI 51 | - Change log 52 | - Quick start guide 53 | 54 | When `REFERENCE_RELEASE_TYPE` is `1.3` or `1.3.1`, reference release contains following components: 55 | - Raspberry Pi image containing OTBR service with border routing feature, service registry feature and OT Commissioner 56 | - Firmware 57 | - Change log 58 | - Quick start guide 59 | 60 | **Note**: Currently, only the following boards are supported for CLI/RCP firmwares: 61 | 62 | - nRF52840 dongles 63 | - EFR32MG12 BRD4166A boards 64 | 65 | If the `REFERENCE_PLATFORM` is set to `none`, the firmware won't be generated. 66 | 67 | # Contributing 68 | 69 | We would love for you to contribute to OpenThread and help make it even better than it is today! See our [Contributing Guidelines](https://github.com/openthread/openthread/blob/main/CONTRIBUTING.md) for more information. 70 | 71 | Contributors are required to abide by our [Code of Conduct](https://github.com/openthread/openthread/blob/main/CODE_OF_CONDUCT.md) and [Coding Conventions and Style Guide](https://github.com/openthread/openthread/blob/main/STYLE_GUIDE.md). 72 | 73 | # License 74 | 75 | OpenThread is released under the [BSD 3-Clause license](https://github.com/openthread/ot-reference-release/blob/main/LICENSE). See the [`LICENSE`](https://github.com/openthread/ot-reference-release/blob/main/LICENSE) file for more information. 76 | 77 | Please only use the OpenThread 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. 78 | 79 | # Need help? 80 | 81 | OpenThread support is available on GitHub: 82 | 83 | - Bugs and feature requests pertaining to the Reference Release — [submit to the openthread/ot-reference-release Issue Tracker](https://github.com/openthread/ot-reference-release/issues) 84 | - OpenThread bugs and feature requests — [submit to the OpenThread Issue Tracker](https://github.com/openthread/openthread/issues) 85 | - Community Discussion - [ask questions, share ideas, and engage with other community members](https://github.com/openthread/openthread/discussions) 86 | -------------------------------------------------------------------------------- /config/ncs/overlay-common.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2025 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable reference device 8 | CONFIG_OPENTHREAD_REFERENCE_DEVICE=y 9 | 10 | # Enable master OpenThread features set 11 | CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER=y 12 | 13 | # Set USB device PID 14 | CONFIG_USB_DEVICE_PID=0xCAFF 15 | 16 | # Configure logging 17 | CONFIG_LOG=y 18 | 19 | # Increase logging stack 20 | CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=2048 21 | 22 | # Always build from sources 23 | CONFIG_OPENTHREAD_SOURCES=y 24 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-cli-ftd-1.1.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable OpenThread features set for Thread 1.1 8 | CONFIG_OPENTHREAD_THREAD_VERSION_1_1=y 9 | 10 | # Disable most of the logging 11 | CONFIG_OPENTHREAD_LOG_LEVEL_CRIT=y 12 | CONFIG_ASSERT=n 13 | 14 | # Increase workqueue stack 15 | CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2144 16 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-cli-ftd-1.2.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable OpenThread features set for Thread 1.2 8 | CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y 9 | 10 | # Number of external addresses 11 | CONFIG_OPENTHREAD_IP6_MAX_EXT_MCAST_ADDRS=4 12 | 13 | # Increase stacks 14 | CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2144 15 | 16 | # Configure Thread 1.2 features 17 | CONFIG_OPENTHREAD_CSL_AUTO_SYNC=n 18 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD=104 19 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER=0 20 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-cli-ftd-1.3.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable OpenThread features set for Thread 1.3 8 | CONFIG_OPENTHREAD_THREAD_VERSION_1_3=y 9 | 10 | # Number of external addresses 11 | CONFIG_OPENTHREAD_IP6_MAX_EXT_MCAST_ADDRS=4 12 | 13 | # Increase stacks 14 | CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2144 15 | 16 | # Configure Thread 1.2 features 17 | CONFIG_OPENTHREAD_CSL_AUTO_SYNC=n 18 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD=104 19 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER=0 20 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-cli-ftd-1.4.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2024 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable OpenThread features set for Thread 1.4 8 | CONFIG_OPENTHREAD_THREAD_VERSION_1_4=y 9 | 10 | # Number of external addresses 11 | CONFIG_OPENTHREAD_IP6_MAX_EXT_MCAST_ADDRS=4 12 | 13 | # Increase stacks 14 | CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2144 15 | 16 | # Configure Thread 1.2 features 17 | CONFIG_OPENTHREAD_CSL_AUTO_SYNC=n 18 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD=104 19 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER=0 20 | 21 | # Enable TCAT support 22 | CONFIG_BT=y 23 | CONFIG_BT_PERIPHERAL=y 24 | CONFIG_BT_DEVICE_NAME="Thread BLE" 25 | CONFIG_BT_DEVICE_APPEARANCE=833 26 | CONFIG_OPENTHREAD_BLE_TCAT=y 27 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-cli-ftd-common.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2025 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Disable most of the logging 8 | CONFIG_LOG_MODE_DEFERRED=y 9 | CONFIG_BOOT_BANNER=n 10 | CONFIG_NET_LOG=n 11 | CONFIG_NET_STATISTICS=n 12 | CONFIG_OPENTHREAD_DEBUG=n 13 | CONFIG_OPENTHREAD_L2_DEBUG=y 14 | 15 | # Shell configuration for harness 16 | CONFIG_SHELL_PROMPT_UART="" 17 | CONFIG_SHELL_VT100_COLORS=n 18 | CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE=1024 19 | CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE=1024 20 | CONFIG_SHELL_DEFAULT_TERMINAL_WIDTH=640 21 | CONFIG_SHELL_CMD_BUFF_SIZE=640 22 | CONFIG_OPENTHREAD_CLI_MAX_LINE_LENGTH=640 23 | 24 | # Increase workqueue stack 25 | CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2144 26 | 27 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-rcp-1.2.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable OpenThread features set for Thread 1.2 8 | CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y 9 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-rcp-1.3.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2021 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable OpenThread features set for Thread 1.3 8 | CONFIG_OPENTHREAD_THREAD_VERSION_1_3=y 9 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-rcp-1.4.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2024 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable OpenThread features set for Thread 1.4 8 | CONFIG_OPENTHREAD_THREAD_VERSION_1_4=y 9 | -------------------------------------------------------------------------------- /config/ncs/overlay-ot-rcp-common.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2025 Nordic Semiconductor 3 | # 4 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 | # 6 | 7 | # Enable RCP coprocessor 8 | CONFIG_OPENTHREAD_COPROCESSOR_RCP=y 9 | 10 | # Configure logging 11 | CONFIG_LOG_BACKEND_SPINEL=y 12 | CONFIG_LOG_BACKEND_UART=n 13 | 14 | # Configure Thread 1.2 features 15 | CONFIG_OPENTHREAD_CSL_AUTO_SYNC=n 16 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD=104 17 | CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER=0 18 | -------------------------------------------------------------------------------- /config/ncs/requirements-nrfutil.txt: -------------------------------------------------------------------------------- 1 | intelhex 2 | click 3 | crcmod 4 | ecdsa 5 | libusb1==1.9.3 6 | piccata 7 | protobuf==3.18.3 8 | pyserial 9 | pyspinel 10 | pyyaml 11 | tqdm 12 | pc_ble_driver_py 13 | -------------------------------------------------------------------------------- /config/ncs/sdk-nrf-commit: -------------------------------------------------------------------------------- 1 | aeda4cd8b5735c196b2042a1bd31f0e21359ad0b 2 | -------------------------------------------------------------------------------- /doc/OpenThread 1.2 Reference Release QSG.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openthread/ot-reference-release/d2a362e94f2cd29ed196cb1e2383a15999f9eb18/doc/OpenThread 1.2 Reference Release QSG.pdf -------------------------------------------------------------------------------- /doc/nRF52840 Dongle Programming Guide_v4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openthread/ot-reference-release/d2a362e94f2cd29ed196cb1e2383a15999f9eb18/doc/nRF52840 Dongle Programming Guide_v4.pdf -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | git_archive_all 2 | -------------------------------------------------------------------------------- /script/bootstrap.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2023, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | # ============================================================================== 33 | # Bash definitions 34 | 35 | if [[ -n ${BASH_SOURCE[0]} ]]; then 36 | script_path="${BASH_SOURCE[0]}" 37 | else 38 | script_path="$0" 39 | fi 40 | script_dir="$(realpath "$(dirname "${script_path}")")" 41 | repo_dir="$(dirname "${script_dir}")" 42 | 43 | # ============================================================================== 44 | 45 | install_packages_apt() 46 | { 47 | echo 'Installing apt dependencies...' 48 | 49 | # apt-get update and install dependencies 50 | sudo apt-get update 51 | sudo apt-get --no-install-recommends install -y \ 52 | parted \ 53 | fdisk \ 54 | git \ 55 | wget \ 56 | file \ 57 | xz-utils \ 58 | zip \ 59 | python3-pip \ 60 | dcfldd \ 61 | lsof 62 | } 63 | 64 | install_packages_opkg() 65 | { 66 | echo 'opkg not supported currently' && false 67 | } 68 | 69 | install_packages_rpm() 70 | { 71 | echo 'rpm not supported currently' && false 72 | } 73 | 74 | install_packages_brew() 75 | { 76 | echo 'brew not supported currently' && false 77 | } 78 | 79 | install_packages_source() 80 | { 81 | echo 'source not supported currently' && false 82 | } 83 | 84 | install_packages_pip3() 85 | { 86 | echo 'Installing python3 dependencies...' 87 | pip3 install --upgrade -r "${repo_dir}/requirements.txt" 88 | } 89 | 90 | install_packages() 91 | { 92 | PM=source 93 | if command -v apt-get; then 94 | PM=apt 95 | elif command -v rpm; then 96 | PM=rpm 97 | elif command -v opkg; then 98 | PM=opkg 99 | elif command -v brew; then 100 | PM=brew 101 | fi 102 | install_packages_$PM 103 | 104 | if command -v pip3; then 105 | install_packages_pip3 106 | fi 107 | } 108 | 109 | install_qemu() 110 | { 111 | # Different versions of Linux may support qemu or qemu-system-arm. 112 | # Search for the correct one to install 113 | if apt-cache search '^qemu$' | grep -q 'qemu'; then 114 | QEMU=qemu 115 | elif apt-cache search '^qemu-system-arm$' | grep -q 'qemu-system-arm'; then 116 | QEMU=qemu-system-arm 117 | else 118 | echo "ERROR: Could not find 'qemu' or 'qemu-system-arm'" 119 | exit 1 120 | fi 121 | 122 | sudo apt-get install --no-install-recommends --allow-unauthenticated -y \ 123 | $QEMU \ 124 | qemu-user-static \ 125 | binfmt-support 126 | } 127 | 128 | main() 129 | { 130 | if [ $# == 0 ]; then 131 | install_packages 132 | install_qemu 133 | elif [ "$1" == 'packages' ]; then 134 | install_packages 135 | elif [ "$1" == 'python' ]; then 136 | install_packages_pip3 137 | elif [ "$1" == 'qemu' ]; then 138 | install_qemu 139 | else 140 | echo >&2 "Unsupported action: $1. Supported: packages, python, qemu" 141 | # 128 for Invalid arguments 142 | exit 128 143 | fi 144 | 145 | echo "Bootstrap completed successfully." 146 | } 147 | 148 | main "$@" 149 | -------------------------------------------------------------------------------- /script/make-commissioner.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2021, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | cd ot-commissioner 33 | 34 | pip3 install -r tools/commissioner_thci/requirements.txt 35 | ./script/bootstrap.sh || true 36 | 37 | mkdir -p build 38 | cd build 39 | 40 | /usr/local/bin/cmake -GNinja -DCMAKE_INSTALL_PREFIX=/usr -DOT_COMM_REFERENCE_DEVICE=ON .. 41 | ninja -j10 42 | ninja install 43 | 44 | sudo systemctl enable commissionerd 45 | -------------------------------------------------------------------------------- /script/make-firmware.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2021, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | if [[ -n ${BASH_SOURCE[0]} ]]; then 33 | script_path="${BASH_SOURCE[0]}" 34 | else 35 | script_path="$0" 36 | fi 37 | 38 | script_dir="$(dirname "$(realpath "$script_path")")" 39 | repo_dir="$(dirname "$script_dir")" 40 | 41 | # Global Vars 42 | platform="" 43 | build_dir="" 44 | build_script_flags=() 45 | NRFUTIL="" 46 | 47 | readonly build_1_4_options_common=( 48 | "-DOT_THREAD_VERSION=1.4" 49 | "-DOT_SRP_SERVER=ON" 50 | "-DOT_ECDSA=ON" 51 | "-DOT_SERVICE=ON" 52 | "-DOT_DNSSD_SERVER=ON" 53 | "-DOT_SRP_CLIENT=ON" 54 | ) 55 | 56 | readonly build_1_4_options_nrf=( 57 | "" 58 | ) 59 | 60 | readonly build_1_3_options_common=( 61 | "-DOT_THREAD_VERSION=1.3" 62 | "-DOT_SRP_SERVER=ON" 63 | "-DOT_ECDSA=ON" 64 | "-DOT_SERVICE=ON" 65 | "-DOT_DNSSD_SERVER=ON" 66 | "-DOT_SRP_CLIENT=ON" 67 | ) 68 | 69 | readonly build_1_3_options_nrf=( 70 | "" 71 | ) 72 | 73 | readonly build_1_2_options_common=( 74 | '-DOT_THREAD_VERSION=1.2' 75 | '-DOT_REFERENCE_DEVICE=ON' 76 | '-DOT_BORDER_ROUTER=ON' 77 | '-DOT_SERVICE=ON' 78 | '-DOT_COMMISSIONER=ON' 79 | '-DOT_JOINER=ON' 80 | '-DOT_MAC_FILTER=ON' 81 | '-DOT_DHCP6_SERVER=ON' 82 | '-DOT_DHCP6_CLIENT=ON' 83 | '-DOT_DUA=ON' 84 | '-DOT_MLR=ON' 85 | '-DOT_LINK_METRICS_INITIATOR=ON' 86 | '-DOT_LINK_METRICS_SUBJECT=ON' 87 | '-DOT_CSL_RECEIVER=ON' 88 | '-DOT_BORDER_AGENT=OFF' 89 | '-DOT_COAP=OFF' 90 | '-DOT_COAPS=OFF' 91 | '-DOT_ECDSA=OFF' 92 | '-DOT_FULL_LOGS=OFF' 93 | '-DOT_IP6_FRAGM=OFF' 94 | '-DOT_LINK_RAW=OFF' 95 | '-DOT_NETDIAG_CLIENT=OFF' 96 | '-DOT_SNTP_CLIENT=OFF' 97 | '-DOT_UDP_FORWARD=OFF' 98 | ) 99 | 100 | readonly build_1_2_options_nrf=( 101 | '-DOT_BOOTLOADER=USB' 102 | '-DOT_CSL_RECEIVER=ON' 103 | ) 104 | 105 | readonly build_1_1_env_common=( 106 | 'BORDER_ROUTER=1' 107 | 'REFERENCE_DEVICE=1' 108 | 'COMMISSIONER=1' 109 | 'DHCP6_CLIENT=1' 110 | 'DHCP6_SERVER=1' 111 | 'JOINER=1' 112 | 'MAC_FILTER=1' 113 | 'BOOTLOADER=USB' 114 | ) 115 | 116 | readonly build_1_1_env_nrf=( 117 | 'USB=1' 118 | ) 119 | 120 | # Args 121 | # - $1: The name of the hex file to zip 122 | # - $2: The basename of the file 123 | # - $3: Thread version number, e.g. 1.2 124 | # - $4: Timestamp 125 | # - $5: Commit ID 126 | distribute() 127 | { 128 | local hex_file=$1 129 | local zip_file="$2-$3-$4-$5.zip" 130 | 131 | case "${platform}" in 132 | nrf* | ncs*) 133 | ${NRFUTIL} pkg generate --debug-mode --hw-version 52 --sd-req 0 --application "${hex_file}" --key-file /tmp/private.pem "${zip_file}" 134 | ;; 135 | *) 136 | zip "${zip_file}" "${hex_file}" 137 | ;; 138 | esac 139 | 140 | mv "${zip_file}" "$OUTPUT_ROOT" 141 | } 142 | 143 | # Environment Vars 144 | # - $thread_version: Thread version number, e.g. 1.2 145 | # Args 146 | # - $1: The basename of the file to zip, e.g. ot-cli-ftd 147 | # - $2: The binary path (optional) 148 | package_ot() 149 | { 150 | # Parse Args 151 | local basename=${1?Please specify app basename} 152 | local binary_path=${2:-"${build_dir}/bin/${basename}"} 153 | thread_version=${thread_version?} 154 | 155 | # Get build info 156 | local commit_id 157 | local timestamp 158 | commit_id=$(cd "${repo_dir}"/openthread && git rev-parse --short HEAD) 159 | timestamp=$(date +%Y%m%d) 160 | 161 | # Generate .hex file 162 | local hex_file="${basename}"-"${thread_version}".hex 163 | if [ ! -f "$binary_path" ]; then 164 | echo "WARN: $binary_path does not exist. Skipping packaging" 165 | return 166 | fi 167 | arm-none-eabi-objcopy -O ihex "$binary_path" "${hex_file}" 168 | 169 | # Distribute 170 | distribute "${hex_file}" "${basename}" "${thread_version}" "${timestamp}" "${commit_id}" 171 | } 172 | 173 | # Envionment variables: 174 | # - build_type: Type of build (optional) 175 | # - build_script_flags: Any flags specific to the platform repo's build script (optional) 176 | # Args: 177 | # - $1 - thread_version: Thread version number, e.g. 1.2 178 | # - $2 - platform_repo: Path to platform's repo, e.g. ot-efr32, ot-nrf528xx 179 | build_ot() 180 | { 181 | thread_version=${thread_version?} 182 | platform_repo=${platform_repo?} 183 | 184 | mkdir -p "$OUTPUT_ROOT" 185 | 186 | case "${thread_version}" in 187 | "1.2"|"1.3"|"1.4") 188 | # Build OpenThread 1.2 or 1.3 or 1.4 189 | cd "${platform_repo}" 190 | git clean -xfd 191 | 192 | # Use OpenThread from top-level of repo 193 | rm -rf openthread 194 | # git_archive_all doesn't accept symbolic link, so make a copy of openthread and make 195 | # it not a submodule 196 | cp -rp ../openthread . 197 | rm openthread/.git 198 | 199 | # Build 200 | build_dir=${OT_CMAKE_BUILD_DIR:-"${repo_dir}"/build-"${thread_version}"/"${platform}"} 201 | 202 | if [ -z "${build_script_flags[@]}" ]; then 203 | OT_CMAKE_BUILD_DIR="${build_dir}" ./script/build "${platform}" "${build_type:-}" "$@" 204 | else 205 | OT_CMAKE_BUILD_DIR="${build_dir}" ./script/build "${build_script_flags[@]}" "${platform}" "${build_type:-}" "$@" 206 | fi 207 | 208 | # Package and distribute 209 | local dist_apps=( 210 | ot-cli-ftd 211 | ot-rcp 212 | ) 213 | for app in "${dist_apps[@]}"; do 214 | package_ot "${app}" 215 | done 216 | 217 | # Clean up 218 | git clean -xfd 219 | ;; 220 | "1.1") 221 | # Build OpenThread 1.1 222 | cd openthread-1.1 223 | 224 | # Prep 225 | git clean -xfd 226 | ./bootstrap 227 | 228 | # Build 229 | make -f examples/Makefile-"${platform}" "${options[@]}" 230 | 231 | # Package and distribute 232 | local dist_apps=( 233 | ot-cli-ftd 234 | ot-rcp 235 | ) 236 | for app in "${dist_apps[@]}"; do 237 | package_ot "${app}" "${thread_version}" output/"${platform}"/bin/"${app}" 238 | done 239 | 240 | # Clean up 241 | git clean -xfd 242 | ;; 243 | esac 244 | 245 | cd "${repo_dir}" 246 | } 247 | 248 | die() 249 | { 250 | echo "$*" 1>&2 251 | exit 1 252 | } 253 | 254 | nrfutil_setup() 255 | { 256 | # Setup nrfutil 257 | if [[ $OSTYPE == "linux"* ]]; then 258 | ostype=unknown-linux-gnu 259 | arch=x86_64 260 | elif [[ $OSTYPE == "darwin"* ]]; then 261 | ostype=apple-darwin 262 | arch=$(uname -m) 263 | fi 264 | NRFUTIL=/tmp/nrfutil-${ostype}-${arch} 265 | 266 | if [ ! -f $NRFUTIL ]; then 267 | wget -O $NRFUTIL https://files.nordicsemi.com/ui/api/v1/download?repoKey=swtools\&path=external/nrfutil/executables/${arch}-${ostype}/nrfutil 268 | chmod +x $NRFUTIL 269 | fi 270 | 271 | $NRFUTIL install nrf5sdk-tools 272 | 273 | # Generate private key 274 | if [ ! -f /tmp/private.pem ]; then 275 | $NRFUTIL keys generate /tmp/private.pem 276 | fi 277 | } 278 | 279 | deploy_ncs() 280 | { 281 | local commit_hash 282 | commit_hash=$(<"${script_dir}"'/../config/ncs/sdk-nrf-commit') 283 | 284 | sudo apt install --no-install-recommends git cmake ninja-build gperf \ 285 | ccache dfu-util device-tree-compiler wget \ 286 | python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file \ 287 | make gcc gcc-multilib g++-multilib libsdl2-dev 288 | pip3 install --user west 289 | mkdir -p "${script_dir}"/../ncs 290 | cd "${script_dir}"/../ncs 291 | unset ZEPHYR_BASE 292 | west init -m https://github.com/nrfconnect/sdk-nrf --mr main || true 293 | cd nrf 294 | git fetch origin 295 | git reset --hard "$commit_hash" || die "ERROR: unable to checkout the specified sdk-nrf commit." 296 | west update -n -o=--depth=1 297 | cd .. 298 | 299 | if [[ -n ${OPENTHREAD_COMMIT_HASH:=} ]]; then 300 | echo "Using custom OT SHA: ${OPENTHREAD_COMMIT_HASH?}" 301 | cd modules/lib/openthread 302 | # remove remote if exists to make clean repository 303 | if git remote | grep -q openthread; then 304 | git remote remove openthread 305 | fi 306 | git remote add openthread https://github.com/openthread/openthread.git 307 | git fetch openthread "$OPENTHREAD_COMMIT_HASH" 308 | git checkout FETCH_HEAD || die "ERROR: unable to checkout the specified openthread commit." 309 | cd ../../../ 310 | fi 311 | 312 | pip3 install --user -r zephyr/scripts/requirements.txt 313 | pip3 install --user -r nrf/scripts/requirements.txt 314 | pip3 install --user -r bootloader/mcuboot/scripts/requirements.txt 315 | 316 | # shellcheck disable=SC1091 317 | source zephyr/zephyr-env.sh 318 | west config manifest.path nrf 319 | } 320 | 321 | build_ncs() 322 | { 323 | mkdir -p "$OUTPUT_ROOT" 324 | deploy_ncs 325 | cd nrf 326 | 327 | thread_version=${thread_version?} 328 | local timestamp=$(date +%Y%m%d) 329 | local commit_id=$(git rev-parse --short HEAD) 330 | 331 | # variant is a list of entries: "app:sample_name" 332 | local variants 333 | case "${thread_version}" in 334 | 1.1) 335 | variants=("ot-cli-ftd:cli") 336 | ;; 337 | *) 338 | variants=("ot-cli-ftd:cli" "ot-rcp:coprocessor") 339 | ;; 340 | 341 | esac 342 | 343 | for variant in "${variants[@]}"; do 344 | local app=$(echo $variant | cut -d':' -f1) 345 | local sample_name=$(echo $variant | cut -d':' -f2) 346 | local sample_path="samples/openthread/${sample_name}" 347 | local sample_config_path="${script_dir}/../config/ncs/overlay" 348 | local sample_config="${sample_config_path}-common.conf;${sample_config_path}-${app}-common.conf;${sample_config_path}-${app}-${thread_version}.conf" 349 | local build_path="/tmp/ncs_${app}_${thread_version}" 350 | local hex_path="${build_path}/${sample_name}/zephyr/zephyr.hex" 351 | 352 | west build -d "${build_path}" -b nrf52840dongle/nrf52840 -p always "${sample_path}" --sysbuild -- -DOVERLAY_CONFIG="${sample_config}" 353 | 354 | distribute "${hex_path}" "${app}" "${thread_version}" "${timestamp}" "${commit_id}" 355 | done 356 | } 357 | 358 | build() 359 | { 360 | if [ "${REFERENCE_RELEASE_TYPE?}" = "1.2" ]; then 361 | build_1_2_options=("${build_1_2_options_common[@]}") 362 | build_1_1_env=("${build_1_1_env_common[@]}") 363 | 364 | case "${platform}" in 365 | nrf*) 366 | build_1_2_options+=("${build_1_2_options_nrf[@]}") 367 | build_1_1_env+=("${build_1_1_env_nrf[@]}") 368 | platform_repo=ot-nrf528xx 369 | 370 | thread_version=1.2 build_type="USB_trans" build_ot "${build_1_2_options[@]}" "$@" 371 | thread_version=1.1 build_type="USB_trans" build_ot "${build_1_1_env[@]}" "$@" 372 | ;; 373 | ncs) 374 | thread_version=1.2 build_ncs 375 | thread_version=1.1 build_ncs 376 | ;; 377 | esac 378 | elif [ "${REFERENCE_RELEASE_TYPE}" = "1.3" ]; then 379 | options=("${build_1_3_options_common[@]}") 380 | 381 | case "${platform}" in 382 | nrf*) 383 | options+=("${build_1_3_options_nrf[@]}") 384 | platform_repo=ot-nrf528xx 385 | 386 | thread_version=1.3 build_type="USB_trans" build_ot "${options[@]}" "$@" 387 | ;; 388 | efr32mg12) 389 | platform_repo=ot-efr32 390 | build_script_flags=("--skip-silabs-apps") 391 | thread_version=1.3 build_ot "-DBOARD=brd4166a" "${options[@]}" "$@" 392 | ;; 393 | ncs) 394 | thread_version=1.3 build_ncs 395 | ;; 396 | esac 397 | elif [ "${REFERENCE_RELEASE_TYPE}" = "1.4" ]; then 398 | options=("${build_1_4_options_common[@]}") 399 | 400 | case "${platform}" in 401 | nrf*) 402 | options+=("${build_1_4_options_nrf[@]}") 403 | platform_repo=ot-nrf528xx 404 | 405 | thread_version=1.4 build_type="USB_trans" build_ot "${options[@]}" "$@" 406 | ;; 407 | efr32mg12) 408 | platform_repo=ot-efr32 409 | build_script_flags=("--skip-silabs-apps") 410 | thread_version=1.4 build_ot "-DBOARD=brd4166a" "${options[@]}" "$@" 411 | ;; 412 | ncs) 413 | thread_version=1.4 build_ncs 414 | ;; 415 | esac 416 | else 417 | die "Error: REFERENCE_RELEASE_TYPE = ${REFERENCE_RELEASE_TYPE} is unsupported" 418 | fi 419 | } 420 | 421 | main() 422 | { 423 | readonly OT_PLATFORMS=(nrf52840 efr32mg12 ncs) 424 | 425 | local platforms=() 426 | 427 | if [[ $# == 0 ]]; then 428 | platforms=("${OT_PLATFORMS[@]}") 429 | else 430 | platforms=("$1") 431 | shift 432 | fi 433 | 434 | # Print OUTPUT_ROOT. Error if OUTPUT_ROOT is not defined 435 | OUTPUT_ROOT=$(realpath "${OUTPUT_ROOT?}") 436 | echo "OUTPUT_ROOT=${OUTPUT_ROOT}" 437 | mkdir -p "${OUTPUT_ROOT}" 438 | 439 | for p in "${platforms[@]}"; do 440 | # Check if the platform is supported. 441 | echo "${OT_PLATFORMS[@]}" | grep -wq "${p}" || die "ERROR: Unsupported platform: ${p}" 442 | printf "\n\n======================================\nBuilding firmware for %s\n======================================\n\n" "${p}" 443 | platform=${p} 444 | case "${platform}" in 445 | nrf* | ncs*) 446 | nrfutil_setup 447 | ;; 448 | esac 449 | 450 | build "$@" 451 | done 452 | 453 | } 454 | 455 | main "$@" 456 | -------------------------------------------------------------------------------- /script/make-pretty: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | # 31 | # The script to check or format source code of OpenThread. 32 | # 33 | # Format c/c++, markdown, and shell: 34 | # 35 | # script/make-pretty 36 | # 37 | # Format c/c++ only: 38 | # 39 | # script/make-pretty clang-format 40 | # 41 | # Format markdown only: 42 | # 43 | # script/make-pretty markdown 44 | # 45 | # Format shell only: 46 | # 47 | # script/make-pretty shell 48 | # 49 | # Check only: 50 | # 51 | # script/make-pretty check clang-format 52 | # script/make-pretty check markdown 53 | # script/make-pretty check shell 54 | # 55 | 56 | set -euo pipefail 57 | 58 | readonly OT_BUILD_JOBS=$(getconf _NPROCESSORS_ONLN) 59 | readonly OT_EXCLUDE_DIRS=( 60 | config 61 | doc 62 | docker-rpi-emu 63 | media 64 | mnt-rpi 65 | openthread 66 | openthread-1.1 67 | ot-br-posix 68 | ot-commissioner 69 | ot-efr32 70 | ot-nrf528xx 71 | thci 72 | third_party 73 | ) 74 | 75 | readonly OT_MARKDOWN_SOURCES=('*.md') 76 | 77 | do_markdown_format() 78 | { 79 | echo -e '========================================' 80 | echo -e ' format markdown' 81 | echo -e '========================================' 82 | 83 | git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ 84 | | xargs -n10 -P"$OT_BUILD_JOBS" npx prettier@2.0.4 --write 85 | } 86 | 87 | do_markdown_check() 88 | { 89 | echo -e '========================================' 90 | echo -e ' check markdown' 91 | echo -e '========================================' 92 | 93 | git ls-files "${OT_MARKDOWN_SOURCES[@]}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ 94 | | xargs -n10 -P"$OT_BUILD_JOBS" npx prettier@2.0.4 --check 95 | } 96 | 97 | do_shell_format() 98 | { 99 | echo -e '========================================' 100 | echo -e ' format shell' 101 | echo -e '========================================' 102 | 103 | git ls-files | xargs -I {} shfmt -f "{}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ 104 | | xargs -n10 -P"$OT_BUILD_JOBS" -I {} shfmt -i 4 -bn -ci -fn -s -w "{}" 105 | } 106 | 107 | do_shell_check() 108 | { 109 | echo -e '========================================' 110 | echo -e ' check shell' 111 | echo -e '========================================' 112 | 113 | git ls-files | xargs -I {} shfmt -f "{}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ 114 | | xargs -n10 -P"$OT_BUILD_JOBS" -I {} shfmt -i 4 -bn -ci -fn -s -d "{}" 115 | 116 | git ls-files | xargs -I {} shfmt -f "{}" | grep -v -E "^($(echo "${OT_EXCLUDE_DIRS[@]}" | tr ' ' '|'))" \ 117 | | xargs -n10 -P"$OT_BUILD_JOBS" -I {} shellcheck "{}" 118 | } 119 | 120 | do_check() 121 | { 122 | if [ $# == 0 ]; then 123 | do_markdown_check 124 | do_shell_check 125 | elif [ "$1" == 'markdown' ]; then 126 | do_markdown_check 127 | elif [ "$1" == 'shell' ]; then 128 | do_shell_check 129 | else 130 | echo >&2 "Unsupported check: $1. Supported: markdown, shell" 131 | # 128 for Invalid arguments 132 | exit 128 133 | fi 134 | } 135 | 136 | main() 137 | { 138 | if [ $# == 0 ]; then 139 | do_markdown_format 140 | do_shell_format 141 | elif [ "$1" == 'markdown' ]; then 142 | do_markdown_format 143 | elif [ "$1" == 'shell' ]; then 144 | do_shell_format 145 | elif [ "$1" == 'check' ]; then 146 | shift 147 | do_check "$@" 148 | else 149 | echo >&2 "Unsupported action: $1. Supported: clang-format, markdown, shell" 150 | # 128 for Invalid arguments 151 | exit 128 152 | fi 153 | 154 | } 155 | 156 | main "$@" 157 | -------------------------------------------------------------------------------- /script/make-raspbian.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2021, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | if [[ -n ${BASH_SOURCE[0]} ]]; then 33 | script_path="${BASH_SOURCE[0]}" 34 | else 35 | script_path="$0" 36 | fi 37 | 38 | script_dir="$(dirname "$(realpath "$script_path")")" 39 | OT_REFERENCE_RELEASE="$(dirname "$script_dir")" 40 | 41 | echo "REFERENCE_RELEASE_TYPE=${REFERENCE_RELEASE_TYPE?}" 42 | echo "IN_CHINA=${IN_CHINA:=0}" 43 | echo "OUTPUT_ROOT=${OUTPUT_ROOT?}" 44 | echo "OTBR_RCP_BUS=${OTBR_RCP_BUS:=UART}" 45 | echo "REFERENCE_PLATFORM=${REFERENCE_PLATFORM?}" 46 | echo "OTBR_RADIO_URL=${OTBR_RADIO_URL:=spinel+hdlc+uart:///dev/ttyACM0}" 47 | 48 | if [ "$REFERENCE_RELEASE_TYPE" != "1.2" ] && [ "$REFERENCE_RELEASE_TYPE" != "1.3" ] && [ "$REFERENCE_RELEASE_TYPE" != "1.4" ]; then 49 | echo "Invalid reference release type: $REFERENCE_RELEASE_TYPE" 50 | exit 1 51 | fi 52 | 53 | STAGE_DIR=/tmp/raspbian 54 | QEMU_ROOT=${OT_REFERENCE_RELEASE}/mnt-rpi 55 | IMAGES_DIR="${IMAGES_DIR-"${HOME}/.cache/tools/images"}" 56 | 57 | cleanup() 58 | { 59 | set +e 60 | for pid in $(sudo lsof -t "$QEMU_ROOT"); do 61 | sudo kill -9 "$pid" 62 | done 63 | 64 | # Teardown QEMU machine 65 | sudo "${OT_REFERENCE_RELEASE}"/docker-rpi-emu/scripts/qemu-cleanup.sh "$QEMU_ROOT" || true 66 | 67 | # Unmount 68 | sudo umount -f -R "$QEMU_ROOT" || true 69 | set -e 70 | } 71 | 72 | trap cleanup EXIT 73 | 74 | main() 75 | { 76 | OPENTHREAD_COMMIT_HASH=$(git -C "${OT_REFERENCE_RELEASE}"/openthread rev-parse --short HEAD) 77 | OT_BR_POSIX_COMMIT_HASH=$(git -C "${OT_REFERENCE_RELEASE}"/ot-br-posix rev-parse --short HEAD) 78 | 79 | # Ensure qemu is installed 80 | if ! command -v /usr/bin/qemu-arm-static; then 81 | "${OT_REFERENCE_RELEASE}"/script/bootstrap.bash qemu 82 | fi 83 | 84 | # Ensure OUTPUT_ROOT exists 85 | mkdir -p "$OUTPUT_ROOT" 86 | 87 | # Ensure IMAGES_DIR exists 88 | [ -d "$IMAGES_DIR" ] || mkdir -p "$IMAGES_DIR" 89 | 90 | # Download raspios image 91 | RASPIOS_URL=https://downloads.raspberrypi.org/raspios_lite_armhf/images/raspios_lite_armhf-2021-05-28/2021-05-07-raspios-buster-armhf-lite.zip 92 | IMAGE_ARCHIVE=$(basename "${RASPIOS_URL}") 93 | IMAGE_FILE=$(basename "${IMAGE_ARCHIVE}" .zip).img 94 | wget -q -O "$IMAGES_DIR/$IMAGE_ARCHIVE" -c "$RASPIOS_URL" 95 | 96 | # Extract the downloaded archive 97 | mime_type=$(file "$IMAGES_DIR/$IMAGE_ARCHIVE" --mime-type) 98 | if [[ $mime_type == *"application/zip"* ]]; then 99 | unzip -o "$IMAGES_DIR/$IMAGE_ARCHIVE" -d $IMAGES_DIR 100 | elif [[ $mime_type == *"application/"* ]]; then 101 | xz -f -k -d "$IMAGES_DIR/$IMAGE_ARCHIVE" 102 | else 103 | echo "ERROR: Unrecognized archive type\n${mime_type}" 104 | exit 3 105 | fi 106 | ls -alh $IMAGES_DIR/$IMAGE_FILE 107 | 108 | # Ensure STAGE_DIR exists. Create a copy of IMAGE_FILE in STAGE_DIR 109 | [ -d "$STAGE_DIR" ] || mkdir -p "$STAGE_DIR" 110 | 111 | export STAGING_IMAGE_FILE="$STAGE_DIR/otbr.${REFERENCE_RELEASE_TYPE?}-$(date +%Y%m%d).ot_${OPENTHREAD_COMMIT_HASH}.ot-br_${OT_BR_POSIX_COMMIT_HASH}.img" 112 | cp "$IMAGES_DIR/$IMAGE_FILE" "$STAGING_IMAGE_FILE" 113 | 114 | # Expand IMAGE_FILE by EXPAND_SIZE 115 | # unit MB 116 | EXPAND_SIZE=6144 117 | dd if=/dev/zero bs=1M count=$EXPAND_SIZE >>"$STAGING_IMAGE_FILE" 118 | ls -alh "$STAGING_IMAGE_FILE" 119 | sudo "${OT_REFERENCE_RELEASE}"/docker-rpi-emu/scripts/expand.sh "$STAGING_IMAGE_FILE" "$EXPAND_SIZE" 120 | 121 | # Create mount dir 122 | mkdir -p "$QEMU_ROOT" 123 | 124 | # Mount .img 125 | sudo "${OT_REFERENCE_RELEASE}"/docker-rpi-emu/scripts/mount.sh "$STAGING_IMAGE_FILE" $QEMU_ROOT 126 | 127 | # Mount /etc/resolv.conf 128 | if [ -f "/etc/resolv.conf" ]; then 129 | sudo mount -o ro,bind /etc/resolv.conf "$QEMU_ROOT"/etc/resolv.conf 130 | fi 131 | 132 | # Start RPi QEMU machine 133 | sudo "${OT_REFERENCE_RELEASE}"/docker-rpi-emu/scripts/qemu-setup.sh "$QEMU_ROOT" 134 | 135 | # Ensure git_archive_all is installed 136 | if ! python3 -m pip show git_archive_all; then 137 | "${OT_REFERENCE_RELEASE}"/script/bootstrap.bash python 138 | fi 139 | 140 | # Copy ot-reference-release repo into QEMU_ROOT 141 | python3 -m git_archive_all "$STAGE_DIR"/repo.tar.gz 142 | sudo mkdir -p "$QEMU_ROOT"/home/pi/repo 143 | sudo tar xzf "$STAGE_DIR"/repo.tar.gz --absolute-names --strip-components 1 -C "$QEMU_ROOT"/home/pi/repo 144 | 145 | # Run OTBR install 146 | sudo chroot "$QEMU_ROOT" /bin/bash -c "export DOCKER=${DOCKER-0}; /home/pi/repo/script/otbr-setup.bash ${REFERENCE_RELEASE_TYPE?} $IN_CHINA ${REFERENCE_PLATFORM?} ${OPENTHREAD_COMMIT_HASH} ${OT_BR_POSIX_COMMIT_HASH} ${OTBR_RCP_BUS} ${OTBR_RADIO_URL}" 147 | sudo chroot "$QEMU_ROOT" /bin/bash /home/pi/repo/script/otbr-cleanup.bash 148 | echo "enable_uart=1" | sudo tee -a "$QEMU_ROOT"/boot/config.txt 149 | echo "dtoverlay=disable-bt" | sudo tee -a "$QEMU_ROOT"/boot/config.txt 150 | if [[ ${OTBR_RCP_BUS} == "SPI" ]]; then 151 | echo "dtparam=spi=on" | sudo tee -a "$QEMU_ROOT"/boot/config.txt 152 | fi 153 | sudo touch "$QEMU_ROOT"/boot/ssh && sync && sleep 1 154 | 155 | # Shrink .img 156 | if [[ ! -f /usr/bin/pishrink.sh ]]; then 157 | sudo wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh -O /usr/bin/pishrink.sh && sudo chmod a+x /usr/bin/pishrink.sh 158 | fi 159 | set +e 160 | sudo /usr/bin/pishrink.sh "$STAGING_IMAGE_FILE" 161 | ret_val=$? 162 | # Ignore error when pishrink can't shrink the image any further 163 | if [[ $ret_val -ne 11 ]] && [[ $ret_val -ne 0 ]]; then 164 | exit $ret_val 165 | fi 166 | set -e 167 | 168 | # Write .img to SD Card 169 | if [[ -n ${SD_CARD:=} ]]; then 170 | sudo sh -c "dcfldd if="$STAGING_IMAGE_FILE" of=$SD_CARD bs=1m && sync" 171 | fi 172 | 173 | # Compress .img and move archive to OUTPUT_ROOT 174 | IMG_ZIP_FILE="$(basename "$STAGING_IMAGE_FILE").zip" 175 | zip -j "$OUTPUT_ROOT/$IMG_ZIP_FILE" "$STAGING_IMAGE_FILE" 176 | } 177 | 178 | main "$@" 179 | -------------------------------------------------------------------------------- /script/make-reference-release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2021, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | main() 33 | { 34 | # ========================================================================== 35 | # Prebuild 36 | # ========================================================================== 37 | echo "REFERENCE_RELEASE_TYPE=${REFERENCE_RELEASE_TYPE?}" 38 | mkdir -p build 39 | OUTPUT_ROOT=$(realpath build/ot-"${REFERENCE_RELEASE_TYPE?}-$(date +%Y%m%d)-$(cd openthread && git rev-parse --short HEAD)") 40 | mkdir -p "$OUTPUT_ROOT" 41 | ./script/bootstrap.bash 42 | 43 | # ========================================================================== 44 | # Build firmware 45 | # ========================================================================== 46 | if [ "${REFERENCE_PLATFORM}" != "none" ]; then 47 | OUTPUT_ROOT="$OUTPUT_ROOT"/fw_dongle_${REFERENCE_PLATFORM}/ ./script/make-firmware.bash "${REFERENCE_PLATFORM}" 48 | fi 49 | 50 | # ========================================================================== 51 | # Build THCI 52 | # ========================================================================== 53 | if [ "${REFERENCE_RELEASE_TYPE?}" = "1.2" ]; then 54 | mkdir -p "$OUTPUT_ROOT"/thci 55 | OUTPUT_ROOT="$OUTPUT_ROOT"/thci/ ./script/make-thci.bash 56 | fi 57 | 58 | # ========================================================================== 59 | # Build raspbian 60 | # ========================================================================== 61 | mkdir -p "$OUTPUT_ROOT" 62 | OUTPUT_ROOT="$OUTPUT_ROOT" ./script/make-raspbian.bash 63 | 64 | # ========================================================================== 65 | # Package docs 66 | # ========================================================================== 67 | case "${REFERENCE_PLATFORM}" in 68 | ncs*) 69 | cp -r doc/nRF5* "$OUTPUT_ROOT" 70 | ;; 71 | *) 72 | cp -r doc/OpenThread* "$OUTPUT_ROOT" 73 | ;; 74 | esac 75 | cp CHANGELOG.txt "$OUTPUT_ROOT" 76 | } 77 | 78 | main "$@" 79 | -------------------------------------------------------------------------------- /script/make-thci.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2021, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | echo "OUTPUT_ROOT=${OUTPUT_ROOT?}" 33 | 34 | mkdir -p "$OUTPUT_ROOT"/ot-comm 35 | 36 | # Args: 37 | # - $1 - src_path: Source path of the THCI file 38 | # - $2 - out_name: Name of the output file 39 | ncs_adapt() 40 | { 41 | local src_path="${1}" 42 | local out_path="$OUTPUT_ROOT"/"${2}" 43 | 44 | cp "${src_path}" "${out_path}" 45 | sed -i 's/Device : OpenThread/Device : OTNCS/g' "${out_path}" 46 | sed -i 's/Class : OpenThread/Class : OTNCS/g' "${out_path}" 47 | sed -i 's/class OpenThread(/class OTNCS(/g' "${out_path}" 48 | sed -i 's/class OpenThread_/class OTNCS_/g' "${out_path}" 49 | sed -i 's/THCI.OpenThread/THCI.OTNCS/g' "${out_path}" 50 | sed -i 's/super(OpenThread/super(OTNCS/g' "${out_path}" 51 | } 52 | 53 | # Args: 54 | # - $1 - base_path: Base path of the Zephyr build 55 | get_version() 56 | { 57 | local base_path="${1}" 58 | local bin_path="$base_path/zephyr/zephyr.bin" 59 | 60 | grep -ao 'OPENTHREAD/.*[0-2][0-9]:[0-5][0-9]:[0-5][0-9]' "$bin_path" 61 | } 62 | 63 | # Args: 64 | # - $1 - path: Path of the THCI file 65 | set_version_string() 66 | { 67 | local path="${1}" 68 | 69 | sed -i "s#OT11_VERSION = 'OPENTHREAD'#OT11_VERSION = '$(get_version /tmp/ncs_cli_1_1)'#g" "${path}" 70 | sed -i "s#OT12_VERSION = 'OPENTHREAD'#OT12_VERSION = '$(get_version /tmp/ncs_cli_1_2)'#g" "${path}" 71 | sed -i "s#OT13_VERSION = 'OPENTHREAD'#OT13_VERSION = 'Not Supported'#g" "${path}" 72 | } 73 | 74 | src_dir=openthread/tools/harness-thci 75 | ( 76 | case "${REFERENCE_PLATFORM}" in 77 | nrf*) 78 | cp "${src_dir}/OpenThread_BR.py" "$OUTPUT_ROOT" 79 | cp "${src_dir}/OpenThread.py" "$OUTPUT_ROOT" 80 | ;; 81 | ncs*) 82 | ncs_adapt "${src_dir}/OpenThread.py" OTNCS.py 83 | set_version_string "$OUTPUT_ROOT"/"OTNCS.py" 84 | ncs_adapt "${src_dir}/OpenThread_BR.py" OTNCS_BR.py 85 | ;; 86 | esac 87 | ) 88 | 89 | ( 90 | cd ot-commissioner/tools/commissioner_thci 91 | cp commissioner.py "$OUTPUT_ROOT"/ot-comm 92 | cp commissioner_impl.py "$OUTPUT_ROOT"/ot-comm 93 | ) 94 | 95 | sync 96 | -------------------------------------------------------------------------------- /script/mount.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The MIT License (MIT) Copyright (c) 2016 Ryan Kurte 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | # 24 | # Script to mount a provided raspbian image to a provided location 25 | # 26 | 27 | set -euxo pipefail 28 | 29 | # Check inputs 30 | if [ "$#" -ne 2 ]; then 31 | echo "Usage: $0 IMAGE MOUNT" 32 | echo "IMAGE - raspberry pi .img file" 33 | echo "MOUNT - mount location in the file system" 34 | exit 35 | fi 36 | 37 | if [ ! -f "$1" ]; then 38 | echo "Image file $1 does not exist" 39 | exit 1 40 | fi 41 | 42 | if [ ! -d "$2" ]; then 43 | echo "Mount point $2 does not exist" 44 | exit 2 45 | fi 46 | 47 | echo "Attempting to mount $1 to $2" 48 | 49 | set -e 50 | 51 | # Attach loopback device 52 | LOOP_BASE=$(sudo losetup -f -P --show "$1") 53 | 54 | echo "Attached base loopback at: $LOOP_BASE" 55 | 56 | P1_NAME=${LOOP_BASE}p1 57 | P2_NAME=${LOOP_BASE}p2 58 | 59 | # Mount image with the offsets determined above 60 | mkdir -p "$2" 61 | sudo mount "$P2_NAME" -o rw "$2" 62 | sudo mount "$P1_NAME" -o rw "$2"/boot 63 | 64 | echo "Mounted to $2 and $2/boot" 65 | -------------------------------------------------------------------------------- /script/otbr-cleanup.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2021, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | readonly OTBR_BUILD_DEPS='apt-utils build-essential ninja-build cmake wget ca-certificates 33 | libreadline-dev libncurses-dev libdbus-1-dev libavahi-common-dev 34 | libavahi-client-dev libboost-dev libboost-filesystem-dev libboost-system-dev libjsoncpp-dev 35 | libnetfilter-queue-dev npm nodejs' 36 | readonly OTBR_DOCKER_DEPS='git ca-certificates' 37 | 38 | cd /home/pi/repo/ot-br-posix 39 | mv ./script /tmp 40 | mv ./etc /tmp 41 | find . -delete 42 | rm -rf /usr/include 43 | mv /tmp/script . 44 | mv /tmp/etc . 45 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false "$OTBR_DOCKER_DEPS" || true 46 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false "$OTBR_BUILD_DEPS" || true 47 | rm -rf /var/lib/apt/lists/* 48 | 49 | sync 50 | -------------------------------------------------------------------------------- /script/otbr-setup.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2021, The OpenThread Authors. 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 3. Neither the name of the copyright holder nor the 14 | # names of its contributors may be used to endorse or promote products 15 | # derived from this software without specific prior written permission. 16 | # 17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | # POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | 30 | set -euxo pipefail 31 | 32 | export LC_ALL=C 33 | export DEBIAN_FRONTEND=noninteractive 34 | export PATH=$PATH:/usr/local/bin 35 | 36 | REFERENCE_RELEASE_TYPE=$1 37 | IN_CHINA=$2 38 | REFERENCE_PLATFORM=$3 39 | OPENTHREAD_COMMIT_HASH=$4 40 | OT_BR_POSIX_COMMIT_HASH=$5 41 | OTBR_RCP_BUS=$6 42 | OTBR_RADIO_URL=$7 43 | 44 | readonly OTBR_COMMON_OPTIONS=( 45 | "-DOT_DIAGNOSTIC=ON" 46 | "-DOT_FULL_LOGS=ON" 47 | "-DOT_PACKAGE_VERSION=${OPENTHREAD_COMMIT_HASH}" 48 | "-DOTBR_PACKAGE_VERSION=${OT_BR_POSIX_COMMIT_HASH}" 49 | "-DOT_POSIX_RCP_HDLC_BUS=${OTBR_RCP_BUS}" 50 | "-DOTBR_RADIO_URL=${OTBR_RADIO_URL}" 51 | ) 52 | 53 | readonly OTBR_THREAD_1_2_OPTIONS=( 54 | ${OTBR_COMMON_OPTIONS[@]} 55 | "-DOT_THREAD_VERSION=1.2" 56 | "-DOTBR_DUA_ROUTING=ON" 57 | "-DOT_DUA=ON" 58 | "-DOT_MLR=ON" 59 | "-DOTBR_DNSSD_DISCOVERY_PROXY=OFF" 60 | "-DOTBR_SRP_ADVERTISING_PROXY=OFF" 61 | "-DOTBR_TREL=OFF" 62 | ) 63 | 64 | readonly OTBR_THREAD_1_3_OPTIONS=( 65 | ${OTBR_COMMON_OPTIONS[@]} 66 | "-DOT_THREAD_VERSION=1.3" 67 | "-DOTBR_DUA_ROUTING=ON" 68 | "-DOT_DUA=ON" 69 | "-DOT_MLR=ON" 70 | "-DOTBR_DNSSD_DISCOVERY_PROXY=ON" 71 | "-DOTBR_SRP_ADVERTISING_PROXY=ON" 72 | "-DOT_BORDER_ROUTING=ON" 73 | "-DOT_SRP_CLIENT=ON" 74 | "-DOT_DNS_CLIENT=ON" 75 | "-DOT_TCP=ON" 76 | "-DOT_DNS_CLIENT_OVER_TCP=ON" 77 | "-DOTBR_TREL=ON" 78 | "-DOTBR_NAT64=ON" 79 | "-DOTBR_DHCP6_PD=ON" 80 | ) 81 | 82 | readonly OTBR_THREAD_1_4_OPTIONS=( 83 | ${OTBR_COMMON_OPTIONS[@]} 84 | "-DOT_THREAD_VERSION=1.4" 85 | "-DOTBR_DUA_ROUTING=ON" 86 | "-DOT_DUA=ON" 87 | "-DOT_MLR=ON" 88 | "-DOTBR_DNSSD_DISCOVERY_PROXY=ON" 89 | "-DOTBR_SRP_ADVERTISING_PROXY=ON" 90 | "-DOT_BORDER_ROUTING=ON" 91 | "-DOT_SRP_CLIENT=ON" 92 | "-DOT_DNS_CLIENT=ON" 93 | "-DOT_TCP=ON" 94 | "-DOT_DNS_CLIENT_OVER_TCP=ON" 95 | "-DOTBR_TREL=ON" 96 | "-DOTBR_NAT64=ON" 97 | "-DOTBR_DHCP6_PD=ON" 98 | ) 99 | 100 | build_options=( 101 | "INFRA_IF_NAME=eth0" 102 | "RELEASE=1" 103 | "REFERENCE_DEVICE=1" 104 | "BACKBONE_ROUTER=1" 105 | "NETWORK_MANAGER=0" 106 | "DHCPV6_PD=0" 107 | "WEB_GUI=0" 108 | "REST_API=0" 109 | ) 110 | 111 | if [ "${REFERENCE_RELEASE_TYPE?}" = "1.2" ]; then 112 | case "${REFERENCE_PLATFORM}" in 113 | efr32mg12) 114 | readonly LOCAL_OPTIONS=( 115 | 'BORDER_ROUTING=0' 116 | 'NAT64=0' 117 | 'DNS64=0' 118 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_2_OPTIONS[@]} -DOT_RCP_RESTORATION_MAX_COUNT=100 -DCMAKE_CXX_FLAGS='-DOPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US=5000'\"" 119 | ) 120 | build_options+=("${LOCAL_OPTIONS[@]}") 121 | ;; 122 | ncs) 123 | readonly LOCAL_OPTIONS=( 124 | 'BORDER_ROUTING=0' 125 | 'NAT64=0' 126 | 'DNS64=0' 127 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_2_OPTIONS[@]} -DOT_PLATFORM_BOOTLOADER_MODE=ON\"" 128 | ) 129 | build_options+=("${LOCAL_OPTIONS[@]}") 130 | ;; 131 | *) 132 | readonly LOCAL_OPTIONS=( 133 | 'BORDER_ROUTING=0' 134 | 'NAT64=0' 135 | 'DNS64=0' 136 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_2_OPTIONS[@]}\"" 137 | ) 138 | build_options+=("${LOCAL_OPTIONS[@]}") 139 | ;; 140 | esac 141 | elif [ "${REFERENCE_RELEASE_TYPE?}" = "1.3" ]; then 142 | case "${REFERENCE_PLATFORM}" in 143 | efr32mg12) 144 | readonly LOCAL_OPTIONS=( 145 | 'BORDER_ROUTING=1' 146 | 'NAT64=0' 147 | 'DNS64=0' 148 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_3_OPTIONS[@]} -DOT_RCP_RESTORATION_MAX_COUNT=100 -DCMAKE_CXX_FLAGS='-DOPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US=5000'\"" 149 | ) 150 | build_options+=("${LOCAL_OPTIONS[@]}") 151 | ;; 152 | ncs) 153 | readonly LOCAL_OPTIONS=( 154 | 'BORDER_ROUTING=1' 155 | 'NAT64=0' 156 | 'DNS64=0' 157 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_3_OPTIONS[@]} -DOT_PLATFORM_BOOTLOADER_MODE=ON\"" 158 | ) 159 | build_options+=("${LOCAL_OPTIONS[@]}") 160 | ;; 161 | *) 162 | readonly LOCAL_OPTIONS=( 163 | 'BORDER_ROUTING=1' 164 | 'NAT64=0' 165 | 'DNS64=0' 166 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_3_OPTIONS[@]}\"" 167 | ) 168 | build_options+=("${LOCAL_OPTIONS[@]}") 169 | ;; 170 | esac 171 | elif [ "${REFERENCE_RELEASE_TYPE?}" = "1.4" ]; then 172 | case "${REFERENCE_PLATFORM}" in 173 | efr32mg12) 174 | readonly LOCAL_OPTIONS=( 175 | 'BORDER_ROUTING=1' 176 | 'NAT64=1' 177 | 'DNS64=1' 178 | 'DHCPV6_PD_REF=1' 179 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_4_OPTIONS[@]} -DOT_RCP_RESTORATION_MAX_COUNT=100 -DCMAKE_CXX_FLAGS='-DOPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US=5000'\"" 180 | ) 181 | build_options+=("${LOCAL_OPTIONS[@]}") 182 | ;; 183 | ncs) 184 | readonly LOCAL_OPTIONS=( 185 | 'BORDER_ROUTING=1' 186 | 'NAT64=1' 187 | 'DNS64=1' 188 | 'DHCPV6_PD_REF=1' 189 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_4_OPTIONS[@]} -DOT_PLATFORM_BOOTLOADER_MODE=ON\"" 190 | ) 191 | build_options+=("${LOCAL_OPTIONS[@]}") 192 | ;; 193 | *) 194 | readonly LOCAL_OPTIONS=( 195 | 'BORDER_ROUTING=1' 196 | 'NAT64=1' 197 | 'DNS64=1' 198 | 'DHCPV6_PD_REF=1' 199 | "OTBR_OPTIONS=\"${OTBR_THREAD_1_4_OPTIONS[@]}\"" 200 | ) 201 | build_options+=("${LOCAL_OPTIONS[@]}") 202 | ;; 203 | esac 204 | fi 205 | 206 | configure_apt_source() 207 | { 208 | if [ "$IN_CHINA" = 1 ]; then 209 | echo 'deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib rpi 210 | deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib rpi' | sudo tee /etc/apt/sources.list 211 | echo 'deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ buster main ui' | sudo tee /etc/apt/sources.list.d/raspi.list 212 | fi 213 | } 214 | configure_apt_source 215 | 216 | echo "127.0.0.1 $(hostname)" >>/etc/hosts 217 | chown -R pi:pi /home/pi/repo 218 | cd /home/pi/repo/ot-br-posix 219 | apt-get update 220 | apt-get install -y --no-install-recommends git python3-pip 221 | su -c "DOCKER=1 ${build_options[*]} script/bootstrap" pi 222 | 223 | rm -rf /home/pi/repo/ot-br-posix/third_party/openthread/repo 224 | cp -rp /home/pi/repo/openthread /home/pi/repo/ot-br-posix/third_party/openthread/repo 225 | 226 | apt-get purge -y cmake 227 | pip3 install scikit-build 228 | pip3 install cmake==3.20.2 229 | cmake --version 230 | 231 | pip3 install zeroconf 232 | 233 | apt-get install -y --no-install-recommends libgirepository1.0-dev 234 | pip3 install dbus-python==1.3.2 235 | pip3 install PyGObject 236 | 237 | su -c "${build_options[*]} script/setup" pi 238 | 239 | if [[ "$REFERENCE_RELEASE_TYPE" = "1.2" || "$REFERENCE_RELEASE_TYPE" = "1.3" || "$REFERENCE_RELEASE_TYPE" = "1.4" ]]; then 240 | cd /home/pi/repo/ 241 | ./script/make-commissioner.bash 242 | fi 243 | 244 | # nRF Connect SDK related actions 245 | if [ "${REFERENCE_PLATFORM?}" = "ncs" ]; then 246 | pip3 install -r /home/pi/repo/config/ncs/requirements-nrfutil.txt 247 | pip3 install --no-dependencies nrfutil==6.0.1 248 | apt-get install -y --no-install-recommends vim wiringpi 249 | pip3 install wrapt==1.12.1 250 | 251 | # add calling of link_dongle.py script at startup to update symlink to the dongle 252 | sed -i '/exit 0/d' /etc/rc.local 253 | grep -qxF 'sudo systemctl restart otbr-agent.service' /etc/rc.local || echo 'sudo systemctl restart otbr-agent.service' >>/etc/rc.local 254 | echo 'exit 0' >>/etc/rc.local 255 | 256 | # update testharness-discovery script to fix autodiscovery issue 257 | if [ "$REFERENCE_RELEASE_TYPE" = "1.2" ]; then 258 | sed -i 's/OpenThread_BR/OTNCS_BR/g' /usr/sbin/testharness-discovery 259 | else 260 | sed -i 's/OpenThread_BR/OTNCS13_BR/g' /usr/sbin/testharness-discovery 261 | fi 262 | 263 | elif [ "${REFERENCE_PLATFORM?}" = "efr32mg12" ]; then 264 | # update testharness-discovery script to fix autodiscovery issue 265 | sed -i "s/OpenThread_BR/OTS${REFERENCE_RELEASE_TYPE//./}_BR/g" /usr/sbin/testharness-discovery 266 | fi 267 | 268 | sync 269 | -------------------------------------------------------------------------------- /thci/OTNCS_BR.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (c) 2021 Nordic Semiconductor ASA 4 | # 5 | # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 6 | # 7 | # Copyright (c) 2016, The OpenThread Authors. 8 | # All rights reserved. 9 | # 10 | # Redistribution and use in source and binary forms, with or without 11 | # modification, are permitted provided that the following conditions are met: 12 | # 1. Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # 2. Redistributions in binary form must reproduce the above copyright 15 | # notice, this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # 3. Neither the name of the copyright holder nor the 18 | # names of its contributors may be used to endorse or promote products 19 | # derived from this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 25 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | 33 | """ 34 | >> Thread Host Controller Interface 35 | >> Device : OTNCS_BR THCI 36 | >> Class : OTNCS_BR 37 | """ 38 | import logging 39 | import re 40 | import sys 41 | import time 42 | import ipaddress 43 | 44 | import serial 45 | from GRLLibs.UtilityModules.ModuleHelper import ModuleHelper 46 | from IThci import IThci 47 | from THCI.OTNCS import OpenThreadTHCI, watched, API 48 | 49 | RPI_FULL_PROMPT = 'pi@raspberrypi:~$ ' 50 | RPI_USERNAME_PROMPT = 'raspberrypi login: ' 51 | RPI_PASSWORD_PROMPT = 'Password: ' 52 | """regex: used to split lines""" 53 | LINESEPX = re.compile(r'\r\n|\n') 54 | 55 | LOGX = re.compile(r'.*Under-voltage detected!') 56 | """regex: used to filter logging""" 57 | 58 | assert LOGX.match('[57522.618196] Under-voltage detected! (0x00050005)') 59 | 60 | OTBR_AGENT_SYSLOG_PATTERN = re.compile(r'raspberrypi otbr-agent\[\d+\]: (.*)') 61 | assert OTBR_AGENT_SYSLOG_PATTERN.search( 62 | 'Jun 23 05:21:22 raspberrypi otbr-agent[323]: =========[[THCI] direction=send | type=JOIN_FIN.req | len=039]==========]' 63 | ).group(1) == '=========[[THCI] direction=send | type=JOIN_FIN.req | len=039]==========]' 64 | 65 | 66 | class SSHHandle(object): 67 | 68 | def __init__(self, ip, port, username, password): 69 | self.ip = ip 70 | self.port = int(port) 71 | self.username = username 72 | self.password = password 73 | self.__handle = None 74 | 75 | self.__connect() 76 | 77 | def __connect(self): 78 | import paramiko 79 | 80 | self.close() 81 | 82 | self.__handle = paramiko.SSHClient() 83 | self.__handle.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 84 | self.__handle.connect(self.ip, port=self.port, username=self.username, password=self.password) 85 | 86 | def close(self): 87 | if self.__handle is not None: 88 | self.__handle.close() 89 | self.__handle = None 90 | 91 | def bash(self, cmd, timeout): 92 | from paramiko import SSHException 93 | retry = 3 94 | for i in range(retry): 95 | try: 96 | stdin, stdout, stderr = self.__handle.exec_command(cmd, timeout=timeout) 97 | 98 | sys.stderr.write(stderr.read()) 99 | output = [r.encode('utf8').rstrip('\r\n') for r in stdout.readlines()] 100 | return output 101 | 102 | except Exception: 103 | if i < retry - 1: 104 | print('SSH connection is lost, try reconnect after 1 second.') 105 | time.sleep(1) 106 | self.__connect() 107 | else: 108 | raise 109 | 110 | def log(self, fmt, *args): 111 | try: 112 | msg = fmt % args 113 | print('%s - %s - %s' % (self.port, time.strftime('%b %d %H:%M:%S'), msg)) 114 | except Exception: 115 | pass 116 | 117 | 118 | class SerialHandle: 119 | 120 | def __init__(self, port, baudrate): 121 | self.port = port 122 | self.__handle = serial.Serial(port, baudrate, timeout=0) 123 | 124 | self.__lines = [''] 125 | assert len(self.__lines) >= 1, self.__lines 126 | 127 | self.log("inputing username ...") 128 | self.__bashWriteLine('pi') 129 | deadline = time.time() + 20 130 | loginOk = False 131 | while time.time() < deadline: 132 | time.sleep(1) 133 | 134 | lastLine = None 135 | while True: 136 | line = self.__bashReadLine(timeout=1) 137 | 138 | if not line: 139 | break 140 | 141 | lastLine = line 142 | 143 | if lastLine == RPI_FULL_PROMPT: 144 | self.log("prompt found, login success!") 145 | loginOk = True 146 | break 147 | 148 | if lastLine == RPI_PASSWORD_PROMPT: 149 | self.log("inputing password ...") 150 | self.__bashWriteLine('raspberry') 151 | elif lastLine == RPI_USERNAME_PROMPT: 152 | self.log("inputing username ...") 153 | self.__bashWriteLine('pi') 154 | elif not lastLine: 155 | self.log("inputing username ...") 156 | self.__bashWriteLine('pi') 157 | 158 | if not loginOk: 159 | raise Exception('login fail') 160 | 161 | self.bash('stty cols 256') 162 | 163 | def log(self, fmt, *args): 164 | try: 165 | msg = fmt % args 166 | print('%s - %s - %s' % (self.port, time.strftime('%b %d %H:%M:%S'), msg)) 167 | except Exception: 168 | pass 169 | 170 | def close(self): 171 | self.__handle.close() 172 | 173 | def bash(self, cmd, timeout=10): 174 | """ 175 | Execute the command in bash. 176 | """ 177 | self.__bashClearLines() 178 | self.__bashWriteLine(cmd) 179 | self.__bashExpect(cmd, timeout=timeout, endswith=True) 180 | 181 | response = [] 182 | 183 | deadline = time.time() + timeout 184 | while time.time() < deadline: 185 | line = self.__bashReadLine() 186 | if line is None: 187 | time.sleep(0.01) 188 | continue 189 | 190 | if line == RPI_FULL_PROMPT: 191 | # return response lines without prompt 192 | return response 193 | 194 | response.append(line) 195 | 196 | self.__bashWrite('\x03') 197 | raise Exception('%s: failed to find end of response' % self.port) 198 | 199 | def __bashExpect(self, expected, timeout=20, endswith=False): 200 | print('[%s] Expecting [%r]' % (self.port, expected)) 201 | 202 | deadline = time.time() + timeout 203 | while time.time() < deadline: 204 | line = self.__bashReadLine() 205 | if line is None: 206 | time.sleep(0.01) 207 | continue 208 | 209 | print('[%s] Got line [%r]' % (self.port, line)) 210 | 211 | if endswith: 212 | matched = line.endswith(expected) 213 | else: 214 | matched = line == expected 215 | 216 | if matched: 217 | print('[%s] Expected [%r]' % (self.port, expected)) 218 | return 219 | 220 | # failed to find the expected string 221 | # send Ctrl+C to terminal 222 | self.__bashWrite('\x03') 223 | raise Exception('failed to find expected string[%s]' % expected) 224 | 225 | def __bashRead(self, timeout=1): 226 | deadline = time.time() + timeout 227 | data = '' 228 | while True: 229 | piece = self.__handle.read() 230 | data = data + piece.decode('utf8') 231 | if piece: 232 | continue 233 | 234 | if data or time.time() >= deadline: 235 | break 236 | 237 | if data: 238 | self.log('>>> %r', data) 239 | 240 | return data 241 | 242 | def __bashReadLine(self, timeout=1): 243 | line = self.__bashGetNextLine() 244 | if line is not None: 245 | return line 246 | 247 | assert len(self.__lines) == 1, self.__lines 248 | tail = self.__lines.pop() 249 | 250 | try: 251 | tail += self.__bashRead(timeout=timeout) 252 | tail = tail.replace(RPI_FULL_PROMPT, RPI_FULL_PROMPT + '\r\n') 253 | tail = tail.replace(RPI_USERNAME_PROMPT, RPI_USERNAME_PROMPT + '\r\n') 254 | tail = tail.replace(RPI_PASSWORD_PROMPT, RPI_PASSWORD_PROMPT + '\r\n') 255 | finally: 256 | self.__lines += [l.rstrip('\r') for l in LINESEPX.split(tail)] 257 | assert len(self.__lines) >= 1, self.__lines 258 | 259 | return self.__bashGetNextLine() 260 | 261 | def __bashGetNextLine(self): 262 | assert len(self.__lines) >= 1, self.__lines 263 | while len(self.__lines) > 1: 264 | line = self.__lines.pop(0) 265 | assert len(self.__lines) >= 1, self.__lines 266 | if LOGX.match(line): 267 | logging.info('LOG: %s', line) 268 | continue 269 | else: 270 | return line 271 | assert len(self.__lines) >= 1, self.__lines 272 | return None 273 | 274 | def __bashWrite(self, data): 275 | self.__handle.write(data) 276 | self.log("<<< %r", data) 277 | 278 | def __bashClearLines(self): 279 | assert len(self.__lines) >= 1, self.__lines 280 | while self.__bashReadLine(timeout=0) is not None: 281 | pass 282 | assert len(self.__lines) >= 1, self.__lines 283 | 284 | def __bashWriteLine(self, line): 285 | self.__bashWrite(line + '\n') 286 | 287 | 288 | class OTNCS_BR(OpenThreadTHCI, IThci): 289 | DEFAULT_COMMAND_TIMEOUT = 20 290 | NCS_CMD_PREFIX = '' 291 | IsBorderRouter = True 292 | 293 | def _connect(self): 294 | self.log("logining Raspberry Pi ...") 295 | self.__cli_output_lines = [] 296 | self.__syslog_skip_lines = None 297 | self.__syslog_last_read_ts = 0 298 | 299 | if self.connectType == 'ip': 300 | self.__handle = SSHHandle(self.telnetIp, self.telnetPort, self.telnetUsername, self.telnetPassword) 301 | else: 302 | self.__handle = SerialHandle(self.port, 115200) 303 | 304 | self.__afterConnect() 305 | 306 | def _disconnect(self): 307 | if self.__handle: 308 | self.__handle.close() 309 | self.__handle = None 310 | 311 | def _deviceBeforeReset(self): 312 | if self.IsHost: 313 | self.__stopRadvdService() 314 | self.bash('sudo ip -6 addr del 910b::1 dev eth0 || true') 315 | self.bash('sudo ip -6 addr del fd00:7d03:7d03:7d03::1 dev eth0 || true') 316 | 317 | def _deviceAfterReset(self): 318 | self.__dumpSyslog() 319 | self.__truncateSyslog() 320 | 321 | @API 322 | def setupHost(self, setDua=False): 323 | self.IsHost = True 324 | 325 | if not setDua: 326 | cmd = 'sudo ip -6 addr add 910b::1 dev eth0' 327 | else: 328 | cmd = 'sudo ip -6 addr add fd00:7d03:7d03:7d03::1 dev eth0' 329 | self.bash(cmd) 330 | 331 | self.__startRadvdService() 332 | 333 | def _deviceEscapeEscapable(self, string): 334 | """Escape CLI escapable characters in the given string. 335 | 336 | Args: 337 | string (str): UTF-8 input string. 338 | 339 | Returns: 340 | [str]: The modified string with escaped characters. 341 | """ 342 | return '"' + string + '"' 343 | 344 | @watched 345 | def bash(self, cmd, timeout=DEFAULT_COMMAND_TIMEOUT): 346 | return self.__handle.bash(cmd, timeout=timeout) 347 | 348 | def bash_unwatched(self, cmd, timeout=DEFAULT_COMMAND_TIMEOUT): 349 | return self.__handle.bash(cmd, timeout=timeout) 350 | 351 | # Override send_udp 352 | @API 353 | def send_udp(self, interface, dst, port, payload): 354 | if interface == 0: # Thread Interface 355 | super(OTNCS_BR, self).send_udp(interface, dst, port, payload) 356 | return 357 | 358 | if interface == 1: 359 | ifname = 'eth0' 360 | else: 361 | print('invalid interface') 362 | return 363 | 364 | cmd = 'sudo /home/pi/ot-br-posix/script/reference-device/send_udp.py %s %s %s %s' % (ifname, dst, port, 365 | payload) 366 | print(cmd) 367 | self.bash(cmd) 368 | 369 | @API 370 | def ip_neighbors_flush(self): 371 | print('%s call clear_cache' % self.port) 372 | # clear neigh cache on linux 373 | cmd1 = 'sudo ip -6 neigh flush nud all nud failed nud noarp dev eth0' 374 | cmd2 = 'sudo ip -6 neigh list nud all dev eth0 ' \ 375 | '| cut -d " " -f1 ' \ 376 | '| sudo xargs -I{} ip -6 neigh delete {} dev eth0' 377 | cmd = '%s ; %s' % (cmd1, cmd2) 378 | self.bash(cmd) 379 | 380 | @API 381 | def ip_neighbors_add(self, addr, lladdr, nud='noarp'): 382 | print('%s ip_neighbors_add' % self.port) 383 | cmd1 = 'sudo ip -6 neigh delete %s dev eth0' % addr 384 | cmd2 = 'sudo ip -6 neigh add %s dev eth0 lladdr %s nud %s' % (addr, lladdr, nud) 385 | cmd = '%s ; %s' % (cmd1, cmd2) 386 | self.bash(cmd) 387 | 388 | @API 389 | def get_eth_ll(self): 390 | print('%s get_eth_ll' % self.port) 391 | cmd = "ip -6 addr list dev eth0 | grep 'inet6 fe80' | awk '{print $2}'" 392 | ret = self.bash(cmd)[0].split('/')[0] 393 | return ret 394 | 395 | @API 396 | def ping(self, strDestination, ilength=0, hop_limit=5, timeout=5): 397 | """ send ICMPv6 echo request with a given length to a unicast destination 398 | address 399 | 400 | Args: 401 | strDestination: the unicast destination address of ICMPv6 echo request 402 | ilength: the size of ICMPv6 echo request payload 403 | hop_limit: the hop limit 404 | timeout: time before ping() stops 405 | """ 406 | if hop_limit is None: 407 | hop_limit = 5 408 | 409 | if self.IsHost or self.IsBackboneRouter: 410 | ifName = 'eth0' 411 | else: 412 | ifName = 'wpan0' 413 | 414 | cmd = 'ping -6 -I %s %s -c 1 -s %d -W %d -t %d' % ( 415 | ifName, 416 | strDestination, 417 | int(ilength), 418 | int(timeout), 419 | int(hop_limit), 420 | ) 421 | 422 | self.bash(cmd) 423 | time.sleep(1) 424 | 425 | def multicast_Ping(self, destination, length=20): 426 | """send ICMPv6 echo request with a given length to a multicast destination 427 | address 428 | 429 | Args: 430 | destination: the multicast destination address of ICMPv6 echo request 431 | length: the size of ICMPv6 echo request payload 432 | """ 433 | print('%s call multicast_Ping' % self.port) 434 | print('destination: %s' % destination) 435 | hop_limit = 5 436 | 437 | if self.IsHost or self.IsBackboneRouter: 438 | ifName = 'eth0' 439 | else: 440 | ifName = 'wpan0' 441 | 442 | cmd = 'ping -6 -I %s %s -c 1 -s %d -t %d' % (ifName, destination, str(length), hop_limit) 443 | 444 | self.bash(cmd) 445 | 446 | @API 447 | def getGUA(self, filterByPrefix=None, eth=False): 448 | """get expected global unicast IPv6 address of Thread device 449 | 450 | note: existing filterByPrefix are string of in lowercase. e.g. 451 | '2001' or '2001:0db8:0001:0000". 452 | 453 | Args: 454 | filterByPrefix: a given expected global IPv6 prefix to be matched 455 | 456 | Returns: 457 | a global IPv6 address 458 | """ 459 | # get global addrs set if multiple 460 | if eth: 461 | return self.__getEthGUA(filterByPrefix=filterByPrefix) 462 | else: 463 | return super(OTNCS_BR, self).getGUA(filterByPrefix=filterByPrefix) 464 | 465 | def __getEthGUA(self, filterByPrefix=None): 466 | globalAddrs = [] 467 | 468 | cmd = 'ip -6 addr list dev eth0 | grep inet6' 469 | output = self.bash(cmd) 470 | for line in output: 471 | # example: inet6 2401:fa00:41:23:274a:1329:3ab9:d953/64 scope global dynamic noprefixroute 472 | line = line.strip().split() 473 | 474 | if len(line) < 4 or line[2] != 'scope': 475 | continue 476 | 477 | if line[3] != 'global': 478 | continue 479 | 480 | addr = line[1].split('/')[0] 481 | addr = str(ipaddress.IPv6Address(addr.decode()).exploded) 482 | globalAddrs.append(addr) 483 | 484 | if not filterByPrefix: 485 | return globalAddrs[0] 486 | else: 487 | if filterByPrefix[-2:] != '::': 488 | filterByPrefix = '%s::' % filterByPrefix 489 | prefix = ipaddress.IPv6Address(filterByPrefix.decode()) 490 | for fullIp in globalAddrs: 491 | address = ipaddress.IPv6Address(fullIp.decode()) 492 | if address.packed[:8] == prefix.packed[:8]: 493 | return fullIp 494 | 495 | def _cliReadLine(self): 496 | # read commissioning log if it's commissioning 497 | if not self.__cli_output_lines: 498 | self.__readSyslogToCli() 499 | 500 | if self.__cli_output_lines: 501 | return self.__cli_output_lines.pop(0) 502 | 503 | return None 504 | 505 | @watched 506 | def _deviceGetEtherMac(self): 507 | # Harness wants it in string. Because wireshark filter for eth 508 | # cannot be applies in hex 509 | return self.bash('ip addr list dev eth0 | grep ether')[0].strip().split()[1] 510 | 511 | @watched 512 | def _onCommissionStart(self): 513 | assert self.__syslog_skip_lines is None 514 | self.__syslog_skip_lines = int(self.bash('wc -l /var/log/syslog')[0].split()[0]) 515 | self.__syslog_last_read_ts = 0 516 | 517 | @watched 518 | def _onCommissionStop(self): 519 | assert self.__syslog_skip_lines is not None 520 | self.__syslog_skip_lines = None 521 | 522 | def _deviceBeforeThreadStart(self): 523 | self.bash('sudo sysctl net.ipv6.conf.eth0.accept_ra=2') 524 | 525 | @watched 526 | def __startRadvdService(self): 527 | assert self.IsHost, "radvd service runs on Host only" 528 | 529 | self.bash("""sudo sh -c "cat >/etc/radvd.conf <