From 0b0db37a13c45196e30b373ad0a9b82a5d89ccb2 Mon Sep 17 00:00:00 2001 From: Mason Tran Date: Fri, 27 Oct 2023 18:54:15 -0400 Subject: [PATCH 1/5] [api] add API to reset to bootloader mode (#9523) --- etc/cmake/options.cmake | 1 + examples/platforms/simulation/misc.c | 9 +++++++++ include/openthread/instance.h | 16 ++++++++++++++- include/openthread/platform/misc.h | 14 ++++++++++++++ script/test | 18 ++++++++++++++++- src/cli/README.md | 11 +++++++++++ src/cli/cli.cpp | 29 +++++++++++++++++++++++++--- src/core/api/instance_api.cpp | 4 ++++ src/core/instance/instance.cpp | 4 ++++ src/core/instance/instance.hpp | 12 ++++++++++++ src/lib/spinel/radio_spinel.cpp | 11 +++++++++++ src/lib/spinel/radio_spinel.hpp | 12 +++++++----- src/lib/spinel/spinel.c | 2 ++ src/lib/spinel/spinel.h | 12 ++++++++---- src/ncp/ncp_base.cpp | 12 ++++++++++++ src/posix/platform/radio.cpp | 9 +++++++++ tests/scripts/expect/cli-reset.exp | 3 +++ tests/unit/test_platform.cpp | 2 ++ 18 files changed, 167 insertions(+), 14 deletions(-) diff --git a/etc/cmake/options.cmake b/etc/cmake/options.cmake index 0c667d0eed5..227e0faa160 100644 --- a/etc/cmake/options.cmake +++ b/etc/cmake/options.cmake @@ -225,6 +225,7 @@ ot_option(OT_NETDIAG_CLIENT OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE "Network ot_option(OT_OPERATIONAL_DATASET_AUTO_INIT OPENTHREAD_CONFIG_OPERATIONAL_DATASET_AUTO_INIT "operational dataset auto init") ot_option(OT_OTNS OPENTHREAD_CONFIG_OTNS_ENABLE "OTNS") ot_option(OT_PING_SENDER OPENTHREAD_CONFIG_PING_SENDER_ENABLE "ping sender" ${OT_APP_CLI}) +ot_option(OT_PLATFORM_BOOTLOADER_MODE OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE "platform bootloader mode") ot_option(OT_PLATFORM_NETIF OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE "platform netif") ot_option(OT_PLATFORM_UDP OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE "platform UDP") ot_option(OT_REFERENCE_DEVICE OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE "test harness reference device") diff --git a/examples/platforms/simulation/misc.c b/examples/platforms/simulation/misc.c index aefbca5def1..07739a2fef8 100644 --- a/examples/platforms/simulation/misc.c +++ b/examples/platforms/simulation/misc.c @@ -60,6 +60,15 @@ void otPlatReset(otInstance *aInstance) #endif // OPENTHREAD_PLATFORM_USE_PSEUDO_RESET } +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE +otError otPlatResetToBootloader(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return OT_ERROR_NOT_CAPABLE; +} +#endif + otPlatResetReason otPlatGetResetReason(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); diff --git a/include/openthread/instance.h b/include/openthread/instance.h index b9c0b82b1b0..03f5c623ad6 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (369) +#define OPENTHREAD_API_VERSION (370) /** * @addtogroup api-instance @@ -255,6 +255,20 @@ void otRemoveStateChangeCallback(otInstance *aInstance, otStateChangedCallback a */ void otInstanceReset(otInstance *aInstance); +/** + * Triggers a platform reset to bootloader mode, if supported. + * + * Requires `OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE`. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @retval OT_ERROR_NONE Reset to bootloader successfully. + * @retval OT_ERROR_BUSY Failed due to another operation is ongoing. + * @retval OT_ERROR_NOT_CAPABLE Not capable of resetting to bootloader. + * + */ +otError otInstanceResetToBootloader(otInstance *aInstance); + /** * Deletes all the settings stored on non-volatile memory, and then triggers a platform reset. * diff --git a/include/openthread/platform/misc.h b/include/openthread/platform/misc.h index 7fbee54b1fd..b1b20211112 100644 --- a/include/openthread/platform/misc.h +++ b/include/openthread/platform/misc.h @@ -61,6 +61,20 @@ extern "C" { */ void otPlatReset(otInstance *aInstance); +/** + * Performs a hardware reset on the platform to launch bootloader mode, if supported. + * + * Used when `OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE` is enabled. + * + * @param[in] aInstance The OpenThread instance structure. + * + * @retval OT_ERROR_NONE Reset to bootloader successfully. + * @retval OT_ERROR_BUSY Failed due to another operation is ongoing. + * @retval OT_ERROR_NOT_CAPABLE Not capable of resetting to bootloader. + * + */ +otError otPlatResetToBootloader(otInstance *aInstance); + /** * Enumeration of possible reset reason codes. * diff --git a/script/test b/script/test index e716f5abb61..a9a71b3b55c 100755 --- a/script/test +++ b/script/test @@ -132,6 +132,17 @@ build_simulation() options+=("-DOT_LINK_METRICS_MANAGER=ON") fi + if [[ ${OT_NODE_TYPE} == cli* ]]; then + # Only enable OT_PLATFORM_BOOTLOADER_MODE when testing cli. + # This is intended to test that the "reset bootloader" CLI command returns a "NotCapable" error + + # Note: Setting this option to ON for all OT_NODE_TYPEs will cause the posix/expects CI check to fail. + # This is because the simulation RCP will have the SPINEL_CAP_RCP_RESET_TO_BOOTLOADER capability, + # causing the ot-cli POSIX app to send the reset to simulation RCP successfully instead of printing + # the expected error. + options+=("-DOT_PLATFORM_BOOTLOADER_MODE=ON") + fi + if [[ ${ot_extra_options[*]+x} ]]; then options+=("${ot_extra_options[@]}") fi @@ -158,7 +169,12 @@ build_simulation() build_posix() { local version="$1" - local options=("-DOT_MESSAGE_USE_HEAP=ON" "-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON") + local options=( + "-DBUILD_TESTING=ON" + "-DOT_MESSAGE_USE_HEAP=ON" + "-DOT_PLATFORM_BOOTLOADER_MODE=ON" + "-DOT_THREAD_VERSION=${version}" + ) if [[ ${version} != "1.1" ]]; then options+=("-DOT_DUA=ON") diff --git a/src/cli/README.md b/src/cli/README.md index e13f03204e8..9bc0ffb3e3d 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -3075,6 +3075,17 @@ Signal a platform reset. > reset ``` +### reset bootloader + +Signal a platform reset to bootloader mode, if supported. + +Requires `OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE`. + +```bash +> reset bootloader +Done +``` + ### rloc16 Get the Thread RLOC16 value. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 845127a4a32..e4e62620165 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -276,11 +276,34 @@ template <> otError Interpreter::Process(Arg aArgs[]) template <> otError Interpreter::Process(Arg aArgs[]) { - OT_UNUSED_VARIABLE(aArgs); + otError error = OT_ERROR_NONE; - otInstanceReset(GetInstancePtr()); + if (aArgs[0].IsEmpty()) + { + otInstanceReset(GetInstancePtr()); + } - return OT_ERROR_NONE; +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE + /** + * @cli reset bootloader + * @code + * reset bootloader + * @endcode + * @cparam reset bootloader + * @par api_copy + * #otInstanceResetToBootloader + */ + else if (aArgs[0] == "bootloader") + { + error = otInstanceResetToBootloader(GetInstancePtr()); + } +#endif + else + { + error = OT_ERROR_INVALID_COMMAND; + } + + return error; } void Interpreter::ProcessLine(char *aBuf) diff --git a/src/core/api/instance_api.cpp b/src/core/api/instance_api.cpp index ad2a89e16ce..6d51d3c3986 100644 --- a/src/core/api/instance_api.cpp +++ b/src/core/api/instance_api.cpp @@ -86,6 +86,10 @@ void otInstanceFinalize(otInstance *aInstance) { AsCoreType(aInstance).Finalize( void otInstanceReset(otInstance *aInstance) { AsCoreType(aInstance).Reset(); } +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE +otError otInstanceResetToBootloader(otInstance *aInstance) { return AsCoreType(aInstance).ResetToBootloader(); } +#endif + #if OPENTHREAD_CONFIG_UPTIME_ENABLE uint64_t otInstanceGetUptime(otInstance *aInstance) { return AsCoreType(aInstance).Get().GetUptime(); } diff --git a/src/core/instance/instance.cpp b/src/core/instance/instance.cpp index 6dcc3e8927c..872718fafc0 100644 --- a/src/core/instance/instance.cpp +++ b/src/core/instance/instance.cpp @@ -312,6 +312,10 @@ Instance *Instance::Init(void *aBuffer, size_t *aBufferSize) void Instance::Reset(void) { otPlatReset(this); } +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE +Error Instance::ResetToBootloader(void) { return otPlatResetToBootloader(this); } +#endif + #if OPENTHREAD_RADIO void Instance::ResetRadioStack(void) { diff --git a/src/core/instance/instance.hpp b/src/core/instance/instance.hpp index 6b26825abdb..1d5f5b5a553 100644 --- a/src/core/instance/instance.hpp +++ b/src/core/instance/instance.hpp @@ -236,6 +236,18 @@ class Instance : public otInstance, private NonCopyable */ void Reset(void); +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE + /** + * Triggers a platform reset to bootloader mode, if supported. + * + * @retval kErrorNone Reset to bootloader successfully. + * @retval kErrorBusy Failed due to another operation is ongoing. + * @retval kErrorNotCapable Not capable of resetting to bootloader. + * + */ + Error ResetToBootloader(void); +#endif + #if OPENTHREAD_RADIO /** * Resets the internal states of the radio. diff --git a/src/lib/spinel/radio_spinel.cpp b/src/lib/spinel/radio_spinel.cpp index a592c3f1636..ab031ae66d5 100644 --- a/src/lib/spinel/radio_spinel.cpp +++ b/src/lib/spinel/radio_spinel.cpp @@ -72,6 +72,7 @@ RadioSpinel::RadioSpinel(void) , mIsPromiscuous(false) , mIsReady(false) , mSupportsLogStream(false) + , mSupportsResetToBootloader(false) , mIsTimeSynced(false) #if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0 , mRcpFailureCount(0) @@ -236,6 +237,11 @@ bool RadioSpinel::IsRcp(bool &aSupportsRcpApiVersion, bool &aSupportsRcpMinHostA aSupportsRcpApiVersion = true; } + if (capability == SPINEL_CAP_RCP_RESET_TO_BOOTLOADER) + { + mSupportsResetToBootloader = true; + } + if (capability == SPINEL_PROP_RCP_MIN_HOST_API_VERSION) { aSupportsRcpMinHostApiVersion = true; @@ -1469,6 +1475,11 @@ otError RadioSpinel::SendReset(uint8_t aResetType) uint8_t buffer[kMaxSpinelFrame]; spinel_ssize_t packed; + if ((aResetType == SPINEL_RESET_BOOTLOADER) && !mSupportsResetToBootloader) + { + ExitNow(error = OT_ERROR_NOT_CAPABLE); + } + // Pack the header, command and key packed = spinel_datatype_pack(buffer, sizeof(buffer), SPINEL_DATATYPE_COMMAND_S SPINEL_DATATYPE_UINT8_S, SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_RESET, aResetType); diff --git a/src/lib/spinel/radio_spinel.hpp b/src/lib/spinel/radio_spinel.hpp index c85e2be7b8c..a1249854507 100644 --- a/src/lib/spinel/radio_spinel.hpp +++ b/src/lib/spinel/radio_spinel.hpp @@ -808,10 +808,11 @@ class RadioSpinel /** * Tries to reset the co-processor. * - * @prarm[in] aResetType The reset type, SPINEL_RESET_PLATFORM or SPINEL_RESET_STACK. + * @prarm[in] aResetType The reset type, SPINEL_RESET_PLATFORM, SPINEL_RESET_STACK, or SPINEL_RESET_BOOTLOADER. * * @retval OT_ERROR_NONE Successfully removed item from the property. * @retval OT_ERROR_BUSY Failed due to another operation is on going. + * @retval OT_ERROR_NOT_CAPABLE Requested reset type is not supported by the co-processor * */ otError SendReset(uint8_t aResetType); @@ -1065,10 +1066,11 @@ class RadioSpinel otExtAddress mIeeeEui64; State mState; - bool mIsPromiscuous : 1; ///< Promiscuous mode. - bool mIsReady : 1; ///< NCP ready. - bool mSupportsLogStream : 1; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format. - bool mIsTimeSynced : 1; ///< Host has calculated the time difference between host and RCP. + bool mIsPromiscuous : 1; ///< Promiscuous mode. + bool mIsReady : 1; ///< NCP ready. + bool mSupportsLogStream : 1; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format. + bool mSupportsResetToBootloader : 1; ///< RCP supports resetting into bootloader mode. + bool mIsTimeSynced : 1; ///< Host has calculated the time difference between host and RCP. #if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0 diff --git a/src/lib/spinel/spinel.c b/src/lib/spinel/spinel.c index 5cf3836b7a6..af95176dd5f 100644 --- a/src/lib/spinel/spinel.c +++ b/src/lib/spinel/spinel.c @@ -1606,6 +1606,8 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability) {SPINEL_CAP_NET_THREAD_1_1, "NET_THREAD_1_1"}, {SPINEL_CAP_NET_THREAD_1_2, "NET_THREAD_1_2"}, {SPINEL_CAP_RCP_API_VERSION, "RCP_API_VERSION"}, + {SPINEL_CAP_RCP_MIN_HOST_API_VERSION, "RCP_MIN_HOST_API_VERSION"}, + {SPINEL_CAP_RCP_RESET_TO_BOOTLOADER, "RCP_RESET_TO_BOOTLOADER"}, {SPINEL_CAP_MAC_ALLOWLIST, "MAC_ALLOWLIST"}, {SPINEL_CAP_MAC_RAW, "MAC_RAW"}, {SPINEL_CAP_OOB_STEERING_DATA, "OOB_STEERING_DATA"}, diff --git a/src/lib/spinel/spinel.h b/src/lib/spinel/spinel.h index ffa370786bf..770cc96e1c9 100644 --- a/src/lib/spinel/spinel.h +++ b/src/lib/spinel/spinel.h @@ -897,8 +897,9 @@ enum enum { - SPINEL_RESET_PLATFORM = 1, - SPINEL_RESET_STACK = 2, + SPINEL_RESET_PLATFORM = 1, + SPINEL_RESET_STACK = 2, + SPINEL_RESET_BOOTLOADER = 3, }; enum @@ -928,8 +929,10 @@ enum * `PROP_LAST_STATUS` has been set to `STATUS_RESET_SOFTWARE`. * * The optional command payload specifies the reset type, can be - * `SPINEL_RESET_PLATFORM` or `SPINEL_RESET_STACK`. Defaults to stack - * reset if unspecified. + * `SPINEL_RESET_PLATFORM`, `SPINEL_RESET_STACK`, or + * `SPINEL_RESET_BOOTLOADER`. + * + * Defaults to stack reset if unspecified. * * If an error occurs, the value of `PROP_LAST_STATUS` will be emitted * instead with the value set to the generated status code for the error. @@ -1284,6 +1287,7 @@ enum SPINEL_CAP_RCP__BEGIN = 64, SPINEL_CAP_RCP_API_VERSION = (SPINEL_CAP_RCP__BEGIN + 0), SPINEL_CAP_RCP_MIN_HOST_API_VERSION = (SPINEL_CAP_RCP__BEGIN + 1), + SPINEL_CAP_RCP_RESET_TO_BOOTLOADER = (SPINEL_CAP_RCP__BEGIN + 2), SPINEL_CAP_RCP__END = 80, SPINEL_CAP_OPENTHREAD__BEGIN = 512, diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 78077287990..acff7845e22 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -1211,6 +1211,14 @@ otError NcpBase::CommandHandler_RESET(uint8_t aHeader) SuccessOrAssert( error = WriteLastStatusFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_STATUS_RESET_POWER_ON)); } +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE + else if (reset_type == SPINEL_RESET_BOOTLOADER) + { + // Signal a platform reset to bootloader mode. + // If implemented, this function shouldn't return. + error = otInstanceResetToBootloader(mInstance); + } +#endif else #endif { @@ -1843,6 +1851,10 @@ template <> otError NcpBase::HandlePropertyGet(void) SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_RCP_MIN_HOST_API_VERSION)); #endif +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE + SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_RCP_RESET_TO_BOOTLOADER)); +#endif + #if OPENTHREAD_PLATFORM_POSIX SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_POSIX)); #endif diff --git a/src/posix/platform/radio.cpp b/src/posix/platform/radio.cpp index aafe9b50200..86901dd7df1 100644 --- a/src/posix/platform/radio.cpp +++ b/src/posix/platform/radio.cpp @@ -978,6 +978,15 @@ otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t a return OT_ERROR_NOT_IMPLEMENTED; } +#if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE +otError otPlatResetToBootloader(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return GetRadioSpinel().SendReset(SPINEL_RESET_BOOTLOADER); +} +#endif + const otRadioSpinelMetrics *otSysGetRadioSpinelMetrics(void) { return GetRadioSpinel().GetRadioSpinelMetrics(); } const otRcpInterfaceMetrics *otSysGetRcpInterfaceMetrics(void) diff --git a/tests/scripts/expect/cli-reset.exp b/tests/scripts/expect/cli-reset.exp index b4306971708..9e828ef925c 100755 --- a/tests/scripts/expect/cli-reset.exp +++ b/tests/scripts/expect/cli-reset.exp @@ -71,4 +71,7 @@ send "panid\n" expect "0xffff" expect_line "Done" +send "reset bootloader\n" +expect_line "Error 27: NotCapable" + dispose_all diff --git a/tests/unit/test_platform.cpp b/tests/unit/test_platform.cpp index 5487643140e..237c5eb0137 100644 --- a/tests/unit/test_platform.cpp +++ b/tests/unit/test_platform.cpp @@ -223,6 +223,8 @@ OT_TOOL_WEAK void otPlatUartReceived(const uint8_t *, uint16_t) {} OT_TOOL_WEAK void otPlatReset(otInstance *) {} +OT_TOOL_WEAK otError otPlatResetToBootloader(otInstance *) { return OT_ERROR_NOT_CAPABLE; } + OT_TOOL_WEAK otPlatResetReason otPlatGetResetReason(otInstance *) { return OT_PLAT_RESET_REASON_POWER_ON; } OT_TOOL_WEAK void otPlatLog(otLogLevel, otLogRegion, const char *, ...) {} From 7074a43e4577d32d5535d52e7940ed2ea7e3a528 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 14:04:51 -0700 Subject: [PATCH 2/5] github-actions: bump github/codeql-action from 2.22.3 to 2.22.5 (#9571) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2.22.3 to 2.22.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/0116bc2df50751f9724a2e35ef1f24d22f90e4e1...74483a38d39275f33fcff5f35b679b5ca4a26a99) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecards.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1c445b3c35a..0b8a3e76168 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -66,7 +66,7 @@ jobs: sudo apt-get --no-install-recommends install -y ninja-build libreadline-dev libncurses-dev - name: Initialize CodeQL - uses: github/codeql-action/init@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 + uses: github/codeql-action/init@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -80,6 +80,6 @@ jobs: ./script/test build - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.22.3 + uses: github/codeql-action/analyze@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 463559535f4..8239e9dd15f 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -95,6 +95,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@0116bc2df50751f9724a2e35ef1f24d22f90e4e1 # v2.1.27 + uses: github/codeql-action/upload-sarif@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.1.27 with: sarif_file: results.sarif From c6ffe1ae2cec4adfd829db15a50a96de1f226772 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 31 Oct 2023 15:33:33 -0700 Subject: [PATCH 3/5] [mac] validate received ack frame PSDU in `ProcessEnhAckSecurity()` (#9565) --- src/core/mac/mac.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index fe41b62b9da..559d53137de 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -1659,6 +1659,8 @@ Error Mac::ProcessEnhAckSecurity(TxFrame &aTxFrame, RxFrame &aAckFrame) VerifyOrExit(aAckFrame.GetSecurityEnabled(), error = kErrorNone); VerifyOrExit(aAckFrame.IsVersion2015()); + SuccessOrExit(aAckFrame.ValidatePsdu()); + IgnoreError(aAckFrame.GetSecurityLevel(securityLevel)); VerifyOrExit(securityLevel == Frame::kSecurityEncMic32); From 4a9fb0609e5e2423243d4a533fd76fafafd550ff Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 31 Oct 2023 15:36:20 -0700 Subject: [PATCH 4/5] [netdata] simplify `Leader` class (#9563) This commit updates the `NetworkData::Leader` sub-class model, removing `LeaderBase` (which intended to provide common functions shared between FTD and MTD) and instead adding all methods directly in `Leader` class with all `FTD`-specific methods having conditional `#if` check. --- src/core/BUILD.gn | 1 - src/core/thread/network_data_leader.cpp | 96 +++-- src/core/thread/network_data_leader.hpp | 335 +++++++++++++++-- src/core/thread/network_data_leader_ftd.cpp | 19 - src/core/thread/network_data_leader_ftd.hpp | 381 -------------------- 5 files changed, 359 insertions(+), 473 deletions(-) delete mode 100644 src/core/thread/network_data_leader_ftd.hpp diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index abb606ed779..37843dd2ebb 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -657,7 +657,6 @@ openthread_core_files = [ "thread/network_data_leader.cpp", "thread/network_data_leader.hpp", "thread/network_data_leader_ftd.cpp", - "thread/network_data_leader_ftd.hpp", "thread/network_data_local.cpp", "thread/network_data_local.hpp", "thread/network_data_notifier.cpp", diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 11c5441dc45..814b5d14a5e 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -55,18 +55,37 @@ namespace NetworkData { RegisterLogModule("NetworkData"); -void LeaderBase::Reset(void) +Leader::Leader(Instance &aInstance) + : MutableNetworkData(aInstance, mTlvBuffer, 0, sizeof(mTlvBuffer)) + , mMaxLength(0) +#if OPENTHREAD_FTD +#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL + , mIsClone(false) +#endif + , mWaitingForNetDataSync(false) + , mContextIds(aInstance) + , mTimer(aInstance) +#endif +{ + Reset(); +} + +void Leader::Reset(void) { mVersion = Random::NonCrypto::GetUint8(); mStableVersion = Random::NonCrypto::GetUint8(); SetLength(0); SignalNetDataChanged(); + +#if OPENTHREAD_FTD + mContextIds.Clear(); +#endif } -Error LeaderBase::GetServiceId(uint32_t aEnterpriseNumber, - const ServiceData &aServiceData, - bool aServerStable, - uint8_t &aServiceId) const +Error Leader::GetServiceId(uint32_t aEnterpriseNumber, + const ServiceData &aServiceData, + bool aServerStable, + uint8_t &aServiceId) const { Error error = kErrorNotFound; Iterator iterator = kIteratorInit; @@ -89,7 +108,7 @@ Error LeaderBase::GetServiceId(uint32_t aEnterpriseNumber, return error; } -Error LeaderBase::GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const +Error Leader::GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const { Error error = kErrorNotFound; Iterator iterator = kIteratorInit; @@ -113,7 +132,7 @@ Error LeaderBase::GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const return error; } -const PrefixTlv *LeaderBase::FindNextMatchingPrefixTlv(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const +const PrefixTlv *Leader::FindNextMatchingPrefixTlv(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const { // This method iterates over Prefix TLVs which match a given IPv6 // `aAddress`. If `aPrevTlv` is `nullptr` we start from the @@ -135,7 +154,7 @@ const PrefixTlv *LeaderBase::FindNextMatchingPrefixTlv(const Ip6::Address &aAddr return prefixTlv; } -Error LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const +Error Leader::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const { const PrefixTlv *prefixTlv = nullptr; const ContextTlv *contextTlv; @@ -168,7 +187,7 @@ Error LeaderBase::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aCon return (aContext.mPrefix.GetLength() > 0) ? kErrorNone : kErrorNotFound; } -Error LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) const +Error Leader::GetContext(uint8_t aContextId, Lowpan::Context &aContext) const { Error error = kErrorNotFound; TlvIterator tlvIterator(GetTlvsStart(), GetTlvsEnd()); @@ -200,7 +219,7 @@ Error LeaderBase::GetContext(uint8_t aContextId, Lowpan::Context &aContext) cons return error; } -void LeaderBase::GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const +void Leader::GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const { aContext.mPrefix.Set(Get().GetMeshLocalPrefix()); aContext.mContextId = Mle::kMeshLocalPrefixContextId; @@ -208,7 +227,7 @@ void LeaderBase::GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const aContext.mIsValid = true; } -bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress) const +bool Leader::IsOnMesh(const Ip6::Address &aAddress) const { const PrefixTlv *prefixTlv = nullptr; bool isOnMesh = false; @@ -237,7 +256,7 @@ bool LeaderBase::IsOnMesh(const Ip6::Address &aAddress) const return isOnMesh; } -Error LeaderBase::RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint16_t &aRloc16) const +Error Leader::RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint16_t &aRloc16) const { Error error = kErrorNoRoute; const PrefixTlv *prefixTlv = nullptr; @@ -264,18 +283,17 @@ Error LeaderBase::RouteLookup(const Ip6::Address &aSource, const Ip6::Address &a return error; } -template -int LeaderBase::CompareRouteEntries(const EntryType &aFirst, const EntryType &aSecond) const +template int Leader::CompareRouteEntries(const EntryType &aFirst, const EntryType &aSecond) const { // `EntryType` can be `HasRouteEntry` or `BorderRouterEntry`. return CompareRouteEntries(aFirst.GetPreference(), aFirst.GetRloc(), aSecond.GetPreference(), aSecond.GetRloc()); } -int LeaderBase::CompareRouteEntries(int8_t aFirstPreference, - uint16_t aFirstRloc, - int8_t aSecondPreference, - uint16_t aSecondRloc) const +int Leader::CompareRouteEntries(int8_t aFirstPreference, + uint16_t aFirstRloc, + int8_t aSecondPreference, + uint16_t aSecondRloc) const { // Performs three-way comparison between two BR entries. @@ -312,7 +330,7 @@ int LeaderBase::CompareRouteEntries(int8_t aFirstPreference, return result; } -Error LeaderBase::ExternalRouteLookup(uint8_t aDomainId, const Ip6::Address &aDestination, uint16_t &aRloc16) const +Error Leader::ExternalRouteLookup(uint8_t aDomainId, const Ip6::Address &aDestination, uint16_t &aRloc16) const { Error error = kErrorNoRoute; const PrefixTlv *prefixTlv = nullptr; @@ -359,7 +377,7 @@ Error LeaderBase::ExternalRouteLookup(uint8_t aDomainId, const Ip6::Address &aDe return error; } -Error LeaderBase::DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t &aRloc16) const +Error Leader::DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t &aRloc16) const { Error error = kErrorNoRoute; TlvIterator subTlvIterator(aPrefix); @@ -392,12 +410,12 @@ Error LeaderBase::DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t &aRloc16 return error; } -Error LeaderBase::SetNetworkData(uint8_t aVersion, - uint8_t aStableVersion, - Type aType, - const Message &aMessage, - uint16_t aOffset, - uint16_t aLength) +Error Leader::SetNetworkData(uint8_t aVersion, + uint8_t aStableVersion, + Type aType, + const Message &aMessage, + uint16_t aOffset, + uint16_t aLength) { Error error = kErrorNone; @@ -428,12 +446,12 @@ Error LeaderBase::SetNetworkData(uint8_t aVersion, return error; } -const CommissioningDataTlv *LeaderBase::FindCommissioningData(void) const +const CommissioningDataTlv *Leader::FindCommissioningData(void) const { return NetworkDataTlv::Find(GetTlvsStart(), GetTlvsEnd()); } -const MeshCoP::Tlv *LeaderBase::FindCommissioningDataSubTlv(uint8_t aType) const +const MeshCoP::Tlv *Leader::FindCommissioningDataSubTlv(uint8_t aType) const { const MeshCoP::Tlv *subTlv = nullptr; const NetworkDataTlv *dataTlv = FindCommissioningData(); @@ -445,7 +463,7 @@ const MeshCoP::Tlv *LeaderBase::FindCommissioningDataSubTlv(uint8_t aType) const return subTlv; } -Error LeaderBase::ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::Type aType, uint16_t &aValue) const +Error Leader::ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::Type aType, uint16_t &aValue) const { Error error = kErrorNone; const MeshCoP::Tlv *subTlv = FindCommissioningDataSubTlv(aType); @@ -458,7 +476,7 @@ Error LeaderBase::ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::Type aType, ui return error; } -void LeaderBase::GetCommissioningDataset(MeshCoP::CommissioningDataset &aDataset) const +void Leader::GetCommissioningDataset(MeshCoP::CommissioningDataset &aDataset) const { const CommissioningDataTlv *dataTlv = FindCommissioningData(); const MeshCoP::Tlv *subTlv; @@ -496,22 +514,22 @@ void LeaderBase::GetCommissioningDataset(MeshCoP::CommissioningDataset &aDataset return; } -Error LeaderBase::FindBorderAgentRloc(uint16_t &aRloc16) const +Error Leader::FindBorderAgentRloc(uint16_t &aRloc16) const { return ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::kBorderAgentLocator, aRloc16); } -Error LeaderBase::FindCommissioningSessionId(uint16_t &aSessionId) const +Error Leader::FindCommissioningSessionId(uint16_t &aSessionId) const { return ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::kCommissionerSessionId, aSessionId); } -Error LeaderBase::FindJoinerUdpPort(uint16_t &aPort) const +Error Leader::FindJoinerUdpPort(uint16_t &aPort) const { return ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::kJoinerUdpPort, aPort); } -Error LeaderBase::FindSteeringData(MeshCoP::SteeringData &aSteeringData) const +Error Leader::FindSteeringData(MeshCoP::SteeringData &aSteeringData) const { Error error = kErrorNone; const MeshCoP::SteeringDataTlv *steeringDataTlv = FindInCommissioningData(); @@ -523,7 +541,7 @@ Error LeaderBase::FindSteeringData(MeshCoP::SteeringData &aSteeringData) const return error; } -bool LeaderBase::IsJoiningAllowed(void) const +bool Leader::IsJoiningAllowed(void) const { bool isAllowed = false; MeshCoP::SteeringData steeringData; @@ -535,7 +553,7 @@ bool LeaderBase::IsJoiningAllowed(void) const return isAllowed; } -Error LeaderBase::SteeringDataCheck(const FilterIndexes &aFilterIndexes) const +Error Leader::SteeringDataCheck(const FilterIndexes &aFilterIndexes) const { Error error = kErrorInvalidState; MeshCoP::SteeringData steeringData; @@ -547,7 +565,7 @@ Error LeaderBase::SteeringDataCheck(const FilterIndexes &aFilterIndexes) const return error; } -Error LeaderBase::SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const +Error Leader::SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const { FilterIndexes filterIndexes; Mac::ExtAddress joinerId; @@ -558,7 +576,7 @@ Error LeaderBase::SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const return SteeringDataCheck(filterIndexes); } -Error LeaderBase::SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const +Error Leader::SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const { FilterIndexes filterIndexes; @@ -567,7 +585,7 @@ Error LeaderBase::SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDisce return SteeringDataCheck(filterIndexes); } -void LeaderBase::SignalNetDataChanged(void) +void Leader::SignalNetDataChanged(void) { mMaxLength = Max(mMaxLength, GetLength()); Get().Signal(kEventThreadNetdataChanged); diff --git a/src/core/thread/network_data_leader.hpp b/src/core/thread/network_data_leader.hpp index a510844e8c4..4ad1a99f06c 100644 --- a/src/core/thread/network_data_leader.hpp +++ b/src/core/thread/network_data_leader.hpp @@ -40,10 +40,13 @@ #include "coap/coap.hpp" #include "common/const_cast.hpp" +#include "common/non_copyable.hpp" +#include "common/numeric_limits.hpp" #include "common/timer.hpp" #include "net/ip6_address.hpp" #include "thread/mle_router.hpp" #include "thread/network_data.hpp" +#include "thread/tmf.hpp" namespace ot { @@ -63,8 +66,11 @@ namespace NetworkData { * Implements the Thread Network Data maintained by the Leader. * */ -class LeaderBase : public MutableNetworkData +class Leader : public MutableNetworkData, private NonCopyable { + friend class Tmf::Agent; + friend class Notifier; + public: /** * Initializes the object. @@ -72,12 +78,7 @@ class LeaderBase : public MutableNetworkData * @param[in] aInstance A reference to the OpenThread instance. * */ - explicit LeaderBase(Instance &aInstance) - : MutableNetworkData(aInstance, mTlvBuffer, 0, sizeof(mTlvBuffer)) - , mMaxLength(0) - { - Reset(); - } + explicit Leader(Instance &aInstance); /** * Reset the Thread Network Data. @@ -328,18 +329,112 @@ class LeaderBase : public MutableNetworkData */ Error GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const; -protected: - void SignalNetDataChanged(void); - const CommissioningDataTlv *FindCommissioningData(void) const; - CommissioningDataTlv *FindCommissioningData(void) { return AsNonConst(AsConst(this)->FindCommissioningData()); } - const MeshCoP::Tlv *FindCommissioningDataSubTlv(uint8_t aType) const; - MeshCoP::Tlv *FindCommissioningDataSubTlv(uint8_t aType) +#if OPENTHREAD_FTD + /** + * Defines the match mode constants to compare two RLOC16 values. + * + */ + enum MatchMode : uint8_t { - return AsNonConst(AsConst(this)->FindCommissioningDataSubTlv(aType)); - } + kMatchModeRloc16, ///< Perform exact RLOC16 match. + kMatchModeRouterId, ///< Perform Router ID match (match the router and any of its children). + }; - uint8_t mStableVersion; - uint8_t mVersion; + /** + * Starts the Leader services. + * + * The start mode indicates whether device is starting normally as leader or restoring its role as leader after + * reset. In the latter case, we do not accept any new registrations (`HandleServerData()`) and wait for + * `HandleNetworkDataRestoredAfterReset()` to indicate that the leader has successfully recovered the Network Data + * before allowing new Network Data registrations. + * + * @param[in] aStartMode The start mode. + * + */ + void Start(Mle::LeaderStartMode aStartMode); + + /** + * Increments the Thread Network Data version. + * + */ + void IncrementVersion(void); + + /** + * Increments both the Thread Network Data version and stable version. + * + */ + void IncrementVersionAndStableVersion(void); + + /** + * Returns CONTEXT_ID_RESUSE_DELAY value. + * + * @returns The CONTEXT_ID_REUSE_DELAY value (in seconds). + * + */ + uint32_t GetContextIdReuseDelay(void) const { return mContextIds.GetReuseDelay(); } + + /** + * Sets CONTEXT_ID_RESUSE_DELAY value. + * + * @warning This method should only be used for testing. + * + * @param[in] aDelay The CONTEXT_ID_REUSE_DELAY value (in seconds). + * + */ + void SetContextIdReuseDelay(uint32_t aDelay) { mContextIds.SetReuseDelay(aDelay); } + + /** + * Removes Network Data entries matching with a given RLOC16. + * + * @param[in] aRloc16 A RLOC16 value. + * @param[in] aMatchMode A match mode (@sa MatchMode). + * + */ + void RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode); + + /** + * Updates Commissioning Data in Network Data. + * + * @param[in] aData A pointer to the Commissioning Data. + * @param[in] aDataLength The length of @p aData. + * + * @retval kErrorNone Successfully updated the Commissioning Data. + * @retval kErrorNoBufs Insufficient space to add the Commissioning Data. + * + */ + Error SetCommissioningData(const void *aData, uint8_t aDataLength); + + /** + * Synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data. + * + * Note that this method should be called only by the Leader once after reset. + * + */ + void HandleNetworkDataRestoredAfterReset(void); + + /** + * Scans network data for given Service ID and returns pointer to the respective TLV, if present. + * + * @param aServiceId Service ID to look for. + * @return Pointer to the Service TLV for given Service ID, or nullptr if not present. + * + */ + const ServiceTlv *FindServiceById(uint8_t aServiceId) const; + +#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE + /** + * Indicates whether a given Prefix can act as a valid OMR prefix and exists in the network data. + * + * @param[in] aPrefix The OMR prefix to check. + * + * @retval TRUE If @p aPrefix is a valid OMR prefix and Network Data contains @p aPrefix. + * @retval FALSE Otherwise. + * + */ + bool ContainsOmrPrefix(const Ip6::Prefix &aPrefix); +#endif + +#endif // OPENTHREAD_FTD private: using FilterIndexes = MeshCoP::SteeringData::HashBitIndexes; @@ -357,11 +452,201 @@ class LeaderBase : public MutableNetworkData Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const; void GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const; Error ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::Type aType, uint16_t &aValue) const; + void SignalNetDataChanged(void); + const CommissioningDataTlv *FindCommissioningData(void) const; + CommissioningDataTlv *FindCommissioningData(void) { return AsNonConst(AsConst(this)->FindCommissioningData()); } + const MeshCoP::Tlv *FindCommissioningDataSubTlv(uint8_t aType) const; + MeshCoP::Tlv *FindCommissioningDataSubTlv(uint8_t aType) + { + return AsNonConst(AsConst(this)->FindCommissioningDataSubTlv(aType)); + } +#if OPENTHREAD_FTD + static constexpr uint32_t kMaxNetDataSyncWait = 60 * 1000; // Maximum time to wait for netdata sync in msec. + static constexpr uint8_t kMinServiceId = 0x00; + static constexpr uint8_t kMaxServiceId = 0x0f; + + class ChangedFlags + { + public: + ChangedFlags(void) + : mChanged(false) + , mStableChanged(false) + { + } + + void Update(const NetworkDataTlv &aTlv) + { + mChanged = true; + mStableChanged = (mStableChanged || aTlv.IsStable()); + } + + bool DidChange(void) const { return mChanged; } + bool DidStableChange(void) const { return mStableChanged; } + + private: + bool mChanged; // Any (stable or not) network data change (add/remove). + bool mStableChanged; // Stable network data change (add/remove). + }; + + enum UpdateStatus : uint8_t + { + kTlvRemoved, // TLV contained no sub TLVs and therefore is removed. + kTlvUpdated, // TLV stable flag is updated based on its sub TLVs. + }; + + class ContextIds : public InstanceLocator + { + public: + // This class tracks Context IDs. A Context ID can be in one + // of the 3 states: It is unallocated, or it is allocated + // and in-use, or it scheduled to be removed (after reuse delay + // interval is passed). + + static constexpr uint8_t kInvalidId = NumericLimits::kMax; + + explicit ContextIds(Instance &aInstance); + + void Clear(void); + Error GetUnallocatedId(uint8_t &aId); + void MarkAsInUse(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kInUse); } + void ScheduleToRemove(uint8_t aId); + uint32_t GetReuseDelay(void) const { return mReuseDelay; } + void SetReuseDelay(uint32_t aDelay) { mReuseDelay = aDelay; } + void HandleTimer(void); +#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL + void MarkAsClone(void) { mIsClone = true; } +#endif + + private: + static constexpr uint32_t kReuseDelay = 5 * 60; // 5 minutes (in seconds). + + static constexpr uint8_t kMinId = 1; + static constexpr uint8_t kMaxId = 15; + + // The `mRemoveTimes[id]` is used to track the state of a + // Context ID and its remove time. Two specific values + // `kUnallocated` and `kInUse` are used to indicate ID is in + // unallocated or in-use states. Other values indicate we + // are in remove state waiting to remove it at `mRemoveTime`. + + static constexpr uint32_t kUnallocated = 0; + static constexpr uint32_t kInUse = 1; + + bool IsUnallocated(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kUnallocated; } + bool IsInUse(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kInUse; } + TimeMilli GetRemoveTime(uint8_t aId) const { return mRemoveTimes[aId - kMinId]; } + void SetRemoveTime(uint8_t aId, TimeMilli aTime); + void MarkAsUnallocated(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kUnallocated); } + + TimeMilli mRemoveTimes[kMaxId - kMinId + 1]; + uint32_t mReuseDelay; +#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL + bool mIsClone; +#endif + }; + + template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + + void HandleTimer(void); + + void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData); + + Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags); + Error AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags); + Error AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags); + Error AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags); + Error AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags); + + Error AllocateServiceId(uint8_t &aServiceId) const; + + void RemoveContext(uint8_t aContextId); + void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId); + + void RemoveCommissioningData(void); + + void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags); + void RemoveRloc(uint16_t aRloc16, + MatchMode aMatchMode, + const NetworkData &aExcludeNetworkData, + ChangedFlags &aChangedFlags); + void RemoveRlocInPrefix(PrefixTlv &aPrefix, + uint16_t aRloc16, + MatchMode aMatchMode, + const PrefixTlv *aExcludePrefix, + ChangedFlags &aChangedFlags); + void RemoveRlocInService(ServiceTlv &aService, + uint16_t aRloc16, + MatchMode aMatchMode, + const ServiceTlv *aExcludeService, + ChangedFlags &aChangedFlags); + void RemoveRlocInHasRoute(PrefixTlv &aPrefix, + HasRouteTlv &aHasRoute, + uint16_t aRloc16, + MatchMode aMatchMode, + const PrefixTlv *aExcludePrefix, + ChangedFlags &aChangedFlags); + void RemoveRlocInBorderRouter(PrefixTlv &aPrefix, + BorderRouterTlv &aBorderRouter, + uint16_t aRloc16, + MatchMode aMatchMode, + const PrefixTlv *aExcludePrefix, + ChangedFlags &aChangedFlags); + + static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode); + + static Error Validate(const NetworkData &aNetworkData, uint16_t aRloc16); + static Error ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16); + static Error ValidateService(const ServiceTlv &aService, uint16_t aRloc16); + + static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry); + static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry); + static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry); + static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry); + static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer); + + UpdateStatus UpdatePrefix(PrefixTlv &aPrefix); + UpdateStatus UpdateService(ServiceTlv &aService); + UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs); + + Error UpdateCommissioningData(uint16_t aDataLength, CommissioningDataTlv *&aDataTlv); + Error SetCommissioningData(const Message &aMessage); + + void SendCommissioningSetResponse(const Coap::Message &aRequest, + const Ip6::MessageInfo &aMessageInfo, + MeshCoP::StateTlv::State aState); + void IncrementVersions(bool aIncludeStable); + void IncrementVersions(const ChangedFlags &aFlags); + +#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL + void CheckForNetDataGettingFull(const NetworkData &aNetworkData, uint16_t aOldRloc16); + void MarkAsClone(void); +#endif + + using UpdateTimer = TimerMilliIn; +#endif // OPENTHREAD_FTD + + uint8_t mStableVersion; + uint8_t mVersion; uint8_t mTlvBuffer[kMaxSize]; uint8_t mMaxLength; + +#if OPENTHREAD_FTD +#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL + bool mIsClone; +#endif + bool mWaitingForNetDataSync; + ContextIds mContextIds; + UpdateTimer mTimer; +#endif }; +#if OPENTHREAD_FTD +DeclareTmfHandler(Leader, kUriServerData); +DeclareTmfHandler(Leader, kUriCommissionerGet); +DeclareTmfHandler(Leader, kUriCommissionerSet); +#endif + /** * @} */ @@ -369,20 +654,4 @@ class LeaderBase : public MutableNetworkData } // namespace NetworkData } // namespace ot -#if OPENTHREAD_MTD -namespace ot { -namespace NetworkData { -class Leader : public LeaderBase -{ -public: - using LeaderBase::LeaderBase; -}; -} // namespace NetworkData -} // namespace ot -#elif OPENTHREAD_FTD -#include "network_data_leader_ftd.hpp" -#else -#error "Please define OPENTHREAD_MTD=1 or OPENTHREAD_FTD=1" -#endif - #endif // NETWORK_DATA_LEADER_HPP_ diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index aa833f49e7b..fe423ef4f8e 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -58,25 +58,6 @@ namespace NetworkData { RegisterLogModule("NetworkData"); -Leader::Leader(Instance &aInstance) - : LeaderBase(aInstance) -#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL - , mIsClone(false) -#endif - , mWaitingForNetDataSync(false) - , mContextIds(aInstance) - , mTimer(aInstance) -{ - Reset(); -} - -void Leader::Reset(void) -{ - LeaderBase::Reset(); - - mContextIds.Clear(); -} - void Leader::Start(Mle::LeaderStartMode aStartMode) { #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL diff --git a/src/core/thread/network_data_leader_ftd.hpp b/src/core/thread/network_data_leader_ftd.hpp deleted file mode 100644 index 6b723ac7490..00000000000 --- a/src/core/thread/network_data_leader_ftd.hpp +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2016, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file includes definitions for manipulating Thread Network Data managed by the Thread Leader. - */ - -#ifndef NETWORK_DATA_LEADER_FTD_HPP_ -#define NETWORK_DATA_LEADER_FTD_HPP_ - -#include "openthread-core-config.h" - -#if OPENTHREAD_FTD - -#include - -#include "common/non_copyable.hpp" -#include "common/numeric_limits.hpp" -#include "common/timer.hpp" -#include "net/ip6_address.hpp" -#include "thread/mle_router.hpp" -#include "thread/network_data.hpp" -#include "thread/tmf.hpp" - -namespace ot { - -namespace NetworkData { - -class Notifier; - -/** - * @addtogroup core-netdata-leader - * - * @brief - * This module includes definitions for manipulating Thread Network Data managed by the Thread Leader. - * - * @{ - * - */ - -/** - * Implements the Thread Network Data maintained by the Leader. - * - */ -class Leader : public LeaderBase, private NonCopyable -{ - friend class Tmf::Agent; - friend class Notifier; - -public: - /** - * Defines the match mode constants to compare two RLOC16 values. - * - */ - enum MatchMode : uint8_t - { - kMatchModeRloc16, ///< Perform exact RLOC16 match. - kMatchModeRouterId, ///< Perform Router ID match (match the router and any of its children). - }; - - /** - * Initializes the object. - * - * @param[in] aInstance A reference to the OpenThread instance. - * - */ - explicit Leader(Instance &aInstance); - - /** - * Reset the Thread Network Data. - * - */ - void Reset(void); - - /** - * Starts the Leader services. - * - * The start mode indicates whether device is starting normally as leader or restoring its role as leader after - * reset. In the latter case, we do not accept any new registrations (`HandleServerData()`) and wait for - * `HandleNetworkDataRestoredAfterReset()` to indicate that the leader has successfully recovered the Network Data - * before allowing new Network Data registrations. - * - * @param[in] aStartMode The start mode. - * - */ - void Start(Mle::LeaderStartMode aStartMode); - - /** - * Increments the Thread Network Data version. - * - */ - void IncrementVersion(void); - - /** - * Increments both the Thread Network Data version and stable version. - * - */ - void IncrementVersionAndStableVersion(void); - - /** - * Returns CONTEXT_ID_RESUSE_DELAY value. - * - * @returns The CONTEXT_ID_REUSE_DELAY value (in seconds). - * - */ - uint32_t GetContextIdReuseDelay(void) const { return mContextIds.GetReuseDelay(); } - - /** - * Sets CONTEXT_ID_RESUSE_DELAY value. - * - * @warning This method should only be used for testing. - * - * @param[in] aDelay The CONTEXT_ID_REUSE_DELAY value (in seconds). - * - */ - void SetContextIdReuseDelay(uint32_t aDelay) { mContextIds.SetReuseDelay(aDelay); } - - /** - * Removes Network Data entries matching with a given RLOC16. - * - * @param[in] aRloc16 A RLOC16 value. - * @param[in] aMatchMode A match mode (@sa MatchMode). - * - */ - void RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode); - - /** - * Updates Commissioning Data in Network Data. - * - * @param[in] aData A pointer to the Commissioning Data. - * @param[in] aDataLength The length of @p aData. - * - * @retval kErrorNone Successfully updated the Commissioning Data. - * @retval kErrorNoBufs Insufficient space to add the Commissioning Data. - * - */ - Error SetCommissioningData(const void *aData, uint8_t aDataLength); - - /** - * Synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data. - * - * Note that this method should be called only by the Leader once after reset. - * - */ - void HandleNetworkDataRestoredAfterReset(void); - - /** - * Scans network data for given Service ID and returns pointer to the respective TLV, if present. - * - * @param aServiceId Service ID to look for. - * @return Pointer to the Service TLV for given Service ID, or nullptr if not present. - * - */ - const ServiceTlv *FindServiceById(uint8_t aServiceId) const; - -#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE - /** - * Indicates whether a given Prefix can act as a valid OMR prefix and exists in the network data. - * - * @param[in] aPrefix The OMR prefix to check. - * - * @retval TRUE If @p aPrefix is a valid OMR prefix and Network Data contains @p aPrefix. - * @retval FALSE Otherwise. - * - */ - bool ContainsOmrPrefix(const Ip6::Prefix &aPrefix); -#endif - -private: - static constexpr uint32_t kMaxNetDataSyncWait = 60 * 1000; // Maximum time to wait for netdata sync in msec. - - static constexpr uint8_t kMinServiceId = 0x00; - static constexpr uint8_t kMaxServiceId = 0x0f; - - class ChangedFlags - { - public: - ChangedFlags(void) - : mChanged(false) - , mStableChanged(false) - { - } - - void Update(const NetworkDataTlv &aTlv) - { - mChanged = true; - mStableChanged = (mStableChanged || aTlv.IsStable()); - } - - bool DidChange(void) const { return mChanged; } - bool DidStableChange(void) const { return mStableChanged; } - - private: - bool mChanged; // Any (stable or not) network data change (add/remove). - bool mStableChanged; // Stable network data change (add/remove). - }; - - enum UpdateStatus : uint8_t - { - kTlvRemoved, // TLV contained no sub TLVs and therefore is removed. - kTlvUpdated, // TLV stable flag is updated based on its sub TLVs. - }; - - class ContextIds : public InstanceLocator - { - public: - // This class tracks Context IDs. A Context ID can be in one - // of the 3 states: It is unallocated, or it is allocated - // and in-use, or it scheduled to be removed (after reuse delay - // interval is passed). - - static constexpr uint8_t kInvalidId = NumericLimits::kMax; - - explicit ContextIds(Instance &aInstance); - - void Clear(void); - Error GetUnallocatedId(uint8_t &aId); - void MarkAsInUse(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kInUse); } - void ScheduleToRemove(uint8_t aId); - uint32_t GetReuseDelay(void) const { return mReuseDelay; } - void SetReuseDelay(uint32_t aDelay) { mReuseDelay = aDelay; } - void HandleTimer(void); -#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL - void MarkAsClone(void) { mIsClone = true; } -#endif - - private: - static constexpr uint32_t kReuseDelay = 5 * 60; // 5 minutes (in seconds). - - static constexpr uint8_t kMinId = 1; - static constexpr uint8_t kMaxId = 15; - - // The `mRemoveTimes[id]` is used to track the state of a - // Context ID and its remove time. Two specific values - // `kUnallocated` and `kInUse` are used to indicate ID is in - // unallocated or in-use states. Other values indicate we - // are in remove state waiting to remove it at `mRemoveTime`. - - static constexpr uint32_t kUnallocated = 0; - static constexpr uint32_t kInUse = 1; - - bool IsUnallocated(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kUnallocated; } - bool IsInUse(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kInUse; } - TimeMilli GetRemoveTime(uint8_t aId) const { return mRemoveTimes[aId - kMinId]; } - void SetRemoveTime(uint8_t aId, TimeMilli aTime); - void MarkAsUnallocated(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kUnallocated); } - - TimeMilli mRemoveTimes[kMaxId - kMinId + 1]; - uint32_t mReuseDelay; -#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL - bool mIsClone; -#endif - }; - - template void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - - void HandleTimer(void); - - void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData); - - Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags); - Error AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags); - Error AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags); - Error AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags); - Error AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags); - - Error AllocateServiceId(uint8_t &aServiceId) const; - - void RemoveContext(uint8_t aContextId); - void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId); - - void RemoveCommissioningData(void); - - void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags); - void RemoveRloc(uint16_t aRloc16, - MatchMode aMatchMode, - const NetworkData &aExcludeNetworkData, - ChangedFlags &aChangedFlags); - void RemoveRlocInPrefix(PrefixTlv &aPrefix, - uint16_t aRloc16, - MatchMode aMatchMode, - const PrefixTlv *aExcludePrefix, - ChangedFlags &aChangedFlags); - void RemoveRlocInService(ServiceTlv &aService, - uint16_t aRloc16, - MatchMode aMatchMode, - const ServiceTlv *aExcludeService, - ChangedFlags &aChangedFlags); - void RemoveRlocInHasRoute(PrefixTlv &aPrefix, - HasRouteTlv &aHasRoute, - uint16_t aRloc16, - MatchMode aMatchMode, - const PrefixTlv *aExcludePrefix, - ChangedFlags &aChangedFlags); - void RemoveRlocInBorderRouter(PrefixTlv &aPrefix, - BorderRouterTlv &aBorderRouter, - uint16_t aRloc16, - MatchMode aMatchMode, - const PrefixTlv *aExcludePrefix, - ChangedFlags &aChangedFlags); - - static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode); - - static Error Validate(const NetworkData &aNetworkData, uint16_t aRloc16); - static Error ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16); - static Error ValidateService(const ServiceTlv &aService, uint16_t aRloc16); - - static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry); - static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry); - static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry); - static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry); - static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer); - - UpdateStatus UpdatePrefix(PrefixTlv &aPrefix); - UpdateStatus UpdateService(ServiceTlv &aService); - UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs); - - Error UpdateCommissioningData(uint16_t aDataLength, CommissioningDataTlv *&aDataTlv); - Error SetCommissioningData(const Message &aMessage); - - void SendCommissioningSetResponse(const Coap::Message &aRequest, - const Ip6::MessageInfo &aMessageInfo, - MeshCoP::StateTlv::State aState); - void IncrementVersions(bool aIncludeStable); - void IncrementVersions(const ChangedFlags &aFlags); - -#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL - void CheckForNetDataGettingFull(const NetworkData &aNetworkData, uint16_t aOldRloc16); - void MarkAsClone(void); -#endif - - using UpdateTimer = TimerMilliIn; - -#if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL - bool mIsClone; -#endif - bool mWaitingForNetDataSync; - ContextIds mContextIds; - UpdateTimer mTimer; -}; - -DeclareTmfHandler(Leader, kUriServerData); -DeclareTmfHandler(Leader, kUriCommissionerGet); -DeclareTmfHandler(Leader, kUriCommissionerSet); - -/** - * @} - */ - -} // namespace NetworkData -} // namespace ot - -#endif // OPENTHREAD_FTD - -#endif // NETWORK_DATA_LEADER_FTD_HPP_ From 5058500e5d63e1755b89ec25ce3a8b5705f595a5 Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Fri, 3 Nov 2023 00:11:26 +0800 Subject: [PATCH 5/5] [build] move `radio_spinel.cpp` to new lib `openthread-radio-spinel` (#9530) The lib `openthread-spinel-ncp` is used by the NCP build, it doesn't need the file `radio_spinel.cpp`. This commit changes the CMake file to make only the lib `openthread-spinel-rcp` include the file `radio_spinel.cpp`. --- src/lib/spinel/CMakeLists.txt | 23 ++++++++++++----------- src/posix/cli.cmake | 1 + src/posix/daemon.cmake | 1 + src/posix/platform/CMakeLists.txt | 1 + 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/lib/spinel/CMakeLists.txt b/src/lib/spinel/CMakeLists.txt index de68fc25a6a..e6cf16f58fd 100644 --- a/src/lib/spinel/CMakeLists.txt +++ b/src/lib/spinel/CMakeLists.txt @@ -26,27 +26,22 @@ # POSSIBILITY OF SUCH DAMAGE. # +add_library(openthread-radio-spinel) add_library(openthread-spinel-ncp) add_library(openthread-spinel-rcp) target_compile_definitions(openthread-spinel-ncp PRIVATE - OPENTHREAD_FTD=1 PUBLIC OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=1 ) -if (OT_NCP_SPI) - target_compile_definitions(openthread-spinel-ncp PRIVATE OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=0) - target_compile_definitions(openthread-spinel-rcp PRIVATE OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=0) -else() - target_compile_definitions(openthread-spinel-ncp PRIVATE OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1) - target_compile_definitions(openthread-spinel-rcp PRIVATE OPENTHREAD_CONFIG_NCP_HDLC_ENABLE=1) -endif() - target_compile_definitions(openthread-spinel-rcp PRIVATE - OPENTHREAD_RADIO=1 PUBLIC OPENTHREAD_SPINEL_CONFIG_OPENTHREAD_MESSAGE_ENABLE=0 ) +target_compile_options(openthread-radio-spinel PRIVATE + ${OT_CFLAGS} +) + target_compile_options(openthread-spinel-ncp PRIVATE ${OT_CFLAGS} ) @@ -61,19 +56,25 @@ set(COMMON_INCLUDES ) set(COMMON_SOURCES - radio_spinel.cpp spinel.c spinel_buffer.cpp spinel_decoder.cpp spinel_encoder.cpp ) +target_include_directories(openthread-radio-spinel PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES}) target_include_directories(openthread-spinel-ncp PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES}) target_include_directories(openthread-spinel-rcp PUBLIC ${OT_PUBLIC_INCLUDES} PRIVATE ${COMMON_INCLUDES}) +target_sources(openthread-radio-spinel PRIVATE radio_spinel.cpp) target_sources(openthread-spinel-ncp PRIVATE ${COMMON_SOURCES}) target_sources(openthread-spinel-rcp PRIVATE ${COMMON_SOURCES}) +target_link_libraries(openthread-radio-spinel + PRIVATE + ot-config +) + target_link_libraries(openthread-spinel-ncp PRIVATE ot-config-ftd diff --git a/src/posix/cli.cmake b/src/posix/cli.cmake index 4b7347b4039..a11ef0b8545 100644 --- a/src/posix/cli.cmake +++ b/src/posix/cli.cmake @@ -50,6 +50,7 @@ target_link_libraries(ot-cli PRIVATE openthread-posix openthread-cli-ftd openthread-hdlc + openthread-radio-spinel openthread-spinel-rcp ${OT_MBEDTLS} ${READLINE_LINK_LIBRARIES} diff --git a/src/posix/daemon.cmake b/src/posix/daemon.cmake index dd726df27b7..dd19a22806a 100644 --- a/src/posix/daemon.cmake +++ b/src/posix/daemon.cmake @@ -42,6 +42,7 @@ target_link_libraries(ot-daemon PRIVATE openthread-ftd openthread-posix openthread-hdlc + openthread-radio-spinel openthread-spinel-rcp ${OT_MBEDTLS} ot-posix-config diff --git a/src/posix/platform/CMakeLists.txt b/src/posix/platform/CMakeLists.txt index b367d8758d6..dfc62408eba 100644 --- a/src/posix/platform/CMakeLists.txt +++ b/src/posix/platform/CMakeLists.txt @@ -154,6 +154,7 @@ target_link_libraries(openthread-posix openthread-cli-ftd openthread-ftd openthread-hdlc + openthread-radio-spinel openthread-spinel-rcp openthread-url ot-config-ftd