From 142d98c0ee0babdc49807812d0dcd610e10d4518 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Tue, 30 Jul 2019 14:47:17 -0700 Subject: [PATCH] [radio] add Radio class abstracting radio platform APIs (#4045) This commit adds a a `Radio` class which provides all `otPlatRadio` platform APIs (as C++ methods). All OT core modules use the new `Radio` methods to interact with radio platform APIs. --- src/core/api/instance_api.cpp | 6 +- src/core/api/link_api.cpp | 4 +- src/core/api/link_raw_api.cpp | 70 +++-- src/core/common/instance.cpp | 1 + src/core/common/instance.hpp | 10 + src/core/diags/factory_diags.cpp | 25 +- src/core/mac/mac.cpp | 8 +- src/core/mac/sub_mac.cpp | 42 +-- src/core/mac/sub_mac.hpp | 2 +- src/core/meshcop/dataset_manager_ftd.cpp | 2 +- src/core/meshcop/joiner.cpp | 5 +- src/core/net/dhcp6_client.cpp | 4 +- src/core/net/dhcp6_server.cpp | 2 +- src/core/radio/radio.hpp | 370 +++++++++++++++++++++-- src/core/thread/mle.cpp | 4 +- src/core/thread/src_match_controller.cpp | 16 +- src/core/utils/jam_detector.cpp | 2 +- 17 files changed, 459 insertions(+), 114 deletions(-) diff --git a/src/core/api/instance_api.cpp b/src/core/api/instance_api.cpp index 233928952..2ee10831d 100644 --- a/src/core/api/instance_api.cpp +++ b/src/core/api/instance_api.cpp @@ -35,12 +35,12 @@ #include #include -#include #include "common/instance.hpp" #include "common/locator-getters.hpp" #include "common/logging.hpp" #include "common/new.hpp" +#include "radio/radio.hpp" using namespace ot; @@ -153,5 +153,7 @@ const char *otGetVersionString(void) const char *otGetRadioVersionString(otInstance *aInstance) { - return otPlatRadioGetVersionString(aInstance); + Instance &instance = *static_cast(aInstance); + + return instance.Get().GetVersionString(); } diff --git a/src/core/api/link_api.cpp b/src/core/api/link_api.cpp index 29a9830b3..b6783aa3b 100644 --- a/src/core/api/link_api.cpp +++ b/src/core/api/link_api.cpp @@ -132,7 +132,9 @@ exit: void otLinkGetFactoryAssignedIeeeEui64(otInstance *aInstance, otExtAddress *aEui64) { - otPlatRadioGetIeeeEui64(aInstance, aEui64->m8); + Instance &instance = *static_cast(aInstance); + + instance.Get().GetIeeeEui64(*static_cast(aEui64)); } otPanId otLinkGetPanId(otInstance *aInstance) diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp index 0528e4c7c..ed8835f98 100644 --- a/src/core/api/link_raw_api.cpp +++ b/src/core/api/link_raw_api.cpp @@ -67,15 +67,16 @@ otError otLinkRawSetShortAddress(otInstance *aInstance, uint16_t aShortAddress) bool otLinkRawGetPromiscuous(otInstance *aInstance) { - return otPlatRadioGetPromiscuous(aInstance); + return static_cast(aInstance)->Get().GetPromiscuous(); } otError otLinkRawSetPromiscuous(otInstance *aInstance, bool aEnable) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance &instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - otPlatRadioSetPromiscuous(aInstance, aEnable); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + instance.Get().SetPromiscuous(aEnable); exit: return error; @@ -83,11 +84,12 @@ exit: otError otLinkRawSleep(otInstance *aInstance) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance &instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - error = otPlatRadioSleep(aInstance); + error = instance.Get().Sleep(); exit: return error; @@ -110,7 +112,7 @@ otError otLinkRawTransmit(otInstance *aInstance, otLinkRawTransmitDone aCallback int8_t otLinkRawGetRssi(otInstance *aInstance) { - return otPlatRadioGetRssi(aInstance); + return static_cast(aInstance)->Get().GetRssi(); } otRadioCaps otLinkRawGetCaps(otInstance *aInstance) @@ -128,11 +130,12 @@ otError otLinkRawEnergyScan(otInstance * aInstance, otError otLinkRawSrcMatchEnable(otInstance *aInstance, bool aEnable) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance &instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - otPlatRadioEnableSrcMatch(aInstance, aEnable); + instance.Get().EnableSrcMatch(aEnable); exit: return error; @@ -140,11 +143,12 @@ exit: otError otLinkRawSrcMatchAddShortEntry(otInstance *aInstance, const uint16_t aShortAddress) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance &instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - error = otPlatRadioAddSrcMatchShortEntry(aInstance, aShortAddress); + error = instance.Get().AddSrcMatchShortEntry(aShortAddress); exit: return error; @@ -153,13 +157,13 @@ exit: otError otLinkRawSrcMatchAddExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress) { Mac::Address address; - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance & instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); address.SetExtended(aExtAddress->m8, /* aReverse */ true); - - error = otPlatRadioAddSrcMatchExtEntry(aInstance, &address.GetExtended()); + error = instance.Get().AddSrcMatchExtEntry(address.GetExtended()); exit: return error; @@ -167,11 +171,11 @@ exit: otError otLinkRawSrcMatchClearShortEntry(otInstance *aInstance, const uint16_t aShortAddress) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance &instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - - error = otPlatRadioClearSrcMatchShortEntry(aInstance, aShortAddress); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + error = instance.Get().ClearSrcMatchShortEntry(aShortAddress); exit: return error; @@ -180,13 +184,13 @@ exit: otError otLinkRawSrcMatchClearExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress) { Mac::Address address; - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance & instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); address.SetExtended(aExtAddress->m8, /* aReverse */ true); - - error = otPlatRadioClearSrcMatchExtEntry(aInstance, &address.GetExtended()); + error = instance.Get().ClearSrcMatchExtEntry(address.GetExtended()); exit: return error; @@ -194,11 +198,12 @@ exit: otError otLinkRawSrcMatchClearShortEntries(otInstance *aInstance) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance &instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - otPlatRadioClearSrcMatchShortEntries(aInstance); + instance.Get().ClearSrcMatchShortEntries(); exit: return error; @@ -206,11 +211,12 @@ exit: otError otLinkRawSrcMatchClearExtEntries(otInstance *aInstance) { - otError error = OT_ERROR_NONE; + otError error = OT_ERROR_NONE; + Instance &instance = *static_cast(aInstance); - VerifyOrExit(static_cast(aInstance)->Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(instance.Get().IsEnabled(), error = OT_ERROR_INVALID_STATE); - otPlatRadioClearSrcMatchExtEntries(aInstance); + instance.Get().ClearSrcMatchExtEntries(); exit: return error; diff --git a/src/core/common/instance.cpp b/src/core/common/instance.cpp index 966083c34..7c5d9c4aa 100644 --- a/src/core/common/instance.cpp +++ b/src/core/common/instance.cpp @@ -61,6 +61,7 @@ Instance::Instance(void) , mMbedTls() #endif // #if OPENTHREAD_MTD || OPENTHREAD_FTD , mRandomManager() + , mRadio(*this) #if OPENTHREAD_MTD || OPENTHREAD_FTD , mNotifier(*this) , mSettings(*this) diff --git a/src/core/common/instance.hpp b/src/core/common/instance.hpp index ec4e0ebc8..d78073bb2 100644 --- a/src/core/common/instance.hpp +++ b/src/core/common/instance.hpp @@ -323,6 +323,11 @@ private: RandomManager mRandomManager; + // Radio is initialized before other member variables + // (particularly, SubMac and Mac) to allow them to use its methods + // from their constructor. + Radio mRadio; + #if OPENTHREAD_MTD || OPENTHREAD_FTD // Notifier, Settings, and MessagePool are initialized before // other member variables since other classes/objects from their @@ -378,6 +383,11 @@ private: // Specializations of the `Get()` method. +template <> inline Radio &Instance::Get(void) +{ + return mRadio; +} + #if OPENTHREAD_MTD || OPENTHREAD_FTD template <> inline Notifier &Instance::Get(void) { diff --git a/src/core/diags/factory_diags.cpp b/src/core/diags/factory_diags.cpp index 5b2183512..fc7e84853 100644 --- a/src/core/diags/factory_diags.cpp +++ b/src/core/diags/factory_diags.cpp @@ -41,6 +41,7 @@ #include "common/code_utils.hpp" #include "common/instance.hpp" +#include "common/locator-getters.hpp" #include "radio/radio.hpp" #include "utils/parse_cmdline.hpp" #include "utils/wrap_string.h" @@ -148,7 +149,7 @@ Diags::Diags(Instance &aInstance) , mTxLen(0) , mTxPeriod(0) , mTxPackets(0) - , mTxPacket(otPlatRadioGetTransmitBuffer(&aInstance)) + , mTxPacket(&Get().GetTransmitBuffer()) , mRepeatActive(false) { memset(&mStats, 0, sizeof(mStats)); @@ -175,7 +176,7 @@ void Diags::ProcessChannel(int aArgCount, char *aArgVector[], char *aOutput, siz VerifyOrExit(value >= Radio::kChannelMin && value <= Radio::kChannelMax, error = OT_ERROR_INVALID_ARGS); mChannel = static_cast(value); - otPlatRadioReceive(&GetInstance(), mChannel); + Get().Receive(mChannel); otPlatDiagChannelSet(mChannel); snprintf(aOutput, aOutputMaxLen, "set channel to %d\r\nstatus 0x%02x\r\n", mChannel, error); @@ -202,7 +203,7 @@ void Diags::ProcessPower(int aArgCount, char *aArgVector[], char *aOutput, size_ SuccessOrExit(error = ParseLong(aArgVector[0], value)); mTxPower = static_cast(value); - SuccessOrExit(error = otPlatRadioSetTransmitPower(&GetInstance(), mTxPower)); + SuccessOrExit(error = Get().SetTransmitPower(mTxPower)); otPlatDiagTxPowerSet(mTxPower); snprintf(aOutput, aOutputMaxLen, "set tx power to %d dBm\r\nstatus 0x%02x\r\n", mTxPower, error); @@ -279,11 +280,11 @@ void Diags::ProcessStart(int aArgCount, char *aArgVector[], char *aOutput, size_ otError error = OT_ERROR_NONE; - otPlatRadioEnable(&GetInstance()); - otPlatRadioSetPromiscuous(&GetInstance(), true); + Get().Enable(); + Get().SetPromiscuous(true); otPlatAlarmMilliStop(&GetInstance()); - SuccessOrExit(error = otPlatRadioReceive(&GetInstance(), mChannel)); - SuccessOrExit(error = otPlatRadioSetTransmitPower(&GetInstance(), mTxPower)); + SuccessOrExit(error = Get().Receive(mChannel)); + SuccessOrExit(error = Get().SetTransmitPower(mTxPower)); otPlatDiagModeSet(true); memset(&mStats, 0, sizeof(mStats)); snprintf(aOutput, aOutputMaxLen, "start diagnostics mode\r\nstatus 0x%02x\r\n", error); @@ -330,7 +331,7 @@ void Diags::ProcessStop(int aArgCount, char *aArgVector[], char *aOutput, size_t otPlatAlarmMilliStop(&GetInstance()); otPlatDiagModeSet(false); - otPlatRadioSetPromiscuous(&GetInstance(), false); + Get().SetPromiscuous(false); snprintf(aOutput, aOutputMaxLen, "received packets: %d\r\nsent packets: %d\r\n" @@ -355,7 +356,7 @@ void Diags::TransmitPacket(void) mTxPacket->mPsdu[i] = i; } - otPlatRadioTransmit(&GetInstance(), mTxPacket); + Get().Transmit(*static_cast(mTxPacket)); } void Diags::ProcessRadio(int aArgCount, char *aArgVector[], char *aOutput, size_t aOutputMaxLen) @@ -367,13 +368,13 @@ void Diags::ProcessRadio(int aArgCount, char *aArgVector[], char *aOutput, size_ if (strcmp(aArgVector[0], "sleep") == 0) { - SuccessOrExit(error = otPlatRadioSleep(&GetInstance())); + SuccessOrExit(error = Get().Sleep()); snprintf(aOutput, aOutputMaxLen, "set radio from receive to sleep \r\nstatus 0x%02x\r\n", error); } else if (strcmp(aArgVector[0], "receive") == 0) { - SuccessOrExit(error = otPlatRadioReceive(&GetInstance(), mChannel)); - SuccessOrExit(error = otPlatRadioSetTransmitPower(&GetInstance(), mTxPower)); + SuccessOrExit(error = Get().Receive(mChannel)); + SuccessOrExit(error = Get().SetTransmitPower(mTxPower)); otPlatDiagChannelSet(mChannel); otPlatDiagTxPowerSet(mTxPower); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 41b9ba31d..7623e73a4 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -95,7 +95,7 @@ Mac::Mac(Instance &aInstance) , mPanChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL) , mRadioChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL) , mRadioChannelAcquisitionId(0) - , mSupportedChannelMask(otPlatRadioGetSupportedChannelMask(&aInstance)) + , mSupportedChannelMask(Get().GetSupportedChannelMask()) , mScanChannel(Radio::kChannelMin) , mScanDuration(0) , mScanChannelMask() @@ -435,7 +435,7 @@ void Mac::SetSupportedChannelMask(const ChannelMask &aMask) { ChannelMask newMask = aMask; - newMask.Intersect(ChannelMask(otPlatRadioGetSupportedChannelMask(&GetInstance()))); + newMask.Intersect(ChannelMask(Get().GetSupportedChannelMask())); VerifyOrExit(newMask != mSupportedChannelMask, Get().SignalIfFirst(OT_CHANGED_SUPPORTED_CHANNEL_MASK)); mSupportedChannelMask = newMask; @@ -1846,7 +1846,7 @@ bool Mac::HandleMacCommand(RxFrame &aFrame) void Mac::SetPromiscuous(bool aPromiscuous) { mPromiscuous = aPromiscuous; - otPlatRadioSetPromiscuous(&GetInstance(), aPromiscuous); + Get().SetPromiscuous(aPromiscuous); #if OPENTHREAD_CONFIG_MAC_STAY_AWAKE_BETWEEN_FRAGMENTS mDelayingSleep = false; @@ -1864,7 +1864,7 @@ void Mac::ResetCounters(void) int8_t Mac::GetNoiseFloor(void) { - return otPlatRadioGetReceiveSensitivity(&GetInstance()); + return Get().GetReceiveSensitivity(); } // LCOV_EXCL_START diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index 4ab0c0fd4..9d68a1d88 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -47,7 +47,7 @@ namespace Mac { SubMac::SubMac(Instance &aInstance) : InstanceLocator(aInstance) - , mRadioCaps(otPlatRadioGetCaps(&aInstance)) + , mRadioCaps(Get().GetCaps()) , mState(kStateDisabled) , mCsmaBackoffs(0) , mTransmitRetries(0) @@ -55,7 +55,7 @@ SubMac::SubMac(Instance &aInstance) , mRxOnWhenBackoff(true) , mEnergyScanMaxRssi(kInvalidRssiValue) , mEnergyScanEndTime(0) - , mTransmitFrame(*static_cast(otPlatRadioGetTransmitBuffer(&aInstance))) + , mTransmitFrame(Get().GetTransmitBuffer()) , mCallbacks(aInstance) , mPcapCallback(NULL) , mPcapCallbackContext(NULL) @@ -96,14 +96,14 @@ otRadioCaps SubMac::GetCaps(void) const void SubMac::SetPanId(PanId aPanId) { - otPlatRadioSetPanId(&GetInstance(), aPanId); + Get().SetPanId(aPanId); otLogDebgMac("RadioPanId: 0x%04x", aPanId); } void SubMac::SetShortAddress(ShortAddress aShortAddress) { mShortAddress = aShortAddress; - otPlatRadioSetShortAddress(&GetInstance(), mShortAddress); + Get().SetShortAddress(mShortAddress); otLogDebgMac("RadioShortAddress: 0x%04x", mShortAddress); } @@ -115,7 +115,7 @@ void SubMac::SetExtAddress(const ExtAddress &aExtAddress) // Reverse the byte order before setting on radio. address.SetExtended(aExtAddress.m8, /* aReverse */ true); - otPlatRadioSetExtendedAddress(&GetInstance(), &address.GetExtended()); + Get().SetExtendedAddress(address.GetExtended()); otLogDebgMac("RadioExtAddress: %s", mExtAddress.ToString().AsCString()); } @@ -132,8 +132,8 @@ otError SubMac::Enable(void) VerifyOrExit(mState == kStateDisabled); - SuccessOrExit(error = otPlatRadioEnable(&GetInstance())); - SuccessOrExit(error = otPlatRadioSleep(&GetInstance())); + SuccessOrExit(error = Get().Enable()); + SuccessOrExit(error = Get().Sleep()); SetState(kStateSleep); exit: @@ -146,8 +146,8 @@ otError SubMac::Disable(void) otError error; mTimer.Stop(); - SuccessOrExit(error = otPlatRadioSleep(&GetInstance())); - SuccessOrExit(error = otPlatRadioDisable(&GetInstance())); + SuccessOrExit(error = Get().Sleep()); + SuccessOrExit(error = Get().Disable()); SetState(kStateDisabled); exit: @@ -156,11 +156,11 @@ exit: otError SubMac::Sleep(void) { - otError error = otPlatRadioSleep(&GetInstance()); + otError error = Get().Sleep(); if (error != OT_ERROR_NONE) { - otLogWarnMac("otPlatRadioSleep() failed, error: %s", otThreadErrorToString(error)); + otLogWarnMac("RadioSleep() failed, error: %s", otThreadErrorToString(error)); ExitNow(); } @@ -172,11 +172,11 @@ exit: otError SubMac::Receive(uint8_t aChannel) { - otError error = otPlatRadioReceive(&GetInstance(), aChannel); + otError error = Get().Receive(aChannel); if (error != OT_ERROR_NONE) { - otLogWarnMac("otPlatRadioReceive() failed, error: %s", otThreadErrorToString(error)); + otLogWarnMac("RadioReceive() failed, error: %s", otThreadErrorToString(error)); ExitNow(); } @@ -249,11 +249,11 @@ void SubMac::StartCsmaBackoff(void) if (mRxOnWhenBackoff) { - otPlatRadioReceive(&GetInstance(), mTransmitFrame.GetChannel()); + Get().Receive(mTransmitFrame.GetChannel()); } else { - otPlatRadioSleep(&GetInstance()); + Get().Sleep(); } #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE @@ -283,10 +283,10 @@ void SubMac::BeginTransmit(void) mTransmitFrame.SetCsmaCaEnabled(true); } - error = otPlatRadioReceive(&GetInstance(), mTransmitFrame.GetChannel()); + error = Get().Receive(mTransmitFrame.GetChannel()); assert(error == OT_ERROR_NONE); - error = otPlatRadioTransmit(&GetInstance(), &mTransmitFrame); + error = Get().Transmit(mTransmitFrame); assert(error == OT_ERROR_NONE); SetState(kStateTransmit); @@ -386,7 +386,7 @@ exit: int8_t SubMac::GetRssi(void) const { - return otPlatRadioGetRssi(&GetInstance()); + return Get().GetRssi(); } otError SubMac::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration) @@ -408,12 +408,12 @@ otError SubMac::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration) if (RadioSupportsEnergyScan()) { - otPlatRadioEnergyScan(&GetInstance(), aScanChannel, aScanDuration); + Get().EnergyScan(aScanChannel, aScanDuration); SetState(kStateEnergyScan); } else if (ShouldHandleEnergyScan()) { - error = otPlatRadioReceive(&GetInstance(), aScanChannel); + error = Get().Receive(aScanChannel); assert(error == OT_ERROR_NONE); SetState(kStateEnergyScan); @@ -473,7 +473,7 @@ void SubMac::HandleTimer(void) case kStateTransmit: otLogDebgMac("Ack timer timed out"); - otPlatRadioReceive(&GetInstance(), mTransmitFrame.GetChannel()); + Get().Receive(mTransmitFrame.GetChannel()); HandleTransmitDone(mTransmitFrame, NULL, OT_ERROR_NO_ACK); break; diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index 3fccd0d63..71e5051d6 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -37,11 +37,11 @@ #include "openthread-core-config.h" #include -#include #include "common/locator.hpp" #include "common/timer.hpp" #include "mac/mac_frame.hpp" +#include "radio/radio.hpp" namespace ot { diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp index 8d7744f18..dac5d20f4 100644 --- a/src/core/meshcop/dataset_manager_ftd.cpp +++ b/src/core/meshcop/dataset_manager_ftd.cpp @@ -319,7 +319,7 @@ otError ActiveDataset::CreateNewNetwork(otOperationalDataset &aDataset) { otError error = OT_ERROR_NONE; Mac::ChannelMask supportedChannels = Get().GetSupportedChannelMask(); - Mac::ChannelMask preferredChannels(otPlatRadioGetPreferredChannelMask(&GetInstance())); + Mac::ChannelMask preferredChannels(Get().GetPreferredChannelMask()); memset(&aDataset, 0, sizeof(aDataset)); diff --git a/src/core/meshcop/joiner.cpp b/src/core/meshcop/joiner.cpp index c3b56e189..b82c35264 100644 --- a/src/core/meshcop/joiner.cpp +++ b/src/core/meshcop/joiner.cpp @@ -35,8 +35,6 @@ #include -#include - #include "common/code_utils.hpp" #include "common/debug.hpp" #include "common/encoding.hpp" @@ -45,6 +43,7 @@ #include "common/logging.hpp" #include "mac/mac_frame.hpp" #include "meshcop/meshcop.hpp" +#include "radio/radio.hpp" #include "thread/thread_netif.hpp" #include "thread/thread_uri_paths.hpp" @@ -71,7 +70,7 @@ Joiner::Joiner(Instance &aInstance) void Joiner::GetJoinerId(Mac::ExtAddress &aJoinerId) const { - otPlatRadioGetIeeeEui64(&GetInstance(), aJoinerId.m8); + Get().GetIeeeEui64(aJoinerId); ComputeJoinerId(aJoinerId, aJoinerId); } diff --git a/src/core/net/dhcp6_client.cpp b/src/core/net/dhcp6_client.cpp index 151b5a8e6..da20f5dfe 100644 --- a/src/core/net/dhcp6_client.cpp +++ b/src/core/net/dhcp6_client.cpp @@ -321,7 +321,7 @@ otError Dhcp6Client::AppendClientIdentifier(Message &aMessage) ClientIdentifier option; Mac::ExtAddress eui64; - otPlatRadioGetIeeeEui64(&GetInstance(), eui64.m8); + Get().GetIeeeEui64(eui64); option.Init(); option.SetDuidType(kDuidLL); @@ -494,7 +494,7 @@ otError Dhcp6Client::ProcessClientIdentifier(Message &aMessage, uint16_t aOffset ClientIdentifier option; Mac::ExtAddress eui64; - otPlatRadioGetIeeeEui64(&GetInstance(), eui64.m8); + Get().GetIeeeEui64(eui64); VerifyOrExit((((aMessage.Read(aOffset, sizeof(option), &option) == sizeof(option)) && (option.GetLength() == (sizeof(option) - sizeof(Dhcp6Option))) && diff --git a/src/core/net/dhcp6_server.cpp b/src/core/net/dhcp6_server.cpp index 83cebe775..29605b94b 100644 --- a/src/core/net/dhcp6_server.cpp +++ b/src/core/net/dhcp6_server.cpp @@ -375,7 +375,7 @@ otError Dhcp6Server::AppendServerIdentifier(Message &aMessage) ServerIdentifier option; Mac::ExtAddress eui64; - otPlatRadioGetIeeeEui64(&GetInstance(), eui64.m8); + Get().GetIeeeEui64(eui64); option.Init(); option.SetDuidType(kDuidLL); diff --git a/src/core/radio/radio.hpp b/src/core/radio/radio.hpp index 986e7578f..5d28a5011 100644 --- a/src/core/radio/radio.hpp +++ b/src/core/radio/radio.hpp @@ -28,7 +28,7 @@ /** * @file - * This file includes definitions for OpenThread definition of radio abstraction. + * This file includes definitions for OpenThread radio abstraction. */ #ifndef RADIO_HPP_ @@ -38,6 +38,8 @@ #include +#include "common/locator.hpp" +#include "mac/mac_frame.hpp" #include "utils/static_assert.hpp" namespace ot { @@ -52,39 +54,359 @@ namespace ot { * */ -namespace Radio { - /** - * This enumeration defines the IEEE 802.15.4 channel related parameters. + * This class represents an OpenThread radio abstraction. * */ -enum +class Radio : public InstanceLocator { +public: + /** + * This enumeration defines the IEEE 802.15.4 channel related parameters. + * + */ + enum + { #if (OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT) - kNumChannelPages = 2, - kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK | OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK, - kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN, - kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX, - kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK | OT_RADIO_CHANNEL_PAGE_2_MASK, + kNumChannelPages = 2, + kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK | OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK, + kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN, + kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX, + kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK | OT_RADIO_CHANNEL_PAGE_2_MASK, #elif OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT - kNumChannelPages = 1, - kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK, - kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN, - kChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX, - kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_2_MASK, + kNumChannelPages = 1, + kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK, + kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN, + kChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX, + kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_2_MASK, #elif OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT - kNumChannelPages = 1, - kSupportedChannels = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK, - kChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN, - kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX, - kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK, + kNumChannelPages = 1, + kSupportedChannels = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK, + kChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN, + kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX, + kSupportedChannelPages = OT_RADIO_CHANNEL_PAGE_0_MASK, #endif + }; + + OT_STATIC_ASSERT((OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT || OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT), + "OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT or OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT " + "must be set to 1 to specify the radio mode"); + + /** + * This constructor initializes the `Radio` object. + * + * @param[in] aInstance A reference to the OpenThread instance. + * + */ + Radio(Instance &aInstance) + : InstanceLocator(aInstance) + { + } + + /** + * This method gets the radio capabilities. + * + * @returns The radio capability bit vector (see `OT_RADIO_CAP_*` definitions). + * + */ + otRadioCaps GetCaps(void) { return otPlatRadioGetCaps(GetInstance()); } + + /** + * This method gets the radio version string. + * + * @returns A pointer to the OpenThread radio version. + * + */ + const char *GetVersionString(void) { return otPlatRadioGetVersionString(GetInstance()); } + + /** + * This method gets the radio receive sensitivity value. + * + * @returns The radio receive sensitivity value in dBm. + * + */ + int8_t GetReceiveSensitivity(void) { return otPlatRadioGetReceiveSensitivity(GetInstance()); } + + /** + * This method gets the factory-assigned IEEE EUI-64 for the device. + * + * @param[out] aIeeeEui64 A reference to `Mac::ExtAddress` to place the factory-assigned IEEE EUI-64. + * + */ + void GetIeeeEui64(Mac::ExtAddress &aIeeeEui64) { otPlatRadioGetIeeeEui64(GetInstance(), aIeeeEui64.m8); } + + /** + * This method sets the PAN ID for address filtering. + * + * @param[in] aPanId The IEEE 802.15.4 PAN ID. + * + */ + void SetPanId(Mac::PanId aPanId) { otPlatRadioSetPanId(GetInstance(), aPanId); } + + /** + * This method sets the Extended Address for address filtering. + * + * @param[in] aExtAddress The IEEE 802.15.4 Extended Address stored in little-endian byte order. + * + */ + void SetExtendedAddress(const Mac::ExtAddress &aExtAddress) + { + otPlatRadioSetExtendedAddress(GetInstance(), &aExtAddress); + } + + /** + * This method sets the Short Address for address filtering. + * + * @param[in] aShortAddress The IEEE 802.15.4 Short Address. + * + */ + void SetShortAddress(Mac::ShortAddress aShortAddress) { otPlatRadioSetShortAddress(GetInstance(), aShortAddress); } + + /** + * This method gets the radio's transmit power in dBm. + * + * @param[out] aPower A reference to output the transmit power in dBm. + * + * @retval OT_ERROR_NONE Successfully retrieved the transmit power. + * @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented. + * + */ + otError GetTransmitPower(int8_t &aPower) { return otPlatRadioGetTransmitPower(GetInstance(), &aPower); } + + /** + * This method sets the radio's transmit power in dBm. + * + * @param[in] aPower The transmit power in dBm. + * + * @retval OT_ERROR_NONE Successfully set the transmit power. + * @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented. + * + */ + otError SetTransmitPower(int8_t aPower) { return otPlatRadioSetTransmitPower(GetInstance(), aPower); } + + /** + * This method gets the status of promiscuous mode. + * + * @retval TRUE Promiscuous mode is enabled. + * @retval FALSE Promiscuous mode is disabled. + * + */ + bool GetPromiscuous(void) { return otPlatRadioGetPromiscuous(GetInstance()); } + + /** + * This method enables or disables promiscuous mode. + * + * @param[in] aEnable TRUE to enable or FALSE to disable promiscuous mode. + * + */ + void SetPromiscuous(bool aEnable) { otPlatRadioSetPromiscuous(GetInstance(), aEnable); } + + /** + * This method enables the radio. + * + * @retval OT_ERROR_NONE Successfully enabled. + * @retval OT_ERROR_FAILED The radio could not be enabled. + * + */ + otError Enable(void) { return otPlatRadioEnable(GetInstance()); } + + /** + * This method disables the radio. + * + * @retval OT_ERROR_NONE Successfully transitioned to Disabled. + * @retval OT_ERROR_INVALID_STATE The radio was not in sleep state. + * + */ + otError Disable(void) { return otPlatRadioDisable(GetInstance()); } + + /** + * This method indicates whether radio is enabled or not. + * + * @returns TRUE if the radio is enabled, FALSE otherwise. + * + */ + bool IsEnabled(void) { return otPlatRadioIsEnabled(GetInstance()); } + + /** + * This method transitions the radio from Receive to Sleep (turn off the radio). + * + * @retval OT_ERROR_NONE Successfully transitioned to Sleep. + * @retval OT_ERROR_BUSY The radio was transmitting. + * @retval OT_ERROR_INVALID_STATE The radio was disabled. + * + */ + otError Sleep(void) { return otPlatRadioSleep(GetInstance()); } + + /** + * This method transitions the radio from Sleep to Receive (turn on the radio). + * + * @param[in] aChannel The channel to use for receiving. + * + * @retval OT_ERROR_NONE Successfully transitioned to Receive. + * @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting. + * + */ + otError Receive(uint8_t aChannel) { return otPlatRadioReceive(GetInstance(), aChannel); } + + /** + * This method gets the radio transmit frame buffer. + * + * OpenThread forms the IEEE 802.15.4 frame in this buffer then calls `Transmit()` to request transmission. + * + * @returns A reference to the transmit frame buffer. + * + */ + Mac::TxFrame &GetTransmitBuffer(void) + { + return *static_cast(otPlatRadioGetTransmitBuffer(GetInstance())); + } + + /** + * This method starts the transmit sequence on the radio. + * + * The caller must form the IEEE 802.15.4 frame in the buffer provided by `GetTransmitBuffer()` before + * requesting transmission. The channel and transmit power are also included in the frame. + * + * @param[in] aFrame A reference to the frame to be transmitted. + * + * @retval OT_ERROR_NONE Successfully transitioned to Transmit. + * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state. + * + */ + otError Transmit(Mac::TxFrame &aFrame) { return otPlatRadioTransmit(GetInstance(), &aFrame); } + + /** + * This method gets the most recent RSSI measurement. + * + * @returns The RSSI in dBm when it is valid. 127 when RSSI is invalid. + * + */ + int8_t GetRssi(void) { return otPlatRadioGetRssi(GetInstance()); } + + /** + * This method begins the energy scan sequence on the radio. + * + * This function is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability. + * + * @param[in] aScanChannel The channel to perform the energy scan on. + * @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned. + * + * @retval OT_ERROR_NONE Successfully started scanning the channel. + * @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning. + * + */ + otError EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration) + { + return otPlatRadioEnergyScan(GetInstance(), aScanChannel, aScanDuration); + } + + /** + * This method enables/disables source address match feature. + * + * The source address match feature controls how the radio layer decides the "frame pending" bit for acks sent in + * response to data request commands from children. + * + * If disabled, the radio layer must set the "frame pending" on all acks to data request commands. + * + * If enabled, the radio layer uses the source address match table to determine whether to set or clear the "frame + * pending" bit in an ack to a data request command. + * + * The source address match table provides the list of children for which there is a pending frame. Either a short + * address or an extended/long address can be added to the source address match table. + * + * @param[in] aEnable Enable/disable source address match feature. + * + */ + void EnableSrcMatch(bool aEnable) { return otPlatRadioEnableSrcMatch(GetInstance(), aEnable); } + + /** + * This method adds a short address to the source address match table. + * + * @param[in] aShortAddress The short address to be added. + * + * @retval OT_ERROR_NONE Successfully added short address to the source match table. + * @retval OT_ERROR_NO_BUFS No available entry in the source match table. + * + */ + otError AddSrcMatchShortEntry(Mac::ShortAddress aShortAddress) + { + return otPlatRadioAddSrcMatchShortEntry(GetInstance(), aShortAddress); + } + + /** + * This method adds an extended address to the source address match table. + * + * @param[in] aExtAddress The extended address to be added stored in little-endian byte order. + * + * @retval OT_ERROR_NONE Successfully added extended address to the source match table. + * @retval OT_ERROR_NO_BUFS No available entry in the source match table. + * + */ + otError AddSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress) + { + return otPlatRadioAddSrcMatchExtEntry(GetInstance(), &aExtAddress); + } + + /** + * This method removes a short address from the source address match table. + * + * @param[in] aShortAddress The short address to be removed. + * + * @retval OT_ERROR_NONE Successfully removed short address from the source match table. + * @retval OT_ERROR_NO_ADDRESS The short address is not in source address match table. + * + */ + otError ClearSrcMatchShortEntry(Mac::ShortAddress aShortAddress) + { + return otPlatRadioClearSrcMatchShortEntry(GetInstance(), aShortAddress); + } + + /** + * This method removes an extended address from the source address match table. + * + * @param[in] aExtAddress The extended address to be removed stored in little-endian byte order. + * + * @retval OT_ERROR_NONE Successfully removed the extended address from the source match table. + * @retval OT_ERROR_NO_ADDRESS The extended address is not in source address match table. + * + */ + otError ClearSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress) + { + return otPlatRadioClearSrcMatchExtEntry(GetInstance(), &aExtAddress); + } + + /** + * This method clears all short addresses from the source address match table. + * + */ + void ClearSrcMatchShortEntries(void) { otPlatRadioClearSrcMatchShortEntries(GetInstance()); } + + /** + * This method clears all the extended/long addresses from source address match table. + * + */ + void ClearSrcMatchExtEntries(void) { otPlatRadioClearSrcMatchExtEntries(GetInstance()); } + + /** + * This method gets the radio supported channel mask that the device is allowed to be on. + * + * @returns The radio supported channel mask. + * + */ + uint32_t GetSupportedChannelMask(void) { return otPlatRadioGetSupportedChannelMask(GetInstance()); } + + /** + * This method gets the radio preferred channel mask that the device prefers to form on. + * + * @returns The radio preferred channel mask. + * + */ + uint32_t GetPreferredChannelMask(void) { return otPlatRadioGetPreferredChannelMask(GetInstance()); } + +private: + otInstance *GetInstance(void) { return reinterpret_cast(&InstanceLocator::GetInstance()); } }; -OT_STATIC_ASSERT((OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT || OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT), - "OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT or OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT " - "must be set to 1 to specify the radio mode"); -} // namespace Radio } // namespace ot #endif // RADIO_HPP_ diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 4ac230491..b0b79c7fc 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -240,7 +240,7 @@ otError Mle::Start(bool aAnnounceAttach) otError error = OT_ERROR_NONE; // cannot bring up the interface if IEEE 802.15.4 promiscuous mode is enabled - VerifyOrExit(!otPlatRadioGetPromiscuous(&GetInstance()), error = OT_ERROR_INVALID_STATE); + VerifyOrExit(!Get().GetPromiscuous(), error = OT_ERROR_INVALID_STATE); VerifyOrExit(Get().IsUp(), error = OT_ERROR_INVALID_STATE); if (Get().GetPanId() == Mac::kPanIdBroadcast) @@ -527,7 +527,7 @@ otError Mle::Discover(const Mac::ChannelMask &aScanChannels, Crc16 ccitt(Crc16::kCcitt); Crc16 ansi(Crc16::kAnsi); - otPlatRadioGetIeeeEui64(&GetInstance(), extAddress.m8); + Get().GetIeeeEui64(extAddress); MeshCoP::ComputeJoinerId(extAddress, extAddress); // Compute bloom filter (for steering data) diff --git a/src/core/thread/src_match_controller.cpp b/src/core/thread/src_match_controller.cpp index a597be218..0561b6edb 100644 --- a/src/core/thread/src_match_controller.cpp +++ b/src/core/thread/src_match_controller.cpp @@ -36,8 +36,10 @@ #include "common/code_utils.hpp" #include "common/debug.hpp" #include "common/instance.hpp" +#include "common/locator-getters.hpp" #include "common/logging.hpp" #include "mac/mac_frame.hpp" +#include "radio/radio.hpp" #include "thread/mesh_forwarder.hpp" #include "thread/thread_netif.hpp" #include "thread/topology.hpp" @@ -107,15 +109,15 @@ exit: void SourceMatchController::ClearTable(void) { - otPlatRadioClearSrcMatchShortEntries(&GetInstance()); - otPlatRadioClearSrcMatchExtEntries(&GetInstance()); + Get().ClearSrcMatchShortEntries(); + Get().ClearSrcMatchExtEntries(); otLogDebgMac("SrcAddrMatch - Cleared all entries"); } void SourceMatchController::Enable(bool aEnable) { mEnabled = aEnable; - otPlatRadioEnableSrcMatch(&GetInstance(), mEnabled); + Get().EnableSrcMatch(mEnabled); otLogDebgMac("SrcAddrMatch - %sabling", mEnabled ? "En" : "Dis"); } @@ -144,7 +146,7 @@ otError SourceMatchController::AddAddress(const Child &aChild) if (aChild.IsIndirectSourceMatchShort()) { - error = otPlatRadioAddSrcMatchShortEntry(&GetInstance(), aChild.GetRloc16()); + error = Get().AddSrcMatchShortEntry(aChild.GetRloc16()); otLogDebgMac("SrcAddrMatch - Adding short addr: 0x%04x -- %s (%d)", aChild.GetRloc16(), otThreadErrorToString(error), error); @@ -154,7 +156,7 @@ otError SourceMatchController::AddAddress(const Child &aChild) Mac::Address address; address.SetExtended(aChild.GetExtAddress().m8, /* aReverse */ true); - error = otPlatRadioAddSrcMatchExtEntry(&GetInstance(), &address.GetExtended()); + error = Get().AddSrcMatchExtEntry(address.GetExtended()); otLogDebgMac("SrcAddrMatch - Adding addr: %s -- %s (%d)", aChild.GetExtAddress().ToString().AsCString(), otThreadErrorToString(error), error); @@ -176,7 +178,7 @@ void SourceMatchController::ClearEntry(Child &aChild) if (aChild.IsIndirectSourceMatchShort()) { - error = otPlatRadioClearSrcMatchShortEntry(&GetInstance(), aChild.GetRloc16()); + error = Get().ClearSrcMatchShortEntry(aChild.GetRloc16()); otLogDebgMac("SrcAddrMatch - Clearing short addr: 0x%04x -- %s (%d)", aChild.GetRloc16(), otThreadErrorToString(error), error); @@ -186,7 +188,7 @@ void SourceMatchController::ClearEntry(Child &aChild) Mac::Address address; address.SetExtended(aChild.GetExtAddress().m8, /* aReverse */ true); - error = otPlatRadioClearSrcMatchExtEntry(&GetInstance(), &address.GetExtended()); + error = Get().ClearSrcMatchExtEntry(address.GetExtended()); otLogDebgMac("SrcAddrMatch - Clearing addr: %s -- %s (%d)", aChild.GetExtAddress().ToString().AsCString(), otThreadErrorToString(error), error); diff --git a/src/core/utils/jam_detector.cpp b/src/core/utils/jam_detector.cpp index 35b7ec9e3..545f109b5 100644 --- a/src/core/utils/jam_detector.cpp +++ b/src/core/utils/jam_detector.cpp @@ -172,7 +172,7 @@ void JamDetector::HandleTimer(void) VerifyOrExit(mEnabled); - rssi = otPlatRadioGetRssi(&GetInstance()); + rssi = Get().GetRssi(); // If the RSSI is valid, check if it exceeds the threshold // and try to update the history bit map