From e8b9b874f51b74ce6339f3f963897aee0eb0879f Mon Sep 17 00:00:00 2001 From: hemanth-silabs <50145824+hemanth-silabs@users.noreply.github.com> Date: Thu, 26 May 2022 22:02:07 +0100 Subject: [PATCH] [mac] re-add API to receive Thread-specific Beacon payload (#7736) Some of the current implementations of thread stack use active scans to find out the joining network name and extended panids. These details are then used as part of commissioning process. So at the very minimum we will need processing the incoming beacons to extract these information. --- include/openthread/instance.h | 2 +- include/openthread/link.h | 4 ++ script/check-simulation-build-autotools | 1 + src/core/config/mac.h | 11 ++++ src/core/mac/mac.cpp | 22 +++++++ src/core/mac/mac_frame.hpp | 87 +++++++++++++++++++++++++ 6 files changed, 126 insertions(+), 1 deletion(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 1148de43d..6bd2e7148 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 (212) +#define OPENTHREAD_API_VERSION (213) /** * @addtogroup api-instance diff --git a/include/openthread/link.h b/include/openthread/link.h index 7c77e964d..0a7280cee 100644 --- a/include/openthread/link.h +++ b/include/openthread/link.h @@ -391,6 +391,10 @@ typedef struct otActiveScanResult unsigned int mVersion : 4; ///< Version bool mIsNative : 1; ///< Native Commissioner flag bool mDiscover : 1; ///< Result from MLE Discovery + + // Applicable/Required only when beacon payload parsing feature + // (`OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE`) is enabled. + bool mIsJoinable : 1; ///< Joining Permitted flag } otActiveScanResult; /** diff --git a/script/check-simulation-build-autotools b/script/check-simulation-build-autotools index 6b16957ac..c08a266f5 100755 --- a/script/check-simulation-build-autotools +++ b/script/check-simulation-build-autotools @@ -89,6 +89,7 @@ build_all_features() "-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1" "-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1" "-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE=1" ) local options_1_2=( diff --git a/src/core/config/mac.h b/src/core/config/mac.h index 6572dd0e8..0af268449 100644 --- a/src/core/config/mac.h +++ b/src/core/config/mac.h @@ -499,4 +499,15 @@ #define OPENTHREAD_CONFIG_MAC_SCAN_DURATION 300 #endif +/** + * @def OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE + * + * This setting configures if the beacon payload parsing needs to be enabled in MAC. This is optional and is disabled by + * default because Thread 1.2.1 has removed support for beacon payloads. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE +#define OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE 0 +#endif + #endif // CONFIG_MAC_H_ diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index faaea8094..b42300d83 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -210,6 +210,11 @@ Error Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveSc { Error error = kErrorNone; Address address; +#if OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE + const BeaconPayload *beaconPayload = nullptr; + const Beacon * beacon = nullptr; + uint16_t payloadLength; +#endif memset(&aResult, 0, sizeof(ActiveScanResult)); @@ -229,6 +234,23 @@ Error Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveSc aResult.mRssi = aBeaconFrame->GetRssi(); aResult.mLqi = aBeaconFrame->GetLqi(); +#if OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE + payloadLength = aBeaconFrame->GetPayloadLength(); + + beacon = reinterpret_cast(aBeaconFrame->GetPayload()); + beaconPayload = reinterpret_cast(beacon->GetPayload()); + + if ((payloadLength >= (sizeof(*beacon) + sizeof(*beaconPayload))) && beacon->IsValid() && beaconPayload->IsValid()) + { + aResult.mVersion = beaconPayload->GetProtocolVersion(); + aResult.mIsJoinable = beaconPayload->IsJoiningPermitted(); + aResult.mIsNative = beaconPayload->IsNative(); + IgnoreError(AsCoreType(&aResult.mNetworkName).Set(beaconPayload->GetNetworkName())); + VerifyOrExit(IsValidUtf8String(aResult.mNetworkName.m8), error = kErrorParse); + aResult.mExtendedPanId = beaconPayload->GetExtendedPanId(); + } +#endif + LogBeacon("Received"); exit: diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 1c1a1a504..10de014ed 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -1482,6 +1482,93 @@ private: uint8_t mPendingAddressSpec; } OT_TOOL_PACKED_END; +#if OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE +/** + * This class implements IEEE 802.15.4 Beacon Payload generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class BeaconPayload +{ +public: + static constexpr uint8_t kProtocolId = 3; ///< Thread Protocol ID. + static constexpr uint8_t kVersionOffset = 4; ///< Version field bit offset. + static constexpr uint8_t kNativeFlag = 1 << 3; ///< Native Commissioner flag. + static constexpr uint8_t kJoiningFlag = 1 << 0; ///< Joining Permitted flag. + + /** + * This constant specified the maximum number of chars in Network Name (excludes null char). + * + */ + static constexpr uint8_t kMaxSize = OT_NETWORK_NAME_MAX_SIZE; + + /** + * This method indicates whether or not the beacon appears to be a valid Thread Beacon Payload. + * + * @retval TRUE If the beacon appears to be a valid Thread Beacon Payload. + * @retval FALSE If the beacon does not appear to be a valid Thread Beacon Payload. + * + */ + bool IsValid(void) const { return (mProtocolId == kProtocolId); } + + /** + * This method returns the Protocol ID value. + * + * @returns the Protocol ID value. + * + */ + uint8_t GetProtocolId(void) const { return mProtocolId; } + + /** + * This method returns the Protocol Version value. + * + * @returns The Protocol Version value. + * + */ + uint8_t GetProtocolVersion(void) const { return mFlags >> kVersionOffset; } + + /** + * This method indicates whether or not the Native Commissioner flag is set. + * + * @retval TRUE If the Native Commissioner flag is set. + * @retval FALSE If the Native Commissioner flag is not set. + * + */ + bool IsNative(void) const { return (mFlags & kNativeFlag) != 0; } + + /** + * This method indicates whether or not the Joining Permitted flag is set. + * + * @retval TRUE If the Joining Permitted flag is set. + * @retval FALSE If the Joining Permitted flag is not set. + * + */ + bool IsJoiningPermitted(void) const { return (mFlags & kJoiningFlag) != 0; } + + /** + * This method gets the Network Name field. + * + * @returns The Network Name field as `NameData`. + * + */ + const char *GetNetworkName(void) const { return mNetworkName; } + + /** + * This method returns the Extended PAN ID field. + * + * @returns The Extended PAN ID field. + * + */ + const otExtendedPanId &GetExtendedPanId(void) const { return mExtendedPanId; } + +private: + uint8_t mProtocolId; + uint8_t mFlags; + char mNetworkName[kMaxSize]; + otExtendedPanId mExtendedPanId; +} OT_TOOL_PACKED_END; +#endif // OPENTHREAD_CONFIG_MAC_BEACON_PAYLOAD_PARSING_ENABLE + /** * This class implements CSL IE data structure. *