Add support for radio energy scan API (#749)

* Add support for radio energy scan API
This commit is contained in:
Nick Banks
2016-10-06 23:20:50 -07:00
committed by Jonathan Hui
parent eb2277ab60
commit 2df41313a9
6 changed files with 112 additions and 29 deletions
+8
View File
@@ -737,3 +737,11 @@ void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
HWREG(addrAutoPendEn++) = 0;
}
}
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
{
(void)aInstance;
(void)aScanChannel;
(void)aScanDuration;
return kThreadError_NotImplemented;
}
+8
View File
@@ -763,3 +763,11 @@ void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
{
(void)aInstance;
}
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration)
{
(void)aInstance;
(void)aScanChannel;
(void)aScanDuration;
return kThreadError_NotImplemented;
}
+22
View File
@@ -89,6 +89,7 @@ typedef enum otRadioCaps
{
kRadioCapsNone = 0, ///< None
kRadioCapsAckTimeout = 1, ///< Radio supports AckTime event
kRadioCapsEnergyScan = 2, ///< Radio supports Enegery Scans
} otRadioCaps;
/**
@@ -436,6 +437,27 @@ extern void otPlatDiagRadioTransmitDone(otInstance *aInstance, bool aFramePendin
*/
extern void otPlatDiagRadioReceiveDone(otInstance *aInstance, RadioPacket *aPacket, ThreadError aError);
/**
* This method begins the energy scan sequence on the radio.
*
* @param[in] aInstance The OpenThread instance structure.
* @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 ::kThreadError_None Successfully started scanning the channel.
* @retval ::kThreadError_NotImplemented The radio doesn't support energy scanning.
*/
ThreadError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration);
/**
* The radio driver calls this method to notify OpenThread that the energy scan is complete.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aEnergyScanMaxRssi The maximum RSSI encountered on the scanned channel.
*
*/
extern void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi);
/**
* @}
*
+61 -29
View File
@@ -222,10 +222,66 @@ bool Mac::IsEnergyScanInProgress(void)
void Mac::StartEnergyScan(void)
{
mState = kStateEnergyScan;
mEnergyScanCurrentMaxRssi = kInvalidRssiValue;
mMacTimer.Start(mScanDuration);
mEnergyScanSampleRssiTask.Post();
NextOperation();
if (!(otPlatRadioGetCaps(mNetif.GetInstance()) & kRadioCapsEnergyScan))
{
mEnergyScanCurrentMaxRssi = kInvalidRssiValue;
mMacTimer.Start(mScanDuration);
mEnergyScanSampleRssiTask.Post();
NextOperation();
}
else
{
ThreadError error = otPlatRadioEnergyScan(mNetif.GetInstance(), mScanChannel, mScanDuration);
if (error != kThreadError_None)
{
// Cancel scan
mEnergyScanHandler(mScanContext, NULL);
ScheduleNextTransmission();
}
}
}
extern "C" void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi)
{
aInstance->mThreadNetif.GetMac().EnergyScanDone(aEnergyScanMaxRssi);
}
void Mac::EnergyScanDone(int8_t aEnergyScanMaxRssi)
{
// Trigger a energy scan handler callback if necessary
if (aEnergyScanMaxRssi != kInvalidRssiValue)
{
otEnergyScanResult result;
result.mChannel = mScanChannel;
result.mMaxRssi = aEnergyScanMaxRssi;
mEnergyScanHandler(mScanContext, &result);
}
// Update to the next scan channel
do
{
mScanChannels >>= 1;
mScanChannel++;
// If we have scanned all the channels, then fire the final callback
// and start the next transmission task
if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel)
{
mEnergyScanHandler(mScanContext, NULL);
ScheduleNextTransmission();
ExitNow();
}
}
while ((mScanChannels & 1) == 0);
// Start scanning the next channel
StartEnergyScan();
exit:
return;
}
void Mac::HandleEnergyScanSampleRssi(void *aContext)
@@ -769,31 +825,7 @@ void Mac::HandleMacTimer(void)
break;
case kStateEnergyScan:
if (mEnergyScanCurrentMaxRssi != kInvalidRssiValue)
{
otEnergyScanResult result;
result.mChannel = mScanChannel;
result.mMaxRssi = mEnergyScanCurrentMaxRssi;
mEnergyScanHandler(mScanContext, &result);
}
do
{
mScanChannels >>= 1;
mScanChannel++;
if (mScanChannels == 0 || mScanChannel > kPhyMaxChannel)
{
mEnergyScanHandler(mScanContext, NULL);
ScheduleNextTransmission();
ExitNow();
}
}
while ((mScanChannels & 1) == 0);
mEnergyScanCurrentMaxRssi = kInvalidRssiValue;
mMacTimer.Start(mScanDuration);
EnergyScanDone(mEnergyScanCurrentMaxRssi);
break;
case kStateTransmitData:
+8
View File
@@ -235,6 +235,14 @@ public:
*/
ThreadError EnergyScan(uint32_t aScanChannels, uint16_t aScanDuration, EnergyScanHandler aHandler, void *aContext);
/**
* This function indicates the energy scan for the current channel is complete.
*
* @param[in] aEnergyScanMaxRssi The maximum RSSI encountered on the scanned channel.
*
*/
void EnergyScanDone(int8_t aEnergyScanMaxRssi);
/**
* This method indicates whether or not rx-on-when-idle is enabled.
*
+5
View File
@@ -204,6 +204,11 @@ extern "C" {
(void)aInstance;
}
ThreadError otPlatRadioEnergyScan(otInstance *, uint8_t, uint16_t)
{
return kThreadError_NotImplemented;
}
//
// Random
//