NCP Raw Link-Layer Energy Scan Usage (#1215)

This commit is contained in:
Nick Banks
2017-02-02 12:08:04 -08:00
committed by Jonathan Hui
parent ea4047b1cf
commit e8b53a3804
2 changed files with 130 additions and 14 deletions
+122 -14
View File
@@ -57,6 +57,7 @@ namespace Thread
static NcpBase *sNcpContext = NULL;
#define NCP_INVALID_SCAN_CHANNEL (-1)
#define NCP_PLAT_RESET_REASON (1U<<31)
#define NCP_ON_MESH_NETS_CHANGED_BIT_FLAG (1U<<30)
@@ -491,6 +492,7 @@ NcpBase::NcpBase(otInstance *aInstance):
#if OPENTHREAD_ENABLE_RAW_LINK_API
mCurTransmitTID(0),
mCurReceiveChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL),
mCurScanChannel(NCP_INVALID_SCAN_CHANNEL),
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
mFramingErrorCounter(0),
@@ -850,6 +852,40 @@ void NcpBase::LinkRawTransmitDone(RadioPacket *, bool aFramePending, ThreadError
otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
}
void NcpBase::LinkRawEnergyScanDone(otInstance *, int8_t aEnergyScanMaxRssi)
{
sNcpContext->LinkRawEnergyScanDone(aEnergyScanMaxRssi);
}
void NcpBase::LinkRawEnergyScanDone(int8_t aEnergyScanMaxRssi)
{
SendPropertyUpdate(
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
SPINEL_CMD_PROP_VALUE_IS,
SPINEL_PROP_MAC_ENERGY_SCAN_RESULT,
"Cc",
mCurScanChannel,
aEnergyScanMaxRssi
);
// Clear current scan channel
mCurScanChannel = NCP_INVALID_SCAN_CHANNEL;
// Make sure we are back listening on the original receive channel,
// since the energy scan could have been on a different channel.
otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
// We are finished with the scan, so send out
// a property update indicating such.
SendPropertyUpdate(
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
SPINEL_CMD_PROP_VALUE_IS,
SPINEL_PROP_MAC_SCAN_STATE,
SPINEL_DATATYPE_UINT8_S,
SPINEL_SCAN_STATE_IDLE
);
}
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
// ----------------------------------------------------------------------------
@@ -1798,6 +1834,21 @@ ThreadError NcpBase::GetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_pr
{
ThreadError errorCode = kThreadError_None;
#if OPENTHREAD_ENABLE_RAW_LINK_API
if (otLinkRawIsEnabled(mInstance))
{
errorCode = SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_IS,
key,
SPINEL_DATATYPE_UINT8_S,
mCurScanChannel == NCP_INVALID_SCAN_CHANNEL ?
SPINEL_SCAN_STATE_IDLE :
SPINEL_SCAN_STATE_ENERGY
);
}
else
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
if (otIsActiveScanInProgress(mInstance))
{
errorCode = SendPropertyUpdate(
@@ -3460,6 +3511,21 @@ ThreadError NcpBase::SetPropertyHandler_NET_REQUIRE_JOIN_EXISTING(uint8_t header
return errorCode;
}
bool HasOnly1BitSet(uint32_t aValue)
{
return aValue != 0 && ((aValue & (aValue-1)) == 0);
}
uint8_t IndexOfMSB(uint32_t aValue)
{
uint8_t index = 0;
while (aValue >>= 1)
{
index++;
}
return index;
}
ThreadError NcpBase::SetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
@@ -3483,13 +3549,22 @@ ThreadError NcpBase::SetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_pr
break;
case SPINEL_SCAN_STATE_BEACON:
errorCode = otActiveScan(
mInstance,
mChannelMask,
mScanPeriod,
&HandleActiveScanResult_Jump,
this
);
#if OPENTHREAD_ENABLE_RAW_LINK_API
if (otLinkRawIsEnabled(mInstance))
{
errorCode = kThreadError_NotImplemented;
}
else
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
{
errorCode = otActiveScan(
mInstance,
mChannelMask,
mScanPeriod,
&HandleActiveScanResult_Jump,
this
);
}
if (errorCode == kThreadError_None)
{
@@ -3499,13 +3574,46 @@ ThreadError NcpBase::SetPropertyHandler_MAC_SCAN_STATE(uint8_t header, spinel_pr
break;
case SPINEL_SCAN_STATE_ENERGY:
errorCode = otEnergyScan(
mInstance,
mChannelMask,
mScanPeriod,
&HandleEnergyScanResult_Jump,
this
);
#if OPENTHREAD_ENABLE_RAW_LINK_API
if (otLinkRawIsEnabled(mInstance))
{
// Make sure we aren't already scanning and that we have
// only 1 bit set for the channel mask.
if (mCurScanChannel == NCP_INVALID_SCAN_CHANNEL)
{
if (HasOnly1BitSet(mChannelMask))
{
uint8_t scanChannel = IndexOfMSB(mChannelMask);
mCurScanChannel = (int8_t)scanChannel;
errorCode = otLinkRawEnergyScan(
mInstance,
scanChannel,
mScanPeriod,
LinkRawEnergyScanDone
);
}
else
{
errorCode = kThreadError_InvalidArgs;
}
}
else
{
errorCode = kThreadError_InvalidState;
}
}
else
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
{
errorCode = otEnergyScan(
mInstance,
mChannelMask,
mScanPeriod,
&HandleEnergyScanResult_Jump,
this
);
}
if (errorCode == kThreadError_None)
{
+8
View File
@@ -205,6 +205,13 @@ private:
void LinkRawTransmitDone(RadioPacket *aPacket, bool aFramePending, ThreadError aError);
/**
* Trampoline for LinkRawEnergyScanDone().
*/
static void LinkRawEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi);
void LinkRawEnergyScanDone(int8_t aEnergyScanMaxRssi);
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
static void HandleNetifStateChanged(uint32_t flags, void *context);
@@ -554,6 +561,7 @@ private:
#if OPENTHREAD_ENABLE_RAW_LINK_API
uint8_t mCurTransmitTID;
uint8_t mCurReceiveChannel;
int8_t mCurScanChannel;
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
uint32_t mFramingErrorCounter; // Number of improperly formed received spinel frames.