[ncp] allow pcap without link-raw (#3274)

This commit adds a new spinel property `SPINEL_PROP_PHY_PCAP_ENABLED`
to allow packet capture (pcap) to be enabled independently of
link-raw mode. This allows pcap to be used on NCPs while running full
Thread protocol.
This commit is contained in:
Abtin Keshavarzian
2018-11-09 08:59:20 -08:00
committed by Jonathan Hui
parent 8440656f88
commit 765c45c2ed
6 changed files with 97 additions and 55 deletions
+3 -51
View File
@@ -224,6 +224,7 @@ NcpBase::NcpBase(Instance *aInstance)
, mAllowLocalNetworkDataChange(false)
, mRequireJoinExistingNetwork(false)
, mIsRawStreamEnabled(false)
, mPcapEnabled(false)
, mDisableStreamWrite(false)
, mShouldEmitChildTableUpdate(false)
#if OPENTHREAD_FTD
@@ -271,7 +272,6 @@ NcpBase::NcpBase(Instance *aInstance)
#if OPENTHREAD_ENABLE_UDP_FORWARD
otUdpForwardSetForwarder(mInstance, &NcpBase::HandleUdpForwardStream, this);
#endif
otLinkSetPcapCallback(mInstance, &NcpBase::HandleRawFrame, static_cast<void *>(this));
otIcmp6SetEchoMode(mInstance, OT_ICMP6_ECHO_HANDLER_DISABLED);
#if OPENTHREAD_FTD
otThreadSetChildTableCallback(mInstance, &NcpBase::HandleChildTableChanged);
@@ -639,56 +639,6 @@ void NcpBase::RegisterPeekPokeDelagates(otNcpDelegateAllowPeekPoke aAllowPeekDel
#endif // OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE
// ----------------------------------------------------------------------------
// MARK: Raw frame handling
// ----------------------------------------------------------------------------
void NcpBase::HandleRawFrame(const otRadioFrame *aFrame, void *aContext)
{
static_cast<NcpBase *>(aContext)->HandleRawFrame(aFrame);
}
void NcpBase::HandleRawFrame(const otRadioFrame *aFrame)
{
uint16_t flags = 0;
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
if (!mIsRawStreamEnabled)
{
goto exit;
}
if (aFrame->mDidTx)
{
flags |= SPINEL_MD_FLAG_TX;
}
// Append frame header and frame length
SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_STREAM_RAW));
SuccessOrExit(mEncoder.WriteUint16(aFrame->mLength));
// Append the frame contents
SuccessOrExit(mEncoder.WriteData(aFrame->mPsdu, aFrame->mLength));
// Append metadata (rssi, etc)
SuccessOrExit(mEncoder.WriteInt8(aFrame->mInfo.mRxInfo.mRssi)); // RSSI
SuccessOrExit(mEncoder.WriteInt8(-128)); // Noise floor (Currently unused)
SuccessOrExit(mEncoder.WriteUint16(flags)); // Flags
SuccessOrExit(mEncoder.OpenStruct()); // PHY-data
// Empty for now
SuccessOrExit(mEncoder.CloseStruct());
SuccessOrExit(mEncoder.OpenStruct()); // Vendor-data
// Empty for now
SuccessOrExit(mEncoder.CloseStruct());
SuccessOrExit(mEncoder.EndFrame());
exit:
return;
}
// ----------------------------------------------------------------------------
// MARK: Spinel Response Handling
// ----------------------------------------------------------------------------
@@ -1789,6 +1739,8 @@ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CAPS>(void)
#if OPENTHREAD_MTD || OPENTHREAD_FTD
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_NET_THREAD_1_1));
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_PCAP));
#if OPENTHREAD_ENABLE_MAC_FILTER
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_MAC_WHITELIST));
#endif
+4 -3
View File
@@ -237,9 +237,6 @@ protected:
NcpFrameBuffer * aNcpBuffer);
void HandleFrameRemovedFromNcpBuffer(NcpFrameBuffer::FrameTag aFrameTag);
static void HandleRawFrame(const otRadioFrame *aFrame, void *aContext);
void HandleRawFrame(const otRadioFrame *aFrame);
otError EncodeChannelMask(uint32_t aChannelMask);
otError DecodeChannelMask(uint32_t &aChannelMask);
@@ -263,6 +260,9 @@ protected:
static void HandleStateChanged(otChangedFlags aFlags, void *aContext);
void ProcessThreadChangedFlags(void);
static void HandlePcapFrame(const otRadioFrame *aFrame, void *aContext);
void HandlePcapFrame(const otRadioFrame *aFrame);
static void HandleTimeSyncUpdate(void *aContext);
void HandleTimeSyncUpdate(void);
@@ -530,6 +530,7 @@ protected:
bool mAllowLocalNetworkDataChange;
bool mRequireJoinExistingNetwork;
bool mIsRawStreamEnabled;
bool mPcapEnabled;
bool mDisableStreamWrite;
bool mShouldEmitChildTableUpdate;
+6
View File
@@ -139,6 +139,9 @@ NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
// MTD (or FTD) Properties (Get Handler)
#if OPENTHREAD_MTD || OPENTHREAD_FTD
case SPINEL_PROP_PHY_PCAP_ENABLED:
handler = &NcpBase::HandlePropertyGet<SPINEL_PROP_PHY_PCAP_ENABLED>;
break;
case SPINEL_PROP_MAC_DATA_POLL_PERIOD:
handler = &NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_DATA_POLL_PERIOD>;
break;
@@ -687,6 +690,9 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
// MTD (or FTD) Properties (Set Handler)
#if OPENTHREAD_MTD || OPENTHREAD_FTD
case SPINEL_PROP_PHY_PCAP_ENABLED:
handler = &NcpBase::HandlePropertySet<SPINEL_PROP_PHY_PCAP_ENABLED>;
break;
case SPINEL_PROP_PHY_CHAN_SUPPORTED:
handler = &NcpBase::HandlePropertySet<SPINEL_PROP_PHY_CHAN_SUPPORTED>;
break;
+73
View File
@@ -2929,6 +2929,79 @@ exit:
}
#endif // OPENTHREAD_ENABLE_UDP_FORWARD
// ----------------------------------------------------------------------------
// MARK: Pcap frame handling
// ----------------------------------------------------------------------------
void NcpBase::HandlePcapFrame(const otRadioFrame *aFrame, void *aContext)
{
static_cast<NcpBase *>(aContext)->HandlePcapFrame(aFrame);
}
void NcpBase::HandlePcapFrame(const otRadioFrame *aFrame)
{
uint16_t flags = 0;
uint8_t header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
VerifyOrExit(mPcapEnabled);
if (aFrame->mDidTx)
{
flags |= SPINEL_MD_FLAG_TX;
}
SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_STREAM_RAW));
SuccessOrExit(mEncoder.WriteUint16(aFrame->mLength));
SuccessOrExit(mEncoder.WriteData(aFrame->mPsdu, aFrame->mLength));
// Append metadata (rssi, etc)
SuccessOrExit(mEncoder.WriteInt8(aFrame->mInfo.mRxInfo.mRssi)); // RSSI
SuccessOrExit(mEncoder.WriteInt8(-128)); // Noise floor (Currently unused)
SuccessOrExit(mEncoder.WriteUint16(flags)); // Flags
SuccessOrExit(mEncoder.OpenStruct()); // PHY-data
// Empty for now
SuccessOrExit(mEncoder.CloseStruct());
SuccessOrExit(mEncoder.OpenStruct()); // Vendor-data
// Empty for now
SuccessOrExit(mEncoder.CloseStruct());
SuccessOrExit(mEncoder.EndFrame());
exit:
return;
}
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_PHY_PCAP_ENABLED>(void)
{
return mEncoder.WriteBool(mPcapEnabled);
}
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_PHY_PCAP_ENABLED>(void)
{
otError error = OT_ERROR_NONE;
bool enabled;
SuccessOrExit(error = mDecoder.ReadBool(enabled));
VerifyOrExit(enabled != mPcapEnabled);
mPcapEnabled = enabled;
if (mPcapEnabled)
{
otLinkSetPcapCallback(mInstance, &NcpBase::HandlePcapFrame, static_cast<void *>(this));
}
else
{
otLinkSetPcapCallback(mInstance, NULL, NULL);
}
exit:
return error;
}
// ----------------------------------------------------------------------------
// MARK: Property/Status Changed
// ----------------------------------------------------------------------------
+8
View File
@@ -1290,6 +1290,10 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
ret = "PHY_RX_SENSITIVITY";
break;
case SPINEL_PROP_PHY_PCAP_ENABLED:
ret = "PHY_PCAP_ENABLED";
break;
case SPINEL_PROP_JAM_DETECT_ENABLE:
ret = "JAM_DETECT_ENABLE";
break;
@@ -2359,6 +2363,10 @@ const char *spinel_capability_to_cstr(unsigned int capability)
ret = "MCU_POWER_STATE";
break;
case SPINEL_CAP_PCAP:
ret = "PCAP";
break;
case SPINEL_CAP_802_15_4_2003:
ret = "802_15_4_2003";
break;
+3 -1
View File
@@ -724,6 +724,7 @@ enum
SPINEL_CAP_CMD_MULTI = 11,
SPINEL_CAP_UNSOL_UPDATE_FILTER = 12,
SPINEL_CAP_MCU_POWER_STATE = 13,
SPINEL_CAP_PCAP = 14,
SPINEL_CAP_802_15_4__BEGIN = 16,
SPINEL_CAP_802_15_4_2003 = (SPINEL_CAP_802_15_4__BEGIN + 0),
@@ -987,6 +988,7 @@ typedef enum
SPINEL_PROP_PHY_TX_POWER = SPINEL_PROP_PHY__BEGIN + 5, ///< [c]
SPINEL_PROP_PHY_RSSI = SPINEL_PROP_PHY__BEGIN + 6, ///< dBm [c]
SPINEL_PROP_PHY_RX_SENSITIVITY = SPINEL_PROP_PHY__BEGIN + 7, ///< dBm [c]
SPINEL_PROP_PHY_PCAP_ENABLED = SPINEL_PROP_PHY__BEGIN + 8, ///< [b]
SPINEL_PROP_PHY__END = 0x30,
SPINEL_PROP_PHY_EXT__BEGIN = 0x1200,
@@ -1150,7 +1152,7 @@ typedef enum
SPINEL_PROP_MAC_15_4_LADDR = SPINEL_PROP_MAC__BEGIN + 4, ///< [E]
SPINEL_PROP_MAC_15_4_SADDR = SPINEL_PROP_MAC__BEGIN + 5, ///< [S]
SPINEL_PROP_MAC_15_4_PANID = SPINEL_PROP_MAC__BEGIN + 6, ///< [S]
SPINEL_PROP_MAC_RAW_STREAM_ENABLED = SPINEL_PROP_MAC__BEGIN + 7, ///< [C]
SPINEL_PROP_MAC_RAW_STREAM_ENABLED = SPINEL_PROP_MAC__BEGIN + 7, ///< [b]
SPINEL_PROP_MAC_PROMISCUOUS_MODE = SPINEL_PROP_MAC__BEGIN + 8, ///< [C]
SPINEL_PROP_MAC_ENERGY_SCAN_RESULT = SPINEL_PROP_MAC__BEGIN + 9, ///< chan,maxRssi [Cc]
SPINEL_PROP_MAC_DATA_POLL_PERIOD = SPINEL_PROP_MAC__BEGIN + 10, ///< pollPeriod (in ms) [L]