5656#if OPENTHREAD_FTD
5757#include < openthread/thread_ftd.h>
5858#endif
59+ #if OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_LISTENER_ENABLE
60+ #include < openthread/thread_direct.h>
61+ #endif
5962#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
6063#include < openthread/server.h>
6164#endif
@@ -4831,12 +4834,11 @@ void NcpBase::ProcessThreadChangedFlags(void)
48314834#if OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_INITIATOR_ENABLE || OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_LISTENER_ENABLE
48324835template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DIRECT_WAKE_CHANNEL >(void )
48334836{
4834- uint8_t wakeupChannel ;
4837+ uint8_t wakeChannel ;
48354838 otError error = OT_ERROR_NONE ;
48364839
4837- SuccessOrExit (error = mDecoder .ReadUint8 (wakeupChannel));
4838-
4839- error = otLinkSetWakeupChannel (mInstance , wakeupChannel);
4840+ SuccessOrExit (error = mDecoder .ReadUint8 (wakeChannel));
4841+ error = otLinkSetWakeupChannel (mInstance , wakeChannel);
48404842
48414843exit:
48424844 return error;
@@ -4846,7 +4848,163 @@ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DIRECT_WAKE_CH
48464848{
48474849 return mEncoder .WriteUint8 (otLinkGetWakeupChannel (mInstance ));
48484850}
4849- #endif
4851+
4852+ #if OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_LISTENER_ENABLE
4853+ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DIRECT_WAKE_LISTEN_ENABLED >(void )
4854+ {
4855+ return mEncoder .WriteBool (otThreadDirectIsWakeListenerEnabled (mInstance ));
4856+ }
4857+
4858+ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DIRECT_WAKE_LISTEN_ENABLED >(void )
4859+ {
4860+ bool enable;
4861+ otError error = OT_ERROR_NONE ;
4862+
4863+ SuccessOrExit (error = mDecoder .ReadBool (enable));
4864+ error = otThreadDirectWakeListenerEnable (mInstance , enable);
4865+
4866+ exit:
4867+ return error;
4868+ }
4869+
4870+ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DIRECT_WAKE_LISTEN_PARAMS >(void )
4871+ {
4872+ uint32_t interval;
4873+ uint32_t duration;
4874+
4875+ otLinkGetWakeupListenParameters (mInstance , &interval, &duration);
4876+ SuccessOrExit (mEncoder .WriteUint32 (interval));
4877+ SuccessOrExit (mEncoder .WriteUint32 (duration));
4878+
4879+ exit:
4880+ return OT_ERROR_NONE ;
4881+ }
4882+
4883+ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DIRECT_WAKE_LISTEN_PARAMS >(void )
4884+ {
4885+ uint32_t interval;
4886+ uint32_t duration;
4887+ otError error = OT_ERROR_NONE ;
4888+
4889+ SuccessOrExit (error = mDecoder .ReadUint32 (interval));
4890+ SuccessOrExit (error = mDecoder .ReadUint32 (duration));
4891+ error = otLinkSetWakeupListenParameters (mInstance , interval, duration);
4892+
4893+ exit:
4894+ return error;
4895+ }
4896+ #endif // OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_LISTENER_ENABLE
4897+
4898+ #if OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_INITIATOR_ENABLE
4899+ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DIRECT_WAKE >(void )
4900+ {
4901+ otExtAddress extAddress;
4902+ uint8_t wakeType;
4903+ uint16_t intervalUs;
4904+ uint16_t durationMs;
4905+ uint8_t keyIndex;
4906+ const uint8_t *keyData;
4907+ uint16_t keyLength;
4908+ otError error = OT_ERROR_NONE ;
4909+
4910+ SuccessOrExit (error = mDecoder .ReadEui64 (extAddress));
4911+ SuccessOrExit (error = mDecoder .ReadUint8 (wakeType));
4912+ SuccessOrExit (error = mDecoder .ReadUint16 (intervalUs));
4913+ SuccessOrExit (error = mDecoder .ReadUint16 (durationMs));
4914+ SuccessOrExit (error = mDecoder .ReadUint8 (keyIndex));
4915+ // Consume the inline-key data field for wire compatibility; guest keys must be
4916+ // provisioned via SPINEL_PROP_THREAD_DIRECT_GUEST_WAKE_KEY before calling this property.
4917+ SuccessOrExit (error = mDecoder .ReadDataWithLen (keyData, keyLength));
4918+ OT_UNUSED_VARIABLE (keyData);
4919+ OT_UNUSED_VARIABLE (keyLength);
4920+
4921+ error = otThreadDirectWakeup (mInstance , &extAddress, static_cast <otThreadDirectWakeType>(wakeType), intervalUs,
4922+ durationMs, keyIndex);
4923+
4924+ exit:
4925+ return error;
4926+ }
4927+ #endif // OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_INITIATOR_ENABLE
4928+
4929+ template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_THREAD_DIRECT_GUEST_WAKE_KEY >(void )
4930+ {
4931+ uint8_t keyIndex;
4932+ const uint8_t *keyData;
4933+ uint16_t keyLength;
4934+ otThreadDirectWakeKey key;
4935+ otError error = OT_ERROR_NONE ;
4936+
4937+ SuccessOrExit (error = mDecoder .ReadUint8 (keyIndex));
4938+ SuccessOrExit (error = mDecoder .ReadDataWithLen (keyData, keyLength));
4939+ VerifyOrExit (keyLength == sizeof (key.m8 ), error = OT_ERROR_PARSE );
4940+ memcpy (key.m8 , keyData, sizeof (key.m8 ));
4941+ error = otThreadDirectSetGuestWakeKey (mInstance , keyIndex, &key);
4942+
4943+ exit:
4944+ return error;
4945+ }
4946+
4947+ template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_THREAD_DIRECT_GUEST_WAKE_KEY >(void )
4948+ {
4949+ uint8_t keyIndex;
4950+ otError error = OT_ERROR_NONE ;
4951+
4952+ SuccessOrExit (error = mDecoder .ReadUint8 (keyIndex));
4953+ error = otThreadDirectRemoveGuestWakeKey (mInstance , keyIndex);
4954+
4955+ exit:
4956+ return error;
4957+ }
4958+
4959+ #if OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_INITIATOR_ENABLE
4960+ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DIRECT_WAKE_BURST_ACTIVE >(void )
4961+ {
4962+ return mEncoder .WriteBool (otThreadDirectIsWakeBurstActive (mInstance ));
4963+ }
4964+
4965+ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DIRECT_WAKE_FRAME_COUNTER >(void )
4966+ {
4967+ return mEncoder .WriteUint32 (mInstance ->Get <Mac::SubMac>().GetWakeFrameCounter ());
4968+ }
4969+
4970+ template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DIRECT_WAKE_FRAME_COUNTER >(void )
4971+ {
4972+ uint32_t counter;
4973+ otError error = OT_ERROR_NONE ;
4974+
4975+ SuccessOrExit (error = mDecoder .ReadUint32 (counter));
4976+ mInstance ->Get <Mac::SubMac>().SetWakeFrameCounter (counter, /* aSetIfLarger */ false );
4977+
4978+ exit:
4979+ return error;
4980+ }
4981+ #endif // OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_INITIATOR_ENABLE
4982+
4983+ void NcpBase::HandleThreadDirectEvent (otThreadDirectEvent aEvent,
4984+ const otThreadDirectPeerInfo *aPeerInfo,
4985+ void *aContext)
4986+ {
4987+ static_cast <NcpBase *>(aContext)->HandleThreadDirectEvent (aEvent, aPeerInfo);
4988+ }
4989+
4990+ void NcpBase::HandleThreadDirectEvent (otThreadDirectEvent aEvent, const otThreadDirectPeerInfo *aPeerInfo)
4991+ {
4992+ otExtAddress noAddr;
4993+ otError error = OT_ERROR_NONE ;
4994+
4995+ memset (&noAddr, 0 , sizeof (noAddr));
4996+
4997+ SuccessOrExit (error = mEncoder .BeginFrame (SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 , SPINEL_CMD_PROP_VALUE_IS ,
4998+ SPINEL_PROP_THREAD_DIRECT_LINK_EVENT ));
4999+ SuccessOrExit (error = mEncoder .WriteUint8 (static_cast <uint8_t >(aEvent)));
5000+ SuccessOrExit (error = mEncoder .WriteEui64 (aPeerInfo != nullptr ? aPeerInfo->mExtAddress : noAddr));
5001+ SuccessOrExit (error = mEncoder .WriteBool (aEvent != OT_THREAD_DIRECT_EVENT_LINK_FAILED ));
5002+ SuccessOrExit (error = mEncoder .EndFrame ());
5003+
5004+ exit:
5005+ return ;
5006+ }
5007+ #endif // OPENTHREAD_CONFIG_THREAD_DIRECT_WAKE_INITIATOR_ENABLE || ...WAKE_LISTENER_ENABLE
48505008
48515009} // namespace Ncp
48525010} // namespace ot
0 commit comments