xref: /aosp_15_r20/external/openthread/src/ncp/ncp_base_radio.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *    Copyright (c) 2016-2017, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *    All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17*cfb92d14SAndroid Build Coastguard Worker  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*cfb92d14SAndroid Build Coastguard Worker  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*cfb92d14SAndroid Build Coastguard Worker  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20*cfb92d14SAndroid Build Coastguard Worker  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21*cfb92d14SAndroid Build Coastguard Worker  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22*cfb92d14SAndroid Build Coastguard Worker  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23*cfb92d14SAndroid Build Coastguard Worker  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*cfb92d14SAndroid Build Coastguard Worker  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*cfb92d14SAndroid Build Coastguard Worker  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*cfb92d14SAndroid Build Coastguard Worker  */
27*cfb92d14SAndroid Build Coastguard Worker 
28*cfb92d14SAndroid Build Coastguard Worker /**
29*cfb92d14SAndroid Build Coastguard Worker  * @file
30*cfb92d14SAndroid Build Coastguard Worker  *   This file implements raw link required Spinel interface to the OpenThread stack.
31*cfb92d14SAndroid Build Coastguard Worker  */
32*cfb92d14SAndroid Build Coastguard Worker 
33*cfb92d14SAndroid Build Coastguard Worker #include "ncp_base.hpp"
34*cfb92d14SAndroid Build Coastguard Worker 
35*cfb92d14SAndroid Build Coastguard Worker #include <openthread/link.h>
36*cfb92d14SAndroid Build Coastguard Worker #include <openthread/link_raw.h>
37*cfb92d14SAndroid Build Coastguard Worker #include <openthread/ncp.h>
38*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/misc.h>
39*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/multipan.h>
40*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/radio.h>
41*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/time.h>
42*cfb92d14SAndroid Build Coastguard Worker 
43*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
44*cfb92d14SAndroid Build Coastguard Worker #include "common/debug.hpp"
45*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
46*cfb92d14SAndroid Build Coastguard Worker #include "mac/mac_frame.hpp"
47*cfb92d14SAndroid Build Coastguard Worker 
48*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
49*cfb92d14SAndroid Build Coastguard Worker 
50*cfb92d14SAndroid Build Coastguard Worker namespace ot {
51*cfb92d14SAndroid Build Coastguard Worker namespace Ncp {
52*cfb92d14SAndroid Build Coastguard Worker 
53*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_RADIO
HandlePropertyGet(void)54*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_RCP_API_VERSION>(void)
55*cfb92d14SAndroid Build Coastguard Worker {
56*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUintPacked(SPINEL_RCP_API_VERSION);
57*cfb92d14SAndroid Build Coastguard Worker }
58*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)59*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_RCP_MIN_HOST_API_VERSION>(void)
60*cfb92d14SAndroid Build Coastguard Worker {
61*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUintPacked(SPINEL_MIN_HOST_SUPPORTED_RCP_API_VERSION);
62*cfb92d14SAndroid Build Coastguard Worker }
63*cfb92d14SAndroid Build Coastguard Worker #endif
64*cfb92d14SAndroid Build Coastguard Worker 
65*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
66*cfb92d14SAndroid Build Coastguard Worker // MARK: Raw Link-Layer Datapath Glue
67*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
68*cfb92d14SAndroid Build Coastguard Worker 
PackRadioFrame(otRadioFrame * aFrame,otError aError)69*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::PackRadioFrame(otRadioFrame *aFrame, otError aError)
70*cfb92d14SAndroid Build Coastguard Worker {
71*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_FAILED;
72*cfb92d14SAndroid Build Coastguard Worker     uint16_t flags = 0;
73*cfb92d14SAndroid Build Coastguard Worker 
74*cfb92d14SAndroid Build Coastguard Worker     if (aFrame != nullptr && aError == OT_ERROR_NONE)
75*cfb92d14SAndroid Build Coastguard Worker     {
76*cfb92d14SAndroid Build Coastguard Worker         // Append the frame contents
77*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(mEncoder.WriteDataWithLen(aFrame->mPsdu, aFrame->mLength));
78*cfb92d14SAndroid Build Coastguard Worker     }
79*cfb92d14SAndroid Build Coastguard Worker     else
80*cfb92d14SAndroid Build Coastguard Worker     {
81*cfb92d14SAndroid Build Coastguard Worker         // Append length
82*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(mEncoder.WriteUint16(0));
83*cfb92d14SAndroid Build Coastguard Worker     }
84*cfb92d14SAndroid Build Coastguard Worker 
85*cfb92d14SAndroid Build Coastguard Worker     // Append metadata (rssi, etc)
86*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteInt8(aFrame ? aFrame->mInfo.mRxInfo.mRssi : 0)); // RSSI
87*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteInt8(-128));                                     // Noise Floor (Currently unused)
88*cfb92d14SAndroid Build Coastguard Worker 
89*cfb92d14SAndroid Build Coastguard Worker     if (aFrame != nullptr)
90*cfb92d14SAndroid Build Coastguard Worker     {
91*cfb92d14SAndroid Build Coastguard Worker         if (aFrame->mInfo.mRxInfo.mAckedWithFramePending)
92*cfb92d14SAndroid Build Coastguard Worker         {
93*cfb92d14SAndroid Build Coastguard Worker             flags |= SPINEL_MD_FLAG_ACKED_FP;
94*cfb92d14SAndroid Build Coastguard Worker         }
95*cfb92d14SAndroid Build Coastguard Worker 
96*cfb92d14SAndroid Build Coastguard Worker         if (aFrame->mInfo.mRxInfo.mAckedWithSecEnhAck)
97*cfb92d14SAndroid Build Coastguard Worker         {
98*cfb92d14SAndroid Build Coastguard Worker             flags |= SPINEL_MD_FLAG_ACKED_SEC;
99*cfb92d14SAndroid Build Coastguard Worker         }
100*cfb92d14SAndroid Build Coastguard Worker     }
101*cfb92d14SAndroid Build Coastguard Worker 
102*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint16(flags)); // Flags
103*cfb92d14SAndroid Build Coastguard Worker 
104*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.OpenStruct());                              // PHY-data
105*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(aFrame ? aFrame->mChannel : 0)); // 802.15.4 channel (Receive channel)
106*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(aFrame ? aFrame->mInfo.mRxInfo.mLqi
107*cfb92d14SAndroid Build Coastguard Worker                                              : static_cast<uint8_t>(OT_RADIO_LQI_NONE))); // 802.15.4 LQI
108*cfb92d14SAndroid Build Coastguard Worker 
109*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint64(aFrame ? aFrame->mInfo.mRxInfo.mTimestamp : 0)); // The timestamp in microseconds
110*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.CloseStruct());
111*cfb92d14SAndroid Build Coastguard Worker 
112*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.OpenStruct());            // Vendor-data
113*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUintPacked(aError)); // Receive error
114*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.CloseStruct());
115*cfb92d14SAndroid Build Coastguard Worker 
116*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.OpenStruct());                                             // MAC-data
117*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(aFrame ? aFrame->mInfo.mRxInfo.mAckKeyId : 0)); // The ACK auxiliary key ID
118*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(
119*cfb92d14SAndroid Build Coastguard Worker         mEncoder.WriteUint32(aFrame ? aFrame->mInfo.mRxInfo.mAckFrameCounter : 0)); // The ACK auxiliary frame counter
120*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.CloseStruct());
121*cfb92d14SAndroid Build Coastguard Worker 
122*cfb92d14SAndroid Build Coastguard Worker     error = OT_ERROR_NONE;
123*cfb92d14SAndroid Build Coastguard Worker 
124*cfb92d14SAndroid Build Coastguard Worker exit:
125*cfb92d14SAndroid Build Coastguard Worker     return error;
126*cfb92d14SAndroid Build Coastguard Worker }
127*cfb92d14SAndroid Build Coastguard Worker 
128*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
NotifySwitchoverDone(otInstance * aInstance,bool aSuccess)129*cfb92d14SAndroid Build Coastguard Worker void NcpBase::NotifySwitchoverDone(otInstance *aInstance, bool aSuccess)
130*cfb92d14SAndroid Build Coastguard Worker {
131*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aInstance);
132*cfb92d14SAndroid Build Coastguard Worker     NotifySwitchoverDone(aSuccess);
133*cfb92d14SAndroid Build Coastguard Worker }
134*cfb92d14SAndroid Build Coastguard Worker 
NotifySwitchoverDone(bool aSuccess)135*cfb92d14SAndroid Build Coastguard Worker void NcpBase::NotifySwitchoverDone(bool aSuccess)
136*cfb92d14SAndroid Build Coastguard Worker {
137*cfb92d14SAndroid Build Coastguard Worker     uint8_t         header = SPINEL_HEADER_FLAG | SPINEL_HEADER_TX_NOTIFICATION_IID;
138*cfb92d14SAndroid Build Coastguard Worker     spinel_status_t result = aSuccess ? SPINEL_STATUS_SWITCHOVER_DONE : SPINEL_STATUS_SWITCHOVER_FAILED;
139*cfb92d14SAndroid Build Coastguard Worker 
140*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(WriteLastStatusFrame(header, result));
141*cfb92d14SAndroid Build Coastguard Worker }
142*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
143*cfb92d14SAndroid Build Coastguard Worker 
LinkRawReceiveDone(otInstance * aInstance,otRadioFrame * aFrame,otError aError)144*cfb92d14SAndroid Build Coastguard Worker void NcpBase::LinkRawReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError)
145*cfb92d14SAndroid Build Coastguard Worker {
146*cfb92d14SAndroid Build Coastguard Worker     sNcpInstance->LinkRawReceiveDone(GetNcpBaseIid(aInstance), aFrame, aError);
147*cfb92d14SAndroid Build Coastguard Worker }
148*cfb92d14SAndroid Build Coastguard Worker 
LinkRawReceiveDone(uint8_t aIid,otRadioFrame * aFrame,otError aError)149*cfb92d14SAndroid Build Coastguard Worker void NcpBase::LinkRawReceiveDone(uint8_t aIid, otRadioFrame *aFrame, otError aError)
150*cfb92d14SAndroid Build Coastguard Worker {
151*cfb92d14SAndroid Build Coastguard Worker     uint8_t header = SPINEL_HEADER_FLAG;
152*cfb92d14SAndroid Build Coastguard Worker 
153*cfb92d14SAndroid Build Coastguard Worker     header |= SPINEL_HEADER_IID(aIid);
154*cfb92d14SAndroid Build Coastguard Worker     // Append frame header
155*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_STREAM_RAW));
156*cfb92d14SAndroid Build Coastguard Worker 
157*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(PackRadioFrame(aFrame, aError));
158*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
159*cfb92d14SAndroid Build Coastguard Worker 
160*cfb92d14SAndroid Build Coastguard Worker exit:
161*cfb92d14SAndroid Build Coastguard Worker     return;
162*cfb92d14SAndroid Build Coastguard Worker }
163*cfb92d14SAndroid Build Coastguard Worker 
LinkRawTransmitDone(otInstance * aInstance,otRadioFrame * aFrame,otRadioFrame * aAckFrame,otError aError)164*cfb92d14SAndroid Build Coastguard Worker void NcpBase::LinkRawTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
165*cfb92d14SAndroid Build Coastguard Worker {
166*cfb92d14SAndroid Build Coastguard Worker     sNcpInstance->LinkRawTransmitDone(GetNcpBaseIid(aInstance), aFrame, aAckFrame, aError);
167*cfb92d14SAndroid Build Coastguard Worker }
168*cfb92d14SAndroid Build Coastguard Worker 
LinkRawTransmitDone(uint8_t aIid,otRadioFrame * aFrame,otRadioFrame * aAckFrame,otError aError)169*cfb92d14SAndroid Build Coastguard Worker void NcpBase::LinkRawTransmitDone(uint8_t aIid, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError)
170*cfb92d14SAndroid Build Coastguard Worker {
171*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aFrame);
172*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT(aIid < kSpinelInterfaceCount);
173*cfb92d14SAndroid Build Coastguard Worker 
174*cfb92d14SAndroid Build Coastguard Worker     if (mCurTransmitTID[aIid])
175*cfb92d14SAndroid Build Coastguard Worker     {
176*cfb92d14SAndroid Build Coastguard Worker         uint8_t header        = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID(aIid) | mCurTransmitTID[aIid];
177*cfb92d14SAndroid Build Coastguard Worker         bool    framePending  = (aAckFrame != nullptr && static_cast<Mac::RxFrame *>(aAckFrame)->GetFramePending());
178*cfb92d14SAndroid Build Coastguard Worker         bool    headerUpdated = static_cast<Mac::TxFrame *>(aFrame)->IsHeaderUpdated();
179*cfb92d14SAndroid Build Coastguard Worker 
180*cfb92d14SAndroid Build Coastguard Worker         // Clear cached transmit TID
181*cfb92d14SAndroid Build Coastguard Worker         mCurTransmitTID[aIid] = 0;
182*cfb92d14SAndroid Build Coastguard Worker 
183*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_LAST_STATUS));
184*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(mEncoder.WriteUintPacked(ThreadErrorToSpinelStatus(aError)));
185*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(mEncoder.WriteBool(framePending));
186*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(mEncoder.WriteBool(headerUpdated));
187*cfb92d14SAndroid Build Coastguard Worker 
188*cfb92d14SAndroid Build Coastguard Worker         if (aError == OT_ERROR_NONE)
189*cfb92d14SAndroid Build Coastguard Worker         {
190*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(PackRadioFrame(aAckFrame, aError));
191*cfb92d14SAndroid Build Coastguard Worker         }
192*cfb92d14SAndroid Build Coastguard Worker 
193*cfb92d14SAndroid Build Coastguard Worker         if (static_cast<Mac::TxFrame *>(aFrame)->GetSecurityEnabled() && headerUpdated)
194*cfb92d14SAndroid Build Coastguard Worker         {
195*cfb92d14SAndroid Build Coastguard Worker             uint8_t  keyId;
196*cfb92d14SAndroid Build Coastguard Worker             uint32_t frameCounter;
197*cfb92d14SAndroid Build Coastguard Worker 
198*cfb92d14SAndroid Build Coastguard Worker             // Transmit frame auxiliary key index and frame counter
199*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(static_cast<Mac::TxFrame *>(aFrame)->GetKeyId(keyId));
200*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(static_cast<Mac::TxFrame *>(aFrame)->GetFrameCounter(frameCounter));
201*cfb92d14SAndroid Build Coastguard Worker 
202*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(mEncoder.WriteUint8(keyId));
203*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(mEncoder.WriteUint32(frameCounter));
204*cfb92d14SAndroid Build Coastguard Worker         }
205*cfb92d14SAndroid Build Coastguard Worker 
206*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(mEncoder.EndFrame());
207*cfb92d14SAndroid Build Coastguard Worker     }
208*cfb92d14SAndroid Build Coastguard Worker 
209*cfb92d14SAndroid Build Coastguard Worker exit:
210*cfb92d14SAndroid Build Coastguard Worker     return;
211*cfb92d14SAndroid Build Coastguard Worker }
212*cfb92d14SAndroid Build Coastguard Worker 
LinkRawEnergyScanDone(otInstance * aInstance,int8_t aEnergyScanMaxRssi)213*cfb92d14SAndroid Build Coastguard Worker void NcpBase::LinkRawEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi)
214*cfb92d14SAndroid Build Coastguard Worker {
215*cfb92d14SAndroid Build Coastguard Worker     sNcpInstance->LinkRawEnergyScanDone(GetNcpBaseIid(aInstance), aEnergyScanMaxRssi);
216*cfb92d14SAndroid Build Coastguard Worker }
217*cfb92d14SAndroid Build Coastguard Worker 
LinkRawEnergyScanDone(uint8_t aIid,int8_t aEnergyScanMaxRssi)218*cfb92d14SAndroid Build Coastguard Worker void NcpBase::LinkRawEnergyScanDone(uint8_t aIid, int8_t aEnergyScanMaxRssi)
219*cfb92d14SAndroid Build Coastguard Worker {
220*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT(aIid < kSpinelInterfaceCount);
221*cfb92d14SAndroid Build Coastguard Worker     int8_t scanChannel = mCurScanChannel[aIid];
222*cfb92d14SAndroid Build Coastguard Worker 
223*cfb92d14SAndroid Build Coastguard Worker     // Clear current scan channel
224*cfb92d14SAndroid Build Coastguard Worker     mCurScanChannel[aIid] = kInvalidScanChannel;
225*cfb92d14SAndroid Build Coastguard Worker 
226*cfb92d14SAndroid Build Coastguard Worker     // Make sure we are back listening on the original receive channel,
227*cfb92d14SAndroid Build Coastguard Worker     // since the energy scan could have been on a different channel.
228*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otLinkRawReceive(IidToInstance(aIid)));
229*cfb92d14SAndroid Build Coastguard Worker 
230*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID(aIid), SPINEL_CMD_PROP_VALUE_IS,
231*cfb92d14SAndroid Build Coastguard Worker                                       SPINEL_PROP_MAC_ENERGY_SCAN_RESULT));
232*cfb92d14SAndroid Build Coastguard Worker 
233*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(static_cast<uint8_t>(scanChannel)));
234*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteInt8(aEnergyScanMaxRssi));
235*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
236*cfb92d14SAndroid Build Coastguard Worker 
237*cfb92d14SAndroid Build Coastguard Worker     // We are finished with the scan, so send out
238*cfb92d14SAndroid Build Coastguard Worker     // a property update indicating such.
239*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID(aIid), SPINEL_CMD_PROP_VALUE_IS,
240*cfb92d14SAndroid Build Coastguard Worker                                       SPINEL_PROP_MAC_SCAN_STATE));
241*cfb92d14SAndroid Build Coastguard Worker 
242*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(SPINEL_SCAN_STATE_IDLE));
243*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
244*cfb92d14SAndroid Build Coastguard Worker 
245*cfb92d14SAndroid Build Coastguard Worker exit:
246*cfb92d14SAndroid Build Coastguard Worker     return;
247*cfb92d14SAndroid Build Coastguard Worker }
248*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)249*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_RADIO_CAPS>(void)
250*cfb92d14SAndroid Build Coastguard Worker {
251*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUintPacked(otLinkRawGetCaps(mInstance));
252*cfb92d14SAndroid Build Coastguard Worker }
253*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)254*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_SRC_MATCH_ENABLED>(void)
255*cfb92d14SAndroid Build Coastguard Worker {
256*cfb92d14SAndroid Build Coastguard Worker     // TODO: Would be good to add an `otLinkRaw` API to give the status of source match.
257*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(mSrcMatchEnabled[mCurCommandIid]);
258*cfb92d14SAndroid Build Coastguard Worker }
259*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)260*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_RCP_TIMESTAMP>(void)
261*cfb92d14SAndroid Build Coastguard Worker {
262*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
263*cfb92d14SAndroid Build Coastguard Worker 
264*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint64(otLinkRawGetRadioTime(mInstance)));
265*cfb92d14SAndroid Build Coastguard Worker 
266*cfb92d14SAndroid Build Coastguard Worker exit:
267*cfb92d14SAndroid Build Coastguard Worker     return error;
268*cfb92d14SAndroid Build Coastguard Worker }
269*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)270*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_SRC_MATCH_ENABLED>(void)
271*cfb92d14SAndroid Build Coastguard Worker {
272*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
273*cfb92d14SAndroid Build Coastguard Worker 
274*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(mSrcMatchEnabled[mCurCommandIid]));
275*cfb92d14SAndroid Build Coastguard Worker 
276*cfb92d14SAndroid Build Coastguard Worker     error = otLinkRawSrcMatchEnable(mInstance, mSrcMatchEnabled[mCurCommandIid]);
277*cfb92d14SAndroid Build Coastguard Worker 
278*cfb92d14SAndroid Build Coastguard Worker exit:
279*cfb92d14SAndroid Build Coastguard Worker     return error;
280*cfb92d14SAndroid Build Coastguard Worker }
281*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)282*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES>(void)
283*cfb92d14SAndroid Build Coastguard Worker {
284*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
285*cfb92d14SAndroid Build Coastguard Worker 
286*cfb92d14SAndroid Build Coastguard Worker     // Clear the list first
287*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otLinkRawSrcMatchClearShortEntries(mInstance));
288*cfb92d14SAndroid Build Coastguard Worker 
289*cfb92d14SAndroid Build Coastguard Worker     // Loop through the addresses and add them
290*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct() >= sizeof(uint16_t))
291*cfb92d14SAndroid Build Coastguard Worker     {
292*cfb92d14SAndroid Build Coastguard Worker         uint16_t shortAddress;
293*cfb92d14SAndroid Build Coastguard Worker 
294*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUint16(shortAddress));
295*cfb92d14SAndroid Build Coastguard Worker 
296*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otLinkRawSrcMatchAddShortEntry(mInstance, shortAddress));
297*cfb92d14SAndroid Build Coastguard Worker     }
298*cfb92d14SAndroid Build Coastguard Worker 
299*cfb92d14SAndroid Build Coastguard Worker exit:
300*cfb92d14SAndroid Build Coastguard Worker     return error;
301*cfb92d14SAndroid Build Coastguard Worker }
302*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)303*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES>(void)
304*cfb92d14SAndroid Build Coastguard Worker {
305*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
306*cfb92d14SAndroid Build Coastguard Worker 
307*cfb92d14SAndroid Build Coastguard Worker     // Clear the list first
308*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otLinkRawSrcMatchClearExtEntries(mInstance));
309*cfb92d14SAndroid Build Coastguard Worker 
310*cfb92d14SAndroid Build Coastguard Worker     // Loop through the addresses and add them
311*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct() >= sizeof(otExtAddress))
312*cfb92d14SAndroid Build Coastguard Worker     {
313*cfb92d14SAndroid Build Coastguard Worker         const otExtAddress *extAddress;
314*cfb92d14SAndroid Build Coastguard Worker 
315*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
316*cfb92d14SAndroid Build Coastguard Worker 
317*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otLinkRawSrcMatchAddExtEntry(mInstance, extAddress));
318*cfb92d14SAndroid Build Coastguard Worker     }
319*cfb92d14SAndroid Build Coastguard Worker 
320*cfb92d14SAndroid Build Coastguard Worker exit:
321*cfb92d14SAndroid Build Coastguard Worker     return error;
322*cfb92d14SAndroid Build Coastguard Worker }
323*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)324*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES>(void)
325*cfb92d14SAndroid Build Coastguard Worker {
326*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
327*cfb92d14SAndroid Build Coastguard Worker     uint16_t shortAddress;
328*cfb92d14SAndroid Build Coastguard Worker 
329*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(shortAddress));
330*cfb92d14SAndroid Build Coastguard Worker 
331*cfb92d14SAndroid Build Coastguard Worker     error = otLinkRawSrcMatchClearShortEntry(mInstance, shortAddress);
332*cfb92d14SAndroid Build Coastguard Worker 
333*cfb92d14SAndroid Build Coastguard Worker exit:
334*cfb92d14SAndroid Build Coastguard Worker     return error;
335*cfb92d14SAndroid Build Coastguard Worker }
336*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)337*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES>(void)
338*cfb92d14SAndroid Build Coastguard Worker {
339*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
340*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress;
341*cfb92d14SAndroid Build Coastguard Worker 
342*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
343*cfb92d14SAndroid Build Coastguard Worker     ;
344*cfb92d14SAndroid Build Coastguard Worker 
345*cfb92d14SAndroid Build Coastguard Worker     error = otLinkRawSrcMatchClearExtEntry(mInstance, extAddress);
346*cfb92d14SAndroid Build Coastguard Worker 
347*cfb92d14SAndroid Build Coastguard Worker exit:
348*cfb92d14SAndroid Build Coastguard Worker     return error;
349*cfb92d14SAndroid Build Coastguard Worker }
350*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)351*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES>(void)
352*cfb92d14SAndroid Build Coastguard Worker {
353*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
354*cfb92d14SAndroid Build Coastguard Worker     uint16_t shortAddress;
355*cfb92d14SAndroid Build Coastguard Worker 
356*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(shortAddress));
357*cfb92d14SAndroid Build Coastguard Worker 
358*cfb92d14SAndroid Build Coastguard Worker     error = otLinkRawSrcMatchAddShortEntry(mInstance, shortAddress);
359*cfb92d14SAndroid Build Coastguard Worker 
360*cfb92d14SAndroid Build Coastguard Worker exit:
361*cfb92d14SAndroid Build Coastguard Worker     return error;
362*cfb92d14SAndroid Build Coastguard Worker }
363*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)364*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES>(void)
365*cfb92d14SAndroid Build Coastguard Worker {
366*cfb92d14SAndroid Build Coastguard Worker     otError             error      = OT_ERROR_NONE;
367*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress = nullptr;
368*cfb92d14SAndroid Build Coastguard Worker 
369*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
370*cfb92d14SAndroid Build Coastguard Worker 
371*cfb92d14SAndroid Build Coastguard Worker     error = otLinkRawSrcMatchAddExtEntry(mInstance, extAddress);
372*cfb92d14SAndroid Build Coastguard Worker 
373*cfb92d14SAndroid Build Coastguard Worker exit:
374*cfb92d14SAndroid Build Coastguard Worker     return error;
375*cfb92d14SAndroid Build Coastguard Worker }
376*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)377*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_PHY_ENABLED>(void)
378*cfb92d14SAndroid Build Coastguard Worker {
379*cfb92d14SAndroid Build Coastguard Worker     bool    value = false;
380*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
381*cfb92d14SAndroid Build Coastguard Worker 
382*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(value));
383*cfb92d14SAndroid Build Coastguard Worker 
384*cfb92d14SAndroid Build Coastguard Worker     if (!value)
385*cfb92d14SAndroid Build Coastguard Worker     {
386*cfb92d14SAndroid Build Coastguard Worker         error = otLinkRawSetReceiveDone(mInstance, nullptr);
387*cfb92d14SAndroid Build Coastguard Worker     }
388*cfb92d14SAndroid Build Coastguard Worker     else
389*cfb92d14SAndroid Build Coastguard Worker     {
390*cfb92d14SAndroid Build Coastguard Worker         error = otLinkRawSetReceiveDone(mInstance, &NcpBase::LinkRawReceiveDone);
391*cfb92d14SAndroid Build Coastguard Worker     }
392*cfb92d14SAndroid Build Coastguard Worker 
393*cfb92d14SAndroid Build Coastguard Worker exit:
394*cfb92d14SAndroid Build Coastguard Worker     return error;
395*cfb92d14SAndroid Build Coastguard Worker }
396*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)397*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_15_4_SADDR>(void)
398*cfb92d14SAndroid Build Coastguard Worker {
399*cfb92d14SAndroid Build Coastguard Worker     uint16_t shortAddress;
400*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
401*cfb92d14SAndroid Build Coastguard Worker 
402*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(shortAddress));
403*cfb92d14SAndroid Build Coastguard Worker 
404*cfb92d14SAndroid Build Coastguard Worker     error = otLinkRawSetShortAddress(mInstance, shortAddress);
405*cfb92d14SAndroid Build Coastguard Worker 
406*cfb92d14SAndroid Build Coastguard Worker exit:
407*cfb92d14SAndroid Build Coastguard Worker     return error;
408*cfb92d14SAndroid Build Coastguard Worker }
409*cfb92d14SAndroid Build Coastguard Worker 
410*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
HandlePropertySet(void)411*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MULTIPAN_ACTIVE_INTERFACE>(void)
412*cfb92d14SAndroid Build Coastguard Worker {
413*cfb92d14SAndroid Build Coastguard Worker     uint8_t   interface;
414*cfb92d14SAndroid Build Coastguard Worker     Instance *instance;
415*cfb92d14SAndroid Build Coastguard Worker     bool      softSwitch;
416*cfb92d14SAndroid Build Coastguard Worker     otError   error = OT_ERROR_NONE;
417*cfb92d14SAndroid Build Coastguard Worker 
418*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(interface));
419*cfb92d14SAndroid Build Coastguard Worker     softSwitch = (interface & SPINEL_MULTIPAN_INTERFACE_SOFT_SWITCH_MASK) != 0;
420*cfb92d14SAndroid Build Coastguard Worker     instance   = IidToInstance(interface & SPINEL_MULTIPAN_INTERFACE_ID_MASK);
421*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(instance != nullptr, error = OT_ERROR_NOT_IMPLEMENTED); // Instance out of range
422*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otPlatMultipanSetActiveInstance(instance, softSwitch));
423*cfb92d14SAndroid Build Coastguard Worker 
424*cfb92d14SAndroid Build Coastguard Worker exit:
425*cfb92d14SAndroid Build Coastguard Worker     return error;
426*cfb92d14SAndroid Build Coastguard Worker }
427*cfb92d14SAndroid Build Coastguard Worker #endif /* OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE */
428*cfb92d14SAndroid Build Coastguard Worker 
DecodeStreamRawTxRequest(otRadioFrame & aFrame)429*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::DecodeStreamRawTxRequest(otRadioFrame &aFrame)
430*cfb92d14SAndroid Build Coastguard Worker {
431*cfb92d14SAndroid Build Coastguard Worker     otError        error;
432*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *payloadPtr;
433*cfb92d14SAndroid Build Coastguard Worker     uint16_t       payloadLen;
434*cfb92d14SAndroid Build Coastguard Worker     bool           csmaEnable;
435*cfb92d14SAndroid Build Coastguard Worker     bool           isARetx;
436*cfb92d14SAndroid Build Coastguard Worker     bool           isHeaderUpdated;
437*cfb92d14SAndroid Build Coastguard Worker     bool           isSecurityProcessed;
438*cfb92d14SAndroid Build Coastguard Worker 
439*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(payloadPtr, payloadLen));
440*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(payloadLen <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_PARSE);
441*cfb92d14SAndroid Build Coastguard Worker 
442*cfb92d14SAndroid Build Coastguard Worker     aFrame.mLength = static_cast<uint8_t>(payloadLen);
443*cfb92d14SAndroid Build Coastguard Worker     memcpy(aFrame.mPsdu, payloadPtr, aFrame.mLength);
444*cfb92d14SAndroid Build Coastguard Worker 
445*cfb92d14SAndroid Build Coastguard Worker     // Parse the meta data
446*cfb92d14SAndroid Build Coastguard Worker 
447*cfb92d14SAndroid Build Coastguard Worker     // Channel is a required parameter in meta data.
448*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(aFrame.mChannel));
449*cfb92d14SAndroid Build Coastguard Worker 
450*cfb92d14SAndroid Build Coastguard Worker     // Set the default value for all optional parameters.
451*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mRxChannelAfterTxDone = aFrame.mChannel;
452*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs      = OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT;
453*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mMaxFrameRetries      = OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT;
454*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mCsmaCaEnabled        = true;
455*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mIsHeaderUpdated      = false;
456*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mIsARetx              = false;
457*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mIsSecurityProcessed  = false;
458*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mTxDelay              = 0;
459*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mTxDelayBaseTime      = 0;
460*cfb92d14SAndroid Build Coastguard Worker 
461*cfb92d14SAndroid Build Coastguard Worker     // All the next parameters are optional. Note that even if the
462*cfb92d14SAndroid Build Coastguard Worker     // decoder fails to parse any of optional parameters we still want to
463*cfb92d14SAndroid Build Coastguard Worker     // return `OT_ERROR_NONE` (so `error` is not updated after this
464*cfb92d14SAndroid Build Coastguard Worker     // point).
465*cfb92d14SAndroid Build Coastguard Worker 
466*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs));
467*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxFrameRetries));
468*cfb92d14SAndroid Build Coastguard Worker 
469*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadBool(csmaEnable));
470*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mCsmaCaEnabled = csmaEnable;
471*cfb92d14SAndroid Build Coastguard Worker 
472*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadBool(isHeaderUpdated));
473*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mIsHeaderUpdated = isHeaderUpdated;
474*cfb92d14SAndroid Build Coastguard Worker 
475*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadBool(isARetx));
476*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mIsARetx = isARetx;
477*cfb92d14SAndroid Build Coastguard Worker 
478*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadBool(isSecurityProcessed));
479*cfb92d14SAndroid Build Coastguard Worker     aFrame.mInfo.mTxInfo.mIsSecurityProcessed = isSecurityProcessed;
480*cfb92d14SAndroid Build Coastguard Worker 
481*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadUint32(aFrame.mInfo.mTxInfo.mTxDelay));
482*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadUint32(aFrame.mInfo.mTxInfo.mTxDelayBaseTime));
483*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mRxChannelAfterTxDone));
484*cfb92d14SAndroid Build Coastguard Worker 
485*cfb92d14SAndroid Build Coastguard Worker exit:
486*cfb92d14SAndroid Build Coastguard Worker     return error;
487*cfb92d14SAndroid Build Coastguard Worker }
488*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet_SPINEL_PROP_STREAM_RAW(uint8_t aHeader)489*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::HandlePropertySet_SPINEL_PROP_STREAM_RAW(uint8_t aHeader)
490*cfb92d14SAndroid Build Coastguard Worker {
491*cfb92d14SAndroid Build Coastguard Worker     otError       error = OT_ERROR_NONE;
492*cfb92d14SAndroid Build Coastguard Worker     uint8_t       iid   = SPINEL_HEADER_GET_IID(aHeader);
493*cfb92d14SAndroid Build Coastguard Worker     otRadioFrame *frame;
494*cfb92d14SAndroid Build Coastguard Worker 
495*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT(iid < kSpinelInterfaceCount);
496*cfb92d14SAndroid Build Coastguard Worker 
497*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(otLinkRawIsEnabled(mInstance), error = OT_ERROR_INVALID_STATE);
498*cfb92d14SAndroid Build Coastguard Worker 
499*cfb92d14SAndroid Build Coastguard Worker     frame = otLinkRawGetTransmitBuffer(mInstance);
500*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(frame != nullptr, error = OT_ERROR_NO_BUFS);
501*cfb92d14SAndroid Build Coastguard Worker 
502*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeStreamRawTxRequest(*frame));
503*cfb92d14SAndroid Build Coastguard Worker 
504*cfb92d14SAndroid Build Coastguard Worker     // Pass frame to the radio layer. Note, this fails if we
505*cfb92d14SAndroid Build Coastguard Worker     // haven't enabled raw stream or are already transmitting.
506*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otLinkRawTransmit(mInstance, &NcpBase::LinkRawTransmitDone));
507*cfb92d14SAndroid Build Coastguard Worker 
508*cfb92d14SAndroid Build Coastguard Worker     // Cache the transaction ID for async response
509*cfb92d14SAndroid Build Coastguard Worker     mCurTransmitTID[iid] = SPINEL_HEADER_GET_TID(aHeader);
510*cfb92d14SAndroid Build Coastguard Worker 
511*cfb92d14SAndroid Build Coastguard Worker exit:
512*cfb92d14SAndroid Build Coastguard Worker 
513*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NONE)
514*cfb92d14SAndroid Build Coastguard Worker     {
515*cfb92d14SAndroid Build Coastguard Worker         // Don't do anything here yet. We will complete the transaction when we get a transmit done callback
516*cfb92d14SAndroid Build Coastguard Worker     }
517*cfb92d14SAndroid Build Coastguard Worker     else
518*cfb92d14SAndroid Build Coastguard Worker     {
519*cfb92d14SAndroid Build Coastguard Worker         error = WriteLastStatusFrame(aHeader, ThreadErrorToSpinelStatus(error));
520*cfb92d14SAndroid Build Coastguard Worker     }
521*cfb92d14SAndroid Build Coastguard Worker 
522*cfb92d14SAndroid Build Coastguard Worker     return error;
523*cfb92d14SAndroid Build Coastguard Worker }
524*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)525*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_MAC_KEY>(void)
526*cfb92d14SAndroid Build Coastguard Worker {
527*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_NONE;
528*cfb92d14SAndroid Build Coastguard Worker     uint8_t        keyIdMode;
529*cfb92d14SAndroid Build Coastguard Worker     uint8_t        keyId;
530*cfb92d14SAndroid Build Coastguard Worker     uint16_t       keySize;
531*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *prevKey;
532*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *currKey;
533*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *nextKey;
534*cfb92d14SAndroid Build Coastguard Worker 
535*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(keyIdMode));
536*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(keyIdMode == Mac::Frame::kKeyIdMode1, error = OT_ERROR_INVALID_ARGS);
537*cfb92d14SAndroid Build Coastguard Worker 
538*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(keyId));
539*cfb92d14SAndroid Build Coastguard Worker 
540*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(prevKey, keySize));
541*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
542*cfb92d14SAndroid Build Coastguard Worker 
543*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(currKey, keySize));
544*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
545*cfb92d14SAndroid Build Coastguard Worker 
546*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(nextKey, keySize));
547*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(keySize == sizeof(otMacKey), error = OT_ERROR_INVALID_ARGS);
548*cfb92d14SAndroid Build Coastguard Worker 
549*cfb92d14SAndroid Build Coastguard Worker     error =
550*cfb92d14SAndroid Build Coastguard Worker         otLinkRawSetMacKey(mInstance, keyIdMode, keyId, reinterpret_cast<const otMacKey *>(prevKey),
551*cfb92d14SAndroid Build Coastguard Worker                            reinterpret_cast<const otMacKey *>(currKey), reinterpret_cast<const otMacKey *>(nextKey));
552*cfb92d14SAndroid Build Coastguard Worker 
553*cfb92d14SAndroid Build Coastguard Worker exit:
554*cfb92d14SAndroid Build Coastguard Worker     return error;
555*cfb92d14SAndroid Build Coastguard Worker }
556*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)557*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_MAC_FRAME_COUNTER>(void)
558*cfb92d14SAndroid Build Coastguard Worker {
559*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
560*cfb92d14SAndroid Build Coastguard Worker     uint32_t frameCounter;
561*cfb92d14SAndroid Build Coastguard Worker     bool     setIfLarger = false;
562*cfb92d14SAndroid Build Coastguard Worker 
563*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(frameCounter));
564*cfb92d14SAndroid Build Coastguard Worker 
565*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllReadInStruct())
566*cfb92d14SAndroid Build Coastguard Worker     {
567*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadBool(setIfLarger));
568*cfb92d14SAndroid Build Coastguard Worker     }
569*cfb92d14SAndroid Build Coastguard Worker 
570*cfb92d14SAndroid Build Coastguard Worker     if (setIfLarger)
571*cfb92d14SAndroid Build Coastguard Worker     {
572*cfb92d14SAndroid Build Coastguard Worker         error = otLinkRawSetMacFrameCounterIfLarger(mInstance, frameCounter);
573*cfb92d14SAndroid Build Coastguard Worker     }
574*cfb92d14SAndroid Build Coastguard Worker     else
575*cfb92d14SAndroid Build Coastguard Worker     {
576*cfb92d14SAndroid Build Coastguard Worker         error = otLinkRawSetMacFrameCounter(mInstance, frameCounter);
577*cfb92d14SAndroid Build Coastguard Worker     }
578*cfb92d14SAndroid Build Coastguard Worker 
579*cfb92d14SAndroid Build Coastguard Worker exit:
580*cfb92d14SAndroid Build Coastguard Worker     return error;
581*cfb92d14SAndroid Build Coastguard Worker }
582*cfb92d14SAndroid Build Coastguard Worker 
583*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE
HandlePropertyGet(void)584*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MULTIPAN_ACTIVE_INTERFACE>(void)
585*cfb92d14SAndroid Build Coastguard Worker {
586*cfb92d14SAndroid Build Coastguard Worker     otInstance  *instance;
587*cfb92d14SAndroid Build Coastguard Worker     spinel_iid_t iid;
588*cfb92d14SAndroid Build Coastguard Worker     otError      error = OT_ERROR_NONE;
589*cfb92d14SAndroid Build Coastguard Worker 
590*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otPlatMultipanGetActiveInstance(&instance));
591*cfb92d14SAndroid Build Coastguard Worker     iid = InstanceToIid(static_cast<Instance *>(instance));
592*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint8(static_cast<uint8_t>(iid)));
593*cfb92d14SAndroid Build Coastguard Worker 
594*cfb92d14SAndroid Build Coastguard Worker exit:
595*cfb92d14SAndroid Build Coastguard Worker     return error;
596*cfb92d14SAndroid Build Coastguard Worker }
597*cfb92d14SAndroid Build Coastguard Worker #endif /* OPENTHREAD_CONFIG_MULTIPAN_RCP_ENABLE */
598*cfb92d14SAndroid Build Coastguard Worker 
599*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
HandlePropertySet(void)600*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_ENH_ACK_PROBING>(void)
601*cfb92d14SAndroid Build Coastguard Worker {
602*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
603*cfb92d14SAndroid Build Coastguard Worker     uint16_t            shortAddress;
604*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress;
605*cfb92d14SAndroid Build Coastguard Worker     otLinkMetrics       linkMetrics = {false, false, false, false, false};
606*cfb92d14SAndroid Build Coastguard Worker 
607*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(shortAddress));
608*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
609*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ true));
610*cfb92d14SAndroid Build Coastguard Worker 
611*cfb92d14SAndroid Build Coastguard Worker     error = otPlatRadioConfigureEnhAckProbing(mInstance, linkMetrics, shortAddress, extAddress);
612*cfb92d14SAndroid Build Coastguard Worker 
613*cfb92d14SAndroid Build Coastguard Worker exit:
614*cfb92d14SAndroid Build Coastguard Worker     return error;
615*cfb92d14SAndroid Build Coastguard Worker }
616*cfb92d14SAndroid Build Coastguard Worker #endif
617*cfb92d14SAndroid Build Coastguard Worker 
618*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
HandlePropertySet(void)619*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_LOG_CRASH_DUMP>(void) { return otPlatLogCrashDump(); }
620*cfb92d14SAndroid Build Coastguard Worker #endif
621*cfb92d14SAndroid Build Coastguard Worker 
622*cfb92d14SAndroid Build Coastguard Worker } // namespace Ncp
623*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
624*cfb92d14SAndroid Build Coastguard Worker 
625*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
626