[mac] simplify scan handlers (#4503)

This commit changes the energy and active scan callback handlers in
`Mac` class to make them follow the model used by external OpenThread
scan APIs. This in turn simplifies their use, allowing us to remove
the code that saved energy/active scan callbacks and contexts in the
`Instance` object. This commit also adds some missing `const` methods
to Beacon class which allows us to declare the received beacon frame
(from scan operation) as a `const`.
This commit is contained in:
Abtin Keshavarzian
2020-01-23 19:48:02 -08:00
committed by Jonathan Hui
parent 8d22fdd09c
commit a5f2a41cb3
12 changed files with 121 additions and 187 deletions
+2 -27
View File
@@ -42,9 +42,6 @@
using namespace ot;
static void HandleActiveScanResult(Instance &aInstance, Mac::RxFrame *aFrame);
static void HandleEnergyScanResult(Instance &aInstance, otEnergyScanResult *aResult);
uint8_t otLinkGetChannel(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
@@ -418,8 +415,7 @@ otError otLinkActiveScan(otInstance * aInstance,
{
Instance &instance = *static_cast<Instance *>(aInstance);
instance.RegisterActiveScanCallback(aCallback, aCallbackContext);
return instance.Get<Mac::Mac>().ActiveScan(aScanChannels, aScanDuration, &HandleActiveScanResult);
return instance.Get<Mac::Mac>().ActiveScan(aScanChannels, aScanDuration, aCallback, aCallbackContext);
}
bool otLinkIsActiveScanInProgress(otInstance *aInstance)
@@ -429,21 +425,6 @@ bool otLinkIsActiveScanInProgress(otInstance *aInstance)
return instance.Get<Mac::Mac>().IsActiveScanInProgress();
}
void HandleActiveScanResult(Instance &aInstance, Mac::RxFrame *aFrame)
{
if (aFrame == NULL)
{
aInstance.InvokeActiveScanCallback(NULL);
}
else
{
otActiveScanResult result;
aInstance.Get<Mac::Mac>().ConvertBeaconToActiveScanResult(aFrame, result);
aInstance.InvokeActiveScanCallback(&result);
}
}
otError otLinkEnergyScan(otInstance * aInstance,
uint32_t aScanChannels,
uint16_t aScanDuration,
@@ -452,13 +433,7 @@ otError otLinkEnergyScan(otInstance * aInstance,
{
Instance &instance = *static_cast<Instance *>(aInstance);
instance.RegisterEnergyScanCallback(aCallback, aCallbackContext);
return instance.Get<Mac::Mac>().EnergyScan(aScanChannels, aScanDuration, &HandleEnergyScanResult);
}
void HandleEnergyScanResult(Instance &aInstance, otEnergyScanResult *aResult)
{
aInstance.InvokeEnergyScanCallback(aResult);
return instance.Get<Mac::Mac>().EnergyScan(aScanChannels, aScanDuration, aCallback, aCallbackContext);
}
bool otLinkIsEnergyScanInProgress(otInstance *aInstance)
-31
View File
@@ -77,10 +77,6 @@ Instance::Instance(void)
, mNotifier(*this)
, mSettings(*this)
, mMessagePool(*this)
, mActiveScanCallback(NULL)
, mActiveScanCallbackContext(NULL)
, mEnergyScanCallback(NULL)
, mEnergyScanCallbackContext(NULL)
, mIp6(*this)
, mThreadNetif(*this)
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
@@ -229,33 +225,6 @@ exit:
return error;
}
void Instance::RegisterActiveScanCallback(otHandleActiveScanResult aCallback, void *aContext)
{
mActiveScanCallback = aCallback;
mActiveScanCallbackContext = aContext;
}
void Instance::InvokeActiveScanCallback(otActiveScanResult *aResult) const
{
if (mActiveScanCallback != NULL)
{
mActiveScanCallback(aResult, mActiveScanCallbackContext);
}
}
void Instance::RegisterEnergyScanCallback(otHandleEnergyScanResult aCallback, void *aContext)
{
mEnergyScanCallback = aCallback;
mEnergyScanCallbackContext = aContext;
}
void Instance::InvokeEnergyScanCallback(otEnergyScanResult *aResult) const
{
if (mEnergyScanCallback != NULL)
{
mEnergyScanCallback(aResult, mEnergyScanCallbackContext);
}
}
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
} // namespace ot
-43
View File
@@ -214,44 +214,6 @@ public:
*/
otError ErasePersistentInfo(void);
/**
* This method registers the active scan callback.
*
* Subsequent calls to this method will overwrite the previous callback handler.
*
* @param[in] aCallback A pointer to the callback function pointer.
* @param[in] aContext A pointer to application-specific context.
*
*/
void RegisterActiveScanCallback(otHandleActiveScanResult aCallback, void *aContext);
/**
* This method invokes the previously registered active scan callback with a given scan result.
*
* @param[in] aResult A pointer to active scan result.
*
*/
void InvokeActiveScanCallback(otActiveScanResult *aResult) const;
/**
* This method registers the energy scan callback.
*
* Subsequent calls to this method will overwrite the previous callback handler.
*
* @param[in] aCallback A pointer to the callback function pointer.
* @param[in] aContext A pointer to application-specific context.
*
*/
void RegisterEnergyScanCallback(otHandleEnergyScanResult aCallback, void *aContext);
/**
* This method invokes the previously registered energy scan callback with a given result.
*
* @param[in] aResult A pointer to energy scan result.
*
*/
void InvokeEnergyScanCallback(otEnergyScanResult *aResult) const;
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
void HeapFree(void *aPointer)
{
@@ -365,11 +327,6 @@ private:
Settings mSettings;
MessagePool mMessagePool;
otHandleActiveScanResult mActiveScanCallback;
void * mActiveScanCallbackContext;
otHandleEnergyScanResult mEnergyScanCallback;
void * mEnergyScanCallbackContext;
Ip6::Ip6 mIp6;
ThreadNetif mThreadNetif;
+53 -23
View File
@@ -106,6 +106,7 @@ Mac::Mac(Instance &aInstance)
, mMaxFrameRetriesIndirect(kDefaultMaxFrameRetriesIndirect)
#endif
, mActiveScanHandler(NULL) // Initialize `mActiveScanHandler` and `mEnergyScanHandler` union
, mScanHandlerContext(NULL)
, mSubMac(aInstance)
, mOperationTask(aInstance, &Mac::HandleOperationTask, this)
, mTimer(aInstance, &Mac::HandleTimer, this)
@@ -133,14 +134,15 @@ Mac::Mac(Instance &aInstance)
SetShortAddress(GetShortAddress());
}
otError Mac::ActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler)
otError Mac::ActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler, void *aContext)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!IsActiveScanInProgress() && !IsEnergyScanInProgress(), error = OT_ERROR_BUSY);
mActiveScanHandler = aHandler;
mActiveScanHandler = aHandler;
mScanHandlerContext = aContext;
if (aScanDuration == 0)
{
@@ -153,14 +155,15 @@ exit:
return error;
}
otError Mac::EnergyScan(uint32_t aScanChannels, uint16_t aScanDuration, EnergyScanHandler aHandler)
otError Mac::EnergyScan(uint32_t aScanChannels, uint16_t aScanDuration, EnergyScanHandler aHandler, void *aContext)
{
otError error = OT_ERROR_NONE;
VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE);
VerifyOrExit(!IsActiveScanInProgress() && !IsEnergyScanInProgress(), error = OT_ERROR_BUSY);
mEnergyScanHandler = aHandler;
mEnergyScanHandler = aHandler;
mScanHandlerContext = aContext;
Scan(kOperationEnergyScan, aScanChannels, aScanDuration);
@@ -210,15 +213,15 @@ bool Mac::IsInTransmitState(void) const
return retval;
}
otError Mac::ConvertBeaconToActiveScanResult(RxFrame *aBeaconFrame, otActiveScanResult &aResult)
otError Mac::ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveScanResult &aResult)
{
otError error = OT_ERROR_NONE;
Address address;
Beacon * beacon = NULL;
BeaconPayload *beaconPayload = NULL;
uint16_t payloadLength;
otError error = OT_ERROR_NONE;
Address address;
const Beacon * beacon = NULL;
const BeaconPayload *beaconPayload = NULL;
uint16_t payloadLength;
memset(&aResult, 0, sizeof(otActiveScanResult));
memset(&aResult, 0, sizeof(ActiveScanResult));
VerifyOrExit(aBeaconFrame != NULL, error = OT_ERROR_INVALID_ARGS);
@@ -234,8 +237,8 @@ otError Mac::ConvertBeaconToActiveScanResult(RxFrame *aBeaconFrame, otActiveScan
payloadLength = aBeaconFrame->GetPayloadLength();
beacon = reinterpret_cast<Beacon *>(aBeaconFrame->GetPayload());
beaconPayload = reinterpret_cast<BeaconPayload *>(beacon->GetPayload());
beacon = reinterpret_cast<const Beacon *>(aBeaconFrame->GetPayload());
beaconPayload = reinterpret_cast<const BeaconPayload *>(beacon->GetPayload());
if ((payloadLength >= (sizeof(*beacon) + sizeof(*beaconPayload))) && beacon->IsValid() && beaconPayload->IsValid())
{
@@ -275,11 +278,31 @@ void Mac::PerformActiveScan(void)
{
mSubMac.SetPanId(mPanId);
FinishOperation();
mActiveScanHandler(GetInstance(), NULL);
ReportActiveScanResult(NULL);
PerformNextOperation();
}
}
void Mac::ReportActiveScanResult(const RxFrame *aBeaconFrame)
{
VerifyOrExit(mActiveScanHandler != NULL);
if (aBeaconFrame == NULL)
{
mActiveScanHandler(NULL, mScanHandlerContext);
}
else
{
ActiveScanResult result;
SuccessOrExit(ConvertBeaconToActiveScanResult(aBeaconFrame, result));
mActiveScanHandler(&result, mScanHandlerContext);
}
exit:
return;
}
void Mac::PerformEnergyScan(void)
{
otError error = OT_ERROR_NONE;
@@ -305,22 +328,29 @@ exit:
if (error != OT_ERROR_NONE)
{
FinishOperation();
mEnergyScanHandler(GetInstance(), NULL);
if (mEnergyScanHandler != NULL)
{
mEnergyScanHandler(NULL, mScanHandlerContext);
}
PerformNextOperation();
}
}
void Mac::ReportEnergyScanResult(int8_t aRssi)
{
if (aRssi != kInvalidRssiValue)
{
otEnergyScanResult result;
EnergyScanResult result;
result.mChannel = mScanChannel;
result.mMaxRssi = aRssi;
VerifyOrExit((mEnergyScanHandler != NULL) && (aRssi != kInvalidRssiValue));
mEnergyScanHandler(GetInstance(), &result);
}
result.mChannel = mScanChannel;
result.mMaxRssi = aRssi;
mEnergyScanHandler(&result, mScanHandlerContext);
exit:
return;
}
void Mac::EnergyScanDone(int8_t aEnergyScanMaxRssi)
@@ -1647,7 +1677,7 @@ void Mac::HandleReceivedFrame(RxFrame *aFrame, otError aError)
if (aFrame->GetType() == Frame::kFcfFrameBeacon)
{
mCounters.mRxBeacon++;
mActiveScanHandler(GetInstance(), aFrame);
ReportActiveScanResult(aFrame);
ExitNow();
}
+34 -35
View File
@@ -91,6 +91,31 @@ enum
kTxNumBcast = OPENTHREAD_CONFIG_MAC_TX_NUM_BCAST ///< Number of times each broadcast frame is transmitted
};
/**
* This type defines the function pointer called on receiving an IEEE 802.15.4 Beacon during an Active Scan.
*
*/
typedef otHandleActiveScanResult ActiveScanHandler;
/**
* This type defines an Active Scan result.
*
*/
typedef otActiveScanResult ActiveScanResult;
/**
* This type defines the function pointer which is called during an Energy Scan when the scan result for a channel is
* ready or when the scan completes.
*
*/
typedef otHandleEnergyScanResult EnergyScanHandler;
/**
* This type defines an Energy Scan result.
*
*/
typedef otEnergyScanResult EnergyScanResult;
/**
* This class implements the IEEE 802.15.4 MAC.
*
@@ -108,15 +133,6 @@ public:
*/
explicit Mac(Instance &aInstance);
/**
* This function pointer is called on receiving an IEEE 802.15.4 Beacon during an Active Scan.
*
* @param[in] aInstance A reference to the OpenThread instance.
* @param[in] aBeaconFrame A pointer to the Beacon frame or NULL to indicate end of Active Scan operation.
*
*/
typedef void (*ActiveScanHandler)(Instance &aInstance, RxFrame *aBeaconFrame);
/**
* This method starts an IEEE 802.15.4 Active Scan.
*
@@ -124,36 +140,13 @@ public:
* @param[in] aScanDuration The time in milliseconds to spend scanning each channel. Zero duration maps to
* default value `kScanDurationDefault` = 300 ms.
* @param[in] aHandler A pointer to a function that is called on receiving an IEEE 802.15.4 Beacon.
* @param[in] aContext A pointer to an arbitrary context (used when invoking `aHandler` callback).
*
* @retval OT_ERROR_NONE Successfully scheduled the Active Scan request.
* @retval OT_ERROR_BUSY Could not schedule the scan (a scan is ongoing or scheduled).
*
*/
otError ActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler);
/**
* This method converts a beacon frame to an active scan result of type `otActiveScanResult`.
*
* @param[in] aBeaconFrame A pointer to a beacon frame.
* @param[out] aResult A reference to `otActiveScanResult` where the result is stored.
*
* @retval OT_ERROR_NONE Successfully converted the beacon into active scan result.
* @retval OT_ERROR_INVALID_ARGS The @a aBeaconFrame was NULL.
* @retval OT_ERROR_PARSE Failed parsing the beacon frame.
*
*/
otError ConvertBeaconToActiveScanResult(RxFrame *aBeaconFrame, otActiveScanResult &aResult);
/**
* This function pointer is called during an Energy Scan when the result for a channel is ready or the scan
* completes.
*
* @param[in] aInstance A reference to the OpenThread instance.
* @param[in] aResult A valid pointer to the energy scan result information or NULL when the energy scan
* completes.
*
*/
typedef void (*EnergyScanHandler)(Instance &aInstance, otEnergyScanResult *aResult);
otError ActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler, void *aContext);
/**
* This method starts an IEEE 802.15.4 Energy Scan.
@@ -162,12 +155,13 @@ public:
* @param[in] aScanDuration The time in milliseconds to spend scanning each channel. If the duration is set to
* zero, a single RSSI sample will be taken per channel.
* @param[in] aHandler A pointer to a function called to pass on scan result or indicate scan completion.
* @param[in] aContext A pointer to an arbitrary context (used when invoking @p aHandler callback).
*
* @retval OT_ERROR_NONE Accepted the Energy Scan request.
* @retval OT_ERROR_BUSY Could not start the energy scan.
*
*/
otError EnergyScan(uint32_t aScanChannels, uint16_t aScanDuration, EnergyScanHandler aHandler);
otError EnergyScan(uint32_t aScanChannels, uint16_t aScanDuration, EnergyScanHandler aHandler, void *aContext);
/**
* This method indicates the energy scan for the current channel is complete.
@@ -724,6 +718,8 @@ private:
void Scan(Operation aScanOperation, uint32_t aScanChannels, uint16_t aScanDuration);
otError UpdateScanChannel(void);
void PerformActiveScan(void);
void ReportActiveScanResult(const RxFrame *aBeaconFrame);
otError ConvertBeaconToActiveScanResult(const RxFrame *aBeaconFrame, ActiveScanResult &aResult);
void PerformEnergyScan(void);
void ReportEnergyScanResult(int8_t aRssi);
@@ -780,12 +776,15 @@ private:
#if OPENTHREAD_FTD
uint8_t mMaxFrameRetriesIndirect;
#endif
union
{
ActiveScanHandler mActiveScanHandler;
EnergyScanHandler mEnergyScanHandler;
};
void *mScanHandlerContext;
SubMac mSubMac;
Tasklet mOperationTask;
TimerMilli mTimer;
+10 -2
View File
@@ -1164,13 +1164,21 @@ public:
}
/**
* This method returns the pointer to the beacon payload address.
* This method returns the pointer to the beacon payload.
*
* @retval A pointer to the beacon payload address.
* @returns A pointer to the beacon payload.
*
*/
uint8_t *GetPayload(void) { return reinterpret_cast<uint8_t *>(this) + sizeof(*this); }
/**
* This method returns the pointer to the beacon payload.
*
* @returns A pointer to the beacon payload.
*
*/
const uint8_t *GetPayload(void) const { return reinterpret_cast<const uint8_t *>(this) + sizeof(*this); }
private:
uint16_t mSuperframeSpec;
uint8_t mGtsSpec;
+4 -4
View File
@@ -123,7 +123,7 @@ void EnergyScanServer::HandleTimer(void)
{
// grab the lowest channel to scan
uint32_t channelMask = mChannelMaskCurrent & ~(mChannelMaskCurrent - 1);
Get<Mac::Mac>().EnergyScan(channelMask, mScanDuration, HandleScanResult);
Get<Mac::Mac>().EnergyScan(channelMask, mScanDuration, HandleScanResult, this);
}
else
{
@@ -134,12 +134,12 @@ exit:
return;
}
void EnergyScanServer::HandleScanResult(Instance &aInstance, otEnergyScanResult *aResult)
void EnergyScanServer::HandleScanResult(Mac::EnergyScanResult *aResult, void *aContext)
{
aInstance.Get<EnergyScanServer>().HandleScanResult(aResult);
static_cast<EnergyScanServer *>(aContext)->HandleScanResult(aResult);
}
void EnergyScanServer::HandleScanResult(otEnergyScanResult *aResult)
void EnergyScanServer::HandleScanResult(Mac::EnergyScanResult *aResult)
{
VerifyOrExit(mActive);
+2 -2
View File
@@ -69,8 +69,8 @@ private:
static void HandleRequest(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleRequest(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleScanResult(Instance &aInstance, otEnergyScanResult *aResult);
void HandleScanResult(otEnergyScanResult *aResult);
static void HandleScanResult(Mac::EnergyScanResult *aResult, void *aContext);
void HandleScanResult(Mac::EnergyScanResult *aResult);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
+7 -11
View File
@@ -89,22 +89,18 @@ exit:
return;
}
void PanIdQueryServer::HandleScanResult(Instance &aInstance, Mac::RxFrame *aFrame)
void PanIdQueryServer::HandleScanResult(Mac::ActiveScanResult *aScanResult, void *aContext)
{
aInstance.Get<PanIdQueryServer>().HandleScanResult(aFrame);
static_cast<PanIdQueryServer *>(aContext)->HandleScanResult(aScanResult);
}
void PanIdQueryServer::HandleScanResult(Mac::RxFrame *aFrame)
void PanIdQueryServer::HandleScanResult(Mac::ActiveScanResult *aScanResult)
{
uint16_t panId;
if (aFrame != NULL)
if (aScanResult != NULL)
{
aFrame->GetSrcPanId(panId);
if (panId == mPanId)
if (aScanResult->mPanId == mPanId)
{
mChannelMask |= 1 << aFrame->GetChannel();
mChannelMask |= 1 << aScanResult->mChannel;
}
}
else if (mChannelMask != 0)
@@ -158,7 +154,7 @@ void PanIdQueryServer::HandleTimer(Timer &aTimer)
void PanIdQueryServer::HandleTimer(void)
{
Get<Mac::Mac>().ActiveScan(mChannelMask, 0, HandleScanResult);
Get<Mac::Mac>().ActiveScan(mChannelMask, 0, HandleScanResult, this);
mChannelMask = 0;
}
+3 -3
View File
@@ -39,7 +39,7 @@
#include "coap/coap.hpp"
#include "common/locator.hpp"
#include "common/timer.hpp"
#include "mac/mac_frame.hpp"
#include "mac/mac.hpp"
#include "net/ip6_address.hpp"
#include "net/udp6.hpp"
@@ -67,8 +67,8 @@ private:
static void HandleQuery(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo);
void HandleQuery(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleScanResult(Instance &aInstance, Mac::RxFrame *aFrame);
void HandleScanResult(Mac::RxFrame *aFrame);
static void HandleScanResult(Mac::ActiveScanResult *aScanResult, void *aContext);
void HandleScanResult(Mac::ActiveScanResult *aScanResult);
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
+4 -4
View File
@@ -119,17 +119,17 @@ void ChannelMonitor::HandleTimer(Timer &aTimer)
void ChannelMonitor::HandleTimer(void)
{
Get<Mac::Mac>().EnergyScan(mScanChannelMasks[mChannelMaskIndex], 0, &ChannelMonitor::HandleEnergyScanResult);
Get<Mac::Mac>().EnergyScan(mScanChannelMasks[mChannelMaskIndex], 0, &ChannelMonitor::HandleEnergyScanResult, this);
mTimer.StartAt(mTimer.GetFireTime(), Random::NonCrypto::AddJitter(kTimerInterval, kMaxJitterInterval));
}
void ChannelMonitor::HandleEnergyScanResult(Instance &aInstance, otEnergyScanResult *aResult)
void ChannelMonitor::HandleEnergyScanResult(Mac::EnergyScanResult *aResult, void *aContext)
{
aInstance.Get<ChannelMonitor>().HandleEnergyScanResult(aResult);
static_cast<ChannelMonitor *>(aContext)->HandleEnergyScanResult(aResult);
}
void ChannelMonitor::HandleEnergyScanResult(otEnergyScanResult *aResult)
void ChannelMonitor::HandleEnergyScanResult(Mac::EnergyScanResult *aResult)
{
if (aResult == NULL)
{
+2 -2
View File
@@ -200,8 +200,8 @@ private:
static void HandleTimer(Timer &aTimer);
void HandleTimer(void);
static void HandleEnergyScanResult(Instance &aInstance, otEnergyScanResult *aResult);
void HandleEnergyScanResult(otEnergyScanResult *aResult);
static void HandleEnergyScanResult(Mac::EnergyScanResult *aResult, void *aContext);
void HandleEnergyScanResult(Mac::EnergyScanResult *aResult);
void LogResults(void);
static const uint32_t mScanChannelMasks[kNumChannelMasks];