NCP Usage of otLinkRaw API (#1205)

This commit is contained in:
Nick Banks
2017-01-26 11:13:35 -08:00
committed by Jonathan Hui
parent 8769b86c85
commit 827a480787
4 changed files with 262 additions and 8 deletions
+1 -1
View File
@@ -39,8 +39,8 @@ ot_ncp_CPPFLAGS = \
$(NULL)
ot_ncp_LDADD = \
$(top_builddir)/src/core/libopenthread-ftd.a \
$(top_builddir)/src/ncp/libopenthread-ncp.a \
$(top_builddir)/src/core/libopenthread-ftd.a \
$(NULL)
ot_ncp_LDFLAGS = \
+230 -7
View File
@@ -230,7 +230,10 @@ const NcpBase::SetPropertyHandlerEntry NcpBase::mSetPropertyHandlerTable[] =
{
{ SPINEL_PROP_POWER_STATE, &NcpBase::SetPropertyHandler_POWER_STATE },
#if OPENTHREAD_ENABLE_RAW_LINK_API
{ SPINEL_PROP_PHY_ENABLED, &NcpBase::SetPropertyHandler_PHY_ENABLED },
{ SPINEL_PROP_STREAM_RAW, &NcpBase::SetPropertyHandler_STREAM_RAW },
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
{ SPINEL_PROP_PHY_TX_POWER, &NcpBase::SetPropertyHandler_PHY_TX_POWER },
{ SPINEL_PROP_PHY_CHAN, &NcpBase::SetPropertyHandler_PHY_CHAN },
{ SPINEL_PROP_MAC_PROMISCUOUS_MODE, &NcpBase::SetPropertyHandler_MAC_PROMISCUOUS_MODE },
@@ -483,6 +486,10 @@ NcpBase::NcpBase(otInstance *aInstance):
mRequireJoinExistingNetwork(false),
mIsRawStreamEnabled(false),
mDisableStreamWrite(false),
#if OPENTHREAD_ENABLE_RAW_LINK_API
mCurTransmitTID(0),
mCurReceiveChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL),
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
mFramingErrorCounter(0),
mRxSpinelFrameCounter(0),
@@ -750,6 +757,99 @@ void NcpBase::HandleEnergyScanResult(otEnergyScanResult *aResult)
}
}
// ----------------------------------------------------------------------------
// MARK: Raw Link-Layer Datapath Glue
// ----------------------------------------------------------------------------
#if OPENTHREAD_ENABLE_RAW_LINK_API
void NcpBase::LinkRawReceiveDone(otInstance *, RadioPacket *aPacket, ThreadError aError)
{
sNcpContext->LinkRawReceiveDone(aPacket, aError);
}
void NcpBase::LinkRawReceiveDone(RadioPacket *aPacket, ThreadError aError)
{
ThreadError errorCode = kThreadError_None;
uint16_t flags = 0;
SuccessOrExit(errorCode = OutboundFrameBegin());
if (aPacket->mDidTX)
{
flags |= SPINEL_MD_FLAG_TX;
}
// Append frame header and frame length
SuccessOrExit(
errorCode = OutboundFrameFeedPacked(
"CiiS",
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
SPINEL_CMD_PROP_VALUE_IS,
SPINEL_PROP_STREAM_RAW,
(aError == kThreadError_None) ? aPacket->mLength : 0
)
);
if (aError == kThreadError_None)
{
// Append the frame contents
SuccessOrExit(
errorCode = OutboundFrameFeedData(
aPacket->mPsdu,
aPacket->mLength
)
);
}
// Append metadata (rssi, etc)
SuccessOrExit(
errorCode = OutboundFrameFeedPacked(
"ccSiCC",
aPacket->mPower, // TX Power
-128, // Noise Floor (Currently unused)
flags, // Flags
aError, // Receive error
aPacket->mChannel, // Receive channel
aPacket->mLqi // Link quality indicator
)
);
SuccessOrExit(errorCode = OutboundFrameSend());
exit:
return;
}
void NcpBase::LinkRawTransmitDone(otInstance *, RadioPacket *aPacket, bool aFramePending, ThreadError aError)
{
sNcpContext->LinkRawTransmitDone(aPacket, aFramePending, aError);
}
void NcpBase::LinkRawTransmitDone(RadioPacket *, bool aFramePending, ThreadError aError)
{
if (mCurTransmitTID)
{
SendPropertyUpdate(
SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 | mCurTransmitTID,
SPINEL_CMD_PROP_VALUE_IS,
SPINEL_PROP_LAST_STATUS,
"ib",
aError,
aFramePending
);
// Clear cached transmit TID
mCurTransmitTID = 0;
}
// Make sure we are back listening on the original receive channel,
// since the transmit could have been on a different channel.
otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
}
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
// ----------------------------------------------------------------------------
// MARK: Address Table Changed Glue
// ----------------------------------------------------------------------------
@@ -1529,6 +1629,10 @@ ThreadError NcpBase::GetPropertyHandler_CAPS(uint8_t header, spinel_prop_key_t k
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_COUNTERS));
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_MAC_WHITELIST));
#if OPENTHREAD_ENABLE_RAW_LINK_API
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_MAC_RAW));
#endif
#if OPENTHREAD_ENABLE_JAM_DETECTION
SuccessOrExit(errorCode = OutboundFrameFeedPacked(SPINEL_DATATYPE_UINT_PACKED_S, SPINEL_CAP_JAM_DETECT));
#endif
@@ -1611,10 +1715,17 @@ ThreadError NcpBase::GetPropertyHandler_LOCK(uint8_t header, spinel_prop_key_t k
ThreadError NcpBase::GetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_key_t key)
{
// TODO: Implement PHY_ENBLED (Needs API!)
(void)key;
return SendLastStatus(header, SPINEL_STATUS_UNIMPLEMENTED);
return SendPropertyUpdate(
header,
SPINEL_CMD_PROP_VALUE_IS,
key,
SPINEL_DATATYPE_BOOL_S,
#if OPENTHREAD_ENABLE_RAW_LINK_API
otLinkRawIsEnabled(mInstance)
#else
false
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
);
}
ThreadError NcpBase::GetPropertyHandler_PHY_FREQ(uint8_t header, spinel_prop_key_t key)
@@ -3073,6 +3184,8 @@ ThreadError NcpBase::SetPropertyHandler_POWER_STATE(uint8_t header, spinel_prop_
return SendLastStatus(header, SPINEL_STATUS_UNIMPLEMENTED);
}
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError NcpBase::SetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
@@ -3091,11 +3204,23 @@ ThreadError NcpBase::SetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_
{
if (value == false)
{
errorCode = otPlatRadioDisable(mInstance);
// If we have raw stream enabled stop receiving
if (mIsRawStreamEnabled)
{
otLinkRawSleep(mInstance);
}
errorCode = otLinkRawSetEnable(mInstance, false);
}
else
{
errorCode = otPlatRadioEnable(mInstance);
errorCode = otLinkRawSetEnable(mInstance, true);
// If we have raw stream enabled already, start receiving
if (errorCode == kThreadError_None && mIsRawStreamEnabled)
{
errorCode = otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
}
}
}
else
@@ -3115,6 +3240,8 @@ ThreadError NcpBase::SetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_
return errorCode;
}
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError NcpBase::SetPropertyHandler_PHY_TX_POWER(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
@@ -3144,6 +3271,25 @@ ThreadError NcpBase::SetPropertyHandler_PHY_CHAN(uint8_t header, spinel_prop_key
{
errorCode = otSetChannel(mInstance, static_cast<uint8_t>(i));
#if OPENTHREAD_ENABLE_RAW_LINK_API
if (errorCode == kThreadError_None)
{
// Cache the channel. If the raw link layer isn't enabled yet, the otSetChannel call
// doesn't call into the radio layer to set the channel. We will have to do it
// manually whenever the radios are enabled and/or raw stream is enabled.
mCurReceiveChannel = static_cast<uint8_t>(i);
// Make sure we are update the receiving channel if raw link is enabled and we have raw
// stream enabled already
if (otLinkRawIsEnabled(mInstance) && mIsRawStreamEnabled)
{
errorCode = otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
}
}
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
if (errorCode == kThreadError_None)
{
errorCode = HandleCommandPropertyGet(header, key);
@@ -3424,7 +3570,19 @@ ThreadError NcpBase::SetPropertyHandler_MAC_RAW_STREAM_ENABLED(uint8_t header, s
if (parsedLength > 0)
{
mIsRawStreamEnabled = value;
#if OPENTHREAD_ENABLE_RAW_LINK_API
if (otLinkRawIsEnabled(mInstance))
{
if (value)
{
errorCode = otLinkRawReceive(mInstance, mCurReceiveChannel, &NcpBase::LinkRawReceiveDone);
}
else
{
errorCode = otLinkRawSleep(mInstance);
}
}
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
}
else
{
@@ -3433,6 +3591,7 @@ ThreadError NcpBase::SetPropertyHandler_MAC_RAW_STREAM_ENABLED(uint8_t header, s
if (errorCode == kThreadError_None)
{
mIsRawStreamEnabled = value;
errorCode = HandleCommandPropertyGet(header, key);
}
else
@@ -3443,6 +3602,70 @@ ThreadError NcpBase::SetPropertyHandler_MAC_RAW_STREAM_ENABLED(uint8_t header, s
return errorCode;
}
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError NcpBase::SetPropertyHandler_STREAM_RAW(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
ThreadError errorCode = kThreadError_None;
if (otLinkRawIsEnabled(mInstance))
{
spinel_ssize_t parsedLength(0);
uint8_t *frame_buffer(NULL);
unsigned int frame_len(0);
RadioPacket *packet = otLinkRawGetTransmitBuffer(mInstance);
parsedLength = spinel_datatype_unpack(
value_ptr,
value_len,
"DCc",
&frame_buffer,
&frame_len,
&packet->mChannel,
&packet->mPower
);
if (parsedLength > 0 && frame_len <= kMaxPHYPacketSize)
{
// Cache the transaction ID for async response
mCurTransmitTID = SPINEL_HEADER_GET_TID(header);
// Update packet buffer and length
packet->mLength = static_cast<uint8_t>(frame_len);
memcpy(packet->mPsdu, frame_buffer, packet->mLength);
// Pass packet to the radio layer. Note, this fails if we
// haven't enabled raw stream or are already transmitting.
errorCode = otLinkRawTransmit(mInstance, packet, &NcpBase::LinkRawTransmitDone);
}
else
{
errorCode = kThreadError_Parse;
}
}
else
{
errorCode = kThreadError_InvalidState;
}
if (errorCode == kThreadError_None)
{
// Don't do anything here yet. We will complete the transaction when we get a transmit done callback
}
else
{
errorCode = SendLastStatus(header, ThreadErrorToSpinelStatus(errorCode));
}
(void)key;
return errorCode;
}
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError NcpBase::SetPropertyHandler_NET_IF_UP(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len)
{
+30
View File
@@ -188,6 +188,25 @@ private:
void SendDoneTask(void);
#if OPENTHREAD_ENABLE_RAW_LINK_API
/**
* Trampoline for LinkRawReceiveDone().
*/
static void LinkRawReceiveDone(otInstance *aInstance, RadioPacket *aPacket, ThreadError aError);
void LinkRawReceiveDone(RadioPacket *aPacket, ThreadError aError);
/**
* Trampoline for LinkRawTransmitDone().
*/
static void LinkRawTransmitDone(otInstance *aInstance, RadioPacket *aPacket, bool aFramePending,
ThreadError aError);
void LinkRawTransmitDone(RadioPacket *aPacket, bool aFramePending, ThreadError aError);
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
static void HandleNetifStateChanged(uint32_t flags, void *context);
private:
@@ -387,6 +406,10 @@ private:
uint16_t value_len);
ThreadError SetPropertyHandler_MAC_RAW_STREAM_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError SetPropertyHandler_STREAM_RAW(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError SetPropertyHandler_NET_IF_UP(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
ThreadError SetPropertyHandler_NET_STACK_UP(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
@@ -413,8 +436,10 @@ private:
uint16_t value_len);
ThreadError SetPropertyHandler_THREAD_RLOC16_DEBUG_PASSTHRU(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#if OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError SetPropertyHandler_PHY_ENABLED(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
ThreadError SetPropertyHandler_MAC_PROMISCUOUS_MODE(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
uint16_t value_len);
ThreadError SetPropertyHandler_MAC_SCAN_PERIOD(uint8_t header, spinel_prop_key_t key, const uint8_t *value_ptr,
@@ -526,6 +551,11 @@ private:
bool mIsRawStreamEnabled;
bool mDisableStreamWrite;
#if OPENTHREAD_ENABLE_RAW_LINK_API
uint8_t mCurTransmitTID;
uint8_t mCurReceiveChannel;
#endif // OPENTHREAD_ENABLE_RAW_LINK_API
uint32_t mFramingErrorCounter; // Number of improperly formed received spinel frames.
uint32_t mRxSpinelFrameCounter; // Number of received (inbound) spinel frames.
uint32_t mRxSpinelOutOfOrderTidCounter; // Number of out of order received spinel frames (tid increase > 1).
+1
View File
@@ -337,6 +337,7 @@ enum
SPINEL_CAP_OPENTHREAD__BEGIN = 512,
SPINEL_CAP_MAC_WHITELIST = (SPINEL_CAP_OPENTHREAD__BEGIN + 0),
SPINEL_CAP_MAC_RAW = (SPINEL_CAP_OPENTHREAD__BEGIN + 1),
SPINEL_CAP_OPENTHREAD__END = 640,
SPINEL_CAP_NEST__BEGIN = 15296,