mirror of
https://github.com/espressif/openthread.git
synced 2026-08-18 16:39:52 +00:00
NCP Usage of otLinkRaw API (#1205)
This commit is contained in:
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user