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. *