xref: /aosp_15_r20/external/openthread/src/ncp/ncp_base_mtd.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 minimal thread device required Spinel interface to the OpenThread stack.
31*cfb92d14SAndroid Build Coastguard Worker  */
32*cfb92d14SAndroid Build Coastguard Worker 
33*cfb92d14SAndroid Build Coastguard Worker #include "openthread-core-config.h"
34*cfb92d14SAndroid Build Coastguard Worker 
35*cfb92d14SAndroid Build Coastguard Worker #include "ncp_base.hpp"
36*cfb92d14SAndroid Build Coastguard Worker 
37*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
38*cfb92d14SAndroid Build Coastguard Worker #include <openthread/border_router.h>
39*cfb92d14SAndroid Build Coastguard Worker #endif
40*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
41*cfb92d14SAndroid Build Coastguard Worker #include <openthread/channel_monitor.h>
42*cfb92d14SAndroid Build Coastguard Worker #endif
43*cfb92d14SAndroid Build Coastguard Worker #include <openthread/child_supervision.h>
44*cfb92d14SAndroid Build Coastguard Worker #include <openthread/diag.h>
45*cfb92d14SAndroid Build Coastguard Worker #include <openthread/icmp6.h>
46*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
47*cfb92d14SAndroid Build Coastguard Worker #include <openthread/jam_detection.h>
48*cfb92d14SAndroid Build Coastguard Worker #endif
49*cfb92d14SAndroid Build Coastguard Worker #include <openthread/ncp.h>
50*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
51*cfb92d14SAndroid Build Coastguard Worker #include <openthread/network_time.h>
52*cfb92d14SAndroid Build Coastguard Worker #endif
53*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/misc.h>
54*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/radio.h>
55*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_FTD
56*cfb92d14SAndroid Build Coastguard Worker #include <openthread/thread_ftd.h>
57*cfb92d14SAndroid Build Coastguard Worker #endif
58*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
59*cfb92d14SAndroid Build Coastguard Worker #include <openthread/server.h>
60*cfb92d14SAndroid Build Coastguard Worker #endif
61*cfb92d14SAndroid Build Coastguard Worker #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
62*cfb92d14SAndroid Build Coastguard Worker #include "openthread/backbone_router.h"
63*cfb92d14SAndroid Build Coastguard Worker #endif
64*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE
65*cfb92d14SAndroid Build Coastguard Worker #include <openthread/srp_client_buffers.h>
66*cfb92d14SAndroid Build Coastguard Worker #endif
67*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
68*cfb92d14SAndroid Build Coastguard Worker #include <openthread/trel.h>
69*cfb92d14SAndroid Build Coastguard Worker #endif
70*cfb92d14SAndroid Build Coastguard Worker 
71*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
72*cfb92d14SAndroid Build Coastguard Worker #include "common/debug.hpp"
73*cfb92d14SAndroid Build Coastguard Worker #include "common/string.hpp"
74*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
75*cfb92d14SAndroid Build Coastguard Worker #include "net/ip6.hpp"
76*cfb92d14SAndroid Build Coastguard Worker 
77*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_MTD || OPENTHREAD_FTD
78*cfb92d14SAndroid Build Coastguard Worker 
79*cfb92d14SAndroid Build Coastguard Worker namespace ot {
80*cfb92d14SAndroid Build Coastguard Worker namespace Ncp {
81*cfb92d14SAndroid Build Coastguard Worker 
BorderRouterConfigToFlagByte(const otBorderRouterConfig & aConfig)82*cfb92d14SAndroid Build Coastguard Worker static uint8_t BorderRouterConfigToFlagByte(const otBorderRouterConfig &aConfig)
83*cfb92d14SAndroid Build Coastguard Worker {
84*cfb92d14SAndroid Build Coastguard Worker     uint8_t flags = 0;
85*cfb92d14SAndroid Build Coastguard Worker 
86*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mPreferred)
87*cfb92d14SAndroid Build Coastguard Worker     {
88*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_PREFERRED;
89*cfb92d14SAndroid Build Coastguard Worker     }
90*cfb92d14SAndroid Build Coastguard Worker 
91*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mSlaac)
92*cfb92d14SAndroid Build Coastguard Worker     {
93*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_SLAAC;
94*cfb92d14SAndroid Build Coastguard Worker     }
95*cfb92d14SAndroid Build Coastguard Worker 
96*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mDhcp)
97*cfb92d14SAndroid Build Coastguard Worker     {
98*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_DHCP;
99*cfb92d14SAndroid Build Coastguard Worker     }
100*cfb92d14SAndroid Build Coastguard Worker 
101*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mDefaultRoute)
102*cfb92d14SAndroid Build Coastguard Worker     {
103*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_DEFAULT_ROUTE;
104*cfb92d14SAndroid Build Coastguard Worker     }
105*cfb92d14SAndroid Build Coastguard Worker 
106*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mConfigure)
107*cfb92d14SAndroid Build Coastguard Worker     {
108*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_CONFIGURE;
109*cfb92d14SAndroid Build Coastguard Worker     }
110*cfb92d14SAndroid Build Coastguard Worker 
111*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mOnMesh)
112*cfb92d14SAndroid Build Coastguard Worker     {
113*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_ON_MESH;
114*cfb92d14SAndroid Build Coastguard Worker     }
115*cfb92d14SAndroid Build Coastguard Worker 
116*cfb92d14SAndroid Build Coastguard Worker     flags |= (static_cast<uint8_t>(aConfig.mPreference) << SPINEL_NET_FLAG_PREFERENCE_OFFSET);
117*cfb92d14SAndroid Build Coastguard Worker 
118*cfb92d14SAndroid Build Coastguard Worker     return flags;
119*cfb92d14SAndroid Build Coastguard Worker }
120*cfb92d14SAndroid Build Coastguard Worker 
BorderRouterConfigToFlagByteExtended(const otBorderRouterConfig & aConfig)121*cfb92d14SAndroid Build Coastguard Worker static uint8_t BorderRouterConfigToFlagByteExtended(const otBorderRouterConfig &aConfig)
122*cfb92d14SAndroid Build Coastguard Worker {
123*cfb92d14SAndroid Build Coastguard Worker     uint8_t flags = 0;
124*cfb92d14SAndroid Build Coastguard Worker 
125*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mNdDns)
126*cfb92d14SAndroid Build Coastguard Worker     {
127*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_EXT_DNS;
128*cfb92d14SAndroid Build Coastguard Worker     }
129*cfb92d14SAndroid Build Coastguard Worker 
130*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mDp)
131*cfb92d14SAndroid Build Coastguard Worker     {
132*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_NET_FLAG_EXT_DP;
133*cfb92d14SAndroid Build Coastguard Worker     }
134*cfb92d14SAndroid Build Coastguard Worker 
135*cfb92d14SAndroid Build Coastguard Worker     return flags;
136*cfb92d14SAndroid Build Coastguard Worker }
137*cfb92d14SAndroid Build Coastguard Worker 
ExternalRouteConfigToFlagByte(const otExternalRouteConfig & aConfig)138*cfb92d14SAndroid Build Coastguard Worker static uint8_t ExternalRouteConfigToFlagByte(const otExternalRouteConfig &aConfig)
139*cfb92d14SAndroid Build Coastguard Worker {
140*cfb92d14SAndroid Build Coastguard Worker     uint8_t flags = 0;
141*cfb92d14SAndroid Build Coastguard Worker 
142*cfb92d14SAndroid Build Coastguard Worker     switch (aConfig.mPreference)
143*cfb92d14SAndroid Build Coastguard Worker     {
144*cfb92d14SAndroid Build Coastguard Worker     case OT_ROUTE_PREFERENCE_LOW:
145*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_ROUTE_PREFERENCE_LOW;
146*cfb92d14SAndroid Build Coastguard Worker         break;
147*cfb92d14SAndroid Build Coastguard Worker 
148*cfb92d14SAndroid Build Coastguard Worker     case OT_ROUTE_PREFERENCE_HIGH:
149*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_ROUTE_PREFERENCE_HIGH;
150*cfb92d14SAndroid Build Coastguard Worker         break;
151*cfb92d14SAndroid Build Coastguard Worker 
152*cfb92d14SAndroid Build Coastguard Worker     case OT_ROUTE_PREFERENCE_MED:
153*cfb92d14SAndroid Build Coastguard Worker     default:
154*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_ROUTE_PREFERENCE_MEDIUM;
155*cfb92d14SAndroid Build Coastguard Worker         break;
156*cfb92d14SAndroid Build Coastguard Worker     }
157*cfb92d14SAndroid Build Coastguard Worker 
158*cfb92d14SAndroid Build Coastguard Worker     if (aConfig.mNat64)
159*cfb92d14SAndroid Build Coastguard Worker     {
160*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_ROUTE_FLAG_NAT64;
161*cfb92d14SAndroid Build Coastguard Worker     }
162*cfb92d14SAndroid Build Coastguard Worker 
163*cfb92d14SAndroid Build Coastguard Worker     return flags;
164*cfb92d14SAndroid Build Coastguard Worker }
165*cfb92d14SAndroid Build Coastguard Worker 
LinkFlagsToFlagByte(bool aRxOnWhenIdle,bool aDeviceType,bool aNetworkData)166*cfb92d14SAndroid Build Coastguard Worker uint8_t NcpBase::LinkFlagsToFlagByte(bool aRxOnWhenIdle, bool aDeviceType, bool aNetworkData)
167*cfb92d14SAndroid Build Coastguard Worker {
168*cfb92d14SAndroid Build Coastguard Worker     uint8_t flags(0);
169*cfb92d14SAndroid Build Coastguard Worker 
170*cfb92d14SAndroid Build Coastguard Worker     if (aRxOnWhenIdle)
171*cfb92d14SAndroid Build Coastguard Worker     {
172*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_THREAD_MODE_RX_ON_WHEN_IDLE;
173*cfb92d14SAndroid Build Coastguard Worker     }
174*cfb92d14SAndroid Build Coastguard Worker 
175*cfb92d14SAndroid Build Coastguard Worker     if (aDeviceType)
176*cfb92d14SAndroid Build Coastguard Worker     {
177*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_THREAD_MODE_FULL_THREAD_DEV;
178*cfb92d14SAndroid Build Coastguard Worker     }
179*cfb92d14SAndroid Build Coastguard Worker 
180*cfb92d14SAndroid Build Coastguard Worker     if (aNetworkData)
181*cfb92d14SAndroid Build Coastguard Worker     {
182*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_THREAD_MODE_FULL_NETWORK_DATA;
183*cfb92d14SAndroid Build Coastguard Worker     }
184*cfb92d14SAndroid Build Coastguard Worker 
185*cfb92d14SAndroid Build Coastguard Worker     return flags;
186*cfb92d14SAndroid Build Coastguard Worker }
187*cfb92d14SAndroid Build Coastguard Worker 
EncodeNeighborInfo(const otNeighborInfo & aNeighborInfo)188*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::EncodeNeighborInfo(const otNeighborInfo &aNeighborInfo)
189*cfb92d14SAndroid Build Coastguard Worker {
190*cfb92d14SAndroid Build Coastguard Worker     otError error;
191*cfb92d14SAndroid Build Coastguard Worker     uint8_t modeFlags;
192*cfb92d14SAndroid Build Coastguard Worker 
193*cfb92d14SAndroid Build Coastguard Worker     modeFlags = LinkFlagsToFlagByte(aNeighborInfo.mRxOnWhenIdle, aNeighborInfo.mFullThreadDevice,
194*cfb92d14SAndroid Build Coastguard Worker                                     aNeighborInfo.mFullNetworkData);
195*cfb92d14SAndroid Build Coastguard Worker 
196*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
197*cfb92d14SAndroid Build Coastguard Worker 
198*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteEui64(aNeighborInfo.mExtAddress));
199*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(aNeighborInfo.mRloc16));
200*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(aNeighborInfo.mAge));
201*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint8(aNeighborInfo.mLinkQualityIn));
202*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteInt8(aNeighborInfo.mAverageRssi));
203*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint8(modeFlags));
204*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteBool(aNeighborInfo.mIsChild));
205*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(aNeighborInfo.mLinkFrameCounter));
206*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(aNeighborInfo.mMleFrameCounter));
207*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteInt8(aNeighborInfo.mLastRssi));
208*cfb92d14SAndroid Build Coastguard Worker 
209*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
210*cfb92d14SAndroid Build Coastguard Worker 
211*cfb92d14SAndroid Build Coastguard Worker exit:
212*cfb92d14SAndroid Build Coastguard Worker     return error;
213*cfb92d14SAndroid Build Coastguard Worker }
214*cfb92d14SAndroid Build Coastguard Worker 
215*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
EncodeLinkMetricsValues(const otLinkMetricsValues * aMetricsValues)216*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::EncodeLinkMetricsValues(const otLinkMetricsValues *aMetricsValues)
217*cfb92d14SAndroid Build Coastguard Worker {
218*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
219*cfb92d14SAndroid Build Coastguard Worker 
220*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
221*cfb92d14SAndroid Build Coastguard Worker 
222*cfb92d14SAndroid Build Coastguard Worker     if (aMetricsValues->mMetrics.mPduCount)
223*cfb92d14SAndroid Build Coastguard Worker     {
224*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
225*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_THREAD_LINK_METRIC_PDU_COUNT));
226*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(aMetricsValues->mPduCountValue));
227*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
228*cfb92d14SAndroid Build Coastguard Worker     }
229*cfb92d14SAndroid Build Coastguard Worker 
230*cfb92d14SAndroid Build Coastguard Worker     if (aMetricsValues->mMetrics.mLqi)
231*cfb92d14SAndroid Build Coastguard Worker     {
232*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
233*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_THREAD_LINK_METRIC_LQI));
234*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(aMetricsValues->mLqiValue));
235*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
236*cfb92d14SAndroid Build Coastguard Worker     }
237*cfb92d14SAndroid Build Coastguard Worker 
238*cfb92d14SAndroid Build Coastguard Worker     if (aMetricsValues->mMetrics.mLinkMargin)
239*cfb92d14SAndroid Build Coastguard Worker     {
240*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
241*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_THREAD_LINK_METRIC_LINK_MARGIN));
242*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(aMetricsValues->mLinkMarginValue));
243*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
244*cfb92d14SAndroid Build Coastguard Worker     }
245*cfb92d14SAndroid Build Coastguard Worker 
246*cfb92d14SAndroid Build Coastguard Worker     if (aMetricsValues->mMetrics.mRssi)
247*cfb92d14SAndroid Build Coastguard Worker     {
248*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
249*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(SPINEL_THREAD_LINK_METRIC_RSSI));
250*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteInt8(aMetricsValues->mRssiValue));
251*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
252*cfb92d14SAndroid Build Coastguard Worker     }
253*cfb92d14SAndroid Build Coastguard Worker 
254*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
255*cfb92d14SAndroid Build Coastguard Worker 
256*cfb92d14SAndroid Build Coastguard Worker exit:
257*cfb92d14SAndroid Build Coastguard Worker     return error;
258*cfb92d14SAndroid Build Coastguard Worker }
259*cfb92d14SAndroid Build Coastguard Worker #endif
260*cfb92d14SAndroid Build Coastguard Worker 
261*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
HandlePropertySet(void)262*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_CSL_PERIOD>(void)
263*cfb92d14SAndroid Build Coastguard Worker {
264*cfb92d14SAndroid Build Coastguard Worker     uint32_t cslPeriod;
265*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
266*cfb92d14SAndroid Build Coastguard Worker 
267*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(cslPeriod));
268*cfb92d14SAndroid Build Coastguard Worker 
269*cfb92d14SAndroid Build Coastguard Worker     error = otLinkSetCslPeriod(mInstance, cslPeriod);
270*cfb92d14SAndroid Build Coastguard Worker 
271*cfb92d14SAndroid Build Coastguard Worker exit:
272*cfb92d14SAndroid Build Coastguard Worker     return error;
273*cfb92d14SAndroid Build Coastguard Worker }
274*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)275*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CSL_PERIOD>(void)
276*cfb92d14SAndroid Build Coastguard Worker {
277*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCslPeriod(mInstance));
278*cfb92d14SAndroid Build Coastguard Worker }
279*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)280*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_CSL_TIMEOUT>(void)
281*cfb92d14SAndroid Build Coastguard Worker {
282*cfb92d14SAndroid Build Coastguard Worker     uint32_t cslTimeout;
283*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
284*cfb92d14SAndroid Build Coastguard Worker 
285*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(cslTimeout));
286*cfb92d14SAndroid Build Coastguard Worker 
287*cfb92d14SAndroid Build Coastguard Worker     error = otLinkSetCslTimeout(mInstance, cslTimeout);
288*cfb92d14SAndroid Build Coastguard Worker 
289*cfb92d14SAndroid Build Coastguard Worker exit:
290*cfb92d14SAndroid Build Coastguard Worker     return error;
291*cfb92d14SAndroid Build Coastguard Worker }
292*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)293*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CSL_TIMEOUT>(void)
294*cfb92d14SAndroid Build Coastguard Worker {
295*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCslTimeout(mInstance));
296*cfb92d14SAndroid Build Coastguard Worker }
297*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)298*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_CSL_CHANNEL>(void)
299*cfb92d14SAndroid Build Coastguard Worker {
300*cfb92d14SAndroid Build Coastguard Worker     uint8_t cslChannel;
301*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
302*cfb92d14SAndroid Build Coastguard Worker 
303*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(cslChannel));
304*cfb92d14SAndroid Build Coastguard Worker 
305*cfb92d14SAndroid Build Coastguard Worker     error = otLinkSetCslChannel(mInstance, cslChannel);
306*cfb92d14SAndroid Build Coastguard Worker 
307*cfb92d14SAndroid Build Coastguard Worker exit:
308*cfb92d14SAndroid Build Coastguard Worker     return error;
309*cfb92d14SAndroid Build Coastguard Worker }
310*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)311*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CSL_CHANNEL>(void)
312*cfb92d14SAndroid Build Coastguard Worker {
313*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(otLinkGetCslChannel(mInstance));
314*cfb92d14SAndroid Build Coastguard Worker }
315*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
316*cfb92d14SAndroid Build Coastguard Worker 
317*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
HandlePropertySet(void)318*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MLR_REQUEST>(void)
319*cfb92d14SAndroid Build Coastguard Worker {
320*cfb92d14SAndroid Build Coastguard Worker     otError      error = OT_ERROR_NONE;
321*cfb92d14SAndroid Build Coastguard Worker     otIp6Address addresses[OT_IP6_MAX_MLR_ADDRESSES];
322*cfb92d14SAndroid Build Coastguard Worker     uint8_t      addressesCount = 0U;
323*cfb92d14SAndroid Build Coastguard Worker     bool         timeoutPresent = false;
324*cfb92d14SAndroid Build Coastguard Worker     uint32_t     timeout;
325*cfb92d14SAndroid Build Coastguard Worker 
326*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.OpenStruct());
327*cfb92d14SAndroid Build Coastguard Worker 
328*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct())
329*cfb92d14SAndroid Build Coastguard Worker     {
330*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(addressesCount < Ip6AddressesTlv::kMaxAddresses, error = OT_ERROR_NO_BUFS);
331*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadIp6Address(addresses[addressesCount]));
332*cfb92d14SAndroid Build Coastguard Worker         ++addressesCount;
333*cfb92d14SAndroid Build Coastguard Worker     }
334*cfb92d14SAndroid Build Coastguard Worker 
335*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.CloseStruct());
336*cfb92d14SAndroid Build Coastguard Worker 
337*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct())
338*cfb92d14SAndroid Build Coastguard Worker     {
339*cfb92d14SAndroid Build Coastguard Worker         uint8_t paramId;
340*cfb92d14SAndroid Build Coastguard Worker 
341*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.OpenStruct());
342*cfb92d14SAndroid Build Coastguard Worker 
343*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUint8(paramId));
344*cfb92d14SAndroid Build Coastguard Worker 
345*cfb92d14SAndroid Build Coastguard Worker         switch (paramId)
346*cfb92d14SAndroid Build Coastguard Worker         {
347*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_THREAD_MLR_PARAMID_TIMEOUT:
348*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mDecoder.ReadUint32(timeout));
349*cfb92d14SAndroid Build Coastguard Worker             timeoutPresent = true;
350*cfb92d14SAndroid Build Coastguard Worker             break;
351*cfb92d14SAndroid Build Coastguard Worker 
352*cfb92d14SAndroid Build Coastguard Worker         default:
353*cfb92d14SAndroid Build Coastguard Worker             ExitNow(error = OT_ERROR_INVALID_ARGS);
354*cfb92d14SAndroid Build Coastguard Worker         }
355*cfb92d14SAndroid Build Coastguard Worker 
356*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.CloseStruct());
357*cfb92d14SAndroid Build Coastguard Worker     }
358*cfb92d14SAndroid Build Coastguard Worker 
359*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otIp6RegisterMulticastListeners(mInstance, addresses, addressesCount,
360*cfb92d14SAndroid Build Coastguard Worker                                                           timeoutPresent ? &timeout : nullptr,
361*cfb92d14SAndroid Build Coastguard Worker                                                           &NcpBase::HandleMlrRegResult_Jump, this));
362*cfb92d14SAndroid Build Coastguard Worker exit:
363*cfb92d14SAndroid Build Coastguard Worker     return error;
364*cfb92d14SAndroid Build Coastguard Worker }
365*cfb92d14SAndroid Build Coastguard Worker 
HandleMlrRegResult_Jump(void * aContext,otError aError,uint8_t aMlrStatus,const otIp6Address * aFailedAddresses,uint8_t aFailedAddressNum)366*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleMlrRegResult_Jump(void               *aContext,
367*cfb92d14SAndroid Build Coastguard Worker                                       otError             aError,
368*cfb92d14SAndroid Build Coastguard Worker                                       uint8_t             aMlrStatus,
369*cfb92d14SAndroid Build Coastguard Worker                                       const otIp6Address *aFailedAddresses,
370*cfb92d14SAndroid Build Coastguard Worker                                       uint8_t             aFailedAddressNum)
371*cfb92d14SAndroid Build Coastguard Worker {
372*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleMlrRegResult(aError, aMlrStatus, aFailedAddresses, aFailedAddressNum);
373*cfb92d14SAndroid Build Coastguard Worker }
374*cfb92d14SAndroid Build Coastguard Worker 
HandleMlrRegResult(otError aError,uint8_t aMlrStatus,const otIp6Address * aFailedAddresses,uint8_t aFailedAddressNum)375*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleMlrRegResult(otError             aError,
376*cfb92d14SAndroid Build Coastguard Worker                                  uint8_t             aMlrStatus,
377*cfb92d14SAndroid Build Coastguard Worker                                  const otIp6Address *aFailedAddresses,
378*cfb92d14SAndroid Build Coastguard Worker                                  uint8_t             aFailedAddressNum)
379*cfb92d14SAndroid Build Coastguard Worker {
380*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
381*cfb92d14SAndroid Build Coastguard Worker                                       SPINEL_PROP_THREAD_MLR_RESPONSE));
382*cfb92d14SAndroid Build Coastguard Worker 
383*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(static_cast<uint8_t>(ThreadErrorToSpinelStatus(aError))));
384*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(aMlrStatus));
385*cfb92d14SAndroid Build Coastguard Worker 
386*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.OpenStruct());
387*cfb92d14SAndroid Build Coastguard Worker 
388*cfb92d14SAndroid Build Coastguard Worker     if (aError == OT_ERROR_NONE)
389*cfb92d14SAndroid Build Coastguard Worker     {
390*cfb92d14SAndroid Build Coastguard Worker         for (size_t i = 0U; i < aFailedAddressNum; ++i)
391*cfb92d14SAndroid Build Coastguard Worker         {
392*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(mEncoder.WriteIp6Address(aFailedAddresses[i]));
393*cfb92d14SAndroid Build Coastguard Worker         }
394*cfb92d14SAndroid Build Coastguard Worker     }
395*cfb92d14SAndroid Build Coastguard Worker 
396*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.CloseStruct());
397*cfb92d14SAndroid Build Coastguard Worker 
398*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
399*cfb92d14SAndroid Build Coastguard Worker 
400*cfb92d14SAndroid Build Coastguard Worker exit:
401*cfb92d14SAndroid Build Coastguard Worker     return;
402*cfb92d14SAndroid Build Coastguard Worker }
403*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
404*cfb92d14SAndroid Build Coastguard Worker 
405*cfb92d14SAndroid Build Coastguard Worker #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
HandlePropertyGet(void)406*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_BACKBONE_ROUTER_PRIMARY>(void)
407*cfb92d14SAndroid Build Coastguard Worker {
408*cfb92d14SAndroid Build Coastguard Worker     otError                error = OT_ERROR_NONE;
409*cfb92d14SAndroid Build Coastguard Worker     otBackboneRouterConfig bbrConfig;
410*cfb92d14SAndroid Build Coastguard Worker 
411*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otBackboneRouterGetPrimary(mInstance, &bbrConfig));
412*cfb92d14SAndroid Build Coastguard Worker 
413*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bbrConfig.mServer16));
414*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bbrConfig.mReregistrationDelay));
415*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(bbrConfig.mMlrTimeout));
416*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint8(bbrConfig.mSequenceNumber));
417*cfb92d14SAndroid Build Coastguard Worker 
418*cfb92d14SAndroid Build Coastguard Worker exit:
419*cfb92d14SAndroid Build Coastguard Worker     return error;
420*cfb92d14SAndroid Build Coastguard Worker }
421*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
422*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)423*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_DATA_POLL_PERIOD>(void)
424*cfb92d14SAndroid Build Coastguard Worker {
425*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetPollPeriod(mInstance));
426*cfb92d14SAndroid Build Coastguard Worker }
427*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)428*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_DATA_POLL_PERIOD>(void)
429*cfb92d14SAndroid Build Coastguard Worker {
430*cfb92d14SAndroid Build Coastguard Worker     uint32_t pollPeriod;
431*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
432*cfb92d14SAndroid Build Coastguard Worker 
433*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(pollPeriod));
434*cfb92d14SAndroid Build Coastguard Worker 
435*cfb92d14SAndroid Build Coastguard Worker     error = otLinkSetPollPeriod(mInstance, pollPeriod);
436*cfb92d14SAndroid Build Coastguard Worker 
437*cfb92d14SAndroid Build Coastguard Worker exit:
438*cfb92d14SAndroid Build Coastguard Worker     return error;
439*cfb92d14SAndroid Build Coastguard Worker }
440*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)441*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_EXTENDED_ADDR>(void)
442*cfb92d14SAndroid Build Coastguard Worker {
443*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteEui64(*otLinkGetExtendedAddress(mInstance));
444*cfb92d14SAndroid Build Coastguard Worker }
445*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)446*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT>(void)
447*cfb92d14SAndroid Build Coastguard Worker {
448*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(otLinkGetMaxFrameRetriesDirect(mInstance));
449*cfb92d14SAndroid Build Coastguard Worker }
450*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)451*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT>(void)
452*cfb92d14SAndroid Build Coastguard Worker {
453*cfb92d14SAndroid Build Coastguard Worker     uint8_t maxFrameRetriesDirect;
454*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
455*cfb92d14SAndroid Build Coastguard Worker 
456*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(maxFrameRetriesDirect));
457*cfb92d14SAndroid Build Coastguard Worker     otLinkSetMaxFrameRetriesDirect(mInstance, maxFrameRetriesDirect);
458*cfb92d14SAndroid Build Coastguard Worker 
459*cfb92d14SAndroid Build Coastguard Worker exit:
460*cfb92d14SAndroid Build Coastguard Worker     return error;
461*cfb92d14SAndroid Build Coastguard Worker }
462*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)463*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_PHY_CHAN_SUPPORTED>(void)
464*cfb92d14SAndroid Build Coastguard Worker {
465*cfb92d14SAndroid Build Coastguard Worker     uint32_t newMask = 0;
466*cfb92d14SAndroid Build Coastguard Worker     otError  error   = OT_ERROR_NONE;
467*cfb92d14SAndroid Build Coastguard Worker 
468*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeChannelMask(newMask));
469*cfb92d14SAndroid Build Coastguard Worker     error = otLinkSetSupportedChannelMask(mInstance, newMask);
470*cfb92d14SAndroid Build Coastguard Worker 
471*cfb92d14SAndroid Build Coastguard Worker exit:
472*cfb92d14SAndroid Build Coastguard Worker     return error;
473*cfb92d14SAndroid Build Coastguard Worker }
474*cfb92d14SAndroid Build Coastguard Worker 
CommandHandler_NET_CLEAR(uint8_t aHeader)475*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::CommandHandler_NET_CLEAR(uint8_t aHeader)
476*cfb92d14SAndroid Build Coastguard Worker {
477*cfb92d14SAndroid Build Coastguard Worker     return PrepareLastStatusResponse(aHeader, ThreadErrorToSpinelStatus(otInstanceErasePersistentInfo(mInstance)));
478*cfb92d14SAndroid Build Coastguard Worker }
479*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)480*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_SAVED>(void)
481*cfb92d14SAndroid Build Coastguard Worker {
482*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otDatasetIsCommissioned(mInstance));
483*cfb92d14SAndroid Build Coastguard Worker }
484*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)485*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_IF_UP>(void)
486*cfb92d14SAndroid Build Coastguard Worker {
487*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otIp6IsEnabled(mInstance));
488*cfb92d14SAndroid Build Coastguard Worker }
489*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)490*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_IF_UP>(void)
491*cfb92d14SAndroid Build Coastguard Worker {
492*cfb92d14SAndroid Build Coastguard Worker     bool    enabled = false;
493*cfb92d14SAndroid Build Coastguard Worker     otError error   = OT_ERROR_NONE;
494*cfb92d14SAndroid Build Coastguard Worker 
495*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
496*cfb92d14SAndroid Build Coastguard Worker 
497*cfb92d14SAndroid Build Coastguard Worker     error = otIp6SetEnabled(mInstance, enabled);
498*cfb92d14SAndroid Build Coastguard Worker 
499*cfb92d14SAndroid Build Coastguard Worker exit:
500*cfb92d14SAndroid Build Coastguard Worker     return error;
501*cfb92d14SAndroid Build Coastguard Worker }
502*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)503*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_STACK_UP>(void)
504*cfb92d14SAndroid Build Coastguard Worker {
505*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otThreadGetDeviceRole(mInstance) != OT_DEVICE_ROLE_DISABLED);
506*cfb92d14SAndroid Build Coastguard Worker }
507*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)508*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_STACK_UP>(void)
509*cfb92d14SAndroid Build Coastguard Worker {
510*cfb92d14SAndroid Build Coastguard Worker     bool    enabled = false;
511*cfb92d14SAndroid Build Coastguard Worker     otError error   = OT_ERROR_NONE;
512*cfb92d14SAndroid Build Coastguard Worker 
513*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
514*cfb92d14SAndroid Build Coastguard Worker 
515*cfb92d14SAndroid Build Coastguard Worker     // If the value has changed...
516*cfb92d14SAndroid Build Coastguard Worker     if (enabled != (otThreadGetDeviceRole(mInstance) != OT_DEVICE_ROLE_DISABLED))
517*cfb92d14SAndroid Build Coastguard Worker     {
518*cfb92d14SAndroid Build Coastguard Worker         if (enabled)
519*cfb92d14SAndroid Build Coastguard Worker         {
520*cfb92d14SAndroid Build Coastguard Worker             error = otThreadSetEnabled(mInstance, true);
521*cfb92d14SAndroid Build Coastguard Worker         }
522*cfb92d14SAndroid Build Coastguard Worker         else
523*cfb92d14SAndroid Build Coastguard Worker         {
524*cfb92d14SAndroid Build Coastguard Worker             error = otThreadSetEnabled(mInstance, false);
525*cfb92d14SAndroid Build Coastguard Worker         }
526*cfb92d14SAndroid Build Coastguard Worker     }
527*cfb92d14SAndroid Build Coastguard Worker 
528*cfb92d14SAndroid Build Coastguard Worker exit:
529*cfb92d14SAndroid Build Coastguard Worker     return error;
530*cfb92d14SAndroid Build Coastguard Worker }
531*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)532*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_ROLE>(void)
533*cfb92d14SAndroid Build Coastguard Worker {
534*cfb92d14SAndroid Build Coastguard Worker     spinel_net_role_t role(SPINEL_NET_ROLE_DETACHED);
535*cfb92d14SAndroid Build Coastguard Worker 
536*cfb92d14SAndroid Build Coastguard Worker     switch (otThreadGetDeviceRole(mInstance))
537*cfb92d14SAndroid Build Coastguard Worker     {
538*cfb92d14SAndroid Build Coastguard Worker     case OT_DEVICE_ROLE_DISABLED:
539*cfb92d14SAndroid Build Coastguard Worker         role = SPINEL_NET_ROLE_DISABLED;
540*cfb92d14SAndroid Build Coastguard Worker         break;
541*cfb92d14SAndroid Build Coastguard Worker 
542*cfb92d14SAndroid Build Coastguard Worker     case OT_DEVICE_ROLE_DETACHED:
543*cfb92d14SAndroid Build Coastguard Worker         role = SPINEL_NET_ROLE_DETACHED;
544*cfb92d14SAndroid Build Coastguard Worker         break;
545*cfb92d14SAndroid Build Coastguard Worker 
546*cfb92d14SAndroid Build Coastguard Worker     case OT_DEVICE_ROLE_CHILD:
547*cfb92d14SAndroid Build Coastguard Worker         role = SPINEL_NET_ROLE_CHILD;
548*cfb92d14SAndroid Build Coastguard Worker         break;
549*cfb92d14SAndroid Build Coastguard Worker 
550*cfb92d14SAndroid Build Coastguard Worker     case OT_DEVICE_ROLE_ROUTER:
551*cfb92d14SAndroid Build Coastguard Worker         role = SPINEL_NET_ROLE_ROUTER;
552*cfb92d14SAndroid Build Coastguard Worker         break;
553*cfb92d14SAndroid Build Coastguard Worker 
554*cfb92d14SAndroid Build Coastguard Worker     case OT_DEVICE_ROLE_LEADER:
555*cfb92d14SAndroid Build Coastguard Worker         role = SPINEL_NET_ROLE_LEADER;
556*cfb92d14SAndroid Build Coastguard Worker         break;
557*cfb92d14SAndroid Build Coastguard Worker     }
558*cfb92d14SAndroid Build Coastguard Worker 
559*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(role);
560*cfb92d14SAndroid Build Coastguard Worker }
561*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)562*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_ROLE>(void)
563*cfb92d14SAndroid Build Coastguard Worker {
564*cfb92d14SAndroid Build Coastguard Worker     unsigned int role  = 0;
565*cfb92d14SAndroid Build Coastguard Worker     otError      error = OT_ERROR_NONE;
566*cfb92d14SAndroid Build Coastguard Worker 
567*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUintPacked(role));
568*cfb92d14SAndroid Build Coastguard Worker 
569*cfb92d14SAndroid Build Coastguard Worker     switch (role)
570*cfb92d14SAndroid Build Coastguard Worker     {
571*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_NET_ROLE_DETACHED:
572*cfb92d14SAndroid Build Coastguard Worker         error = otThreadBecomeDetached(mInstance);
573*cfb92d14SAndroid Build Coastguard Worker         break;
574*cfb92d14SAndroid Build Coastguard Worker 
575*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_FTD
576*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_NET_ROLE_ROUTER:
577*cfb92d14SAndroid Build Coastguard Worker         error = otThreadBecomeRouter(mInstance);
578*cfb92d14SAndroid Build Coastguard Worker         break;
579*cfb92d14SAndroid Build Coastguard Worker 
580*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_NET_ROLE_LEADER:
581*cfb92d14SAndroid Build Coastguard Worker         error = otThreadBecomeLeader(mInstance);
582*cfb92d14SAndroid Build Coastguard Worker         break;
583*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_FTD
584*cfb92d14SAndroid Build Coastguard Worker 
585*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_NET_ROLE_CHILD:
586*cfb92d14SAndroid Build Coastguard Worker         error = otThreadBecomeChild(mInstance);
587*cfb92d14SAndroid Build Coastguard Worker         break;
588*cfb92d14SAndroid Build Coastguard Worker     }
589*cfb92d14SAndroid Build Coastguard Worker 
590*cfb92d14SAndroid Build Coastguard Worker exit:
591*cfb92d14SAndroid Build Coastguard Worker     return error;
592*cfb92d14SAndroid Build Coastguard Worker }
593*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)594*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_NETWORK_NAME>(void)
595*cfb92d14SAndroid Build Coastguard Worker {
596*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUtf8(otThreadGetNetworkName(mInstance));
597*cfb92d14SAndroid Build Coastguard Worker }
598*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)599*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_NETWORK_NAME>(void)
600*cfb92d14SAndroid Build Coastguard Worker {
601*cfb92d14SAndroid Build Coastguard Worker     const char *string = nullptr;
602*cfb92d14SAndroid Build Coastguard Worker     otError     error  = OT_ERROR_NONE;
603*cfb92d14SAndroid Build Coastguard Worker 
604*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUtf8(string));
605*cfb92d14SAndroid Build Coastguard Worker 
606*cfb92d14SAndroid Build Coastguard Worker     error = otThreadSetNetworkName(mInstance, string);
607*cfb92d14SAndroid Build Coastguard Worker 
608*cfb92d14SAndroid Build Coastguard Worker exit:
609*cfb92d14SAndroid Build Coastguard Worker     return error;
610*cfb92d14SAndroid Build Coastguard Worker }
611*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)612*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_XPANID>(void)
613*cfb92d14SAndroid Build Coastguard Worker {
614*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteData(otThreadGetExtendedPanId(mInstance)->m8, sizeof(spinel_net_xpanid_t));
615*cfb92d14SAndroid Build Coastguard Worker }
616*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)617*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_XPANID>(void)
618*cfb92d14SAndroid Build Coastguard Worker {
619*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *ptr = nullptr;
620*cfb92d14SAndroid Build Coastguard Worker     uint16_t       len;
621*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_NONE;
622*cfb92d14SAndroid Build Coastguard Worker 
623*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadData(ptr, len));
624*cfb92d14SAndroid Build Coastguard Worker 
625*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(len == sizeof(spinel_net_xpanid_t), error = OT_ERROR_PARSE);
626*cfb92d14SAndroid Build Coastguard Worker 
627*cfb92d14SAndroid Build Coastguard Worker     error = otThreadSetExtendedPanId(mInstance, reinterpret_cast<const otExtendedPanId *>(ptr));
628*cfb92d14SAndroid Build Coastguard Worker 
629*cfb92d14SAndroid Build Coastguard Worker exit:
630*cfb92d14SAndroid Build Coastguard Worker     return error;
631*cfb92d14SAndroid Build Coastguard Worker }
632*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)633*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_NETWORK_KEY>(void)
634*cfb92d14SAndroid Build Coastguard Worker {
635*cfb92d14SAndroid Build Coastguard Worker     otNetworkKey networkKey;
636*cfb92d14SAndroid Build Coastguard Worker 
637*cfb92d14SAndroid Build Coastguard Worker     otThreadGetNetworkKey(mInstance, &networkKey);
638*cfb92d14SAndroid Build Coastguard Worker 
639*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteData(networkKey.m8, OT_NETWORK_KEY_SIZE);
640*cfb92d14SAndroid Build Coastguard Worker }
641*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)642*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_NETWORK_KEY>(void)
643*cfb92d14SAndroid Build Coastguard Worker {
644*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *ptr = nullptr;
645*cfb92d14SAndroid Build Coastguard Worker     uint16_t       len;
646*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_NONE;
647*cfb92d14SAndroid Build Coastguard Worker 
648*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadData(ptr, len));
649*cfb92d14SAndroid Build Coastguard Worker 
650*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(len == OT_NETWORK_KEY_SIZE, error = OT_ERROR_PARSE);
651*cfb92d14SAndroid Build Coastguard Worker 
652*cfb92d14SAndroid Build Coastguard Worker     error = otThreadSetNetworkKey(mInstance, reinterpret_cast<const otNetworkKey *>(ptr));
653*cfb92d14SAndroid Build Coastguard Worker 
654*cfb92d14SAndroid Build Coastguard Worker exit:
655*cfb92d14SAndroid Build Coastguard Worker     return error;
656*cfb92d14SAndroid Build Coastguard Worker }
657*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)658*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER>(void)
659*cfb92d14SAndroid Build Coastguard Worker {
660*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetKeySequenceCounter(mInstance));
661*cfb92d14SAndroid Build Coastguard Worker }
662*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)663*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER>(void)
664*cfb92d14SAndroid Build Coastguard Worker {
665*cfb92d14SAndroid Build Coastguard Worker     uint32_t keySeqCounter;
666*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
667*cfb92d14SAndroid Build Coastguard Worker 
668*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(keySeqCounter));
669*cfb92d14SAndroid Build Coastguard Worker 
670*cfb92d14SAndroid Build Coastguard Worker     otThreadSetKeySequenceCounter(mInstance, keySeqCounter);
671*cfb92d14SAndroid Build Coastguard Worker 
672*cfb92d14SAndroid Build Coastguard Worker exit:
673*cfb92d14SAndroid Build Coastguard Worker     return error;
674*cfb92d14SAndroid Build Coastguard Worker }
675*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)676*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_PARTITION_ID>(void)
677*cfb92d14SAndroid Build Coastguard Worker {
678*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetPartitionId(mInstance));
679*cfb92d14SAndroid Build Coastguard Worker }
680*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)681*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME>(void)
682*cfb92d14SAndroid Build Coastguard Worker {
683*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetKeySwitchGuardTime(mInstance));
684*cfb92d14SAndroid Build Coastguard Worker }
685*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)686*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME>(void)
687*cfb92d14SAndroid Build Coastguard Worker {
688*cfb92d14SAndroid Build Coastguard Worker     uint32_t keyGuardTime;
689*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
690*cfb92d14SAndroid Build Coastguard Worker 
691*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(keyGuardTime));
692*cfb92d14SAndroid Build Coastguard Worker 
693*cfb92d14SAndroid Build Coastguard Worker     otThreadSetKeySwitchGuardTime(mInstance, static_cast<uint16_t>(keyGuardTime));
694*cfb92d14SAndroid Build Coastguard Worker 
695*cfb92d14SAndroid Build Coastguard Worker exit:
696*cfb92d14SAndroid Build Coastguard Worker     return error;
697*cfb92d14SAndroid Build Coastguard Worker }
698*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)699*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_NETWORK_DATA_VERSION>(void)
700*cfb92d14SAndroid Build Coastguard Worker {
701*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(otNetDataGetVersion(mInstance));
702*cfb92d14SAndroid Build Coastguard Worker }
703*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)704*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION>(void)
705*cfb92d14SAndroid Build Coastguard Worker {
706*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(otNetDataGetStableVersion(mInstance));
707*cfb92d14SAndroid Build Coastguard Worker }
708*cfb92d14SAndroid Build Coastguard Worker 
709*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
HandlePropertyGet(void)710*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_NETWORK_DATA>(void)
711*cfb92d14SAndroid Build Coastguard Worker {
712*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkData[255];
713*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkDataLen = 255;
714*cfb92d14SAndroid Build Coastguard Worker 
715*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otBorderRouterGetNetData(mInstance,
716*cfb92d14SAndroid Build Coastguard Worker                                          false, // Stable?
717*cfb92d14SAndroid Build Coastguard Worker                                          networkData, &networkDataLen));
718*cfb92d14SAndroid Build Coastguard Worker 
719*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteData(networkData, networkDataLen);
720*cfb92d14SAndroid Build Coastguard Worker }
721*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)722*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_STABLE_NETWORK_DATA>(void)
723*cfb92d14SAndroid Build Coastguard Worker {
724*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkData[255];
725*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkDataLen = 255;
726*cfb92d14SAndroid Build Coastguard Worker 
727*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otBorderRouterGetNetData(mInstance,
728*cfb92d14SAndroid Build Coastguard Worker                                          true, // Stable?
729*cfb92d14SAndroid Build Coastguard Worker                                          networkData, &networkDataLen));
730*cfb92d14SAndroid Build Coastguard Worker 
731*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteData(networkData, networkDataLen);
732*cfb92d14SAndroid Build Coastguard Worker }
733*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
734*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)735*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_LEADER_NETWORK_DATA>(void)
736*cfb92d14SAndroid Build Coastguard Worker {
737*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkData[255];
738*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkDataLen = 255;
739*cfb92d14SAndroid Build Coastguard Worker 
740*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otNetDataGet(mInstance,
741*cfb92d14SAndroid Build Coastguard Worker                              false, // Stable?
742*cfb92d14SAndroid Build Coastguard Worker                              networkData, &networkDataLen));
743*cfb92d14SAndroid Build Coastguard Worker 
744*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteData(networkData, networkDataLen);
745*cfb92d14SAndroid Build Coastguard Worker }
746*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)747*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA>(void)
748*cfb92d14SAndroid Build Coastguard Worker {
749*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkData[255];
750*cfb92d14SAndroid Build Coastguard Worker     uint8_t networkDataLen = 255;
751*cfb92d14SAndroid Build Coastguard Worker 
752*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otNetDataGet(mInstance,
753*cfb92d14SAndroid Build Coastguard Worker                              true, // Stable?
754*cfb92d14SAndroid Build Coastguard Worker                              networkData, &networkDataLen));
755*cfb92d14SAndroid Build Coastguard Worker 
756*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteData(networkData, networkDataLen);
757*cfb92d14SAndroid Build Coastguard Worker }
758*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)759*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_LEADER_RID>(void)
760*cfb92d14SAndroid Build Coastguard Worker {
761*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(otThreadGetLeaderRouterId(mInstance));
762*cfb92d14SAndroid Build Coastguard Worker }
763*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)764*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_LEADER_ADDR>(void)
765*cfb92d14SAndroid Build Coastguard Worker {
766*cfb92d14SAndroid Build Coastguard Worker     otError      error = OT_ERROR_NONE;
767*cfb92d14SAndroid Build Coastguard Worker     otIp6Address address;
768*cfb92d14SAndroid Build Coastguard Worker 
769*cfb92d14SAndroid Build Coastguard Worker     error = otThreadGetLeaderRloc(mInstance, &address);
770*cfb92d14SAndroid Build Coastguard Worker 
771*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NONE)
772*cfb92d14SAndroid Build Coastguard Worker     {
773*cfb92d14SAndroid Build Coastguard Worker         error = mEncoder.WriteIp6Address(address);
774*cfb92d14SAndroid Build Coastguard Worker     }
775*cfb92d14SAndroid Build Coastguard Worker     else
776*cfb92d14SAndroid Build Coastguard Worker     {
777*cfb92d14SAndroid Build Coastguard Worker         error = mEncoder.OverwriteWithLastStatusError(ThreadErrorToSpinelStatus(error));
778*cfb92d14SAndroid Build Coastguard Worker     }
779*cfb92d14SAndroid Build Coastguard Worker 
780*cfb92d14SAndroid Build Coastguard Worker     return error;
781*cfb92d14SAndroid Build Coastguard Worker }
782*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)783*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_PARENT>(void)
784*cfb92d14SAndroid Build Coastguard Worker {
785*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
786*cfb92d14SAndroid Build Coastguard Worker 
787*cfb92d14SAndroid Build Coastguard Worker     otRouterInfo parentInfo;
788*cfb92d14SAndroid Build Coastguard Worker 
789*cfb92d14SAndroid Build Coastguard Worker     error = otThreadGetParentInfo(mInstance, &parentInfo);
790*cfb92d14SAndroid Build Coastguard Worker 
791*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NONE)
792*cfb92d14SAndroid Build Coastguard Worker     {
793*cfb92d14SAndroid Build Coastguard Worker         if (parentInfo.mLinkEstablished)
794*cfb92d14SAndroid Build Coastguard Worker         {
795*cfb92d14SAndroid Build Coastguard Worker             int8_t averageRssi;
796*cfb92d14SAndroid Build Coastguard Worker             int8_t lastRssi;
797*cfb92d14SAndroid Build Coastguard Worker 
798*cfb92d14SAndroid Build Coastguard Worker             IgnoreError(otThreadGetParentAverageRssi(mInstance, &averageRssi));
799*cfb92d14SAndroid Build Coastguard Worker             IgnoreError(otThreadGetParentLastRssi(mInstance, &lastRssi));
800*cfb92d14SAndroid Build Coastguard Worker 
801*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteEui64(parentInfo.mExtAddress));
802*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint16(parentInfo.mRloc16));
803*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint32(parentInfo.mAge));
804*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteInt8(averageRssi));
805*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteInt8(lastRssi));
806*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint8(parentInfo.mLinkQualityIn));
807*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint8(parentInfo.mLinkQualityOut));
808*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint8(parentInfo.mVersion));
809*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
810*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint8(parentInfo.mCslClockAccuracy));
811*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint8(parentInfo.mCslUncertainty));
812*cfb92d14SAndroid Build Coastguard Worker #endif
813*cfb92d14SAndroid Build Coastguard Worker         }
814*cfb92d14SAndroid Build Coastguard Worker         else
815*cfb92d14SAndroid Build Coastguard Worker         {
816*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.OverwriteWithLastStatusError(SPINEL_STATUS_ITEM_NOT_FOUND));
817*cfb92d14SAndroid Build Coastguard Worker         }
818*cfb92d14SAndroid Build Coastguard Worker     }
819*cfb92d14SAndroid Build Coastguard Worker     else
820*cfb92d14SAndroid Build Coastguard Worker     {
821*cfb92d14SAndroid Build Coastguard Worker         error = mEncoder.OverwriteWithLastStatusError(ThreadErrorToSpinelStatus(error));
822*cfb92d14SAndroid Build Coastguard Worker     }
823*cfb92d14SAndroid Build Coastguard Worker 
824*cfb92d14SAndroid Build Coastguard Worker exit:
825*cfb92d14SAndroid Build Coastguard Worker     return error;
826*cfb92d14SAndroid Build Coastguard Worker }
827*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)828*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_NEIGHBOR_TABLE>(void)
829*cfb92d14SAndroid Build Coastguard Worker {
830*cfb92d14SAndroid Build Coastguard Worker     otError                error = OT_ERROR_NONE;
831*cfb92d14SAndroid Build Coastguard Worker     otNeighborInfoIterator iter  = OT_NEIGHBOR_INFO_ITERATOR_INIT;
832*cfb92d14SAndroid Build Coastguard Worker     otNeighborInfo         neighInfo;
833*cfb92d14SAndroid Build Coastguard Worker 
834*cfb92d14SAndroid Build Coastguard Worker     while (otThreadGetNextNeighborInfo(mInstance, &iter, &neighInfo) == OT_ERROR_NONE)
835*cfb92d14SAndroid Build Coastguard Worker     {
836*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = EncodeNeighborInfo(neighInfo));
837*cfb92d14SAndroid Build Coastguard Worker     }
838*cfb92d14SAndroid Build Coastguard Worker 
839*cfb92d14SAndroid Build Coastguard Worker exit:
840*cfb92d14SAndroid Build Coastguard Worker     return error;
841*cfb92d14SAndroid Build Coastguard Worker }
842*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)843*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_NEIGHBOR_TABLE_ERROR_RATES>(void)
844*cfb92d14SAndroid Build Coastguard Worker {
845*cfb92d14SAndroid Build Coastguard Worker     otError                error = OT_ERROR_NONE;
846*cfb92d14SAndroid Build Coastguard Worker     otNeighborInfoIterator iter  = OT_NEIGHBOR_INFO_ITERATOR_INIT;
847*cfb92d14SAndroid Build Coastguard Worker     otNeighborInfo         neighInfo;
848*cfb92d14SAndroid Build Coastguard Worker 
849*cfb92d14SAndroid Build Coastguard Worker     while (otThreadGetNextNeighborInfo(mInstance, &iter, &neighInfo) == OT_ERROR_NONE)
850*cfb92d14SAndroid Build Coastguard Worker     {
851*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
852*cfb92d14SAndroid Build Coastguard Worker 
853*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteEui64(neighInfo.mExtAddress));
854*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(neighInfo.mRloc16));
855*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(neighInfo.mFrameErrorRate));
856*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(neighInfo.mMessageErrorRate));
857*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteInt8(neighInfo.mAverageRssi));
858*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteInt8(neighInfo.mLastRssi));
859*cfb92d14SAndroid Build Coastguard Worker 
860*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
861*cfb92d14SAndroid Build Coastguard Worker     }
862*cfb92d14SAndroid Build Coastguard Worker 
863*cfb92d14SAndroid Build Coastguard Worker exit:
864*cfb92d14SAndroid Build Coastguard Worker     return error;
865*cfb92d14SAndroid Build Coastguard Worker }
866*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)867*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ASSISTING_PORTS>(void)
868*cfb92d14SAndroid Build Coastguard Worker {
869*cfb92d14SAndroid Build Coastguard Worker     otError         error      = OT_ERROR_NONE;
870*cfb92d14SAndroid Build Coastguard Worker     uint8_t         numEntries = 0;
871*cfb92d14SAndroid Build Coastguard Worker     const uint16_t *ports      = otIp6GetUnsecurePorts(mInstance, &numEntries);
872*cfb92d14SAndroid Build Coastguard Worker 
873*cfb92d14SAndroid Build Coastguard Worker     for (; numEntries != 0; ports++, numEntries--)
874*cfb92d14SAndroid Build Coastguard Worker     {
875*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(*ports));
876*cfb92d14SAndroid Build Coastguard Worker     }
877*cfb92d14SAndroid Build Coastguard Worker 
878*cfb92d14SAndroid Build Coastguard Worker exit:
879*cfb92d14SAndroid Build Coastguard Worker     return error;
880*cfb92d14SAndroid Build Coastguard Worker }
881*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)882*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ASSISTING_PORTS>(void)
883*cfb92d14SAndroid Build Coastguard Worker {
884*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
885*cfb92d14SAndroid Build Coastguard Worker 
886*cfb92d14SAndroid Build Coastguard Worker     // First, we need to remove all of the current assisting ports.
887*cfb92d14SAndroid Build Coastguard Worker     otIp6RemoveAllUnsecurePorts(mInstance);
888*cfb92d14SAndroid Build Coastguard Worker 
889*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct() >= sizeof(uint16_t))
890*cfb92d14SAndroid Build Coastguard Worker     {
891*cfb92d14SAndroid Build Coastguard Worker         uint16_t port;
892*cfb92d14SAndroid Build Coastguard Worker 
893*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUint16(port));
894*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otIp6AddUnsecurePort(mInstance, port));
895*cfb92d14SAndroid Build Coastguard Worker     }
896*cfb92d14SAndroid Build Coastguard Worker 
897*cfb92d14SAndroid Build Coastguard Worker exit:
898*cfb92d14SAndroid Build Coastguard Worker 
899*cfb92d14SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
900*cfb92d14SAndroid Build Coastguard Worker     {
901*cfb92d14SAndroid Build Coastguard Worker         // We had an error, but we've actually changed
902*cfb92d14SAndroid Build Coastguard Worker         // the state of these ports, so we need to report
903*cfb92d14SAndroid Build Coastguard Worker         // those incomplete changes via an asynchronous
904*cfb92d14SAndroid Build Coastguard Worker         // change event.
905*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(
906*cfb92d14SAndroid Build Coastguard Worker             WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_THREAD_ASSISTING_PORTS));
907*cfb92d14SAndroid Build Coastguard Worker     }
908*cfb92d14SAndroid Build Coastguard Worker 
909*cfb92d14SAndroid Build Coastguard Worker     return error;
910*cfb92d14SAndroid Build Coastguard Worker }
911*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)912*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE>(void)
913*cfb92d14SAndroid Build Coastguard Worker {
914*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(mAllowLocalNetworkDataChange);
915*cfb92d14SAndroid Build Coastguard Worker }
916*cfb92d14SAndroid Build Coastguard Worker 
917*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
HandlePropertySet(void)918*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE>(void)
919*cfb92d14SAndroid Build Coastguard Worker {
920*cfb92d14SAndroid Build Coastguard Worker     bool    value                    = false;
921*cfb92d14SAndroid Build Coastguard Worker     otError error                    = OT_ERROR_NONE;
922*cfb92d14SAndroid Build Coastguard Worker     bool    shouldRegisterWithLeader = false;
923*cfb92d14SAndroid Build Coastguard Worker 
924*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(value));
925*cfb92d14SAndroid Build Coastguard Worker 
926*cfb92d14SAndroid Build Coastguard Worker     // Register any net data changes on transition from `true` to `false`.
927*cfb92d14SAndroid Build Coastguard Worker     shouldRegisterWithLeader = mAllowLocalNetworkDataChange && !value;
928*cfb92d14SAndroid Build Coastguard Worker 
929*cfb92d14SAndroid Build Coastguard Worker     mAllowLocalNetworkDataChange = value;
930*cfb92d14SAndroid Build Coastguard Worker 
931*cfb92d14SAndroid Build Coastguard Worker exit:
932*cfb92d14SAndroid Build Coastguard Worker 
933*cfb92d14SAndroid Build Coastguard Worker     if (shouldRegisterWithLeader)
934*cfb92d14SAndroid Build Coastguard Worker     {
935*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(otBorderRouterRegister(mInstance));
936*cfb92d14SAndroid Build Coastguard Worker     }
937*cfb92d14SAndroid Build Coastguard Worker 
938*cfb92d14SAndroid Build Coastguard Worker     return error;
939*cfb92d14SAndroid Build Coastguard Worker }
940*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
941*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)942*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ON_MESH_NETS>(void)
943*cfb92d14SAndroid Build Coastguard Worker {
944*cfb92d14SAndroid Build Coastguard Worker     otError               error = OT_ERROR_NONE;
945*cfb92d14SAndroid Build Coastguard Worker     otBorderRouterConfig  borderRouterConfig;
946*cfb92d14SAndroid Build Coastguard Worker     otNetworkDataIterator iter = OT_NETWORK_DATA_ITERATOR_INIT;
947*cfb92d14SAndroid Build Coastguard Worker 
948*cfb92d14SAndroid Build Coastguard Worker     // Fill from non-local network data first
949*cfb92d14SAndroid Build Coastguard Worker     while (otNetDataGetNextOnMeshPrefix(mInstance, &iter, &borderRouterConfig) == OT_ERROR_NONE)
950*cfb92d14SAndroid Build Coastguard Worker     {
951*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
952*cfb92d14SAndroid Build Coastguard Worker 
953*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(borderRouterConfig.mPrefix.mPrefix));
954*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(borderRouterConfig.mPrefix.mLength));
955*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(borderRouterConfig.mStable));
956*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(BorderRouterConfigToFlagByte(borderRouterConfig)));
957*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(false)); // isLocal
958*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(borderRouterConfig.mRloc16));
959*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(BorderRouterConfigToFlagByteExtended(borderRouterConfig)));
960*cfb92d14SAndroid Build Coastguard Worker 
961*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
962*cfb92d14SAndroid Build Coastguard Worker     }
963*cfb92d14SAndroid Build Coastguard Worker 
964*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
965*cfb92d14SAndroid Build Coastguard Worker 
966*cfb92d14SAndroid Build Coastguard Worker     iter = OT_NETWORK_DATA_ITERATOR_INIT;
967*cfb92d14SAndroid Build Coastguard Worker 
968*cfb92d14SAndroid Build Coastguard Worker     // Fill from local network data last
969*cfb92d14SAndroid Build Coastguard Worker     while (otBorderRouterGetNextOnMeshPrefix(mInstance, &iter, &borderRouterConfig) == OT_ERROR_NONE)
970*cfb92d14SAndroid Build Coastguard Worker     {
971*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
972*cfb92d14SAndroid Build Coastguard Worker 
973*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(borderRouterConfig.mPrefix.mPrefix));
974*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(borderRouterConfig.mPrefix.mLength));
975*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(borderRouterConfig.mStable));
976*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(BorderRouterConfigToFlagByte(borderRouterConfig)));
977*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(true)); // isLocal
978*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(borderRouterConfig.mRloc16));
979*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(BorderRouterConfigToFlagByteExtended(borderRouterConfig)));
980*cfb92d14SAndroid Build Coastguard Worker 
981*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
982*cfb92d14SAndroid Build Coastguard Worker     }
983*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
984*cfb92d14SAndroid Build Coastguard Worker 
985*cfb92d14SAndroid Build Coastguard Worker exit:
986*cfb92d14SAndroid Build Coastguard Worker     return error;
987*cfb92d14SAndroid Build Coastguard Worker }
988*cfb92d14SAndroid Build Coastguard Worker 
989*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
HandlePropertyInsert(void)990*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_THREAD_ON_MESH_NETS>(void)
991*cfb92d14SAndroid Build Coastguard Worker {
992*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
993*cfb92d14SAndroid Build Coastguard Worker     otBorderRouterConfig borderRouterConfig;
994*cfb92d14SAndroid Build Coastguard Worker     bool                 stable = false;
995*cfb92d14SAndroid Build Coastguard Worker     bool                 isLocal;
996*cfb92d14SAndroid Build Coastguard Worker     uint8_t              flags         = 0;
997*cfb92d14SAndroid Build Coastguard Worker     uint8_t              flagsExtended = 0;
998*cfb92d14SAndroid Build Coastguard Worker     uint8_t              prefixLength;
999*cfb92d14SAndroid Build Coastguard Worker     uint16_t             rloc16;
1000*cfb92d14SAndroid Build Coastguard Worker 
1001*cfb92d14SAndroid Build Coastguard Worker     memset(&borderRouterConfig, 0, sizeof(otBorderRouterConfig));
1002*cfb92d14SAndroid Build Coastguard Worker 
1003*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mAllowLocalNetworkDataChange, error = OT_ERROR_INVALID_STATE);
1004*cfb92d14SAndroid Build Coastguard Worker 
1005*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(borderRouterConfig.mPrefix.mPrefix));
1006*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(prefixLength));
1007*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(stable));
1008*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(flags));
1009*cfb92d14SAndroid Build Coastguard Worker 
1010*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mPrefix.mLength = prefixLength;
1011*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mStable         = stable;
1012*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mPreference   = ((flags & SPINEL_NET_FLAG_PREFERENCE_MASK) >> SPINEL_NET_FLAG_PREFERENCE_OFFSET);
1013*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mPreferred    = ((flags & SPINEL_NET_FLAG_PREFERRED) != 0);
1014*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mSlaac        = ((flags & SPINEL_NET_FLAG_SLAAC) != 0);
1015*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mDhcp         = ((flags & SPINEL_NET_FLAG_DHCP) != 0);
1016*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mConfigure    = ((flags & SPINEL_NET_FLAG_CONFIGURE) != 0);
1017*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mDefaultRoute = ((flags & SPINEL_NET_FLAG_DEFAULT_ROUTE) != 0);
1018*cfb92d14SAndroid Build Coastguard Worker     borderRouterConfig.mOnMesh       = ((flags & SPINEL_NET_FLAG_ON_MESH) != 0);
1019*cfb92d14SAndroid Build Coastguard Worker 
1020*cfb92d14SAndroid Build Coastguard Worker     // A new field 'TLV flags extended' has been added to the SPINEL_PROP_THREAD_ON_MESH_NETS property.
1021*cfb92d14SAndroid Build Coastguard Worker     // To correctly handle a new field for INSERT command, the additional fields 'isLocal' and 'rloc16' are read and
1022*cfb92d14SAndroid Build Coastguard Worker     // ignored.
1023*cfb92d14SAndroid Build Coastguard Worker     if ((mDecoder.ReadBool(isLocal) == OT_ERROR_NONE) && (mDecoder.ReadUint16(rloc16) == OT_ERROR_NONE) &&
1024*cfb92d14SAndroid Build Coastguard Worker         (mDecoder.ReadUint8(flagsExtended) == OT_ERROR_NONE))
1025*cfb92d14SAndroid Build Coastguard Worker     {
1026*cfb92d14SAndroid Build Coastguard Worker         borderRouterConfig.mNdDns = ((flagsExtended & SPINEL_NET_FLAG_EXT_DNS) != 0);
1027*cfb92d14SAndroid Build Coastguard Worker         borderRouterConfig.mDp    = ((flagsExtended & SPINEL_NET_FLAG_EXT_DP) != 0);
1028*cfb92d14SAndroid Build Coastguard Worker     }
1029*cfb92d14SAndroid Build Coastguard Worker 
1030*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRouterAddOnMeshPrefix(mInstance, &borderRouterConfig);
1031*cfb92d14SAndroid Build Coastguard Worker 
1032*cfb92d14SAndroid Build Coastguard Worker exit:
1033*cfb92d14SAndroid Build Coastguard Worker     return error;
1034*cfb92d14SAndroid Build Coastguard Worker }
1035*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)1036*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_THREAD_ON_MESH_NETS>(void)
1037*cfb92d14SAndroid Build Coastguard Worker {
1038*cfb92d14SAndroid Build Coastguard Worker     otError     error = OT_ERROR_NONE;
1039*cfb92d14SAndroid Build Coastguard Worker     otIp6Prefix ip6Prefix;
1040*cfb92d14SAndroid Build Coastguard Worker     uint8_t     prefixLength;
1041*cfb92d14SAndroid Build Coastguard Worker 
1042*cfb92d14SAndroid Build Coastguard Worker     memset(&ip6Prefix, 0, sizeof(otIp6Prefix));
1043*cfb92d14SAndroid Build Coastguard Worker 
1044*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mAllowLocalNetworkDataChange, error = OT_ERROR_INVALID_STATE);
1045*cfb92d14SAndroid Build Coastguard Worker 
1046*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(ip6Prefix.mPrefix));
1047*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(prefixLength));
1048*cfb92d14SAndroid Build Coastguard Worker 
1049*cfb92d14SAndroid Build Coastguard Worker     ip6Prefix.mLength = prefixLength;
1050*cfb92d14SAndroid Build Coastguard Worker 
1051*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRouterRemoveOnMeshPrefix(mInstance, &ip6Prefix);
1052*cfb92d14SAndroid Build Coastguard Worker 
1053*cfb92d14SAndroid Build Coastguard Worker     // If prefix was not on the list, "remove" command can be considered
1054*cfb92d14SAndroid Build Coastguard Worker     // successful.
1055*cfb92d14SAndroid Build Coastguard Worker 
1056*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NOT_FOUND)
1057*cfb92d14SAndroid Build Coastguard Worker     {
1058*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
1059*cfb92d14SAndroid Build Coastguard Worker     }
1060*cfb92d14SAndroid Build Coastguard Worker 
1061*cfb92d14SAndroid Build Coastguard Worker exit:
1062*cfb92d14SAndroid Build Coastguard Worker     return error;
1063*cfb92d14SAndroid Build Coastguard Worker }
1064*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
1065*cfb92d14SAndroid Build Coastguard Worker 
1066*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1067*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1068*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE>(void)
1069*cfb92d14SAndroid Build Coastguard Worker {
1070*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(mAllowLocalServerDataChange);
1071*cfb92d14SAndroid Build Coastguard Worker }
1072*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1073*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE>(void)
1074*cfb92d14SAndroid Build Coastguard Worker {
1075*cfb92d14SAndroid Build Coastguard Worker     bool    value                    = false;
1076*cfb92d14SAndroid Build Coastguard Worker     otError error                    = OT_ERROR_NONE;
1077*cfb92d14SAndroid Build Coastguard Worker     bool    shouldRegisterWithLeader = false;
1078*cfb92d14SAndroid Build Coastguard Worker 
1079*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(value));
1080*cfb92d14SAndroid Build Coastguard Worker 
1081*cfb92d14SAndroid Build Coastguard Worker     // Register any server data changes on transition from `true` to `false`.
1082*cfb92d14SAndroid Build Coastguard Worker     shouldRegisterWithLeader = mAllowLocalServerDataChange && !value;
1083*cfb92d14SAndroid Build Coastguard Worker 
1084*cfb92d14SAndroid Build Coastguard Worker     mAllowLocalServerDataChange = value;
1085*cfb92d14SAndroid Build Coastguard Worker 
1086*cfb92d14SAndroid Build Coastguard Worker exit:
1087*cfb92d14SAndroid Build Coastguard Worker 
1088*cfb92d14SAndroid Build Coastguard Worker     if (shouldRegisterWithLeader)
1089*cfb92d14SAndroid Build Coastguard Worker     {
1090*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(otServerRegister(mInstance));
1091*cfb92d14SAndroid Build Coastguard Worker     }
1092*cfb92d14SAndroid Build Coastguard Worker 
1093*cfb92d14SAndroid Build Coastguard Worker     return error;
1094*cfb92d14SAndroid Build Coastguard Worker }
1095*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)1096*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_SERVER_SERVICES>(void)
1097*cfb92d14SAndroid Build Coastguard Worker {
1098*cfb92d14SAndroid Build Coastguard Worker     otError         error = OT_ERROR_NONE;
1099*cfb92d14SAndroid Build Coastguard Worker     otServiceConfig cfg;
1100*cfb92d14SAndroid Build Coastguard Worker     bool            stable;
1101*cfb92d14SAndroid Build Coastguard Worker     const uint8_t  *data;
1102*cfb92d14SAndroid Build Coastguard Worker     uint16_t        dataLen;
1103*cfb92d14SAndroid Build Coastguard Worker 
1104*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mAllowLocalServerDataChange, error = OT_ERROR_INVALID_STATE);
1105*cfb92d14SAndroid Build Coastguard Worker 
1106*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(cfg.mEnterpriseNumber));
1107*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(data, dataLen));
1108*cfb92d14SAndroid Build Coastguard Worker 
1109*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit((dataLen <= sizeof(cfg.mServiceData)), error = OT_ERROR_INVALID_ARGS);
1110*cfb92d14SAndroid Build Coastguard Worker     memcpy(cfg.mServiceData, data, dataLen);
1111*cfb92d14SAndroid Build Coastguard Worker 
1112*cfb92d14SAndroid Build Coastguard Worker     static_assert((sizeof(cfg.mServiceData) <= UINT8_MAX), "Cannot handle full range of buffer length");
1113*cfb92d14SAndroid Build Coastguard Worker     cfg.mServiceDataLength = static_cast<uint8_t>(dataLen);
1114*cfb92d14SAndroid Build Coastguard Worker 
1115*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(stable));
1116*cfb92d14SAndroid Build Coastguard Worker     cfg.mServerConfig.mStable = stable;
1117*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(data, dataLen));
1118*cfb92d14SAndroid Build Coastguard Worker 
1119*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit((dataLen <= sizeof(cfg.mServerConfig.mServerData)), error = OT_ERROR_INVALID_ARGS);
1120*cfb92d14SAndroid Build Coastguard Worker     memcpy(cfg.mServerConfig.mServerData, data, dataLen);
1121*cfb92d14SAndroid Build Coastguard Worker 
1122*cfb92d14SAndroid Build Coastguard Worker     static_assert((sizeof(cfg.mServerConfig.mServerData) <= UINT8_MAX), "Cannot handle full range of buffer length");
1123*cfb92d14SAndroid Build Coastguard Worker     cfg.mServerConfig.mServerDataLength = static_cast<uint8_t>(dataLen);
1124*cfb92d14SAndroid Build Coastguard Worker 
1125*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otServerAddService(mInstance, &cfg));
1126*cfb92d14SAndroid Build Coastguard Worker exit:
1127*cfb92d14SAndroid Build Coastguard Worker     return error;
1128*cfb92d14SAndroid Build Coastguard Worker }
1129*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)1130*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_SERVER_SERVICES>(void)
1131*cfb92d14SAndroid Build Coastguard Worker {
1132*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
1133*cfb92d14SAndroid Build Coastguard Worker 
1134*cfb92d14SAndroid Build Coastguard Worker     uint32_t       enterpriseNumber;
1135*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *serviceData;
1136*cfb92d14SAndroid Build Coastguard Worker     uint16_t       serviceDataLength;
1137*cfb92d14SAndroid Build Coastguard Worker 
1138*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mAllowLocalServerDataChange, error = OT_ERROR_INVALID_STATE);
1139*cfb92d14SAndroid Build Coastguard Worker 
1140*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(enterpriseNumber));
1141*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(serviceData, serviceDataLength));
1142*cfb92d14SAndroid Build Coastguard Worker 
1143*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(serviceDataLength <= UINT8_MAX, error = OT_ERROR_INVALID_ARGS);
1144*cfb92d14SAndroid Build Coastguard Worker 
1145*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otServerRemoveService(mInstance, enterpriseNumber, serviceData,
1146*cfb92d14SAndroid Build Coastguard Worker                                                 static_cast<uint8_t>(serviceDataLength)));
1147*cfb92d14SAndroid Build Coastguard Worker exit:
1148*cfb92d14SAndroid Build Coastguard Worker     return error;
1149*cfb92d14SAndroid Build Coastguard Worker }
1150*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1151*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SERVER_SERVICES>(void)
1152*cfb92d14SAndroid Build Coastguard Worker {
1153*cfb92d14SAndroid Build Coastguard Worker     otError               error    = OT_ERROR_NONE;
1154*cfb92d14SAndroid Build Coastguard Worker     otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
1155*cfb92d14SAndroid Build Coastguard Worker     otServiceConfig       cfg;
1156*cfb92d14SAndroid Build Coastguard Worker 
1157*cfb92d14SAndroid Build Coastguard Worker     while (otServerGetNextService(mInstance, &iterator, &cfg) == OT_ERROR_NONE)
1158*cfb92d14SAndroid Build Coastguard Worker     {
1159*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1160*cfb92d14SAndroid Build Coastguard Worker 
1161*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(cfg.mEnterpriseNumber));
1162*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteDataWithLen(cfg.mServiceData, cfg.mServiceDataLength));
1163*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(cfg.mServerConfig.mStable));
1164*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(
1165*cfb92d14SAndroid Build Coastguard Worker             error = mEncoder.WriteDataWithLen(cfg.mServerConfig.mServerData, cfg.mServerConfig.mServerDataLength));
1166*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(cfg.mServerConfig.mRloc16));
1167*cfb92d14SAndroid Build Coastguard Worker 
1168*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1169*cfb92d14SAndroid Build Coastguard Worker     }
1170*cfb92d14SAndroid Build Coastguard Worker exit:
1171*cfb92d14SAndroid Build Coastguard Worker     return error;
1172*cfb92d14SAndroid Build Coastguard Worker }
1173*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1174*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1175*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SERVER_LEADER_SERVICES>(void)
1176*cfb92d14SAndroid Build Coastguard Worker {
1177*cfb92d14SAndroid Build Coastguard Worker     otError               error    = OT_ERROR_NONE;
1178*cfb92d14SAndroid Build Coastguard Worker     otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
1179*cfb92d14SAndroid Build Coastguard Worker     otServiceConfig       cfg;
1180*cfb92d14SAndroid Build Coastguard Worker 
1181*cfb92d14SAndroid Build Coastguard Worker     while (otNetDataGetNextService(mInstance, &iterator, &cfg) == OT_ERROR_NONE)
1182*cfb92d14SAndroid Build Coastguard Worker     {
1183*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1184*cfb92d14SAndroid Build Coastguard Worker 
1185*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(cfg.mServiceId));
1186*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(cfg.mEnterpriseNumber));
1187*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteDataWithLen(cfg.mServiceData, cfg.mServiceDataLength));
1188*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(cfg.mServerConfig.mStable));
1189*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(
1190*cfb92d14SAndroid Build Coastguard Worker             error = mEncoder.WriteDataWithLen(cfg.mServerConfig.mServerData, cfg.mServerConfig.mServerDataLength));
1191*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(cfg.mServerConfig.mRloc16));
1192*cfb92d14SAndroid Build Coastguard Worker 
1193*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1194*cfb92d14SAndroid Build Coastguard Worker     }
1195*cfb92d14SAndroid Build Coastguard Worker exit:
1196*cfb92d14SAndroid Build Coastguard Worker     return error;
1197*cfb92d14SAndroid Build Coastguard Worker }
1198*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1199*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG>(void)
1200*cfb92d14SAndroid Build Coastguard Worker {
1201*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(mDiscoveryScanJoinerFlag);
1202*cfb92d14SAndroid Build Coastguard Worker }
1203*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1204*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG>(void)
1205*cfb92d14SAndroid Build Coastguard Worker {
1206*cfb92d14SAndroid Build Coastguard Worker     return mDecoder.ReadBool(mDiscoveryScanJoinerFlag);
1207*cfb92d14SAndroid Build Coastguard Worker }
1208*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1209*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING>(void)
1210*cfb92d14SAndroid Build Coastguard Worker {
1211*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(mDiscoveryScanEnableFiltering);
1212*cfb92d14SAndroid Build Coastguard Worker }
1213*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1214*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING>(void)
1215*cfb92d14SAndroid Build Coastguard Worker {
1216*cfb92d14SAndroid Build Coastguard Worker     return mDecoder.ReadBool(mDiscoveryScanEnableFiltering);
1217*cfb92d14SAndroid Build Coastguard Worker }
1218*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1219*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID>(void)
1220*cfb92d14SAndroid Build Coastguard Worker {
1221*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint16(mDiscoveryScanPanId);
1222*cfb92d14SAndroid Build Coastguard Worker }
1223*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1224*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID>(void)
1225*cfb92d14SAndroid Build Coastguard Worker {
1226*cfb92d14SAndroid Build Coastguard Worker     return mDecoder.ReadUint16(mDiscoveryScanPanId);
1227*cfb92d14SAndroid Build Coastguard Worker }
1228*cfb92d14SAndroid Build Coastguard Worker 
EncodeOperationalDataset(const otOperationalDataset & aDataset)1229*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::EncodeOperationalDataset(const otOperationalDataset &aDataset)
1230*cfb92d14SAndroid Build Coastguard Worker {
1231*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
1232*cfb92d14SAndroid Build Coastguard Worker 
1233*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsActiveTimestampPresent)
1234*cfb92d14SAndroid Build Coastguard Worker     {
1235*cfb92d14SAndroid Build Coastguard Worker         const otTimestamp &activeTimestamp = aDataset.mActiveTimestamp;
1236*cfb92d14SAndroid Build Coastguard Worker 
1237*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1238*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP));
1239*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint64(activeTimestamp.mSeconds));
1240*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1241*cfb92d14SAndroid Build Coastguard Worker     }
1242*cfb92d14SAndroid Build Coastguard Worker 
1243*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsPendingTimestampPresent)
1244*cfb92d14SAndroid Build Coastguard Worker     {
1245*cfb92d14SAndroid Build Coastguard Worker         const otTimestamp &pendingTimestamp = aDataset.mPendingTimestamp;
1246*cfb92d14SAndroid Build Coastguard Worker 
1247*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1248*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_PENDING_TIMESTAMP));
1249*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint64(pendingTimestamp.mSeconds));
1250*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1251*cfb92d14SAndroid Build Coastguard Worker     }
1252*cfb92d14SAndroid Build Coastguard Worker 
1253*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsNetworkKeyPresent)
1254*cfb92d14SAndroid Build Coastguard Worker     {
1255*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1256*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_NET_NETWORK_KEY));
1257*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteData(aDataset.mNetworkKey.m8, OT_NETWORK_KEY_SIZE));
1258*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1259*cfb92d14SAndroid Build Coastguard Worker     }
1260*cfb92d14SAndroid Build Coastguard Worker 
1261*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsNetworkNamePresent)
1262*cfb92d14SAndroid Build Coastguard Worker     {
1263*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1264*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_NET_NETWORK_NAME));
1265*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUtf8(aDataset.mNetworkName.m8));
1266*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1267*cfb92d14SAndroid Build Coastguard Worker     }
1268*cfb92d14SAndroid Build Coastguard Worker 
1269*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsExtendedPanIdPresent)
1270*cfb92d14SAndroid Build Coastguard Worker     {
1271*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1272*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_NET_XPANID));
1273*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteData(aDataset.mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE));
1274*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1275*cfb92d14SAndroid Build Coastguard Worker     }
1276*cfb92d14SAndroid Build Coastguard Worker 
1277*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsMeshLocalPrefixPresent)
1278*cfb92d14SAndroid Build Coastguard Worker     {
1279*cfb92d14SAndroid Build Coastguard Worker         otIp6Address addr;
1280*cfb92d14SAndroid Build Coastguard Worker 
1281*cfb92d14SAndroid Build Coastguard Worker         memcpy(addr.mFields.m8, aDataset.mMeshLocalPrefix.m8, 8);
1282*cfb92d14SAndroid Build Coastguard Worker         memset(addr.mFields.m8 + 8, 0, 8); // Zero out the last 8 bytes.
1283*cfb92d14SAndroid Build Coastguard Worker 
1284*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1285*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_IPV6_ML_PREFIX));
1286*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(addr));             // Mesh local prefix
1287*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(OT_IP6_PREFIX_BITSIZE)); // Prefix length (in bits)
1288*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1289*cfb92d14SAndroid Build Coastguard Worker     }
1290*cfb92d14SAndroid Build Coastguard Worker 
1291*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsDelayPresent)
1292*cfb92d14SAndroid Build Coastguard Worker     {
1293*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1294*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_DELAY_TIMER));
1295*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(aDataset.mDelay));
1296*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1297*cfb92d14SAndroid Build Coastguard Worker     }
1298*cfb92d14SAndroid Build Coastguard Worker 
1299*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsPanIdPresent)
1300*cfb92d14SAndroid Build Coastguard Worker     {
1301*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1302*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_MAC_15_4_PANID));
1303*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(aDataset.mPanId));
1304*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1305*cfb92d14SAndroid Build Coastguard Worker     }
1306*cfb92d14SAndroid Build Coastguard Worker 
1307*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsChannelPresent)
1308*cfb92d14SAndroid Build Coastguard Worker     {
1309*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1310*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_PHY_CHAN));
1311*cfb92d14SAndroid Build Coastguard Worker 
1312*cfb92d14SAndroid Build Coastguard Worker         // The channel is stored in Dataset as `uint16_t` (to accommodate
1313*cfb92d14SAndroid Build Coastguard Worker         // larger number of channels in sub-GHz band),  however the current
1314*cfb92d14SAndroid Build Coastguard Worker         // definition of `SPINEL_PROP_PHY_CHAN` property limits the channel
1315*cfb92d14SAndroid Build Coastguard Worker         // to a `uint8_t`.
1316*cfb92d14SAndroid Build Coastguard Worker 
1317*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(static_cast<uint8_t>(aDataset.mChannel)));
1318*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1319*cfb92d14SAndroid Build Coastguard Worker     }
1320*cfb92d14SAndroid Build Coastguard Worker 
1321*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsPskcPresent)
1322*cfb92d14SAndroid Build Coastguard Worker     {
1323*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1324*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_NET_PSKC));
1325*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteData(aDataset.mPskc.m8, sizeof(spinel_net_pskc_t)));
1326*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1327*cfb92d14SAndroid Build Coastguard Worker     }
1328*cfb92d14SAndroid Build Coastguard Worker 
1329*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsSecurityPolicyPresent)
1330*cfb92d14SAndroid Build Coastguard Worker     {
1331*cfb92d14SAndroid Build Coastguard Worker         uint8_t flags[2];
1332*cfb92d14SAndroid Build Coastguard Worker 
1333*cfb92d14SAndroid Build Coastguard Worker         static_cast<const SecurityPolicy &>(aDataset.mSecurityPolicy).GetFlags(flags, sizeof(flags));
1334*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1335*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_DATASET_SECURITY_POLICY));
1336*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(aDataset.mSecurityPolicy.mRotationTime));
1337*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(flags[0]));
1338*cfb92d14SAndroid Build Coastguard Worker         if (otThreadGetVersion() >= OT_THREAD_VERSION_1_2)
1339*cfb92d14SAndroid Build Coastguard Worker         {
1340*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mEncoder.WriteUint8(flags[1]));
1341*cfb92d14SAndroid Build Coastguard Worker         }
1342*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1343*cfb92d14SAndroid Build Coastguard Worker     }
1344*cfb92d14SAndroid Build Coastguard Worker 
1345*cfb92d14SAndroid Build Coastguard Worker     if (aDataset.mComponents.mIsChannelMaskPresent)
1346*cfb92d14SAndroid Build Coastguard Worker     {
1347*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
1348*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROP_PHY_CHAN_SUPPORTED));
1349*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = EncodeChannelMask(aDataset.mChannelMask));
1350*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
1351*cfb92d14SAndroid Build Coastguard Worker     }
1352*cfb92d14SAndroid Build Coastguard Worker 
1353*cfb92d14SAndroid Build Coastguard Worker exit:
1354*cfb92d14SAndroid Build Coastguard Worker     return error;
1355*cfb92d14SAndroid Build Coastguard Worker }
1356*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1357*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ACTIVE_DATASET>(void)
1358*cfb92d14SAndroid Build Coastguard Worker {
1359*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1360*cfb92d14SAndroid Build Coastguard Worker 
1361*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otDatasetGetActive(mInstance, &dataset));
1362*cfb92d14SAndroid Build Coastguard Worker     return EncodeOperationalDataset(dataset);
1363*cfb92d14SAndroid Build Coastguard Worker }
1364*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1365*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_PENDING_DATASET>(void)
1366*cfb92d14SAndroid Build Coastguard Worker {
1367*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1368*cfb92d14SAndroid Build Coastguard Worker 
1369*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otDatasetGetPending(mInstance, &dataset));
1370*cfb92d14SAndroid Build Coastguard Worker     return EncodeOperationalDataset(dataset);
1371*cfb92d14SAndroid Build Coastguard Worker }
1372*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1373*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ACTIVE_DATASET_TLVS>(void)
1374*cfb92d14SAndroid Build Coastguard Worker {
1375*cfb92d14SAndroid Build Coastguard Worker     otError                  error = OT_ERROR_NONE;
1376*cfb92d14SAndroid Build Coastguard Worker     otOperationalDatasetTlvs dataset;
1377*cfb92d14SAndroid Build Coastguard Worker 
1378*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otDatasetGetActiveTlvs(mInstance, &dataset));
1379*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteData(dataset.mTlvs, dataset.mLength));
1380*cfb92d14SAndroid Build Coastguard Worker 
1381*cfb92d14SAndroid Build Coastguard Worker exit:
1382*cfb92d14SAndroid Build Coastguard Worker     return error;
1383*cfb92d14SAndroid Build Coastguard Worker }
1384*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1385*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_PENDING_DATASET_TLVS>(void)
1386*cfb92d14SAndroid Build Coastguard Worker {
1387*cfb92d14SAndroid Build Coastguard Worker     otError                  error = OT_ERROR_NONE;
1388*cfb92d14SAndroid Build Coastguard Worker     otOperationalDatasetTlvs dataset;
1389*cfb92d14SAndroid Build Coastguard Worker 
1390*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otDatasetGetPendingTlvs(mInstance, &dataset));
1391*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteData(dataset.mTlvs, dataset.mLength));
1392*cfb92d14SAndroid Build Coastguard Worker 
1393*cfb92d14SAndroid Build Coastguard Worker exit:
1394*cfb92d14SAndroid Build Coastguard Worker     return error;
1395*cfb92d14SAndroid Build Coastguard Worker }
1396*cfb92d14SAndroid Build Coastguard Worker 
DecodeOperationalDataset(otOperationalDataset & aDataset,const uint8_t ** aTlvs,uint8_t * aTlvsLength,const otIp6Address ** aDestIpAddress,bool aAllowEmptyValues)1397*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::DecodeOperationalDataset(otOperationalDataset &aDataset,
1398*cfb92d14SAndroid Build Coastguard Worker                                           const uint8_t       **aTlvs,
1399*cfb92d14SAndroid Build Coastguard Worker                                           uint8_t              *aTlvsLength,
1400*cfb92d14SAndroid Build Coastguard Worker                                           const otIp6Address  **aDestIpAddress,
1401*cfb92d14SAndroid Build Coastguard Worker                                           bool                  aAllowEmptyValues)
1402*cfb92d14SAndroid Build Coastguard Worker {
1403*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
1404*cfb92d14SAndroid Build Coastguard Worker 
1405*cfb92d14SAndroid Build Coastguard Worker     memset(&aDataset, 0, sizeof(otOperationalDataset));
1406*cfb92d14SAndroid Build Coastguard Worker 
1407*cfb92d14SAndroid Build Coastguard Worker     if (aTlvs != nullptr)
1408*cfb92d14SAndroid Build Coastguard Worker     {
1409*cfb92d14SAndroid Build Coastguard Worker         *aTlvs = nullptr;
1410*cfb92d14SAndroid Build Coastguard Worker     }
1411*cfb92d14SAndroid Build Coastguard Worker 
1412*cfb92d14SAndroid Build Coastguard Worker     if (aTlvsLength != nullptr)
1413*cfb92d14SAndroid Build Coastguard Worker     {
1414*cfb92d14SAndroid Build Coastguard Worker         *aTlvsLength = 0;
1415*cfb92d14SAndroid Build Coastguard Worker     }
1416*cfb92d14SAndroid Build Coastguard Worker 
1417*cfb92d14SAndroid Build Coastguard Worker     if (aDestIpAddress != nullptr)
1418*cfb92d14SAndroid Build Coastguard Worker     {
1419*cfb92d14SAndroid Build Coastguard Worker         *aDestIpAddress = nullptr;
1420*cfb92d14SAndroid Build Coastguard Worker     }
1421*cfb92d14SAndroid Build Coastguard Worker 
1422*cfb92d14SAndroid Build Coastguard Worker     while (!mDecoder.IsAllReadInStruct())
1423*cfb92d14SAndroid Build Coastguard Worker     {
1424*cfb92d14SAndroid Build Coastguard Worker         unsigned int propKey;
1425*cfb92d14SAndroid Build Coastguard Worker 
1426*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.OpenStruct());
1427*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUintPacked(propKey));
1428*cfb92d14SAndroid Build Coastguard Worker 
1429*cfb92d14SAndroid Build Coastguard Worker         switch (static_cast<spinel_prop_key_t>(propKey))
1430*cfb92d14SAndroid Build Coastguard Worker         {
1431*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP:
1432*cfb92d14SAndroid Build Coastguard Worker 
1433*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1434*cfb92d14SAndroid Build Coastguard Worker             {
1435*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mActiveTimestamp.mSeconds));
1436*cfb92d14SAndroid Build Coastguard Worker                 aDataset.mActiveTimestamp.mTicks         = 0;
1437*cfb92d14SAndroid Build Coastguard Worker                 aDataset.mActiveTimestamp.mAuthoritative = false;
1438*cfb92d14SAndroid Build Coastguard Worker             }
1439*cfb92d14SAndroid Build Coastguard Worker 
1440*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsActiveTimestampPresent = true;
1441*cfb92d14SAndroid Build Coastguard Worker             break;
1442*cfb92d14SAndroid Build Coastguard Worker 
1443*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_DATASET_PENDING_TIMESTAMP:
1444*cfb92d14SAndroid Build Coastguard Worker 
1445*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1446*cfb92d14SAndroid Build Coastguard Worker             {
1447*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint64(aDataset.mPendingTimestamp.mSeconds));
1448*cfb92d14SAndroid Build Coastguard Worker                 aDataset.mPendingTimestamp.mTicks         = 0;
1449*cfb92d14SAndroid Build Coastguard Worker                 aDataset.mPendingTimestamp.mAuthoritative = false;
1450*cfb92d14SAndroid Build Coastguard Worker             }
1451*cfb92d14SAndroid Build Coastguard Worker 
1452*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsPendingTimestampPresent = true;
1453*cfb92d14SAndroid Build Coastguard Worker             break;
1454*cfb92d14SAndroid Build Coastguard Worker 
1455*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_NET_NETWORK_KEY:
1456*cfb92d14SAndroid Build Coastguard Worker 
1457*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1458*cfb92d14SAndroid Build Coastguard Worker             {
1459*cfb92d14SAndroid Build Coastguard Worker                 const uint8_t *key;
1460*cfb92d14SAndroid Build Coastguard Worker                 uint16_t       len;
1461*cfb92d14SAndroid Build Coastguard Worker 
1462*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadData(key, len));
1463*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(len == OT_NETWORK_KEY_SIZE, error = OT_ERROR_INVALID_ARGS);
1464*cfb92d14SAndroid Build Coastguard Worker                 memcpy(aDataset.mNetworkKey.m8, key, len);
1465*cfb92d14SAndroid Build Coastguard Worker             }
1466*cfb92d14SAndroid Build Coastguard Worker 
1467*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsNetworkKeyPresent = true;
1468*cfb92d14SAndroid Build Coastguard Worker             break;
1469*cfb92d14SAndroid Build Coastguard Worker 
1470*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_NET_NETWORK_NAME:
1471*cfb92d14SAndroid Build Coastguard Worker 
1472*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1473*cfb92d14SAndroid Build Coastguard Worker             {
1474*cfb92d14SAndroid Build Coastguard Worker                 const char *name;
1475*cfb92d14SAndroid Build Coastguard Worker                 size_t      len;
1476*cfb92d14SAndroid Build Coastguard Worker 
1477*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUtf8(name));
1478*cfb92d14SAndroid Build Coastguard Worker                 len = strlen(name);
1479*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(len <= OT_NETWORK_NAME_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
1480*cfb92d14SAndroid Build Coastguard Worker                 memcpy(aDataset.mNetworkName.m8, name, len + 1);
1481*cfb92d14SAndroid Build Coastguard Worker             }
1482*cfb92d14SAndroid Build Coastguard Worker 
1483*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsNetworkNamePresent = true;
1484*cfb92d14SAndroid Build Coastguard Worker             break;
1485*cfb92d14SAndroid Build Coastguard Worker 
1486*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_NET_XPANID:
1487*cfb92d14SAndroid Build Coastguard Worker 
1488*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1489*cfb92d14SAndroid Build Coastguard Worker             {
1490*cfb92d14SAndroid Build Coastguard Worker                 const uint8_t *xpanid;
1491*cfb92d14SAndroid Build Coastguard Worker                 uint16_t       len;
1492*cfb92d14SAndroid Build Coastguard Worker 
1493*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadData(xpanid, len));
1494*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(len == OT_EXT_PAN_ID_SIZE, error = OT_ERROR_INVALID_ARGS);
1495*cfb92d14SAndroid Build Coastguard Worker                 memcpy(aDataset.mExtendedPanId.m8, xpanid, len);
1496*cfb92d14SAndroid Build Coastguard Worker             }
1497*cfb92d14SAndroid Build Coastguard Worker 
1498*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsExtendedPanIdPresent = true;
1499*cfb92d14SAndroid Build Coastguard Worker             break;
1500*cfb92d14SAndroid Build Coastguard Worker 
1501*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_IPV6_ML_PREFIX:
1502*cfb92d14SAndroid Build Coastguard Worker 
1503*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1504*cfb92d14SAndroid Build Coastguard Worker             {
1505*cfb92d14SAndroid Build Coastguard Worker                 const otIp6Address *addr;
1506*cfb92d14SAndroid Build Coastguard Worker                 uint8_t             prefixLen;
1507*cfb92d14SAndroid Build Coastguard Worker 
1508*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadIp6Address(addr));
1509*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint8(prefixLen));
1510*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(prefixLen == OT_IP6_PREFIX_BITSIZE, error = OT_ERROR_INVALID_ARGS);
1511*cfb92d14SAndroid Build Coastguard Worker                 memcpy(aDataset.mMeshLocalPrefix.m8, addr, OT_MESH_LOCAL_PREFIX_SIZE);
1512*cfb92d14SAndroid Build Coastguard Worker             }
1513*cfb92d14SAndroid Build Coastguard Worker 
1514*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsMeshLocalPrefixPresent = true;
1515*cfb92d14SAndroid Build Coastguard Worker             break;
1516*cfb92d14SAndroid Build Coastguard Worker 
1517*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_DATASET_DELAY_TIMER:
1518*cfb92d14SAndroid Build Coastguard Worker 
1519*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1520*cfb92d14SAndroid Build Coastguard Worker             {
1521*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint32(aDataset.mDelay));
1522*cfb92d14SAndroid Build Coastguard Worker             }
1523*cfb92d14SAndroid Build Coastguard Worker 
1524*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsDelayPresent = true;
1525*cfb92d14SAndroid Build Coastguard Worker             break;
1526*cfb92d14SAndroid Build Coastguard Worker 
1527*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_MAC_15_4_PANID:
1528*cfb92d14SAndroid Build Coastguard Worker 
1529*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1530*cfb92d14SAndroid Build Coastguard Worker             {
1531*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint16(aDataset.mPanId));
1532*cfb92d14SAndroid Build Coastguard Worker             }
1533*cfb92d14SAndroid Build Coastguard Worker 
1534*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsPanIdPresent = true;
1535*cfb92d14SAndroid Build Coastguard Worker             break;
1536*cfb92d14SAndroid Build Coastguard Worker 
1537*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_CHAN:
1538*cfb92d14SAndroid Build Coastguard Worker 
1539*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1540*cfb92d14SAndroid Build Coastguard Worker             {
1541*cfb92d14SAndroid Build Coastguard Worker                 uint8_t channel;
1542*cfb92d14SAndroid Build Coastguard Worker 
1543*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint8(channel));
1544*cfb92d14SAndroid Build Coastguard Worker                 aDataset.mChannel = channel;
1545*cfb92d14SAndroid Build Coastguard Worker             }
1546*cfb92d14SAndroid Build Coastguard Worker 
1547*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsChannelPresent = true;
1548*cfb92d14SAndroid Build Coastguard Worker             break;
1549*cfb92d14SAndroid Build Coastguard Worker 
1550*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_NET_PSKC:
1551*cfb92d14SAndroid Build Coastguard Worker 
1552*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1553*cfb92d14SAndroid Build Coastguard Worker             {
1554*cfb92d14SAndroid Build Coastguard Worker                 const uint8_t *psk;
1555*cfb92d14SAndroid Build Coastguard Worker                 uint16_t       len;
1556*cfb92d14SAndroid Build Coastguard Worker 
1557*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadData(psk, len));
1558*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(len == OT_PSKC_MAX_SIZE, error = OT_ERROR_INVALID_ARGS);
1559*cfb92d14SAndroid Build Coastguard Worker                 memcpy(aDataset.mPskc.m8, psk, OT_PSKC_MAX_SIZE);
1560*cfb92d14SAndroid Build Coastguard Worker             }
1561*cfb92d14SAndroid Build Coastguard Worker 
1562*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsPskcPresent = true;
1563*cfb92d14SAndroid Build Coastguard Worker             break;
1564*cfb92d14SAndroid Build Coastguard Worker 
1565*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_DATASET_SECURITY_POLICY:
1566*cfb92d14SAndroid Build Coastguard Worker 
1567*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1568*cfb92d14SAndroid Build Coastguard Worker             {
1569*cfb92d14SAndroid Build Coastguard Worker                 uint8_t flags[2];
1570*cfb92d14SAndroid Build Coastguard Worker                 uint8_t flagsLength = 1;
1571*cfb92d14SAndroid Build Coastguard Worker 
1572*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint16(aDataset.mSecurityPolicy.mRotationTime));
1573*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadUint8(flags[0]));
1574*cfb92d14SAndroid Build Coastguard Worker                 if (otThreadGetVersion() >= OT_THREAD_VERSION_1_2 && mDecoder.GetRemainingLengthInStruct() > 0)
1575*cfb92d14SAndroid Build Coastguard Worker                 {
1576*cfb92d14SAndroid Build Coastguard Worker                     SuccessOrExit(error = mDecoder.ReadUint8(flags[1]));
1577*cfb92d14SAndroid Build Coastguard Worker                     ++flagsLength;
1578*cfb92d14SAndroid Build Coastguard Worker                 }
1579*cfb92d14SAndroid Build Coastguard Worker                 static_cast<SecurityPolicy &>(aDataset.mSecurityPolicy).SetFlags(flags, flagsLength);
1580*cfb92d14SAndroid Build Coastguard Worker             }
1581*cfb92d14SAndroid Build Coastguard Worker 
1582*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsSecurityPolicyPresent = true;
1583*cfb92d14SAndroid Build Coastguard Worker             break;
1584*cfb92d14SAndroid Build Coastguard Worker 
1585*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_CHAN_SUPPORTED:
1586*cfb92d14SAndroid Build Coastguard Worker 
1587*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1588*cfb92d14SAndroid Build Coastguard Worker             {
1589*cfb92d14SAndroid Build Coastguard Worker                 uint8_t channel;
1590*cfb92d14SAndroid Build Coastguard Worker 
1591*cfb92d14SAndroid Build Coastguard Worker                 aDataset.mChannelMask = 0;
1592*cfb92d14SAndroid Build Coastguard Worker 
1593*cfb92d14SAndroid Build Coastguard Worker                 while (!mDecoder.IsAllReadInStruct())
1594*cfb92d14SAndroid Build Coastguard Worker                 {
1595*cfb92d14SAndroid Build Coastguard Worker                     SuccessOrExit(error = mDecoder.ReadUint8(channel));
1596*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrExit(channel <= 31, error = OT_ERROR_INVALID_ARGS);
1597*cfb92d14SAndroid Build Coastguard Worker                     aDataset.mChannelMask |= (1UL << channel);
1598*cfb92d14SAndroid Build Coastguard Worker                 }
1599*cfb92d14SAndroid Build Coastguard Worker             }
1600*cfb92d14SAndroid Build Coastguard Worker 
1601*cfb92d14SAndroid Build Coastguard Worker             aDataset.mComponents.mIsChannelMaskPresent = true;
1602*cfb92d14SAndroid Build Coastguard Worker             break;
1603*cfb92d14SAndroid Build Coastguard Worker 
1604*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_DATASET_RAW_TLVS:
1605*cfb92d14SAndroid Build Coastguard Worker 
1606*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1607*cfb92d14SAndroid Build Coastguard Worker             {
1608*cfb92d14SAndroid Build Coastguard Worker                 const uint8_t *tlvs;
1609*cfb92d14SAndroid Build Coastguard Worker                 uint16_t       len;
1610*cfb92d14SAndroid Build Coastguard Worker 
1611*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadData(tlvs, len));
1612*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrExit(len <= 255, error = OT_ERROR_INVALID_ARGS);
1613*cfb92d14SAndroid Build Coastguard Worker 
1614*cfb92d14SAndroid Build Coastguard Worker                 if (aTlvs != nullptr)
1615*cfb92d14SAndroid Build Coastguard Worker                 {
1616*cfb92d14SAndroid Build Coastguard Worker                     *aTlvs = tlvs;
1617*cfb92d14SAndroid Build Coastguard Worker                 }
1618*cfb92d14SAndroid Build Coastguard Worker 
1619*cfb92d14SAndroid Build Coastguard Worker                 if (aTlvsLength != nullptr)
1620*cfb92d14SAndroid Build Coastguard Worker                 {
1621*cfb92d14SAndroid Build Coastguard Worker                     *aTlvsLength = static_cast<uint8_t>(len);
1622*cfb92d14SAndroid Build Coastguard Worker                 }
1623*cfb92d14SAndroid Build Coastguard Worker             }
1624*cfb92d14SAndroid Build Coastguard Worker 
1625*cfb92d14SAndroid Build Coastguard Worker             break;
1626*cfb92d14SAndroid Build Coastguard Worker 
1627*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_DATASET_DEST_ADDRESS:
1628*cfb92d14SAndroid Build Coastguard Worker 
1629*cfb92d14SAndroid Build Coastguard Worker             if (!aAllowEmptyValues || !mDecoder.IsAllReadInStruct())
1630*cfb92d14SAndroid Build Coastguard Worker             {
1631*cfb92d14SAndroid Build Coastguard Worker                 const otIp6Address *addr;
1632*cfb92d14SAndroid Build Coastguard Worker 
1633*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = mDecoder.ReadIp6Address(addr));
1634*cfb92d14SAndroid Build Coastguard Worker 
1635*cfb92d14SAndroid Build Coastguard Worker                 if (aDestIpAddress != nullptr)
1636*cfb92d14SAndroid Build Coastguard Worker                 {
1637*cfb92d14SAndroid Build Coastguard Worker                     *aDestIpAddress = addr;
1638*cfb92d14SAndroid Build Coastguard Worker                 }
1639*cfb92d14SAndroid Build Coastguard Worker             }
1640*cfb92d14SAndroid Build Coastguard Worker 
1641*cfb92d14SAndroid Build Coastguard Worker             break;
1642*cfb92d14SAndroid Build Coastguard Worker 
1643*cfb92d14SAndroid Build Coastguard Worker         default:
1644*cfb92d14SAndroid Build Coastguard Worker             break;
1645*cfb92d14SAndroid Build Coastguard Worker         }
1646*cfb92d14SAndroid Build Coastguard Worker 
1647*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.CloseStruct());
1648*cfb92d14SAndroid Build Coastguard Worker     }
1649*cfb92d14SAndroid Build Coastguard Worker 
1650*cfb92d14SAndroid Build Coastguard Worker exit:
1651*cfb92d14SAndroid Build Coastguard Worker     return error;
1652*cfb92d14SAndroid Build Coastguard Worker }
1653*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1654*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ACTIVE_DATASET>(void)
1655*cfb92d14SAndroid Build Coastguard Worker {
1656*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
1657*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1658*cfb92d14SAndroid Build Coastguard Worker 
1659*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeOperationalDataset(dataset));
1660*cfb92d14SAndroid Build Coastguard Worker     error = otDatasetSetActive(mInstance, &dataset);
1661*cfb92d14SAndroid Build Coastguard Worker 
1662*cfb92d14SAndroid Build Coastguard Worker exit:
1663*cfb92d14SAndroid Build Coastguard Worker     return error;
1664*cfb92d14SAndroid Build Coastguard Worker }
1665*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1666*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_PENDING_DATASET>(void)
1667*cfb92d14SAndroid Build Coastguard Worker {
1668*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
1669*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1670*cfb92d14SAndroid Build Coastguard Worker 
1671*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeOperationalDataset(dataset));
1672*cfb92d14SAndroid Build Coastguard Worker     error = otDatasetSetPending(mInstance, &dataset);
1673*cfb92d14SAndroid Build Coastguard Worker 
1674*cfb92d14SAndroid Build Coastguard Worker exit:
1675*cfb92d14SAndroid Build Coastguard Worker     return error;
1676*cfb92d14SAndroid Build Coastguard Worker }
1677*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1678*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_ACTIVE_DATASET_TLVS>(void)
1679*cfb92d14SAndroid Build Coastguard Worker {
1680*cfb92d14SAndroid Build Coastguard Worker     otError                  error = OT_ERROR_NONE;
1681*cfb92d14SAndroid Build Coastguard Worker     const uint8_t           *tlvs  = nullptr;
1682*cfb92d14SAndroid Build Coastguard Worker     uint16_t                 len   = 0;
1683*cfb92d14SAndroid Build Coastguard Worker     otOperationalDatasetTlvs dataset;
1684*cfb92d14SAndroid Build Coastguard Worker 
1685*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadData(tlvs, len));
1686*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(len <= OT_OPERATIONAL_DATASET_MAX_LENGTH, error = OT_ERROR_PARSE);
1687*cfb92d14SAndroid Build Coastguard Worker     memcpy(&dataset.mTlvs, tlvs, len);
1688*cfb92d14SAndroid Build Coastguard Worker     dataset.mLength = static_cast<uint8_t>(len);
1689*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otDatasetSetActiveTlvs(mInstance, &dataset));
1690*cfb92d14SAndroid Build Coastguard Worker 
1691*cfb92d14SAndroid Build Coastguard Worker exit:
1692*cfb92d14SAndroid Build Coastguard Worker     return error;
1693*cfb92d14SAndroid Build Coastguard Worker }
1694*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1695*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_PENDING_DATASET_TLVS>(void)
1696*cfb92d14SAndroid Build Coastguard Worker {
1697*cfb92d14SAndroid Build Coastguard Worker     otError                  error = OT_ERROR_NONE;
1698*cfb92d14SAndroid Build Coastguard Worker     const uint8_t           *tlvs  = nullptr;
1699*cfb92d14SAndroid Build Coastguard Worker     uint16_t                 len   = 0;
1700*cfb92d14SAndroid Build Coastguard Worker     otOperationalDatasetTlvs dataset;
1701*cfb92d14SAndroid Build Coastguard Worker 
1702*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadData(tlvs, len));
1703*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(len <= OT_OPERATIONAL_DATASET_MAX_LENGTH, error = OT_ERROR_PARSE);
1704*cfb92d14SAndroid Build Coastguard Worker     memcpy(&dataset.mTlvs, tlvs, len);
1705*cfb92d14SAndroid Build Coastguard Worker     dataset.mLength = static_cast<uint8_t>(len);
1706*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otDatasetSetPendingTlvs(mInstance, &dataset));
1707*cfb92d14SAndroid Build Coastguard Worker 
1708*cfb92d14SAndroid Build Coastguard Worker exit:
1709*cfb92d14SAndroid Build Coastguard Worker     return error;
1710*cfb92d14SAndroid Build Coastguard Worker }
1711*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1712*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET>(void)
1713*cfb92d14SAndroid Build Coastguard Worker {
1714*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
1715*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1716*cfb92d14SAndroid Build Coastguard Worker     const uint8_t       *extraTlvs;
1717*cfb92d14SAndroid Build Coastguard Worker     uint8_t              extraTlvsLength;
1718*cfb92d14SAndroid Build Coastguard Worker 
1719*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeOperationalDataset(dataset, &extraTlvs, &extraTlvsLength));
1720*cfb92d14SAndroid Build Coastguard Worker     error = otDatasetSendMgmtActiveSet(mInstance, &dataset, extraTlvs, extraTlvsLength, /* aCallback */ nullptr,
1721*cfb92d14SAndroid Build Coastguard Worker                                        /* aContext */ nullptr);
1722*cfb92d14SAndroid Build Coastguard Worker 
1723*cfb92d14SAndroid Build Coastguard Worker exit:
1724*cfb92d14SAndroid Build Coastguard Worker     return error;
1725*cfb92d14SAndroid Build Coastguard Worker }
1726*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1727*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET>(void)
1728*cfb92d14SAndroid Build Coastguard Worker {
1729*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
1730*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1731*cfb92d14SAndroid Build Coastguard Worker     const uint8_t       *extraTlvs;
1732*cfb92d14SAndroid Build Coastguard Worker     uint8_t              extraTlvsLength;
1733*cfb92d14SAndroid Build Coastguard Worker 
1734*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeOperationalDataset(dataset, &extraTlvs, &extraTlvsLength));
1735*cfb92d14SAndroid Build Coastguard Worker     error = otDatasetSendMgmtPendingSet(mInstance, &dataset, extraTlvs, extraTlvsLength, /* aCallback */ nullptr,
1736*cfb92d14SAndroid Build Coastguard Worker                                         /* aContext */ nullptr);
1737*cfb92d14SAndroid Build Coastguard Worker 
1738*cfb92d14SAndroid Build Coastguard Worker exit:
1739*cfb92d14SAndroid Build Coastguard Worker     return error;
1740*cfb92d14SAndroid Build Coastguard Worker }
1741*cfb92d14SAndroid Build Coastguard Worker 
DatasetSendMgmtPendingSetHandler(otError aResult,void * aContext)1742*cfb92d14SAndroid Build Coastguard Worker void NcpBase::DatasetSendMgmtPendingSetHandler(otError aResult, void *aContext)
1743*cfb92d14SAndroid Build Coastguard Worker {
1744*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->DatasetSendMgmtPendingSetHandler(aResult);
1745*cfb92d14SAndroid Build Coastguard Worker }
1746*cfb92d14SAndroid Build Coastguard Worker 
DatasetSendMgmtPendingSetHandler(otError aResult)1747*cfb92d14SAndroid Build Coastguard Worker void NcpBase::DatasetSendMgmtPendingSetHandler(otError aResult)
1748*cfb92d14SAndroid Build Coastguard Worker {
1749*cfb92d14SAndroid Build Coastguard Worker     mDatasetSendMgmtPendingSetResult = ThreadErrorToSpinelStatus(aResult);
1750*cfb92d14SAndroid Build Coastguard Worker     mChangedPropsSet.AddProperty(SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS);
1751*cfb92d14SAndroid Build Coastguard Worker     mUpdateChangedPropsTask.Post();
1752*cfb92d14SAndroid Build Coastguard Worker }
1753*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1754*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS>(void)
1755*cfb92d14SAndroid Build Coastguard Worker {
1756*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mDatasetSendMgmtPendingSetResult);
1757*cfb92d14SAndroid Build Coastguard Worker }
1758*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1759*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS>(void)
1760*cfb92d14SAndroid Build Coastguard Worker {
1761*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
1762*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset emptyDataset;
1763*cfb92d14SAndroid Build Coastguard Worker     const uint8_t       *data;
1764*cfb92d14SAndroid Build Coastguard Worker     uint16_t             len;
1765*cfb92d14SAndroid Build Coastguard Worker 
1766*cfb92d14SAndroid Build Coastguard Worker     memset(&emptyDataset, 0, sizeof(emptyDataset));
1767*cfb92d14SAndroid Build Coastguard Worker 
1768*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadData(data, len));
1769*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(len < OT_OPERATIONAL_DATASET_MAX_LENGTH, error = OT_ERROR_PARSE);
1770*cfb92d14SAndroid Build Coastguard Worker 
1771*cfb92d14SAndroid Build Coastguard Worker     error = otDatasetSendMgmtPendingSet(mInstance, &emptyDataset, data, static_cast<uint8_t>(len),
1772*cfb92d14SAndroid Build Coastguard Worker                                         DatasetSendMgmtPendingSetHandler, this);
1773*cfb92d14SAndroid Build Coastguard Worker 
1774*cfb92d14SAndroid Build Coastguard Worker exit:
1775*cfb92d14SAndroid Build Coastguard Worker     return error;
1776*cfb92d14SAndroid Build Coastguard Worker }
1777*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1778*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET>(void)
1779*cfb92d14SAndroid Build Coastguard Worker {
1780*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
1781*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1782*cfb92d14SAndroid Build Coastguard Worker     const uint8_t       *extraTlvs;
1783*cfb92d14SAndroid Build Coastguard Worker     uint8_t              extraTlvsLength;
1784*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address  *destIpAddress;
1785*cfb92d14SAndroid Build Coastguard Worker 
1786*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeOperationalDataset(dataset, &extraTlvs, &extraTlvsLength, &destIpAddress, true));
1787*cfb92d14SAndroid Build Coastguard Worker     error = otDatasetSendMgmtActiveGet(mInstance, &dataset.mComponents, extraTlvs, extraTlvsLength, destIpAddress);
1788*cfb92d14SAndroid Build Coastguard Worker 
1789*cfb92d14SAndroid Build Coastguard Worker exit:
1790*cfb92d14SAndroid Build Coastguard Worker     return error;
1791*cfb92d14SAndroid Build Coastguard Worker }
1792*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1793*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET>(void)
1794*cfb92d14SAndroid Build Coastguard Worker {
1795*cfb92d14SAndroid Build Coastguard Worker     otError              error = OT_ERROR_NONE;
1796*cfb92d14SAndroid Build Coastguard Worker     otOperationalDataset dataset;
1797*cfb92d14SAndroid Build Coastguard Worker     const uint8_t       *extraTlvs;
1798*cfb92d14SAndroid Build Coastguard Worker     uint8_t              extraTlvsLength;
1799*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address  *destIpAddress;
1800*cfb92d14SAndroid Build Coastguard Worker 
1801*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeOperationalDataset(dataset, &extraTlvs, &extraTlvsLength, &destIpAddress, true));
1802*cfb92d14SAndroid Build Coastguard Worker     error = otDatasetSendMgmtPendingGet(mInstance, &dataset.mComponents, extraTlvs, extraTlvsLength, destIpAddress);
1803*cfb92d14SAndroid Build Coastguard Worker 
1804*cfb92d14SAndroid Build Coastguard Worker exit:
1805*cfb92d14SAndroid Build Coastguard Worker     return error;
1806*cfb92d14SAndroid Build Coastguard Worker }
1807*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_JOINER_ENABLE
HandlePropertyGet(void)1808*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_JOINER_STATE>(void)
1809*cfb92d14SAndroid Build Coastguard Worker {
1810*cfb92d14SAndroid Build Coastguard Worker     spinel_meshcop_joiner_state_t state = SPINEL_MESHCOP_JOINER_STATE_IDLE;
1811*cfb92d14SAndroid Build Coastguard Worker 
1812*cfb92d14SAndroid Build Coastguard Worker     switch (otJoinerGetState(mInstance))
1813*cfb92d14SAndroid Build Coastguard Worker     {
1814*cfb92d14SAndroid Build Coastguard Worker     case OT_JOINER_STATE_IDLE:
1815*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_MESHCOP_JOINER_STATE_IDLE;
1816*cfb92d14SAndroid Build Coastguard Worker         break;
1817*cfb92d14SAndroid Build Coastguard Worker     case OT_JOINER_STATE_DISCOVER:
1818*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_MESHCOP_JOINER_STATE_DISCOVER;
1819*cfb92d14SAndroid Build Coastguard Worker         break;
1820*cfb92d14SAndroid Build Coastguard Worker     case OT_JOINER_STATE_CONNECT:
1821*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_MESHCOP_JOINER_STATE_CONNECTING;
1822*cfb92d14SAndroid Build Coastguard Worker         break;
1823*cfb92d14SAndroid Build Coastguard Worker     case OT_JOINER_STATE_CONNECTED:
1824*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_MESHCOP_JOINER_STATE_CONNECTED;
1825*cfb92d14SAndroid Build Coastguard Worker         break;
1826*cfb92d14SAndroid Build Coastguard Worker     case OT_JOINER_STATE_ENTRUST:
1827*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_MESHCOP_JOINER_STATE_ENTRUST;
1828*cfb92d14SAndroid Build Coastguard Worker         break;
1829*cfb92d14SAndroid Build Coastguard Worker     case OT_JOINER_STATE_JOINED:
1830*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_MESHCOP_JOINER_STATE_JOINED;
1831*cfb92d14SAndroid Build Coastguard Worker         break;
1832*cfb92d14SAndroid Build Coastguard Worker     }
1833*cfb92d14SAndroid Build Coastguard Worker 
1834*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(state);
1835*cfb92d14SAndroid Build Coastguard Worker }
1836*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1837*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING>(void)
1838*cfb92d14SAndroid Build Coastguard Worker {
1839*cfb92d14SAndroid Build Coastguard Worker     otError     error           = OT_ERROR_NONE;
1840*cfb92d14SAndroid Build Coastguard Worker     bool        action          = false;
1841*cfb92d14SAndroid Build Coastguard Worker     const char *psk             = nullptr;
1842*cfb92d14SAndroid Build Coastguard Worker     const char *provisioningUrl = nullptr;
1843*cfb92d14SAndroid Build Coastguard Worker     const char *vendorName      = nullptr;
1844*cfb92d14SAndroid Build Coastguard Worker     const char *vendorModel     = nullptr;
1845*cfb92d14SAndroid Build Coastguard Worker     const char *vendorSwVersion = nullptr;
1846*cfb92d14SAndroid Build Coastguard Worker     const char *vendorData      = nullptr;
1847*cfb92d14SAndroid Build Coastguard Worker 
1848*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(action));
1849*cfb92d14SAndroid Build Coastguard Worker 
1850*cfb92d14SAndroid Build Coastguard Worker     if (!action)
1851*cfb92d14SAndroid Build Coastguard Worker     {
1852*cfb92d14SAndroid Build Coastguard Worker         otJoinerStop(mInstance);
1853*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
1854*cfb92d14SAndroid Build Coastguard Worker     }
1855*cfb92d14SAndroid Build Coastguard Worker 
1856*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUtf8(psk));
1857*cfb92d14SAndroid Build Coastguard Worker 
1858*cfb92d14SAndroid Build Coastguard Worker     // Parse optional fields
1859*cfb92d14SAndroid Build Coastguard Worker 
1860*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllReadInStruct())
1861*cfb92d14SAndroid Build Coastguard Worker     {
1862*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUtf8(provisioningUrl));
1863*cfb92d14SAndroid Build Coastguard Worker     }
1864*cfb92d14SAndroid Build Coastguard Worker 
1865*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllReadInStruct())
1866*cfb92d14SAndroid Build Coastguard Worker     {
1867*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUtf8(vendorName));
1868*cfb92d14SAndroid Build Coastguard Worker     }
1869*cfb92d14SAndroid Build Coastguard Worker 
1870*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllReadInStruct())
1871*cfb92d14SAndroid Build Coastguard Worker     {
1872*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUtf8(vendorModel));
1873*cfb92d14SAndroid Build Coastguard Worker     }
1874*cfb92d14SAndroid Build Coastguard Worker 
1875*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllReadInStruct())
1876*cfb92d14SAndroid Build Coastguard Worker     {
1877*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUtf8(vendorSwVersion));
1878*cfb92d14SAndroid Build Coastguard Worker     }
1879*cfb92d14SAndroid Build Coastguard Worker 
1880*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllReadInStruct())
1881*cfb92d14SAndroid Build Coastguard Worker     {
1882*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadUtf8(vendorData));
1883*cfb92d14SAndroid Build Coastguard Worker     }
1884*cfb92d14SAndroid Build Coastguard Worker 
1885*cfb92d14SAndroid Build Coastguard Worker     // Use OpenThread default values for vendor name, mode, sw version if
1886*cfb92d14SAndroid Build Coastguard Worker     // not specified or an empty string is given.
1887*cfb92d14SAndroid Build Coastguard Worker 
1888*cfb92d14SAndroid Build Coastguard Worker     if ((vendorName == nullptr) || (vendorName[0] == 0))
1889*cfb92d14SAndroid Build Coastguard Worker     {
1890*cfb92d14SAndroid Build Coastguard Worker         vendorName = PACKAGE_NAME;
1891*cfb92d14SAndroid Build Coastguard Worker     }
1892*cfb92d14SAndroid Build Coastguard Worker 
1893*cfb92d14SAndroid Build Coastguard Worker     if ((vendorModel == nullptr) || (vendorModel[0] == 0))
1894*cfb92d14SAndroid Build Coastguard Worker     {
1895*cfb92d14SAndroid Build Coastguard Worker         vendorModel = OPENTHREAD_CONFIG_PLATFORM_INFO;
1896*cfb92d14SAndroid Build Coastguard Worker     }
1897*cfb92d14SAndroid Build Coastguard Worker 
1898*cfb92d14SAndroid Build Coastguard Worker     if ((vendorSwVersion == nullptr) || (vendorSwVersion[0] == 0))
1899*cfb92d14SAndroid Build Coastguard Worker     {
1900*cfb92d14SAndroid Build Coastguard Worker         vendorSwVersion = PACKAGE_VERSION;
1901*cfb92d14SAndroid Build Coastguard Worker     }
1902*cfb92d14SAndroid Build Coastguard Worker 
1903*cfb92d14SAndroid Build Coastguard Worker     error = otJoinerStart(mInstance, psk, provisioningUrl, vendorName, vendorModel, vendorSwVersion, vendorData,
1904*cfb92d14SAndroid Build Coastguard Worker                           &NcpBase::HandleJoinerCallback_Jump, this);
1905*cfb92d14SAndroid Build Coastguard Worker 
1906*cfb92d14SAndroid Build Coastguard Worker exit:
1907*cfb92d14SAndroid Build Coastguard Worker     return error;
1908*cfb92d14SAndroid Build Coastguard Worker }
1909*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1910*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MESHCOP_JOINER_DISCERNER>(void)
1911*cfb92d14SAndroid Build Coastguard Worker {
1912*cfb92d14SAndroid Build Coastguard Worker     otError                  error;
1913*cfb92d14SAndroid Build Coastguard Worker     const otJoinerDiscerner *discerner = otJoinerGetDiscerner(mInstance);
1914*cfb92d14SAndroid Build Coastguard Worker 
1915*cfb92d14SAndroid Build Coastguard Worker     if (discerner == nullptr)
1916*cfb92d14SAndroid Build Coastguard Worker     {
1917*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(0));
1918*cfb92d14SAndroid Build Coastguard Worker     }
1919*cfb92d14SAndroid Build Coastguard Worker     else
1920*cfb92d14SAndroid Build Coastguard Worker     {
1921*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(discerner->mLength));
1922*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint64(discerner->mValue));
1923*cfb92d14SAndroid Build Coastguard Worker     }
1924*cfb92d14SAndroid Build Coastguard Worker 
1925*cfb92d14SAndroid Build Coastguard Worker exit:
1926*cfb92d14SAndroid Build Coastguard Worker     return error;
1927*cfb92d14SAndroid Build Coastguard Worker }
1928*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1929*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MESHCOP_JOINER_DISCERNER>(void)
1930*cfb92d14SAndroid Build Coastguard Worker {
1931*cfb92d14SAndroid Build Coastguard Worker     otError           error = OT_ERROR_NONE;
1932*cfb92d14SAndroid Build Coastguard Worker     otJoinerDiscerner discerner;
1933*cfb92d14SAndroid Build Coastguard Worker 
1934*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(discerner.mLength));
1935*cfb92d14SAndroid Build Coastguard Worker 
1936*cfb92d14SAndroid Build Coastguard Worker     if (discerner.mLength == 0)
1937*cfb92d14SAndroid Build Coastguard Worker     {
1938*cfb92d14SAndroid Build Coastguard Worker         // Clearing any previously set Joiner Discerner
1939*cfb92d14SAndroid Build Coastguard Worker         error = otJoinerSetDiscerner(mInstance, nullptr);
1940*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
1941*cfb92d14SAndroid Build Coastguard Worker     }
1942*cfb92d14SAndroid Build Coastguard Worker 
1943*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint64(discerner.mValue));
1944*cfb92d14SAndroid Build Coastguard Worker     error = otJoinerSetDiscerner(mInstance, &discerner);
1945*cfb92d14SAndroid Build Coastguard Worker 
1946*cfb92d14SAndroid Build Coastguard Worker exit:
1947*cfb92d14SAndroid Build Coastguard Worker     return error;
1948*cfb92d14SAndroid Build Coastguard Worker }
1949*cfb92d14SAndroid Build Coastguard Worker 
1950*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_JOINER_ENABLE
1951*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1952*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ML_PREFIX>(void)
1953*cfb92d14SAndroid Build Coastguard Worker {
1954*cfb92d14SAndroid Build Coastguard Worker     otError                  error    = OT_ERROR_NONE;
1955*cfb92d14SAndroid Build Coastguard Worker     const otMeshLocalPrefix *mlPrefix = otThreadGetMeshLocalPrefix(mInstance);
1956*cfb92d14SAndroid Build Coastguard Worker     otIp6Address             addr;
1957*cfb92d14SAndroid Build Coastguard Worker 
1958*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mlPrefix != nullptr); // If `mlPrefix` is nullptr send empty response.
1959*cfb92d14SAndroid Build Coastguard Worker 
1960*cfb92d14SAndroid Build Coastguard Worker     memcpy(addr.mFields.m8, mlPrefix->m8, 8);
1961*cfb92d14SAndroid Build Coastguard Worker 
1962*cfb92d14SAndroid Build Coastguard Worker     // Zero out the last 8 bytes.
1963*cfb92d14SAndroid Build Coastguard Worker     memset(addr.mFields.m8 + 8, 0, 8);
1964*cfb92d14SAndroid Build Coastguard Worker 
1965*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteIp6Address(addr));             // Mesh local prefix
1966*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint8(OT_IP6_PREFIX_BITSIZE)); // Prefix length (in bits)
1967*cfb92d14SAndroid Build Coastguard Worker 
1968*cfb92d14SAndroid Build Coastguard Worker exit:
1969*cfb92d14SAndroid Build Coastguard Worker     return error;
1970*cfb92d14SAndroid Build Coastguard Worker }
1971*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)1972*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_IPV6_ML_PREFIX>(void)
1973*cfb92d14SAndroid Build Coastguard Worker {
1974*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
1975*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address *meshLocalPrefix;
1976*cfb92d14SAndroid Build Coastguard Worker     uint8_t             prefixLength;
1977*cfb92d14SAndroid Build Coastguard Worker 
1978*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(meshLocalPrefix));
1979*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(prefixLength));
1980*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(prefixLength == OT_IP6_PREFIX_BITSIZE, error = OT_ERROR_INVALID_ARGS);
1981*cfb92d14SAndroid Build Coastguard Worker 
1982*cfb92d14SAndroid Build Coastguard Worker     error = otThreadSetMeshLocalPrefix(mInstance, reinterpret_cast<const otMeshLocalPrefix *>(meshLocalPrefix));
1983*cfb92d14SAndroid Build Coastguard Worker 
1984*cfb92d14SAndroid Build Coastguard Worker exit:
1985*cfb92d14SAndroid Build Coastguard Worker     return error;
1986*cfb92d14SAndroid Build Coastguard Worker }
1987*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)1988*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ML_ADDR>(void)
1989*cfb92d14SAndroid Build Coastguard Worker {
1990*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
1991*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address *ml64  = otThreadGetMeshLocalEid(mInstance);
1992*cfb92d14SAndroid Build Coastguard Worker 
1993*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(ml64 != nullptr);
1994*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteIp6Address(*ml64));
1995*cfb92d14SAndroid Build Coastguard Worker 
1996*cfb92d14SAndroid Build Coastguard Worker exit:
1997*cfb92d14SAndroid Build Coastguard Worker     return error;
1998*cfb92d14SAndroid Build Coastguard Worker }
1999*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2000*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_LL_ADDR>(void)
2001*cfb92d14SAndroid Build Coastguard Worker {
2002*cfb92d14SAndroid Build Coastguard Worker     otError             error   = OT_ERROR_NONE;
2003*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address *address = otThreadGetLinkLocalIp6Address(mInstance);
2004*cfb92d14SAndroid Build Coastguard Worker 
2005*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(address != nullptr);
2006*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteIp6Address(*address));
2007*cfb92d14SAndroid Build Coastguard Worker 
2008*cfb92d14SAndroid Build Coastguard Worker exit:
2009*cfb92d14SAndroid Build Coastguard Worker     return error;
2010*cfb92d14SAndroid Build Coastguard Worker }
2011*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2012*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ADDRESS_TABLE>(void)
2013*cfb92d14SAndroid Build Coastguard Worker {
2014*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
2015*cfb92d14SAndroid Build Coastguard Worker 
2016*cfb92d14SAndroid Build Coastguard Worker     for (const otNetifAddress *address = otIp6GetUnicastAddresses(mInstance); address; address = address->mNext)
2017*cfb92d14SAndroid Build Coastguard Worker     {
2018*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
2019*cfb92d14SAndroid Build Coastguard Worker 
2020*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(address->mAddress));
2021*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(address->mPrefixLength));
2022*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(address->mPreferred ? 0xffffffff : 0));
2023*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(address->mValid ? 0xffffffff : 0));
2024*cfb92d14SAndroid Build Coastguard Worker 
2025*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
2026*cfb92d14SAndroid Build Coastguard Worker     }
2027*cfb92d14SAndroid Build Coastguard Worker 
2028*cfb92d14SAndroid Build Coastguard Worker exit:
2029*cfb92d14SAndroid Build Coastguard Worker     return error;
2030*cfb92d14SAndroid Build Coastguard Worker }
2031*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)2032*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_IPV6_ADDRESS_TABLE>(void)
2033*cfb92d14SAndroid Build Coastguard Worker {
2034*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_NONE;
2035*cfb92d14SAndroid Build Coastguard Worker     otNetifAddress netifAddr;
2036*cfb92d14SAndroid Build Coastguard Worker     uint32_t       preferredLifetime;
2037*cfb92d14SAndroid Build Coastguard Worker     uint32_t       validLifetime;
2038*cfb92d14SAndroid Build Coastguard Worker 
2039*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(netifAddr.mAddress));
2040*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(netifAddr.mPrefixLength));
2041*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(preferredLifetime));
2042*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(validLifetime));
2043*cfb92d14SAndroid Build Coastguard Worker 
2044*cfb92d14SAndroid Build Coastguard Worker     netifAddr.mAddressOrigin = OT_ADDRESS_ORIGIN_MANUAL;
2045*cfb92d14SAndroid Build Coastguard Worker     netifAddr.mPreferred     = (preferredLifetime != 0);
2046*cfb92d14SAndroid Build Coastguard Worker     netifAddr.mValid         = (validLifetime != 0);
2047*cfb92d14SAndroid Build Coastguard Worker 
2048*cfb92d14SAndroid Build Coastguard Worker     error = otIp6AddUnicastAddress(mInstance, &netifAddr);
2049*cfb92d14SAndroid Build Coastguard Worker 
2050*cfb92d14SAndroid Build Coastguard Worker exit:
2051*cfb92d14SAndroid Build Coastguard Worker     return error;
2052*cfb92d14SAndroid Build Coastguard Worker }
2053*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)2054*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_IPV6_ADDRESS_TABLE>(void)
2055*cfb92d14SAndroid Build Coastguard Worker {
2056*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
2057*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address *addrPtr;
2058*cfb92d14SAndroid Build Coastguard Worker 
2059*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(addrPtr));
2060*cfb92d14SAndroid Build Coastguard Worker 
2061*cfb92d14SAndroid Build Coastguard Worker     error = otIp6RemoveUnicastAddress(mInstance, addrPtr);
2062*cfb92d14SAndroid Build Coastguard Worker 
2063*cfb92d14SAndroid Build Coastguard Worker     // If address was not on the list, "remove" command is successful.
2064*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NOT_FOUND)
2065*cfb92d14SAndroid Build Coastguard Worker     {
2066*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
2067*cfb92d14SAndroid Build Coastguard Worker     }
2068*cfb92d14SAndroid Build Coastguard Worker 
2069*cfb92d14SAndroid Build Coastguard Worker exit:
2070*cfb92d14SAndroid Build Coastguard Worker     return error;
2071*cfb92d14SAndroid Build Coastguard Worker }
2072*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2073*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ROUTE_TABLE>(void)
2074*cfb92d14SAndroid Build Coastguard Worker {
2075*cfb92d14SAndroid Build Coastguard Worker     // TODO: Implement get route table
2076*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.OverwriteWithLastStatusError(SPINEL_STATUS_UNIMPLEMENTED);
2077*cfb92d14SAndroid Build Coastguard Worker }
2078*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2079*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD>(void)
2080*cfb92d14SAndroid Build Coastguard Worker {
2081*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otIcmp6GetEchoMode(mInstance) != OT_ICMP6_ECHO_HANDLER_DISABLED);
2082*cfb92d14SAndroid Build Coastguard Worker }
2083*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2084*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD>(void)
2085*cfb92d14SAndroid Build Coastguard Worker {
2086*cfb92d14SAndroid Build Coastguard Worker     bool    enabled = false;
2087*cfb92d14SAndroid Build Coastguard Worker     otError error   = OT_ERROR_NONE;
2088*cfb92d14SAndroid Build Coastguard Worker 
2089*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
2090*cfb92d14SAndroid Build Coastguard Worker 
2091*cfb92d14SAndroid Build Coastguard Worker     otIcmp6SetEchoMode(mInstance, enabled ? OT_ICMP6_ECHO_HANDLER_ALL : OT_ICMP6_ECHO_HANDLER_DISABLED);
2092*cfb92d14SAndroid Build Coastguard Worker 
2093*cfb92d14SAndroid Build Coastguard Worker exit:
2094*cfb92d14SAndroid Build Coastguard Worker     return error;
2095*cfb92d14SAndroid Build Coastguard Worker }
2096*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2097*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE>(void)
2098*cfb92d14SAndroid Build Coastguard Worker {
2099*cfb92d14SAndroid Build Coastguard Worker     otError                        error = OT_ERROR_NONE;
2100*cfb92d14SAndroid Build Coastguard Worker     const otNetifMulticastAddress *address;
2101*cfb92d14SAndroid Build Coastguard Worker 
2102*cfb92d14SAndroid Build Coastguard Worker     for (address = otIp6GetMulticastAddresses(mInstance); address; address = address->mNext)
2103*cfb92d14SAndroid Build Coastguard Worker     {
2104*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
2105*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(address->mAddress));
2106*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
2107*cfb92d14SAndroid Build Coastguard Worker     }
2108*cfb92d14SAndroid Build Coastguard Worker 
2109*cfb92d14SAndroid Build Coastguard Worker exit:
2110*cfb92d14SAndroid Build Coastguard Worker     return error;
2111*cfb92d14SAndroid Build Coastguard Worker }
2112*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)2113*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE>(void)
2114*cfb92d14SAndroid Build Coastguard Worker {
2115*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
2116*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address *addrPtr;
2117*cfb92d14SAndroid Build Coastguard Worker 
2118*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(addrPtr));
2119*cfb92d14SAndroid Build Coastguard Worker 
2120*cfb92d14SAndroid Build Coastguard Worker     error = otIp6SubscribeMulticastAddress(mInstance, addrPtr);
2121*cfb92d14SAndroid Build Coastguard Worker 
2122*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_ALREADY)
2123*cfb92d14SAndroid Build Coastguard Worker     {
2124*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
2125*cfb92d14SAndroid Build Coastguard Worker     }
2126*cfb92d14SAndroid Build Coastguard Worker 
2127*cfb92d14SAndroid Build Coastguard Worker exit:
2128*cfb92d14SAndroid Build Coastguard Worker     return error;
2129*cfb92d14SAndroid Build Coastguard Worker }
2130*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)2131*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE>(void)
2132*cfb92d14SAndroid Build Coastguard Worker {
2133*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
2134*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address *addrPtr;
2135*cfb92d14SAndroid Build Coastguard Worker 
2136*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(addrPtr));
2137*cfb92d14SAndroid Build Coastguard Worker 
2138*cfb92d14SAndroid Build Coastguard Worker     error = otIp6UnsubscribeMulticastAddress(mInstance, addrPtr);
2139*cfb92d14SAndroid Build Coastguard Worker 
2140*cfb92d14SAndroid Build Coastguard Worker     // If the address was not on the list, "remove" command is successful,
2141*cfb92d14SAndroid Build Coastguard Worker     // and we respond with a `SPINEL_STATUS_OK` status.
2142*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NOT_FOUND)
2143*cfb92d14SAndroid Build Coastguard Worker     {
2144*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
2145*cfb92d14SAndroid Build Coastguard Worker     }
2146*cfb92d14SAndroid Build Coastguard Worker 
2147*cfb92d14SAndroid Build Coastguard Worker exit:
2148*cfb92d14SAndroid Build Coastguard Worker     return error;
2149*cfb92d14SAndroid Build Coastguard Worker }
2150*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2151*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE>(void)
2152*cfb92d14SAndroid Build Coastguard Worker {
2153*cfb92d14SAndroid Build Coastguard Worker     spinel_ipv6_icmp_ping_offload_mode_t mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_DISABLED;
2154*cfb92d14SAndroid Build Coastguard Worker 
2155*cfb92d14SAndroid Build Coastguard Worker     switch (otIcmp6GetEchoMode(mInstance))
2156*cfb92d14SAndroid Build Coastguard Worker     {
2157*cfb92d14SAndroid Build Coastguard Worker     case OT_ICMP6_ECHO_HANDLER_DISABLED:
2158*cfb92d14SAndroid Build Coastguard Worker         mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_DISABLED;
2159*cfb92d14SAndroid Build Coastguard Worker         break;
2160*cfb92d14SAndroid Build Coastguard Worker     case OT_ICMP6_ECHO_HANDLER_UNICAST_ONLY:
2161*cfb92d14SAndroid Build Coastguard Worker         mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY;
2162*cfb92d14SAndroid Build Coastguard Worker         break;
2163*cfb92d14SAndroid Build Coastguard Worker     case OT_ICMP6_ECHO_HANDLER_MULTICAST_ONLY:
2164*cfb92d14SAndroid Build Coastguard Worker         mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY;
2165*cfb92d14SAndroid Build Coastguard Worker         break;
2166*cfb92d14SAndroid Build Coastguard Worker     case OT_ICMP6_ECHO_HANDLER_ALL:
2167*cfb92d14SAndroid Build Coastguard Worker         mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL;
2168*cfb92d14SAndroid Build Coastguard Worker         break;
2169*cfb92d14SAndroid Build Coastguard Worker     case OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY:
2170*cfb92d14SAndroid Build Coastguard Worker         mode = SPINEL_IPV6_ICMP_PING_OFFLOAD_RLOC_ALOC_ONLY;
2171*cfb92d14SAndroid Build Coastguard Worker         break;
2172*cfb92d14SAndroid Build Coastguard Worker     };
2173*cfb92d14SAndroid Build Coastguard Worker 
2174*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(mode);
2175*cfb92d14SAndroid Build Coastguard Worker }
2176*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2177*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE>(void)
2178*cfb92d14SAndroid Build Coastguard Worker {
2179*cfb92d14SAndroid Build Coastguard Worker     otError         error = OT_ERROR_NONE;
2180*cfb92d14SAndroid Build Coastguard Worker     otIcmp6EchoMode mode  = OT_ICMP6_ECHO_HANDLER_DISABLED;
2181*cfb92d14SAndroid Build Coastguard Worker     uint8_t         spinelMode;
2182*cfb92d14SAndroid Build Coastguard Worker 
2183*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(spinelMode));
2184*cfb92d14SAndroid Build Coastguard Worker 
2185*cfb92d14SAndroid Build Coastguard Worker     switch (spinelMode)
2186*cfb92d14SAndroid Build Coastguard Worker     {
2187*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_IPV6_ICMP_PING_OFFLOAD_DISABLED:
2188*cfb92d14SAndroid Build Coastguard Worker         mode = OT_ICMP6_ECHO_HANDLER_DISABLED;
2189*cfb92d14SAndroid Build Coastguard Worker         break;
2190*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_IPV6_ICMP_PING_OFFLOAD_UNICAST_ONLY:
2191*cfb92d14SAndroid Build Coastguard Worker         mode = OT_ICMP6_ECHO_HANDLER_UNICAST_ONLY;
2192*cfb92d14SAndroid Build Coastguard Worker         break;
2193*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_IPV6_ICMP_PING_OFFLOAD_MULTICAST_ONLY:
2194*cfb92d14SAndroid Build Coastguard Worker         mode = OT_ICMP6_ECHO_HANDLER_MULTICAST_ONLY;
2195*cfb92d14SAndroid Build Coastguard Worker         break;
2196*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_IPV6_ICMP_PING_OFFLOAD_ALL:
2197*cfb92d14SAndroid Build Coastguard Worker         mode = OT_ICMP6_ECHO_HANDLER_ALL;
2198*cfb92d14SAndroid Build Coastguard Worker         break;
2199*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_IPV6_ICMP_PING_OFFLOAD_RLOC_ALOC_ONLY:
2200*cfb92d14SAndroid Build Coastguard Worker         mode = OT_ICMP6_ECHO_HANDLER_RLOC_ALOC_ONLY;
2201*cfb92d14SAndroid Build Coastguard Worker         break;
2202*cfb92d14SAndroid Build Coastguard Worker     };
2203*cfb92d14SAndroid Build Coastguard Worker 
2204*cfb92d14SAndroid Build Coastguard Worker     otIcmp6SetEchoMode(mInstance, mode);
2205*cfb92d14SAndroid Build Coastguard Worker 
2206*cfb92d14SAndroid Build Coastguard Worker exit:
2207*cfb92d14SAndroid Build Coastguard Worker     return error;
2208*cfb92d14SAndroid Build Coastguard Worker }
2209*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2210*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU>(void)
2211*cfb92d14SAndroid Build Coastguard Worker {
2212*cfb92d14SAndroid Build Coastguard Worker     // Note reverse logic: passthru enabled = filter disabled
2213*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(!otIp6IsReceiveFilterEnabled(mInstance));
2214*cfb92d14SAndroid Build Coastguard Worker }
2215*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2216*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU>(void)
2217*cfb92d14SAndroid Build Coastguard Worker {
2218*cfb92d14SAndroid Build Coastguard Worker     bool    enabled = false;
2219*cfb92d14SAndroid Build Coastguard Worker     otError error   = OT_ERROR_NONE;
2220*cfb92d14SAndroid Build Coastguard Worker 
2221*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
2222*cfb92d14SAndroid Build Coastguard Worker 
2223*cfb92d14SAndroid Build Coastguard Worker     // Note reverse logic: passthru enabled = filter disabled
2224*cfb92d14SAndroid Build Coastguard Worker     otIp6SetReceiveFilterEnabled(mInstance, !enabled);
2225*cfb92d14SAndroid Build Coastguard Worker 
2226*cfb92d14SAndroid Build Coastguard Worker exit:
2227*cfb92d14SAndroid Build Coastguard Worker     return error;
2228*cfb92d14SAndroid Build Coastguard Worker }
2229*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2230*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_OFF_MESH_ROUTES>(void)
2231*cfb92d14SAndroid Build Coastguard Worker {
2232*cfb92d14SAndroid Build Coastguard Worker     otError               error = OT_ERROR_NONE;
2233*cfb92d14SAndroid Build Coastguard Worker     otExternalRouteConfig routeConfig;
2234*cfb92d14SAndroid Build Coastguard Worker     otNetworkDataIterator iter = OT_NETWORK_DATA_ITERATOR_INIT;
2235*cfb92d14SAndroid Build Coastguard Worker 
2236*cfb92d14SAndroid Build Coastguard Worker     while (otNetDataGetNextRoute(mInstance, &iter, &routeConfig) == OT_ERROR_NONE)
2237*cfb92d14SAndroid Build Coastguard Worker     {
2238*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
2239*cfb92d14SAndroid Build Coastguard Worker 
2240*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(routeConfig.mPrefix.mPrefix));
2241*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(routeConfig.mPrefix.mLength));
2242*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(routeConfig.mStable));
2243*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(ExternalRouteConfigToFlagByte(routeConfig)));
2244*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(false)); // IsLocal
2245*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(routeConfig.mNextHopIsThisDevice));
2246*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(routeConfig.mRloc16));
2247*cfb92d14SAndroid Build Coastguard Worker 
2248*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
2249*cfb92d14SAndroid Build Coastguard Worker     }
2250*cfb92d14SAndroid Build Coastguard Worker 
2251*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
2252*cfb92d14SAndroid Build Coastguard Worker 
2253*cfb92d14SAndroid Build Coastguard Worker     iter = OT_NETWORK_DATA_ITERATOR_INIT;
2254*cfb92d14SAndroid Build Coastguard Worker 
2255*cfb92d14SAndroid Build Coastguard Worker     while (otBorderRouterGetNextRoute(mInstance, &iter, &routeConfig) == OT_ERROR_NONE)
2256*cfb92d14SAndroid Build Coastguard Worker     {
2257*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
2258*cfb92d14SAndroid Build Coastguard Worker 
2259*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(routeConfig.mPrefix.mPrefix));
2260*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(routeConfig.mPrefix.mLength));
2261*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(routeConfig.mStable));
2262*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(ExternalRouteConfigToFlagByte(routeConfig)));
2263*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(true)); // IsLocal
2264*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteBool(routeConfig.mNextHopIsThisDevice));
2265*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(routeConfig.mRloc16));
2266*cfb92d14SAndroid Build Coastguard Worker 
2267*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
2268*cfb92d14SAndroid Build Coastguard Worker     }
2269*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
2270*cfb92d14SAndroid Build Coastguard Worker 
2271*cfb92d14SAndroid Build Coastguard Worker exit:
2272*cfb92d14SAndroid Build Coastguard Worker     return error;
2273*cfb92d14SAndroid Build Coastguard Worker }
2274*cfb92d14SAndroid Build Coastguard Worker 
2275*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
FlagByteToExternalRoutePreference(uint8_t aFlags)2276*cfb92d14SAndroid Build Coastguard Worker static int FlagByteToExternalRoutePreference(uint8_t aFlags)
2277*cfb92d14SAndroid Build Coastguard Worker {
2278*cfb92d14SAndroid Build Coastguard Worker     int route_preference = 0;
2279*cfb92d14SAndroid Build Coastguard Worker 
2280*cfb92d14SAndroid Build Coastguard Worker     switch (aFlags & SPINEL_NET_FLAG_PREFERENCE_MASK)
2281*cfb92d14SAndroid Build Coastguard Worker     {
2282*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_ROUTE_PREFERENCE_HIGH:
2283*cfb92d14SAndroid Build Coastguard Worker         route_preference = OT_ROUTE_PREFERENCE_HIGH;
2284*cfb92d14SAndroid Build Coastguard Worker         break;
2285*cfb92d14SAndroid Build Coastguard Worker 
2286*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_ROUTE_PREFERENCE_MEDIUM:
2287*cfb92d14SAndroid Build Coastguard Worker         route_preference = OT_ROUTE_PREFERENCE_MED;
2288*cfb92d14SAndroid Build Coastguard Worker         break;
2289*cfb92d14SAndroid Build Coastguard Worker 
2290*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_ROUTE_PREFERENCE_LOW:
2291*cfb92d14SAndroid Build Coastguard Worker         route_preference = OT_ROUTE_PREFERENCE_LOW;
2292*cfb92d14SAndroid Build Coastguard Worker         break;
2293*cfb92d14SAndroid Build Coastguard Worker     }
2294*cfb92d14SAndroid Build Coastguard Worker 
2295*cfb92d14SAndroid Build Coastguard Worker     return route_preference;
2296*cfb92d14SAndroid Build Coastguard Worker }
2297*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)2298*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_THREAD_OFF_MESH_ROUTES>(void)
2299*cfb92d14SAndroid Build Coastguard Worker {
2300*cfb92d14SAndroid Build Coastguard Worker     otError               error = OT_ERROR_NONE;
2301*cfb92d14SAndroid Build Coastguard Worker     otExternalRouteConfig routeConfig;
2302*cfb92d14SAndroid Build Coastguard Worker     bool                  stable = false;
2303*cfb92d14SAndroid Build Coastguard Worker     uint8_t               flags  = 0;
2304*cfb92d14SAndroid Build Coastguard Worker     uint8_t               prefixLength;
2305*cfb92d14SAndroid Build Coastguard Worker 
2306*cfb92d14SAndroid Build Coastguard Worker     memset(&routeConfig, 0, sizeof(otExternalRouteConfig));
2307*cfb92d14SAndroid Build Coastguard Worker 
2308*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mAllowLocalNetworkDataChange, error = OT_ERROR_INVALID_STATE);
2309*cfb92d14SAndroid Build Coastguard Worker 
2310*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(routeConfig.mPrefix.mPrefix));
2311*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(prefixLength));
2312*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(stable));
2313*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(flags));
2314*cfb92d14SAndroid Build Coastguard Worker 
2315*cfb92d14SAndroid Build Coastguard Worker     routeConfig.mPrefix.mLength = prefixLength;
2316*cfb92d14SAndroid Build Coastguard Worker     routeConfig.mStable         = stable;
2317*cfb92d14SAndroid Build Coastguard Worker     routeConfig.mPreference     = FlagByteToExternalRoutePreference(flags);
2318*cfb92d14SAndroid Build Coastguard Worker     routeConfig.mNat64          = ((flags & SPINEL_ROUTE_FLAG_NAT64) != 0);
2319*cfb92d14SAndroid Build Coastguard Worker 
2320*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRouterAddRoute(mInstance, &routeConfig);
2321*cfb92d14SAndroid Build Coastguard Worker 
2322*cfb92d14SAndroid Build Coastguard Worker exit:
2323*cfb92d14SAndroid Build Coastguard Worker     return error;
2324*cfb92d14SAndroid Build Coastguard Worker }
2325*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)2326*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_THREAD_OFF_MESH_ROUTES>(void)
2327*cfb92d14SAndroid Build Coastguard Worker {
2328*cfb92d14SAndroid Build Coastguard Worker     otError     error = OT_ERROR_NONE;
2329*cfb92d14SAndroid Build Coastguard Worker     otIp6Prefix ip6Prefix;
2330*cfb92d14SAndroid Build Coastguard Worker     uint8_t     prefixLength;
2331*cfb92d14SAndroid Build Coastguard Worker 
2332*cfb92d14SAndroid Build Coastguard Worker     memset(&ip6Prefix, 0, sizeof(otIp6Prefix));
2333*cfb92d14SAndroid Build Coastguard Worker 
2334*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mAllowLocalNetworkDataChange, error = OT_ERROR_INVALID_STATE);
2335*cfb92d14SAndroid Build Coastguard Worker 
2336*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(ip6Prefix.mPrefix));
2337*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(prefixLength));
2338*cfb92d14SAndroid Build Coastguard Worker 
2339*cfb92d14SAndroid Build Coastguard Worker     ip6Prefix.mLength = prefixLength;
2340*cfb92d14SAndroid Build Coastguard Worker 
2341*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRouterRemoveRoute(mInstance, &ip6Prefix);
2342*cfb92d14SAndroid Build Coastguard Worker 
2343*cfb92d14SAndroid Build Coastguard Worker     // If the route prefix was not on the list, "remove" command is successful.
2344*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NOT_FOUND)
2345*cfb92d14SAndroid Build Coastguard Worker     {
2346*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
2347*cfb92d14SAndroid Build Coastguard Worker     }
2348*cfb92d14SAndroid Build Coastguard Worker 
2349*cfb92d14SAndroid Build Coastguard Worker exit:
2350*cfb92d14SAndroid Build Coastguard Worker     return error;
2351*cfb92d14SAndroid Build Coastguard Worker }
2352*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
2353*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2354*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET>(void)
2355*cfb92d14SAndroid Build Coastguard Worker {
2356*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *framePtr = nullptr;
2357*cfb92d14SAndroid Build Coastguard Worker     uint16_t       frameLen = 0;
2358*cfb92d14SAndroid Build Coastguard Worker     const uint8_t *metaPtr  = nullptr;
2359*cfb92d14SAndroid Build Coastguard Worker     uint16_t       metaLen  = 0;
2360*cfb92d14SAndroid Build Coastguard Worker     otMessage     *message  = nullptr;
2361*cfb92d14SAndroid Build Coastguard Worker     otError        error    = OT_ERROR_NONE;
2362*cfb92d14SAndroid Build Coastguard Worker 
2363*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(framePtr, frameLen));
2364*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadData(metaPtr, metaLen));
2365*cfb92d14SAndroid Build Coastguard Worker 
2366*cfb92d14SAndroid Build Coastguard Worker     // We ignore metadata for now.
2367*cfb92d14SAndroid Build Coastguard Worker     // May later include TX power, allow retransmits, etc...
2368*cfb92d14SAndroid Build Coastguard Worker 
2369*cfb92d14SAndroid Build Coastguard Worker     // STREAM_NET requires layer 2 security.
2370*cfb92d14SAndroid Build Coastguard Worker     message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, nullptr);
2371*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
2372*cfb92d14SAndroid Build Coastguard Worker     otMessageSetOrigin(message, OT_MESSAGE_ORIGIN_HOST_UNTRUSTED);
2373*cfb92d14SAndroid Build Coastguard Worker 
2374*cfb92d14SAndroid Build Coastguard Worker     error = otIp6Send(mInstance, message);
2375*cfb92d14SAndroid Build Coastguard Worker 
2376*cfb92d14SAndroid Build Coastguard Worker exit:
2377*cfb92d14SAndroid Build Coastguard Worker 
2378*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NONE)
2379*cfb92d14SAndroid Build Coastguard Worker     {
2380*cfb92d14SAndroid Build Coastguard Worker         mInboundSecureIpFrameCounter++;
2381*cfb92d14SAndroid Build Coastguard Worker     }
2382*cfb92d14SAndroid Build Coastguard Worker     else
2383*cfb92d14SAndroid Build Coastguard Worker     {
2384*cfb92d14SAndroid Build Coastguard Worker         mDroppedInboundIpFrameCounter++;
2385*cfb92d14SAndroid Build Coastguard Worker     }
2386*cfb92d14SAndroid Build Coastguard Worker 
2387*cfb92d14SAndroid Build Coastguard Worker     return error;
2388*cfb92d14SAndroid Build Coastguard Worker }
2389*cfb92d14SAndroid Build Coastguard Worker 
2390*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
2391*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2392*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_JAM_DETECT_ENABLE>(void)
2393*cfb92d14SAndroid Build Coastguard Worker {
2394*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otJamDetectionIsEnabled(mInstance));
2395*cfb92d14SAndroid Build Coastguard Worker }
2396*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2397*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_JAM_DETECTED>(void)
2398*cfb92d14SAndroid Build Coastguard Worker {
2399*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otJamDetectionGetState(mInstance));
2400*cfb92d14SAndroid Build Coastguard Worker }
2401*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2402*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD>(void)
2403*cfb92d14SAndroid Build Coastguard Worker {
2404*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteInt8(otJamDetectionGetRssiThreshold(mInstance));
2405*cfb92d14SAndroid Build Coastguard Worker }
2406*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2407*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_JAM_DETECT_WINDOW>(void)
2408*cfb92d14SAndroid Build Coastguard Worker {
2409*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(otJamDetectionGetWindow(mInstance));
2410*cfb92d14SAndroid Build Coastguard Worker }
2411*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2412*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_JAM_DETECT_BUSY>(void)
2413*cfb92d14SAndroid Build Coastguard Worker {
2414*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(otJamDetectionGetBusyPeriod(mInstance));
2415*cfb92d14SAndroid Build Coastguard Worker }
2416*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2417*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP>(void)
2418*cfb92d14SAndroid Build Coastguard Worker {
2419*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint64(otJamDetectionGetHistoryBitmap(mInstance));
2420*cfb92d14SAndroid Build Coastguard Worker }
2421*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2422*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_JAM_DETECT_ENABLE>(void)
2423*cfb92d14SAndroid Build Coastguard Worker {
2424*cfb92d14SAndroid Build Coastguard Worker     bool    enabled;
2425*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
2426*cfb92d14SAndroid Build Coastguard Worker 
2427*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
2428*cfb92d14SAndroid Build Coastguard Worker 
2429*cfb92d14SAndroid Build Coastguard Worker     if (enabled)
2430*cfb92d14SAndroid Build Coastguard Worker     {
2431*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(otJamDetectionStart(mInstance, &NcpBase::HandleJamStateChange_Jump, this));
2432*cfb92d14SAndroid Build Coastguard Worker     }
2433*cfb92d14SAndroid Build Coastguard Worker     else
2434*cfb92d14SAndroid Build Coastguard Worker     {
2435*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(otJamDetectionStop(mInstance));
2436*cfb92d14SAndroid Build Coastguard Worker     }
2437*cfb92d14SAndroid Build Coastguard Worker 
2438*cfb92d14SAndroid Build Coastguard Worker exit:
2439*cfb92d14SAndroid Build Coastguard Worker     return error;
2440*cfb92d14SAndroid Build Coastguard Worker }
2441*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2442*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD>(void)
2443*cfb92d14SAndroid Build Coastguard Worker {
2444*cfb92d14SAndroid Build Coastguard Worker     int8_t  threshold = 0;
2445*cfb92d14SAndroid Build Coastguard Worker     otError error     = OT_ERROR_NONE;
2446*cfb92d14SAndroid Build Coastguard Worker 
2447*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadInt8(threshold));
2448*cfb92d14SAndroid Build Coastguard Worker 
2449*cfb92d14SAndroid Build Coastguard Worker     error = otJamDetectionSetRssiThreshold(mInstance, threshold);
2450*cfb92d14SAndroid Build Coastguard Worker 
2451*cfb92d14SAndroid Build Coastguard Worker exit:
2452*cfb92d14SAndroid Build Coastguard Worker     return error;
2453*cfb92d14SAndroid Build Coastguard Worker }
2454*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2455*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_JAM_DETECT_WINDOW>(void)
2456*cfb92d14SAndroid Build Coastguard Worker {
2457*cfb92d14SAndroid Build Coastguard Worker     uint8_t window = 0;
2458*cfb92d14SAndroid Build Coastguard Worker     otError error  = OT_ERROR_NONE;
2459*cfb92d14SAndroid Build Coastguard Worker 
2460*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(window));
2461*cfb92d14SAndroid Build Coastguard Worker 
2462*cfb92d14SAndroid Build Coastguard Worker     error = otJamDetectionSetWindow(mInstance, window);
2463*cfb92d14SAndroid Build Coastguard Worker 
2464*cfb92d14SAndroid Build Coastguard Worker exit:
2465*cfb92d14SAndroid Build Coastguard Worker     return error;
2466*cfb92d14SAndroid Build Coastguard Worker }
2467*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2468*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_JAM_DETECT_BUSY>(void)
2469*cfb92d14SAndroid Build Coastguard Worker {
2470*cfb92d14SAndroid Build Coastguard Worker     uint8_t busy  = 0;
2471*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
2472*cfb92d14SAndroid Build Coastguard Worker 
2473*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(busy));
2474*cfb92d14SAndroid Build Coastguard Worker 
2475*cfb92d14SAndroid Build Coastguard Worker     error = otJamDetectionSetBusyPeriod(mInstance, busy);
2476*cfb92d14SAndroid Build Coastguard Worker 
2477*cfb92d14SAndroid Build Coastguard Worker exit:
2478*cfb92d14SAndroid Build Coastguard Worker     return error;
2479*cfb92d14SAndroid Build Coastguard Worker }
2480*cfb92d14SAndroid Build Coastguard Worker 
HandleJamStateChange_Jump(bool aJamState,void * aContext)2481*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleJamStateChange_Jump(bool aJamState, void *aContext)
2482*cfb92d14SAndroid Build Coastguard Worker {
2483*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleJamStateChange(aJamState);
2484*cfb92d14SAndroid Build Coastguard Worker }
2485*cfb92d14SAndroid Build Coastguard Worker 
HandleJamStateChange(bool aJamState)2486*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleJamStateChange(bool aJamState)
2487*cfb92d14SAndroid Build Coastguard Worker {
2488*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aJamState);
2489*cfb92d14SAndroid Build Coastguard Worker 
2490*cfb92d14SAndroid Build Coastguard Worker     mChangedPropsSet.AddProperty(SPINEL_PROP_JAM_DETECTED);
2491*cfb92d14SAndroid Build Coastguard Worker     mUpdateChangedPropsTask.Post();
2492*cfb92d14SAndroid Build Coastguard Worker }
2493*cfb92d14SAndroid Build Coastguard Worker 
2494*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
2495*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2496*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT>(void)
2497*cfb92d14SAndroid Build Coastguard Worker {
2498*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint16(otChildSupervisionGetCheckTimeout(mInstance));
2499*cfb92d14SAndroid Build Coastguard Worker }
2500*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2501*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT>(void)
2502*cfb92d14SAndroid Build Coastguard Worker {
2503*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
2504*cfb92d14SAndroid Build Coastguard Worker     uint16_t timeout;
2505*cfb92d14SAndroid Build Coastguard Worker 
2506*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(timeout));
2507*cfb92d14SAndroid Build Coastguard Worker     otChildSupervisionSetCheckTimeout(mInstance, timeout);
2508*cfb92d14SAndroid Build Coastguard Worker 
2509*cfb92d14SAndroid Build Coastguard Worker exit:
2510*cfb92d14SAndroid Build Coastguard Worker     return error;
2511*cfb92d14SAndroid Build Coastguard Worker }
2512*cfb92d14SAndroid Build Coastguard Worker 
2513*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
2514*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2515*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL>(void)
2516*cfb92d14SAndroid Build Coastguard Worker {
2517*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otChannelMonitorGetSampleInterval(mInstance));
2518*cfb92d14SAndroid Build Coastguard Worker }
2519*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2520*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD>(void)
2521*cfb92d14SAndroid Build Coastguard Worker {
2522*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteInt8(otChannelMonitorGetRssiThreshold(mInstance));
2523*cfb92d14SAndroid Build Coastguard Worker }
2524*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2525*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW>(void)
2526*cfb92d14SAndroid Build Coastguard Worker {
2527*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otChannelMonitorGetSampleWindow(mInstance));
2528*cfb92d14SAndroid Build Coastguard Worker }
2529*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2530*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT>(void)
2531*cfb92d14SAndroid Build Coastguard Worker {
2532*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otChannelMonitorGetSampleCount(mInstance));
2533*cfb92d14SAndroid Build Coastguard Worker }
2534*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2535*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_OCCUPANCY>(void)
2536*cfb92d14SAndroid Build Coastguard Worker {
2537*cfb92d14SAndroid Build Coastguard Worker     otError  error       = OT_ERROR_NONE;
2538*cfb92d14SAndroid Build Coastguard Worker     uint32_t channelMask = otLinkGetSupportedChannelMask(mInstance);
2539*cfb92d14SAndroid Build Coastguard Worker     uint8_t  channelNum  = sizeof(channelMask) * kBitsPerByte;
2540*cfb92d14SAndroid Build Coastguard Worker 
2541*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t channel = 0; channel < channelNum; channel++)
2542*cfb92d14SAndroid Build Coastguard Worker     {
2543*cfb92d14SAndroid Build Coastguard Worker         if (!((1UL << channel) & channelMask))
2544*cfb92d14SAndroid Build Coastguard Worker         {
2545*cfb92d14SAndroid Build Coastguard Worker             continue;
2546*cfb92d14SAndroid Build Coastguard Worker         }
2547*cfb92d14SAndroid Build Coastguard Worker 
2548*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
2549*cfb92d14SAndroid Build Coastguard Worker 
2550*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(channel));
2551*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(otChannelMonitorGetChannelOccupancy(mInstance, channel)));
2552*cfb92d14SAndroid Build Coastguard Worker 
2553*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
2554*cfb92d14SAndroid Build Coastguard Worker     }
2555*cfb92d14SAndroid Build Coastguard Worker 
2556*cfb92d14SAndroid Build Coastguard Worker exit:
2557*cfb92d14SAndroid Build Coastguard Worker     return error;
2558*cfb92d14SAndroid Build Coastguard Worker }
2559*cfb92d14SAndroid Build Coastguard Worker 
2560*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
2561*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2562*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_CCA_FAILURE_RATE>(void)
2563*cfb92d14SAndroid Build Coastguard Worker {
2564*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint16(otLinkGetCcaFailureRate(mInstance));
2565*cfb92d14SAndroid Build Coastguard Worker }
2566*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2567*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_TOTAL>(void)
2568*cfb92d14SAndroid Build Coastguard Worker {
2569*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxTotal);
2570*cfb92d14SAndroid Build Coastguard Worker }
2571*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2572*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_ACK_REQ>(void)
2573*cfb92d14SAndroid Build Coastguard Worker {
2574*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxAckRequested);
2575*cfb92d14SAndroid Build Coastguard Worker }
2576*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2577*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_ACKED>(void)
2578*cfb92d14SAndroid Build Coastguard Worker {
2579*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxAcked);
2580*cfb92d14SAndroid Build Coastguard Worker }
2581*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2582*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ>(void)
2583*cfb92d14SAndroid Build Coastguard Worker {
2584*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxNoAckRequested);
2585*cfb92d14SAndroid Build Coastguard Worker }
2586*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2587*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_DATA>(void)
2588*cfb92d14SAndroid Build Coastguard Worker {
2589*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxData);
2590*cfb92d14SAndroid Build Coastguard Worker }
2591*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2592*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_DATA_POLL>(void)
2593*cfb92d14SAndroid Build Coastguard Worker {
2594*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxDataPoll);
2595*cfb92d14SAndroid Build Coastguard Worker }
2596*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2597*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_BEACON>(void)
2598*cfb92d14SAndroid Build Coastguard Worker {
2599*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxBeacon);
2600*cfb92d14SAndroid Build Coastguard Worker }
2601*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2602*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ>(void)
2603*cfb92d14SAndroid Build Coastguard Worker {
2604*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxBeaconRequest);
2605*cfb92d14SAndroid Build Coastguard Worker }
2606*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2607*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_OTHER>(void)
2608*cfb92d14SAndroid Build Coastguard Worker {
2609*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxOther);
2610*cfb92d14SAndroid Build Coastguard Worker }
2611*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2612*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_RETRY>(void)
2613*cfb92d14SAndroid Build Coastguard Worker {
2614*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxRetry);
2615*cfb92d14SAndroid Build Coastguard Worker }
2616*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2617*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_ERR_CCA>(void)
2618*cfb92d14SAndroid Build Coastguard Worker {
2619*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxErrCca);
2620*cfb92d14SAndroid Build Coastguard Worker }
2621*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2622*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_UNICAST>(void)
2623*cfb92d14SAndroid Build Coastguard Worker {
2624*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxUnicast);
2625*cfb92d14SAndroid Build Coastguard Worker }
2626*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2627*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_PKT_BROADCAST>(void)
2628*cfb92d14SAndroid Build Coastguard Worker {
2629*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxBroadcast);
2630*cfb92d14SAndroid Build Coastguard Worker }
2631*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2632*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_ERR_ABORT>(void)
2633*cfb92d14SAndroid Build Coastguard Worker {
2634*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mTxErrAbort);
2635*cfb92d14SAndroid Build Coastguard Worker }
2636*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2637*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_TOTAL>(void)
2638*cfb92d14SAndroid Build Coastguard Worker {
2639*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxTotal);
2640*cfb92d14SAndroid Build Coastguard Worker }
2641*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2642*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_DATA>(void)
2643*cfb92d14SAndroid Build Coastguard Worker {
2644*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxData);
2645*cfb92d14SAndroid Build Coastguard Worker }
2646*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2647*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_DATA_POLL>(void)
2648*cfb92d14SAndroid Build Coastguard Worker {
2649*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxDataPoll);
2650*cfb92d14SAndroid Build Coastguard Worker }
2651*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2652*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_BEACON>(void)
2653*cfb92d14SAndroid Build Coastguard Worker {
2654*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxBeacon);
2655*cfb92d14SAndroid Build Coastguard Worker }
2656*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2657*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ>(void)
2658*cfb92d14SAndroid Build Coastguard Worker {
2659*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxBeaconRequest);
2660*cfb92d14SAndroid Build Coastguard Worker }
2661*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2662*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_OTHER>(void)
2663*cfb92d14SAndroid Build Coastguard Worker {
2664*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxOther);
2665*cfb92d14SAndroid Build Coastguard Worker }
2666*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2667*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_FILT_WL>(void)
2668*cfb92d14SAndroid Build Coastguard Worker {
2669*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxAddressFiltered);
2670*cfb92d14SAndroid Build Coastguard Worker }
2671*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2672*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_FILT_DA>(void)
2673*cfb92d14SAndroid Build Coastguard Worker {
2674*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxDestAddrFiltered);
2675*cfb92d14SAndroid Build Coastguard Worker }
2676*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2677*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_DUP>(void)
2678*cfb92d14SAndroid Build Coastguard Worker {
2679*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxDuplicated);
2680*cfb92d14SAndroid Build Coastguard Worker }
2681*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2682*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_UNICAST>(void)
2683*cfb92d14SAndroid Build Coastguard Worker {
2684*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxUnicast);
2685*cfb92d14SAndroid Build Coastguard Worker }
2686*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2687*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_PKT_BROADCAST>(void)
2688*cfb92d14SAndroid Build Coastguard Worker {
2689*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxBroadcast);
2690*cfb92d14SAndroid Build Coastguard Worker }
2691*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2692*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_ERR_EMPTY>(void)
2693*cfb92d14SAndroid Build Coastguard Worker {
2694*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxErrNoFrame);
2695*cfb92d14SAndroid Build Coastguard Worker }
2696*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2697*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR>(void)
2698*cfb92d14SAndroid Build Coastguard Worker {
2699*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxErrUnknownNeighbor);
2700*cfb92d14SAndroid Build Coastguard Worker }
2701*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2702*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR>(void)
2703*cfb92d14SAndroid Build Coastguard Worker {
2704*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxErrInvalidSrcAddr);
2705*cfb92d14SAndroid Build Coastguard Worker }
2706*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2707*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_ERR_SECURITY>(void)
2708*cfb92d14SAndroid Build Coastguard Worker {
2709*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxErrSec);
2710*cfb92d14SAndroid Build Coastguard Worker }
2711*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2712*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_ERR_BAD_FCS>(void)
2713*cfb92d14SAndroid Build Coastguard Worker {
2714*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxErrFcs);
2715*cfb92d14SAndroid Build Coastguard Worker }
2716*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2717*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_ERR_OTHER>(void)
2718*cfb92d14SAndroid Build Coastguard Worker {
2719*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otLinkGetCounters(mInstance)->mRxErrOther);
2720*cfb92d14SAndroid Build Coastguard Worker }
2721*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2722*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL>(void)
2723*cfb92d14SAndroid Build Coastguard Worker {
2724*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mInboundSecureIpFrameCounter);
2725*cfb92d14SAndroid Build Coastguard Worker }
2726*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2727*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL>(void)
2728*cfb92d14SAndroid Build Coastguard Worker {
2729*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mInboundInsecureIpFrameCounter);
2730*cfb92d14SAndroid Build Coastguard Worker }
2731*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2732*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_IP_DROPPED>(void)
2733*cfb92d14SAndroid Build Coastguard Worker {
2734*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mDroppedInboundIpFrameCounter);
2735*cfb92d14SAndroid Build Coastguard Worker }
2736*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2737*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL>(void)
2738*cfb92d14SAndroid Build Coastguard Worker {
2739*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mOutboundSecureIpFrameCounter);
2740*cfb92d14SAndroid Build Coastguard Worker }
2741*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2742*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL>(void)
2743*cfb92d14SAndroid Build Coastguard Worker {
2744*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mOutboundInsecureIpFrameCounter);
2745*cfb92d14SAndroid Build Coastguard Worker }
2746*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2747*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_IP_DROPPED>(void)
2748*cfb92d14SAndroid Build Coastguard Worker {
2749*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mDroppedOutboundIpFrameCounter);
2750*cfb92d14SAndroid Build Coastguard Worker }
2751*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2752*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_TX_SPINEL_TOTAL>(void)
2753*cfb92d14SAndroid Build Coastguard Worker {
2754*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mTxSpinelFrameCounter);
2755*cfb92d14SAndroid Build Coastguard Worker }
2756*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2757*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_SPINEL_TOTAL>(void)
2758*cfb92d14SAndroid Build Coastguard Worker {
2759*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mRxSpinelFrameCounter);
2760*cfb92d14SAndroid Build Coastguard Worker }
2761*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2762*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_SPINEL_OUT_OF_ORDER_TID>(void)
2763*cfb92d14SAndroid Build Coastguard Worker {
2764*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mRxSpinelOutOfOrderTidCounter);
2765*cfb92d14SAndroid Build Coastguard Worker }
2766*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2767*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_RX_SPINEL_ERR>(void)
2768*cfb92d14SAndroid Build Coastguard Worker {
2769*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(mFramingErrorCounter);
2770*cfb92d14SAndroid Build Coastguard Worker }
2771*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2772*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_IP_TX_SUCCESS>(void)
2773*cfb92d14SAndroid Build Coastguard Worker {
2774*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetIp6Counters(mInstance)->mTxSuccess);
2775*cfb92d14SAndroid Build Coastguard Worker }
2776*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2777*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_IP_RX_SUCCESS>(void)
2778*cfb92d14SAndroid Build Coastguard Worker {
2779*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetIp6Counters(mInstance)->mRxSuccess);
2780*cfb92d14SAndroid Build Coastguard Worker }
2781*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2782*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_IP_TX_FAILURE>(void)
2783*cfb92d14SAndroid Build Coastguard Worker {
2784*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetIp6Counters(mInstance)->mTxFailure);
2785*cfb92d14SAndroid Build Coastguard Worker }
2786*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2787*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_IP_RX_FAILURE>(void)
2788*cfb92d14SAndroid Build Coastguard Worker {
2789*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetIp6Counters(mInstance)->mRxFailure);
2790*cfb92d14SAndroid Build Coastguard Worker }
2791*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2792*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MSG_BUFFER_COUNTERS>(void)
2793*cfb92d14SAndroid Build Coastguard Worker {
2794*cfb92d14SAndroid Build Coastguard Worker     otError      error = OT_ERROR_NONE;
2795*cfb92d14SAndroid Build Coastguard Worker     otBufferInfo bufferInfo;
2796*cfb92d14SAndroid Build Coastguard Worker 
2797*cfb92d14SAndroid Build Coastguard Worker     otMessageGetBufferInfo(mInstance, &bufferInfo);
2798*cfb92d14SAndroid Build Coastguard Worker 
2799*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mTotalBuffers));
2800*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mFreeBuffers));
2801*cfb92d14SAndroid Build Coastguard Worker 
2802*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.m6loSendQueue.mNumMessages));
2803*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.m6loSendQueue.mNumBuffers));
2804*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.m6loReassemblyQueue.mNumMessages));
2805*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.m6loReassemblyQueue.mNumBuffers));
2806*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mIp6Queue.mNumMessages));
2807*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mIp6Queue.mNumBuffers));
2808*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mMplQueue.mNumMessages));
2809*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mMplQueue.mNumBuffers));
2810*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mMleQueue.mNumMessages));
2811*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mMleQueue.mNumBuffers));
2812*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(0)); // Write zero for ARP for backward compatibility.
2813*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(0));
2814*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mCoapQueue.mNumMessages));
2815*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(bufferInfo.mCoapQueue.mNumBuffers));
2816*cfb92d14SAndroid Build Coastguard Worker 
2817*cfb92d14SAndroid Build Coastguard Worker exit:
2818*cfb92d14SAndroid Build Coastguard Worker     return error;
2819*cfb92d14SAndroid Build Coastguard Worker }
2820*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2821*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_ALL_MAC_COUNTERS>(void)
2822*cfb92d14SAndroid Build Coastguard Worker {
2823*cfb92d14SAndroid Build Coastguard Worker     otError              error    = OT_ERROR_NONE;
2824*cfb92d14SAndroid Build Coastguard Worker     const otMacCounters *counters = otLinkGetCounters(mInstance);
2825*cfb92d14SAndroid Build Coastguard Worker 
2826*cfb92d14SAndroid Build Coastguard Worker     // Encode Tx related counters
2827*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
2828*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxTotal));
2829*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxUnicast));
2830*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxBroadcast));
2831*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxAckRequested));
2832*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxAcked));
2833*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxNoAckRequested));
2834*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxData));
2835*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxDataPoll));
2836*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxBeacon));
2837*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxBeaconRequest));
2838*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxOther));
2839*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxRetry));
2840*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxErrCca));
2841*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxErrAbort));
2842*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxErrBusyChannel));
2843*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxDirectMaxRetryExpiry));
2844*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxIndirectMaxRetryExpiry));
2845*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
2846*cfb92d14SAndroid Build Coastguard Worker 
2847*cfb92d14SAndroid Build Coastguard Worker     // Encode Rx related counters
2848*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
2849*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxTotal));
2850*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxUnicast));
2851*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxBroadcast));
2852*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxData));
2853*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxDataPoll));
2854*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxBeacon));
2855*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxBeaconRequest));
2856*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxOther));
2857*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxAddressFiltered));
2858*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxDestAddrFiltered));
2859*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxDuplicated));
2860*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxErrNoFrame));
2861*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxErrUnknownNeighbor));
2862*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxErrInvalidSrcAddr));
2863*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxErrSec));
2864*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxErrFcs));
2865*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxErrOther));
2866*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
2867*cfb92d14SAndroid Build Coastguard Worker 
2868*cfb92d14SAndroid Build Coastguard Worker exit:
2869*cfb92d14SAndroid Build Coastguard Worker     return error;
2870*cfb92d14SAndroid Build Coastguard Worker }
2871*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2872*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CNTR_ALL_MAC_COUNTERS>(void)
2873*cfb92d14SAndroid Build Coastguard Worker {
2874*cfb92d14SAndroid Build Coastguard Worker     otLinkResetCounters(mInstance);
2875*cfb92d14SAndroid Build Coastguard Worker 
2876*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
2877*cfb92d14SAndroid Build Coastguard Worker }
2878*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2879*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_MLE_COUNTERS>(void)
2880*cfb92d14SAndroid Build Coastguard Worker {
2881*cfb92d14SAndroid Build Coastguard Worker     otError              error    = OT_ERROR_NONE;
2882*cfb92d14SAndroid Build Coastguard Worker     const otMleCounters *counters = otThreadGetMleCounters(mInstance);
2883*cfb92d14SAndroid Build Coastguard Worker 
2884*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT(counters != nullptr);
2885*cfb92d14SAndroid Build Coastguard Worker 
2886*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mDisabledRole));
2887*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mDetachedRole));
2888*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mChildRole));
2889*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mRouterRole));
2890*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mLeaderRole));
2891*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mAttachAttempts));
2892*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mPartitionIdChanges));
2893*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mBetterPartitionAttachAttempts));
2894*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(counters->mParentChanges));
2895*cfb92d14SAndroid Build Coastguard Worker 
2896*cfb92d14SAndroid Build Coastguard Worker exit:
2897*cfb92d14SAndroid Build Coastguard Worker     return error;
2898*cfb92d14SAndroid Build Coastguard Worker }
2899*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2900*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CNTR_MLE_COUNTERS>(void)
2901*cfb92d14SAndroid Build Coastguard Worker {
2902*cfb92d14SAndroid Build Coastguard Worker     otThreadResetMleCounters(mInstance);
2903*cfb92d14SAndroid Build Coastguard Worker 
2904*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
2905*cfb92d14SAndroid Build Coastguard Worker }
2906*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2907*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_ALL_IP_COUNTERS>(void)
2908*cfb92d14SAndroid Build Coastguard Worker {
2909*cfb92d14SAndroid Build Coastguard Worker     otError             error    = OT_ERROR_NONE;
2910*cfb92d14SAndroid Build Coastguard Worker     const otIpCounters *counters = otThreadGetIp6Counters(mInstance);
2911*cfb92d14SAndroid Build Coastguard Worker 
2912*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT(counters != nullptr);
2913*cfb92d14SAndroid Build Coastguard Worker 
2914*cfb92d14SAndroid Build Coastguard Worker     // Encode Tx related counters
2915*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
2916*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxSuccess));
2917*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mTxFailure));
2918*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
2919*cfb92d14SAndroid Build Coastguard Worker 
2920*cfb92d14SAndroid Build Coastguard Worker     // Encode Rx related counters
2921*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
2922*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxSuccess));
2923*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint32(counters->mRxFailure));
2924*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
2925*cfb92d14SAndroid Build Coastguard Worker 
2926*cfb92d14SAndroid Build Coastguard Worker exit:
2927*cfb92d14SAndroid Build Coastguard Worker     return error;
2928*cfb92d14SAndroid Build Coastguard Worker }
2929*cfb92d14SAndroid Build Coastguard Worker 
2930*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
HandlePropertyGet(void)2931*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM>(void)
2932*cfb92d14SAndroid Build Coastguard Worker {
2933*cfb92d14SAndroid Build Coastguard Worker     otError         error = OT_ERROR_NONE;
2934*cfb92d14SAndroid Build Coastguard Worker     const uint32_t *histogramDirect;
2935*cfb92d14SAndroid Build Coastguard Worker     const uint32_t *histogramIndirect;
2936*cfb92d14SAndroid Build Coastguard Worker     uint8_t         histogramDirectEntries;
2937*cfb92d14SAndroid Build Coastguard Worker     uint8_t         histogramIndirectEntries;
2938*cfb92d14SAndroid Build Coastguard Worker 
2939*cfb92d14SAndroid Build Coastguard Worker     histogramDirect   = otLinkGetTxDirectRetrySuccessHistogram(mInstance, &histogramDirectEntries);
2940*cfb92d14SAndroid Build Coastguard Worker     histogramIndirect = otLinkGetTxIndirectRetrySuccessHistogram(mInstance, &histogramIndirectEntries);
2941*cfb92d14SAndroid Build Coastguard Worker 
2942*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT((histogramDirectEntries == 0) || (histogramDirect != nullptr));
2943*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT((histogramIndirectEntries == 0) || (histogramIndirect != nullptr));
2944*cfb92d14SAndroid Build Coastguard Worker 
2945*cfb92d14SAndroid Build Coastguard Worker     // Encode direct message retries histogram
2946*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
2947*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t i = 0; i < histogramDirectEntries; i++)
2948*cfb92d14SAndroid Build Coastguard Worker     {
2949*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(histogramDirect[i]));
2950*cfb92d14SAndroid Build Coastguard Worker     }
2951*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
2952*cfb92d14SAndroid Build Coastguard Worker 
2953*cfb92d14SAndroid Build Coastguard Worker     // Encode indirect message retries histogram
2954*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
2955*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t i = 0; i < histogramIndirectEntries; i++)
2956*cfb92d14SAndroid Build Coastguard Worker     {
2957*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint32(histogramIndirect[i]));
2958*cfb92d14SAndroid Build Coastguard Worker     }
2959*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
2960*cfb92d14SAndroid Build Coastguard Worker 
2961*cfb92d14SAndroid Build Coastguard Worker exit:
2962*cfb92d14SAndroid Build Coastguard Worker     return error;
2963*cfb92d14SAndroid Build Coastguard Worker }
2964*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2965*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM>(void)
2966*cfb92d14SAndroid Build Coastguard Worker {
2967*cfb92d14SAndroid Build Coastguard Worker     otLinkResetTxRetrySuccessHistogram(mInstance);
2968*cfb92d14SAndroid Build Coastguard Worker 
2969*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
2970*cfb92d14SAndroid Build Coastguard Worker }
2971*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
2972*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)2973*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CNTR_ALL_IP_COUNTERS>(void)
2974*cfb92d14SAndroid Build Coastguard Worker {
2975*cfb92d14SAndroid Build Coastguard Worker     otThreadResetIp6Counters(mInstance);
2976*cfb92d14SAndroid Build Coastguard Worker 
2977*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
2978*cfb92d14SAndroid Build Coastguard Worker }
2979*cfb92d14SAndroid Build Coastguard Worker 
2980*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
2981*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)2982*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_ALLOWLIST>(void)
2983*cfb92d14SAndroid Build Coastguard Worker {
2984*cfb92d14SAndroid Build Coastguard Worker     otMacFilterEntry    entry;
2985*cfb92d14SAndroid Build Coastguard Worker     otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
2986*cfb92d14SAndroid Build Coastguard Worker     otError             error    = OT_ERROR_NONE;
2987*cfb92d14SAndroid Build Coastguard Worker 
2988*cfb92d14SAndroid Build Coastguard Worker     while (otLinkFilterGetNextAddress(mInstance, &iterator, &entry) == OT_ERROR_NONE)
2989*cfb92d14SAndroid Build Coastguard Worker     {
2990*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
2991*cfb92d14SAndroid Build Coastguard Worker 
2992*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteEui64(entry.mExtAddress));
2993*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteInt8(entry.mRssIn));
2994*cfb92d14SAndroid Build Coastguard Worker 
2995*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
2996*cfb92d14SAndroid Build Coastguard Worker     }
2997*cfb92d14SAndroid Build Coastguard Worker 
2998*cfb92d14SAndroid Build Coastguard Worker exit:
2999*cfb92d14SAndroid Build Coastguard Worker     return error;
3000*cfb92d14SAndroid Build Coastguard Worker }
3001*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3002*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_ALLOWLIST_ENABLED>(void)
3003*cfb92d14SAndroid Build Coastguard Worker {
3004*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otLinkFilterGetAddressMode(mInstance) == OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST);
3005*cfb92d14SAndroid Build Coastguard Worker }
3006*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3007*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_DENYLIST>(void)
3008*cfb92d14SAndroid Build Coastguard Worker {
3009*cfb92d14SAndroid Build Coastguard Worker     otMacFilterEntry    entry;
3010*cfb92d14SAndroid Build Coastguard Worker     otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
3011*cfb92d14SAndroid Build Coastguard Worker     otError             error    = OT_ERROR_NONE;
3012*cfb92d14SAndroid Build Coastguard Worker 
3013*cfb92d14SAndroid Build Coastguard Worker     while (otLinkFilterGetNextAddress(mInstance, &iterator, &entry) == OT_ERROR_NONE)
3014*cfb92d14SAndroid Build Coastguard Worker     {
3015*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
3016*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteEui64(entry.mExtAddress));
3017*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
3018*cfb92d14SAndroid Build Coastguard Worker     }
3019*cfb92d14SAndroid Build Coastguard Worker 
3020*cfb92d14SAndroid Build Coastguard Worker exit:
3021*cfb92d14SAndroid Build Coastguard Worker     return error;
3022*cfb92d14SAndroid Build Coastguard Worker }
3023*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3024*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_DENYLIST_ENABLED>(void)
3025*cfb92d14SAndroid Build Coastguard Worker {
3026*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otLinkFilterGetAddressMode(mInstance) == OT_MAC_FILTER_ADDRESS_MODE_DENYLIST);
3027*cfb92d14SAndroid Build Coastguard Worker }
3028*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3029*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_MAC_FIXED_RSS>(void)
3030*cfb92d14SAndroid Build Coastguard Worker {
3031*cfb92d14SAndroid Build Coastguard Worker     otMacFilterEntry    entry;
3032*cfb92d14SAndroid Build Coastguard Worker     otMacFilterIterator iterator = OT_MAC_FILTER_ITERATOR_INIT;
3033*cfb92d14SAndroid Build Coastguard Worker     otError             error    = OT_ERROR_NONE;
3034*cfb92d14SAndroid Build Coastguard Worker 
3035*cfb92d14SAndroid Build Coastguard Worker     while (otLinkFilterGetNextRssIn(mInstance, &iterator, &entry) == OT_ERROR_NONE)
3036*cfb92d14SAndroid Build Coastguard Worker     {
3037*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
3038*cfb92d14SAndroid Build Coastguard Worker 
3039*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteEui64(entry.mExtAddress));
3040*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteInt8(entry.mRssIn));
3041*cfb92d14SAndroid Build Coastguard Worker 
3042*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
3043*cfb92d14SAndroid Build Coastguard Worker     }
3044*cfb92d14SAndroid Build Coastguard Worker 
3045*cfb92d14SAndroid Build Coastguard Worker exit:
3046*cfb92d14SAndroid Build Coastguard Worker     return error;
3047*cfb92d14SAndroid Build Coastguard Worker }
3048*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3049*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_ALLOWLIST>(void)
3050*cfb92d14SAndroid Build Coastguard Worker {
3051*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
3052*cfb92d14SAndroid Build Coastguard Worker 
3053*cfb92d14SAndroid Build Coastguard Worker     // First, clear the address filter entries.
3054*cfb92d14SAndroid Build Coastguard Worker     otLinkFilterClearAddresses(mInstance);
3055*cfb92d14SAndroid Build Coastguard Worker 
3056*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct() > 0)
3057*cfb92d14SAndroid Build Coastguard Worker     {
3058*cfb92d14SAndroid Build Coastguard Worker         const otExtAddress *extAddress = nullptr;
3059*cfb92d14SAndroid Build Coastguard Worker         int8_t              rss;
3060*cfb92d14SAndroid Build Coastguard Worker 
3061*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.OpenStruct());
3062*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3063*cfb92d14SAndroid Build Coastguard Worker 
3064*cfb92d14SAndroid Build Coastguard Worker         if (!mDecoder.IsAllReadInStruct())
3065*cfb92d14SAndroid Build Coastguard Worker         {
3066*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mDecoder.ReadInt8(rss));
3067*cfb92d14SAndroid Build Coastguard Worker         }
3068*cfb92d14SAndroid Build Coastguard Worker         else
3069*cfb92d14SAndroid Build Coastguard Worker         {
3070*cfb92d14SAndroid Build Coastguard Worker             rss = OT_MAC_FILTER_FIXED_RSS_DISABLED;
3071*cfb92d14SAndroid Build Coastguard Worker         }
3072*cfb92d14SAndroid Build Coastguard Worker 
3073*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.CloseStruct());
3074*cfb92d14SAndroid Build Coastguard Worker 
3075*cfb92d14SAndroid Build Coastguard Worker         error = otLinkFilterAddAddress(mInstance, extAddress);
3076*cfb92d14SAndroid Build Coastguard Worker 
3077*cfb92d14SAndroid Build Coastguard Worker         if (error == OT_ERROR_ALREADY)
3078*cfb92d14SAndroid Build Coastguard Worker         {
3079*cfb92d14SAndroid Build Coastguard Worker             error = OT_ERROR_NONE;
3080*cfb92d14SAndroid Build Coastguard Worker         }
3081*cfb92d14SAndroid Build Coastguard Worker 
3082*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error);
3083*cfb92d14SAndroid Build Coastguard Worker 
3084*cfb92d14SAndroid Build Coastguard Worker         if (rss != OT_MAC_FILTER_FIXED_RSS_DISABLED)
3085*cfb92d14SAndroid Build Coastguard Worker         {
3086*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, extAddress, rss));
3087*cfb92d14SAndroid Build Coastguard Worker         }
3088*cfb92d14SAndroid Build Coastguard Worker     }
3089*cfb92d14SAndroid Build Coastguard Worker 
3090*cfb92d14SAndroid Build Coastguard Worker exit:
3091*cfb92d14SAndroid Build Coastguard Worker     // If we had an error, we may have actually changed
3092*cfb92d14SAndroid Build Coastguard Worker     // the state of the allowlist, so we need to report
3093*cfb92d14SAndroid Build Coastguard Worker     // those incomplete changes via an asynchronous
3094*cfb92d14SAndroid Build Coastguard Worker     // change event.
3095*cfb92d14SAndroid Build Coastguard Worker 
3096*cfb92d14SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
3097*cfb92d14SAndroid Build Coastguard Worker     {
3098*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_ALLOWLIST));
3099*cfb92d14SAndroid Build Coastguard Worker     }
3100*cfb92d14SAndroid Build Coastguard Worker 
3101*cfb92d14SAndroid Build Coastguard Worker     return error;
3102*cfb92d14SAndroid Build Coastguard Worker }
3103*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3104*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_ALLOWLIST_ENABLED>(void)
3105*cfb92d14SAndroid Build Coastguard Worker {
3106*cfb92d14SAndroid Build Coastguard Worker     bool                   enabled;
3107*cfb92d14SAndroid Build Coastguard Worker     otError                error = OT_ERROR_NONE;
3108*cfb92d14SAndroid Build Coastguard Worker     otMacFilterAddressMode mode  = OT_MAC_FILTER_ADDRESS_MODE_DISABLED;
3109*cfb92d14SAndroid Build Coastguard Worker 
3110*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
3111*cfb92d14SAndroid Build Coastguard Worker 
3112*cfb92d14SAndroid Build Coastguard Worker     if (enabled)
3113*cfb92d14SAndroid Build Coastguard Worker     {
3114*cfb92d14SAndroid Build Coastguard Worker         mode = OT_MAC_FILTER_ADDRESS_MODE_ALLOWLIST;
3115*cfb92d14SAndroid Build Coastguard Worker     }
3116*cfb92d14SAndroid Build Coastguard Worker 
3117*cfb92d14SAndroid Build Coastguard Worker     otLinkFilterSetAddressMode(mInstance, mode);
3118*cfb92d14SAndroid Build Coastguard Worker 
3119*cfb92d14SAndroid Build Coastguard Worker exit:
3120*cfb92d14SAndroid Build Coastguard Worker     return error;
3121*cfb92d14SAndroid Build Coastguard Worker }
3122*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3123*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_DENYLIST>(void)
3124*cfb92d14SAndroid Build Coastguard Worker {
3125*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
3126*cfb92d14SAndroid Build Coastguard Worker 
3127*cfb92d14SAndroid Build Coastguard Worker     // First, clear the address filter entries.
3128*cfb92d14SAndroid Build Coastguard Worker     otLinkFilterClearAddresses(mInstance);
3129*cfb92d14SAndroid Build Coastguard Worker 
3130*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct() > 0)
3131*cfb92d14SAndroid Build Coastguard Worker     {
3132*cfb92d14SAndroid Build Coastguard Worker         const otExtAddress *extAddress = nullptr;
3133*cfb92d14SAndroid Build Coastguard Worker 
3134*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.OpenStruct());
3135*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3136*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.CloseStruct());
3137*cfb92d14SAndroid Build Coastguard Worker 
3138*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otLinkFilterAddAddress(mInstance, extAddress));
3139*cfb92d14SAndroid Build Coastguard Worker     }
3140*cfb92d14SAndroid Build Coastguard Worker 
3141*cfb92d14SAndroid Build Coastguard Worker exit:
3142*cfb92d14SAndroid Build Coastguard Worker     // If we had an error, we may have actually changed
3143*cfb92d14SAndroid Build Coastguard Worker     // the state of the denylist, so we need to report
3144*cfb92d14SAndroid Build Coastguard Worker     // those incomplete changes via an asynchronous
3145*cfb92d14SAndroid Build Coastguard Worker     // change event.
3146*cfb92d14SAndroid Build Coastguard Worker 
3147*cfb92d14SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
3148*cfb92d14SAndroid Build Coastguard Worker     {
3149*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_DENYLIST));
3150*cfb92d14SAndroid Build Coastguard Worker     }
3151*cfb92d14SAndroid Build Coastguard Worker 
3152*cfb92d14SAndroid Build Coastguard Worker     return error;
3153*cfb92d14SAndroid Build Coastguard Worker }
3154*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3155*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_DENYLIST_ENABLED>(void)
3156*cfb92d14SAndroid Build Coastguard Worker {
3157*cfb92d14SAndroid Build Coastguard Worker     bool                   enabled;
3158*cfb92d14SAndroid Build Coastguard Worker     otError                error = OT_ERROR_NONE;
3159*cfb92d14SAndroid Build Coastguard Worker     otMacFilterAddressMode mode  = OT_MAC_FILTER_ADDRESS_MODE_DISABLED;
3160*cfb92d14SAndroid Build Coastguard Worker 
3161*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
3162*cfb92d14SAndroid Build Coastguard Worker 
3163*cfb92d14SAndroid Build Coastguard Worker     if (enabled)
3164*cfb92d14SAndroid Build Coastguard Worker     {
3165*cfb92d14SAndroid Build Coastguard Worker         mode = OT_MAC_FILTER_ADDRESS_MODE_DENYLIST;
3166*cfb92d14SAndroid Build Coastguard Worker     }
3167*cfb92d14SAndroid Build Coastguard Worker 
3168*cfb92d14SAndroid Build Coastguard Worker     otLinkFilterSetAddressMode(mInstance, mode);
3169*cfb92d14SAndroid Build Coastguard Worker 
3170*cfb92d14SAndroid Build Coastguard Worker exit:
3171*cfb92d14SAndroid Build Coastguard Worker     return error;
3172*cfb92d14SAndroid Build Coastguard Worker }
3173*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3174*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_MAC_FIXED_RSS>(void)
3175*cfb92d14SAndroid Build Coastguard Worker {
3176*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
3177*cfb92d14SAndroid Build Coastguard Worker 
3178*cfb92d14SAndroid Build Coastguard Worker     // First, clear the address filter entries.
3179*cfb92d14SAndroid Build Coastguard Worker     otLinkFilterClearAllRssIn(mInstance);
3180*cfb92d14SAndroid Build Coastguard Worker 
3181*cfb92d14SAndroid Build Coastguard Worker     while (mDecoder.GetRemainingLengthInStruct() > 0)
3182*cfb92d14SAndroid Build Coastguard Worker     {
3183*cfb92d14SAndroid Build Coastguard Worker         const otExtAddress *extAddress;
3184*cfb92d14SAndroid Build Coastguard Worker         int8_t              rss;
3185*cfb92d14SAndroid Build Coastguard Worker 
3186*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.OpenStruct());
3187*cfb92d14SAndroid Build Coastguard Worker 
3188*cfb92d14SAndroid Build Coastguard Worker         if (mDecoder.GetRemainingLengthInStruct() > sizeof(otExtAddress))
3189*cfb92d14SAndroid Build Coastguard Worker         {
3190*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3191*cfb92d14SAndroid Build Coastguard Worker         }
3192*cfb92d14SAndroid Build Coastguard Worker         else
3193*cfb92d14SAndroid Build Coastguard Worker         {
3194*cfb92d14SAndroid Build Coastguard Worker             extAddress = nullptr;
3195*cfb92d14SAndroid Build Coastguard Worker         }
3196*cfb92d14SAndroid Build Coastguard Worker 
3197*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadInt8(rss));
3198*cfb92d14SAndroid Build Coastguard Worker 
3199*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.CloseStruct());
3200*cfb92d14SAndroid Build Coastguard Worker 
3201*cfb92d14SAndroid Build Coastguard Worker         if (extAddress != nullptr)
3202*cfb92d14SAndroid Build Coastguard Worker         {
3203*cfb92d14SAndroid Build Coastguard Worker             SuccessOrExit(error = otLinkFilterAddRssIn(mInstance, extAddress, rss));
3204*cfb92d14SAndroid Build Coastguard Worker         }
3205*cfb92d14SAndroid Build Coastguard Worker         else
3206*cfb92d14SAndroid Build Coastguard Worker         {
3207*cfb92d14SAndroid Build Coastguard Worker             otLinkFilterSetDefaultRssIn(mInstance, rss);
3208*cfb92d14SAndroid Build Coastguard Worker         }
3209*cfb92d14SAndroid Build Coastguard Worker     }
3210*cfb92d14SAndroid Build Coastguard Worker 
3211*cfb92d14SAndroid Build Coastguard Worker exit:
3212*cfb92d14SAndroid Build Coastguard Worker     // If we had an error, we may have actually changed
3213*cfb92d14SAndroid Build Coastguard Worker     // the state of the RssIn filter, so we need to report
3214*cfb92d14SAndroid Build Coastguard Worker     // those incomplete changes via an asynchronous
3215*cfb92d14SAndroid Build Coastguard Worker     // change event.
3216*cfb92d14SAndroid Build Coastguard Worker 
3217*cfb92d14SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
3218*cfb92d14SAndroid Build Coastguard Worker     {
3219*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(WritePropertyValueIsFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_PROP_MAC_FIXED_RSS));
3220*cfb92d14SAndroid Build Coastguard Worker     }
3221*cfb92d14SAndroid Build Coastguard Worker 
3222*cfb92d14SAndroid Build Coastguard Worker     return error;
3223*cfb92d14SAndroid Build Coastguard Worker }
3224*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
3225*cfb92d14SAndroid Build Coastguard Worker 
3226*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
HandlePropertySet(void)3227*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LINK_METRICS_QUERY>(void)
3228*cfb92d14SAndroid Build Coastguard Worker {
3229*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
3230*cfb92d14SAndroid Build Coastguard Worker     struct otIp6Address address;
3231*cfb92d14SAndroid Build Coastguard Worker     uint8_t             seriesId;
3232*cfb92d14SAndroid Build Coastguard Worker     otLinkMetrics       linkMetrics = {false, false, false, false, false};
3233*cfb92d14SAndroid Build Coastguard Worker 
3234*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(address));
3235*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(seriesId));
3236*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ true));
3237*cfb92d14SAndroid Build Coastguard Worker 
3238*cfb92d14SAndroid Build Coastguard Worker     error =
3239*cfb92d14SAndroid Build Coastguard Worker         otLinkMetricsQuery(mInstance, &address, seriesId, &linkMetrics, &NcpBase::HandleLinkMetricsReport_Jump, this);
3240*cfb92d14SAndroid Build Coastguard Worker 
3241*cfb92d14SAndroid Build Coastguard Worker exit:
3242*cfb92d14SAndroid Build Coastguard Worker     return error;
3243*cfb92d14SAndroid Build Coastguard Worker }
3244*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3245*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LINK_METRICS_PROBE>(void)
3246*cfb92d14SAndroid Build Coastguard Worker {
3247*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
3248*cfb92d14SAndroid Build Coastguard Worker     struct otIp6Address address;
3249*cfb92d14SAndroid Build Coastguard Worker     uint8_t             seriesId;
3250*cfb92d14SAndroid Build Coastguard Worker     uint8_t             length;
3251*cfb92d14SAndroid Build Coastguard Worker 
3252*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(address));
3253*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(seriesId));
3254*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(length));
3255*cfb92d14SAndroid Build Coastguard Worker 
3256*cfb92d14SAndroid Build Coastguard Worker     error = otLinkMetricsSendLinkProbe(mInstance, &address, seriesId, length);
3257*cfb92d14SAndroid Build Coastguard Worker 
3258*cfb92d14SAndroid Build Coastguard Worker exit:
3259*cfb92d14SAndroid Build Coastguard Worker     return error;
3260*cfb92d14SAndroid Build Coastguard Worker }
3261*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3262*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LINK_METRICS_MGMT_ENH_ACK>(void)
3263*cfb92d14SAndroid Build Coastguard Worker {
3264*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
3265*cfb92d14SAndroid Build Coastguard Worker     struct otIp6Address address;
3266*cfb92d14SAndroid Build Coastguard Worker     uint8_t             controlFlags;
3267*cfb92d14SAndroid Build Coastguard Worker     otLinkMetrics       linkMetrics = {false, false, false, false, false};
3268*cfb92d14SAndroid Build Coastguard Worker 
3269*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(address));
3270*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(controlFlags));
3271*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ false));
3272*cfb92d14SAndroid Build Coastguard Worker 
3273*cfb92d14SAndroid Build Coastguard Worker     error = otLinkMetricsConfigEnhAckProbing(mInstance, &address, static_cast<otLinkMetricsEnhAckFlags>(controlFlags),
3274*cfb92d14SAndroid Build Coastguard Worker                                              controlFlags ? &linkMetrics : nullptr,
3275*cfb92d14SAndroid Build Coastguard Worker                                              &NcpBase::HandleLinkMetricsMgmtResponse_Jump, this,
3276*cfb92d14SAndroid Build Coastguard Worker                                              &NcpBase::HandleLinkMetricsEnhAckProbingIeReport_Jump, this);
3277*cfb92d14SAndroid Build Coastguard Worker 
3278*cfb92d14SAndroid Build Coastguard Worker exit:
3279*cfb92d14SAndroid Build Coastguard Worker     return error;
3280*cfb92d14SAndroid Build Coastguard Worker }
3281*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3282*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_LINK_METRICS_MGMT_FORWARD>(void)
3283*cfb92d14SAndroid Build Coastguard Worker {
3284*cfb92d14SAndroid Build Coastguard Worker     otError                  error = OT_ERROR_NONE;
3285*cfb92d14SAndroid Build Coastguard Worker     struct otIp6Address      address;
3286*cfb92d14SAndroid Build Coastguard Worker     uint8_t                  seriesId;
3287*cfb92d14SAndroid Build Coastguard Worker     uint8_t                  types;
3288*cfb92d14SAndroid Build Coastguard Worker     otLinkMetrics            linkMetrics = {false, false, false, false, false};
3289*cfb92d14SAndroid Build Coastguard Worker     otLinkMetricsSeriesFlags seriesFlags = {false, false, false, false};
3290*cfb92d14SAndroid Build Coastguard Worker 
3291*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(address));
3292*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(seriesId));
3293*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(types));
3294*cfb92d14SAndroid Build Coastguard Worker 
3295*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = DecodeLinkMetrics(&linkMetrics, /* aAllowPduCount */ true));
3296*cfb92d14SAndroid Build Coastguard Worker 
3297*cfb92d14SAndroid Build Coastguard Worker     if (types & SPINEL_THREAD_FRAME_TYPE_MLE_LINK_PROBE)
3298*cfb92d14SAndroid Build Coastguard Worker     {
3299*cfb92d14SAndroid Build Coastguard Worker         seriesFlags.mLinkProbe = true;
3300*cfb92d14SAndroid Build Coastguard Worker     }
3301*cfb92d14SAndroid Build Coastguard Worker 
3302*cfb92d14SAndroid Build Coastguard Worker     if (types & SPINEL_THREAD_FRAME_TYPE_MAC_DATA)
3303*cfb92d14SAndroid Build Coastguard Worker     {
3304*cfb92d14SAndroid Build Coastguard Worker         seriesFlags.mMacData = true;
3305*cfb92d14SAndroid Build Coastguard Worker     }
3306*cfb92d14SAndroid Build Coastguard Worker 
3307*cfb92d14SAndroid Build Coastguard Worker     if (types & SPINEL_THREAD_FRAME_TYPE_MAC_DATA_REQUEST)
3308*cfb92d14SAndroid Build Coastguard Worker     {
3309*cfb92d14SAndroid Build Coastguard Worker         seriesFlags.mMacDataRequest = true;
3310*cfb92d14SAndroid Build Coastguard Worker     }
3311*cfb92d14SAndroid Build Coastguard Worker 
3312*cfb92d14SAndroid Build Coastguard Worker     if (types & SPINEL_THREAD_FRAME_TYPE_MAC_ACK)
3313*cfb92d14SAndroid Build Coastguard Worker     {
3314*cfb92d14SAndroid Build Coastguard Worker         seriesFlags.mMacAck = true;
3315*cfb92d14SAndroid Build Coastguard Worker     }
3316*cfb92d14SAndroid Build Coastguard Worker 
3317*cfb92d14SAndroid Build Coastguard Worker     error = otLinkMetricsConfigForwardTrackingSeries(mInstance, &address, seriesId, seriesFlags, &linkMetrics,
3318*cfb92d14SAndroid Build Coastguard Worker                                                      &NcpBase::HandleLinkMetricsMgmtResponse_Jump, this);
3319*cfb92d14SAndroid Build Coastguard Worker 
3320*cfb92d14SAndroid Build Coastguard Worker exit:
3321*cfb92d14SAndroid Build Coastguard Worker     return error;
3322*cfb92d14SAndroid Build Coastguard Worker }
3323*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
3324*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3325*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_MODE>(void)
3326*cfb92d14SAndroid Build Coastguard Worker {
3327*cfb92d14SAndroid Build Coastguard Worker     uint8_t          numericMode;
3328*cfb92d14SAndroid Build Coastguard Worker     otLinkModeConfig modeConfig = otThreadGetLinkMode(mInstance);
3329*cfb92d14SAndroid Build Coastguard Worker 
3330*cfb92d14SAndroid Build Coastguard Worker     numericMode = LinkFlagsToFlagByte(modeConfig.mRxOnWhenIdle, modeConfig.mDeviceType, modeConfig.mNetworkData);
3331*cfb92d14SAndroid Build Coastguard Worker 
3332*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint8(numericMode);
3333*cfb92d14SAndroid Build Coastguard Worker }
3334*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3335*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_MODE>(void)
3336*cfb92d14SAndroid Build Coastguard Worker {
3337*cfb92d14SAndroid Build Coastguard Worker     uint8_t          numericMode = 0;
3338*cfb92d14SAndroid Build Coastguard Worker     otLinkModeConfig modeConfig;
3339*cfb92d14SAndroid Build Coastguard Worker     otError          error = OT_ERROR_NONE;
3340*cfb92d14SAndroid Build Coastguard Worker 
3341*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint8(numericMode));
3342*cfb92d14SAndroid Build Coastguard Worker 
3343*cfb92d14SAndroid Build Coastguard Worker     modeConfig.mRxOnWhenIdle =
3344*cfb92d14SAndroid Build Coastguard Worker         ((numericMode & SPINEL_THREAD_MODE_RX_ON_WHEN_IDLE) == SPINEL_THREAD_MODE_RX_ON_WHEN_IDLE);
3345*cfb92d14SAndroid Build Coastguard Worker     modeConfig.mDeviceType = ((numericMode & SPINEL_THREAD_MODE_FULL_THREAD_DEV) == SPINEL_THREAD_MODE_FULL_THREAD_DEV);
3346*cfb92d14SAndroid Build Coastguard Worker     modeConfig.mNetworkData =
3347*cfb92d14SAndroid Build Coastguard Worker         ((numericMode & SPINEL_THREAD_MODE_FULL_NETWORK_DATA) == SPINEL_THREAD_MODE_FULL_NETWORK_DATA);
3348*cfb92d14SAndroid Build Coastguard Worker 
3349*cfb92d14SAndroid Build Coastguard Worker     error = otThreadSetLinkMode(mInstance, modeConfig);
3350*cfb92d14SAndroid Build Coastguard Worker 
3351*cfb92d14SAndroid Build Coastguard Worker exit:
3352*cfb92d14SAndroid Build Coastguard Worker     return error;
3353*cfb92d14SAndroid Build Coastguard Worker }
3354*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3355*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_CHILD_TIMEOUT>(void)
3356*cfb92d14SAndroid Build Coastguard Worker {
3357*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otThreadGetChildTimeout(mInstance));
3358*cfb92d14SAndroid Build Coastguard Worker }
3359*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3360*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_CHILD_TIMEOUT>(void)
3361*cfb92d14SAndroid Build Coastguard Worker {
3362*cfb92d14SAndroid Build Coastguard Worker     uint32_t timeout = 0;
3363*cfb92d14SAndroid Build Coastguard Worker     otError  error   = OT_ERROR_NONE;
3364*cfb92d14SAndroid Build Coastguard Worker 
3365*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(timeout));
3366*cfb92d14SAndroid Build Coastguard Worker 
3367*cfb92d14SAndroid Build Coastguard Worker     otThreadSetChildTimeout(mInstance, timeout);
3368*cfb92d14SAndroid Build Coastguard Worker 
3369*cfb92d14SAndroid Build Coastguard Worker exit:
3370*cfb92d14SAndroid Build Coastguard Worker     return error;
3371*cfb92d14SAndroid Build Coastguard Worker }
3372*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3373*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_RLOC16>(void)
3374*cfb92d14SAndroid Build Coastguard Worker {
3375*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint16(otThreadGetRloc16(mInstance));
3376*cfb92d14SAndroid Build Coastguard Worker }
3377*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3378*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING>(void)
3379*cfb92d14SAndroid Build Coastguard Worker {
3380*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(mRequireJoinExistingNetwork);
3381*cfb92d14SAndroid Build Coastguard Worker }
3382*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3383*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING>(void)
3384*cfb92d14SAndroid Build Coastguard Worker {
3385*cfb92d14SAndroid Build Coastguard Worker     return mDecoder.ReadBool(mRequireJoinExistingNetwork);
3386*cfb92d14SAndroid Build Coastguard Worker }
3387*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3388*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_STREAM_NET_INSECURE>(void)
3389*cfb92d14SAndroid Build Coastguard Worker {
3390*cfb92d14SAndroid Build Coastguard Worker     const uint8_t    *framePtr    = nullptr;
3391*cfb92d14SAndroid Build Coastguard Worker     uint16_t          frameLen    = 0;
3392*cfb92d14SAndroid Build Coastguard Worker     const uint8_t    *metaPtr     = nullptr;
3393*cfb92d14SAndroid Build Coastguard Worker     uint16_t          metaLen     = 0;
3394*cfb92d14SAndroid Build Coastguard Worker     otMessage        *message     = nullptr;
3395*cfb92d14SAndroid Build Coastguard Worker     otError           error       = OT_ERROR_NONE;
3396*cfb92d14SAndroid Build Coastguard Worker     otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
3397*cfb92d14SAndroid Build Coastguard Worker 
3398*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(framePtr, frameLen));
3399*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadData(metaPtr, metaLen));
3400*cfb92d14SAndroid Build Coastguard Worker 
3401*cfb92d14SAndroid Build Coastguard Worker     // We ignore metadata for now.
3402*cfb92d14SAndroid Build Coastguard Worker     // May later include TX power, allow retransmits, etc...
3403*cfb92d14SAndroid Build Coastguard Worker 
3404*cfb92d14SAndroid Build Coastguard Worker     // STREAM_NET_INSECURE packets are not secured at layer 2.
3405*cfb92d14SAndroid Build Coastguard Worker     message = otIp6NewMessageFromBuffer(mInstance, framePtr, frameLen, &msgSettings);
3406*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
3407*cfb92d14SAndroid Build Coastguard Worker     otMessageSetOrigin(message, OT_MESSAGE_ORIGIN_HOST_UNTRUSTED);
3408*cfb92d14SAndroid Build Coastguard Worker 
3409*cfb92d14SAndroid Build Coastguard Worker     // Ensure the insecure message is forwarded using direct transmission.
3410*cfb92d14SAndroid Build Coastguard Worker     otMessageSetDirectTransmission(message, true);
3411*cfb92d14SAndroid Build Coastguard Worker 
3412*cfb92d14SAndroid Build Coastguard Worker     error = otIp6Send(mInstance, message);
3413*cfb92d14SAndroid Build Coastguard Worker 
3414*cfb92d14SAndroid Build Coastguard Worker exit:
3415*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NONE)
3416*cfb92d14SAndroid Build Coastguard Worker     {
3417*cfb92d14SAndroid Build Coastguard Worker         mInboundInsecureIpFrameCounter++;
3418*cfb92d14SAndroid Build Coastguard Worker     }
3419*cfb92d14SAndroid Build Coastguard Worker     else
3420*cfb92d14SAndroid Build Coastguard Worker     {
3421*cfb92d14SAndroid Build Coastguard Worker         mDroppedInboundIpFrameCounter++;
3422*cfb92d14SAndroid Build Coastguard Worker     }
3423*cfb92d14SAndroid Build Coastguard Worker 
3424*cfb92d14SAndroid Build Coastguard Worker     return error;
3425*cfb92d14SAndroid Build Coastguard Worker }
3426*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3427*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_CNTR_RESET>(void)
3428*cfb92d14SAndroid Build Coastguard Worker {
3429*cfb92d14SAndroid Build Coastguard Worker     otLinkResetCounters(mInstance);
3430*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
3431*cfb92d14SAndroid Build Coastguard Worker     otLinkResetTxRetrySuccessHistogram(mInstance);
3432*cfb92d14SAndroid Build Coastguard Worker #endif
3433*cfb92d14SAndroid Build Coastguard Worker     otThreadResetIp6Counters(mInstance);
3434*cfb92d14SAndroid Build Coastguard Worker     otThreadResetMleCounters(mInstance);
3435*cfb92d14SAndroid Build Coastguard Worker     ResetCounters();
3436*cfb92d14SAndroid Build Coastguard Worker 
3437*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
3438*cfb92d14SAndroid Build Coastguard Worker }
3439*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)3440*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_THREAD_ASSISTING_PORTS>(void)
3441*cfb92d14SAndroid Build Coastguard Worker {
3442*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
3443*cfb92d14SAndroid Build Coastguard Worker     uint16_t port;
3444*cfb92d14SAndroid Build Coastguard Worker 
3445*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(port));
3446*cfb92d14SAndroid Build Coastguard Worker 
3447*cfb92d14SAndroid Build Coastguard Worker     error = otIp6AddUnsecurePort(mInstance, port);
3448*cfb92d14SAndroid Build Coastguard Worker exit:
3449*cfb92d14SAndroid Build Coastguard Worker     return error;
3450*cfb92d14SAndroid Build Coastguard Worker }
3451*cfb92d14SAndroid Build Coastguard Worker 
3452*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
3453*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)3454*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_ALLOWLIST>(void)
3455*cfb92d14SAndroid Build Coastguard Worker {
3456*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
3457*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress;
3458*cfb92d14SAndroid Build Coastguard Worker     int8_t              rss = OT_MAC_FILTER_FIXED_RSS_DISABLED;
3459*cfb92d14SAndroid Build Coastguard Worker 
3460*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3461*cfb92d14SAndroid Build Coastguard Worker 
3462*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllRead())
3463*cfb92d14SAndroid Build Coastguard Worker     {
3464*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadInt8(rss));
3465*cfb92d14SAndroid Build Coastguard Worker     }
3466*cfb92d14SAndroid Build Coastguard Worker 
3467*cfb92d14SAndroid Build Coastguard Worker     error = otLinkFilterAddAddress(mInstance, extAddress);
3468*cfb92d14SAndroid Build Coastguard Worker 
3469*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_ALREADY)
3470*cfb92d14SAndroid Build Coastguard Worker     {
3471*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
3472*cfb92d14SAndroid Build Coastguard Worker     }
3473*cfb92d14SAndroid Build Coastguard Worker 
3474*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error);
3475*cfb92d14SAndroid Build Coastguard Worker 
3476*cfb92d14SAndroid Build Coastguard Worker     if (rss != OT_MAC_FILTER_FIXED_RSS_DISABLED)
3477*cfb92d14SAndroid Build Coastguard Worker     {
3478*cfb92d14SAndroid Build Coastguard Worker         error = otLinkFilterAddRssIn(mInstance, extAddress, rss);
3479*cfb92d14SAndroid Build Coastguard Worker     }
3480*cfb92d14SAndroid Build Coastguard Worker 
3481*cfb92d14SAndroid Build Coastguard Worker exit:
3482*cfb92d14SAndroid Build Coastguard Worker     return error;
3483*cfb92d14SAndroid Build Coastguard Worker }
3484*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)3485*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_DENYLIST>(void)
3486*cfb92d14SAndroid Build Coastguard Worker {
3487*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
3488*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress;
3489*cfb92d14SAndroid Build Coastguard Worker 
3490*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3491*cfb92d14SAndroid Build Coastguard Worker 
3492*cfb92d14SAndroid Build Coastguard Worker     error = otLinkFilterAddAddress(mInstance, extAddress);
3493*cfb92d14SAndroid Build Coastguard Worker 
3494*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_ALREADY)
3495*cfb92d14SAndroid Build Coastguard Worker     {
3496*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
3497*cfb92d14SAndroid Build Coastguard Worker     }
3498*cfb92d14SAndroid Build Coastguard Worker 
3499*cfb92d14SAndroid Build Coastguard Worker exit:
3500*cfb92d14SAndroid Build Coastguard Worker     return error;
3501*cfb92d14SAndroid Build Coastguard Worker }
3502*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)3503*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_MAC_FIXED_RSS>(void)
3504*cfb92d14SAndroid Build Coastguard Worker {
3505*cfb92d14SAndroid Build Coastguard Worker     otError             error      = OT_ERROR_NONE;
3506*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress = nullptr;
3507*cfb92d14SAndroid Build Coastguard Worker     int8_t              rss        = OT_MAC_FILTER_FIXED_RSS_DISABLED;
3508*cfb92d14SAndroid Build Coastguard Worker 
3509*cfb92d14SAndroid Build Coastguard Worker     if (mDecoder.GetRemainingLength() > sizeof(int8_t))
3510*cfb92d14SAndroid Build Coastguard Worker     {
3511*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3512*cfb92d14SAndroid Build Coastguard Worker     }
3513*cfb92d14SAndroid Build Coastguard Worker 
3514*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadInt8(rss));
3515*cfb92d14SAndroid Build Coastguard Worker 
3516*cfb92d14SAndroid Build Coastguard Worker     if (extAddress != nullptr)
3517*cfb92d14SAndroid Build Coastguard Worker     {
3518*cfb92d14SAndroid Build Coastguard Worker         error = otLinkFilterAddRssIn(mInstance, extAddress, rss);
3519*cfb92d14SAndroid Build Coastguard Worker     }
3520*cfb92d14SAndroid Build Coastguard Worker     else
3521*cfb92d14SAndroid Build Coastguard Worker     {
3522*cfb92d14SAndroid Build Coastguard Worker         otLinkFilterSetDefaultRssIn(mInstance, rss);
3523*cfb92d14SAndroid Build Coastguard Worker     }
3524*cfb92d14SAndroid Build Coastguard Worker 
3525*cfb92d14SAndroid Build Coastguard Worker exit:
3526*cfb92d14SAndroid Build Coastguard Worker     return error;
3527*cfb92d14SAndroid Build Coastguard Worker }
3528*cfb92d14SAndroid Build Coastguard Worker 
3529*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
3530*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)3531*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_THREAD_ASSISTING_PORTS>(void)
3532*cfb92d14SAndroid Build Coastguard Worker {
3533*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
3534*cfb92d14SAndroid Build Coastguard Worker     uint16_t port;
3535*cfb92d14SAndroid Build Coastguard Worker 
3536*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(port));
3537*cfb92d14SAndroid Build Coastguard Worker 
3538*cfb92d14SAndroid Build Coastguard Worker     error = otIp6RemoveUnsecurePort(mInstance, port);
3539*cfb92d14SAndroid Build Coastguard Worker 
3540*cfb92d14SAndroid Build Coastguard Worker     // If unsecure port was not on the list, "remove" command is successful.
3541*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NOT_FOUND)
3542*cfb92d14SAndroid Build Coastguard Worker     {
3543*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_NONE;
3544*cfb92d14SAndroid Build Coastguard Worker     }
3545*cfb92d14SAndroid Build Coastguard Worker 
3546*cfb92d14SAndroid Build Coastguard Worker exit:
3547*cfb92d14SAndroid Build Coastguard Worker     return error;
3548*cfb92d14SAndroid Build Coastguard Worker }
3549*cfb92d14SAndroid Build Coastguard Worker 
3550*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
3551*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)3552*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_ALLOWLIST>(void)
3553*cfb92d14SAndroid Build Coastguard Worker {
3554*cfb92d14SAndroid Build Coastguard Worker     otError             error      = OT_ERROR_NONE;
3555*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress = nullptr;
3556*cfb92d14SAndroid Build Coastguard Worker 
3557*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3558*cfb92d14SAndroid Build Coastguard Worker 
3559*cfb92d14SAndroid Build Coastguard Worker     otLinkFilterRemoveAddress(mInstance, extAddress);
3560*cfb92d14SAndroid Build Coastguard Worker 
3561*cfb92d14SAndroid Build Coastguard Worker exit:
3562*cfb92d14SAndroid Build Coastguard Worker     return error;
3563*cfb92d14SAndroid Build Coastguard Worker }
3564*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)3565*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_DENYLIST>(void)
3566*cfb92d14SAndroid Build Coastguard Worker {
3567*cfb92d14SAndroid Build Coastguard Worker     otError             error      = OT_ERROR_NONE;
3568*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress = nullptr;
3569*cfb92d14SAndroid Build Coastguard Worker 
3570*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3571*cfb92d14SAndroid Build Coastguard Worker 
3572*cfb92d14SAndroid Build Coastguard Worker     otLinkFilterRemoveAddress(mInstance, extAddress);
3573*cfb92d14SAndroid Build Coastguard Worker 
3574*cfb92d14SAndroid Build Coastguard Worker exit:
3575*cfb92d14SAndroid Build Coastguard Worker     return error;
3576*cfb92d14SAndroid Build Coastguard Worker }
3577*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)3578*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_MAC_FIXED_RSS>(void)
3579*cfb92d14SAndroid Build Coastguard Worker {
3580*cfb92d14SAndroid Build Coastguard Worker     otError             error      = OT_ERROR_NONE;
3581*cfb92d14SAndroid Build Coastguard Worker     const otExtAddress *extAddress = nullptr;
3582*cfb92d14SAndroid Build Coastguard Worker 
3583*cfb92d14SAndroid Build Coastguard Worker     if (mDecoder.GetRemainingLength() > 0)
3584*cfb92d14SAndroid Build Coastguard Worker     {
3585*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadEui64(extAddress));
3586*cfb92d14SAndroid Build Coastguard Worker     }
3587*cfb92d14SAndroid Build Coastguard Worker 
3588*cfb92d14SAndroid Build Coastguard Worker     if (extAddress != nullptr)
3589*cfb92d14SAndroid Build Coastguard Worker     {
3590*cfb92d14SAndroid Build Coastguard Worker         otLinkFilterRemoveRssIn(mInstance, extAddress);
3591*cfb92d14SAndroid Build Coastguard Worker     }
3592*cfb92d14SAndroid Build Coastguard Worker     else
3593*cfb92d14SAndroid Build Coastguard Worker     {
3594*cfb92d14SAndroid Build Coastguard Worker         otLinkFilterClearDefaultRssIn(mInstance);
3595*cfb92d14SAndroid Build Coastguard Worker     }
3596*cfb92d14SAndroid Build Coastguard Worker 
3597*cfb92d14SAndroid Build Coastguard Worker exit:
3598*cfb92d14SAndroid Build Coastguard Worker     return error;
3599*cfb92d14SAndroid Build Coastguard Worker }
3600*cfb92d14SAndroid Build Coastguard Worker 
3601*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
3602*cfb92d14SAndroid Build Coastguard Worker 
3603*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_PLATFORM_POSIX
3604*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3605*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_RCP_VERSION>(void)
3606*cfb92d14SAndroid Build Coastguard Worker {
3607*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUtf8(otGetRadioVersionString(mInstance));
3608*cfb92d14SAndroid Build Coastguard Worker }
3609*cfb92d14SAndroid Build Coastguard Worker 
3610*cfb92d14SAndroid Build Coastguard Worker #endif
3611*cfb92d14SAndroid Build Coastguard Worker 
3612*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
3613*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3614*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SLAAC_ENABLED>(void)
3615*cfb92d14SAndroid Build Coastguard Worker {
3616*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otIp6IsSlaacEnabled(mInstance));
3617*cfb92d14SAndroid Build Coastguard Worker }
3618*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3619*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SLAAC_ENABLED>(void)
3620*cfb92d14SAndroid Build Coastguard Worker {
3621*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
3622*cfb92d14SAndroid Build Coastguard Worker     bool    enabled;
3623*cfb92d14SAndroid Build Coastguard Worker 
3624*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
3625*cfb92d14SAndroid Build Coastguard Worker     otIp6SetSlaacEnabled(mInstance, enabled);
3626*cfb92d14SAndroid Build Coastguard Worker 
3627*cfb92d14SAndroid Build Coastguard Worker exit:
3628*cfb92d14SAndroid Build Coastguard Worker     return error;
3629*cfb92d14SAndroid Build Coastguard Worker }
3630*cfb92d14SAndroid Build Coastguard Worker 
3631*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
3632*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3633*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SUPPORTED_RADIO_LINKS>(void)
3634*cfb92d14SAndroid Build Coastguard Worker {
3635*cfb92d14SAndroid Build Coastguard Worker     otError error;
3636*cfb92d14SAndroid Build Coastguard Worker 
3637*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
3638*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_RADIO_LINK_IEEE_802_15_4));
3639*cfb92d14SAndroid Build Coastguard Worker #endif
3640*cfb92d14SAndroid Build Coastguard Worker 
3641*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
3642*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_RADIO_LINK_TREL_UDP6));
3643*cfb92d14SAndroid Build Coastguard Worker #endif
3644*cfb92d14SAndroid Build Coastguard Worker 
3645*cfb92d14SAndroid Build Coastguard Worker exit:
3646*cfb92d14SAndroid Build Coastguard Worker     return error;
3647*cfb92d14SAndroid Build Coastguard Worker }
3648*cfb92d14SAndroid Build Coastguard Worker 
3649*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MULTI_RADIO
3650*cfb92d14SAndroid Build Coastguard Worker 
EncodeNeighborMultiRadioInfo(uint32_t aSpinelRadioLink,const otRadioLinkInfo & aInfo)3651*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::EncodeNeighborMultiRadioInfo(uint32_t aSpinelRadioLink, const otRadioLinkInfo &aInfo)
3652*cfb92d14SAndroid Build Coastguard Worker {
3653*cfb92d14SAndroid Build Coastguard Worker     otError error;
3654*cfb92d14SAndroid Build Coastguard Worker 
3655*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
3656*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUintPacked(aSpinelRadioLink));
3657*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint8(aInfo.mPreference));
3658*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
3659*cfb92d14SAndroid Build Coastguard Worker 
3660*cfb92d14SAndroid Build Coastguard Worker exit:
3661*cfb92d14SAndroid Build Coastguard Worker     return error;
3662*cfb92d14SAndroid Build Coastguard Worker }
3663*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3664*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO>(void)
3665*cfb92d14SAndroid Build Coastguard Worker {
3666*cfb92d14SAndroid Build Coastguard Worker     otError                  error = OT_ERROR_NONE;
3667*cfb92d14SAndroid Build Coastguard Worker     otNeighborInfoIterator   iter  = OT_NEIGHBOR_INFO_ITERATOR_INIT;
3668*cfb92d14SAndroid Build Coastguard Worker     otNeighborInfo           neighInfo;
3669*cfb92d14SAndroid Build Coastguard Worker     otMultiRadioNeighborInfo multiRadioInfo;
3670*cfb92d14SAndroid Build Coastguard Worker 
3671*cfb92d14SAndroid Build Coastguard Worker     while (otThreadGetNextNeighborInfo(mInstance, &iter, &neighInfo) == OT_ERROR_NONE)
3672*cfb92d14SAndroid Build Coastguard Worker     {
3673*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
3674*cfb92d14SAndroid Build Coastguard Worker 
3675*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteEui64(neighInfo.mExtAddress));
3676*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(neighInfo.mRloc16));
3677*cfb92d14SAndroid Build Coastguard Worker 
3678*cfb92d14SAndroid Build Coastguard Worker         if (otMultiRadioGetNeighborInfo(mInstance, &neighInfo.mExtAddress, &multiRadioInfo) == OT_ERROR_NONE)
3679*cfb92d14SAndroid Build Coastguard Worker         {
3680*cfb92d14SAndroid Build Coastguard Worker             if (multiRadioInfo.mSupportsIeee802154)
3681*cfb92d14SAndroid Build Coastguard Worker             {
3682*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(error = EncodeNeighborMultiRadioInfo(SPINEL_RADIO_LINK_IEEE_802_15_4,
3683*cfb92d14SAndroid Build Coastguard Worker                                                                    multiRadioInfo.mIeee802154Info));
3684*cfb92d14SAndroid Build Coastguard Worker             }
3685*cfb92d14SAndroid Build Coastguard Worker 
3686*cfb92d14SAndroid Build Coastguard Worker             if (multiRadioInfo.mSupportsTrelUdp6)
3687*cfb92d14SAndroid Build Coastguard Worker             {
3688*cfb92d14SAndroid Build Coastguard Worker                 SuccessOrExit(
3689*cfb92d14SAndroid Build Coastguard Worker                     error = EncodeNeighborMultiRadioInfo(SPINEL_RADIO_LINK_TREL_UDP6, multiRadioInfo.mTrelUdp6Info));
3690*cfb92d14SAndroid Build Coastguard Worker             }
3691*cfb92d14SAndroid Build Coastguard Worker         }
3692*cfb92d14SAndroid Build Coastguard Worker 
3693*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
3694*cfb92d14SAndroid Build Coastguard Worker     }
3695*cfb92d14SAndroid Build Coastguard Worker 
3696*cfb92d14SAndroid Build Coastguard Worker exit:
3697*cfb92d14SAndroid Build Coastguard Worker     return error;
3698*cfb92d14SAndroid Build Coastguard Worker }
3699*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_MULTI_RADIO
3700*cfb92d14SAndroid Build Coastguard Worker 
3701*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
3702*cfb92d14SAndroid Build Coastguard Worker // SRP Client
3703*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
3704*cfb92d14SAndroid Build Coastguard Worker 
3705*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
3706*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3707*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_START>(void)
3708*cfb92d14SAndroid Build Coastguard Worker {
3709*cfb92d14SAndroid Build Coastguard Worker     otError    error = OT_ERROR_NONE;
3710*cfb92d14SAndroid Build Coastguard Worker     bool       start;
3711*cfb92d14SAndroid Build Coastguard Worker     bool       callbackEnabled;
3712*cfb92d14SAndroid Build Coastguard Worker     otSockAddr serverAddr;
3713*cfb92d14SAndroid Build Coastguard Worker 
3714*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(start));
3715*cfb92d14SAndroid Build Coastguard Worker 
3716*cfb92d14SAndroid Build Coastguard Worker     if (!start)
3717*cfb92d14SAndroid Build Coastguard Worker     {
3718*cfb92d14SAndroid Build Coastguard Worker         otSrpClientStop(mInstance);
3719*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
3720*cfb92d14SAndroid Build Coastguard Worker     }
3721*cfb92d14SAndroid Build Coastguard Worker 
3722*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(serverAddr.mAddress));
3723*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(serverAddr.mPort));
3724*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(callbackEnabled));
3725*cfb92d14SAndroid Build Coastguard Worker 
3726*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otSrpClientStart(mInstance, &serverAddr));
3727*cfb92d14SAndroid Build Coastguard Worker     mSrpClientCallbackEnabled = callbackEnabled;
3728*cfb92d14SAndroid Build Coastguard Worker 
3729*cfb92d14SAndroid Build Coastguard Worker exit:
3730*cfb92d14SAndroid Build Coastguard Worker     return error;
3731*cfb92d14SAndroid Build Coastguard Worker }
3732*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3733*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL>(void)
3734*cfb92d14SAndroid Build Coastguard Worker {
3735*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otSrpClientGetLeaseInterval(mInstance));
3736*cfb92d14SAndroid Build Coastguard Worker }
3737*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3738*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL>(void)
3739*cfb92d14SAndroid Build Coastguard Worker {
3740*cfb92d14SAndroid Build Coastguard Worker     otError  error;
3741*cfb92d14SAndroid Build Coastguard Worker     uint32_t interval;
3742*cfb92d14SAndroid Build Coastguard Worker 
3743*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(interval));
3744*cfb92d14SAndroid Build Coastguard Worker     otSrpClientSetLeaseInterval(mInstance, interval);
3745*cfb92d14SAndroid Build Coastguard Worker 
3746*cfb92d14SAndroid Build Coastguard Worker exit:
3747*cfb92d14SAndroid Build Coastguard Worker     return error;
3748*cfb92d14SAndroid Build Coastguard Worker }
3749*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3750*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL>(void)
3751*cfb92d14SAndroid Build Coastguard Worker {
3752*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUint32(otSrpClientGetKeyLeaseInterval(mInstance));
3753*cfb92d14SAndroid Build Coastguard Worker }
3754*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3755*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL>(void)
3756*cfb92d14SAndroid Build Coastguard Worker {
3757*cfb92d14SAndroid Build Coastguard Worker     otError  error;
3758*cfb92d14SAndroid Build Coastguard Worker     uint32_t interval;
3759*cfb92d14SAndroid Build Coastguard Worker 
3760*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint32(interval));
3761*cfb92d14SAndroid Build Coastguard Worker     otSrpClientSetKeyLeaseInterval(mInstance, interval);
3762*cfb92d14SAndroid Build Coastguard Worker 
3763*cfb92d14SAndroid Build Coastguard Worker exit:
3764*cfb92d14SAndroid Build Coastguard Worker     return error;
3765*cfb92d14SAndroid Build Coastguard Worker }
3766*cfb92d14SAndroid Build Coastguard Worker 
SrpClientItemStateToSpinel(otSrpClientItemState aItemState)3767*cfb92d14SAndroid Build Coastguard Worker static spinel_srp_client_item_state_t SrpClientItemStateToSpinel(otSrpClientItemState aItemState)
3768*cfb92d14SAndroid Build Coastguard Worker {
3769*cfb92d14SAndroid Build Coastguard Worker     spinel_srp_client_item_state_t state = SPINEL_SRP_CLIENT_ITEM_STATE_REMOVED;
3770*cfb92d14SAndroid Build Coastguard Worker 
3771*cfb92d14SAndroid Build Coastguard Worker     switch (aItemState)
3772*cfb92d14SAndroid Build Coastguard Worker     {
3773*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_TO_ADD:
3774*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_TO_ADD;
3775*cfb92d14SAndroid Build Coastguard Worker         break;
3776*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_ADDING:
3777*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_ADDING;
3778*cfb92d14SAndroid Build Coastguard Worker         break;
3779*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_TO_REFRESH:
3780*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_TO_REFRESH;
3781*cfb92d14SAndroid Build Coastguard Worker         break;
3782*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_REFRESHING:
3783*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_REFRESHING;
3784*cfb92d14SAndroid Build Coastguard Worker         break;
3785*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_TO_REMOVE:
3786*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_TO_REMOVE;
3787*cfb92d14SAndroid Build Coastguard Worker         break;
3788*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_REMOVING:
3789*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_REMOVING;
3790*cfb92d14SAndroid Build Coastguard Worker         break;
3791*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_REGISTERED:
3792*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_REGISTERED;
3793*cfb92d14SAndroid Build Coastguard Worker         break;
3794*cfb92d14SAndroid Build Coastguard Worker     case OT_SRP_CLIENT_ITEM_STATE_REMOVED:
3795*cfb92d14SAndroid Build Coastguard Worker         state = SPINEL_SRP_CLIENT_ITEM_STATE_REMOVED;
3796*cfb92d14SAndroid Build Coastguard Worker         break;
3797*cfb92d14SAndroid Build Coastguard Worker     }
3798*cfb92d14SAndroid Build Coastguard Worker 
3799*cfb92d14SAndroid Build Coastguard Worker     return state;
3800*cfb92d14SAndroid Build Coastguard Worker }
3801*cfb92d14SAndroid Build Coastguard Worker 
EncodeSrpClientHostInfo(const otSrpClientHostInfo & aHostInfo)3802*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::EncodeSrpClientHostInfo(const otSrpClientHostInfo &aHostInfo)
3803*cfb92d14SAndroid Build Coastguard Worker {
3804*cfb92d14SAndroid Build Coastguard Worker     otError error;
3805*cfb92d14SAndroid Build Coastguard Worker 
3806*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUtf8(aHostInfo.mName != nullptr ? aHostInfo.mName : ""));
3807*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint8(SrpClientItemStateToSpinel(aHostInfo.mState)));
3808*cfb92d14SAndroid Build Coastguard Worker 
3809*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
3810*cfb92d14SAndroid Build Coastguard Worker 
3811*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t index = 0; index < aHostInfo.mNumAddresses; index++)
3812*cfb92d14SAndroid Build Coastguard Worker     {
3813*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(aHostInfo.mAddresses[index]));
3814*cfb92d14SAndroid Build Coastguard Worker     }
3815*cfb92d14SAndroid Build Coastguard Worker 
3816*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
3817*cfb92d14SAndroid Build Coastguard Worker 
3818*cfb92d14SAndroid Build Coastguard Worker exit:
3819*cfb92d14SAndroid Build Coastguard Worker     return error;
3820*cfb92d14SAndroid Build Coastguard Worker }
3821*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3822*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_HOST_INFO>(void)
3823*cfb92d14SAndroid Build Coastguard Worker {
3824*cfb92d14SAndroid Build Coastguard Worker     return EncodeSrpClientHostInfo(*otSrpClientGetHostInfo(mInstance));
3825*cfb92d14SAndroid Build Coastguard Worker }
3826*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3827*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_HOST_NAME>(void)
3828*cfb92d14SAndroid Build Coastguard Worker {
3829*cfb92d14SAndroid Build Coastguard Worker     const char *name = otSrpClientGetHostInfo(mInstance)->mName;
3830*cfb92d14SAndroid Build Coastguard Worker 
3831*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteUtf8(name != nullptr ? name : "");
3832*cfb92d14SAndroid Build Coastguard Worker }
3833*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3834*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_NAME>(void)
3835*cfb92d14SAndroid Build Coastguard Worker {
3836*cfb92d14SAndroid Build Coastguard Worker     otError     error;
3837*cfb92d14SAndroid Build Coastguard Worker     const char *name;
3838*cfb92d14SAndroid Build Coastguard Worker     uint16_t    size;
3839*cfb92d14SAndroid Build Coastguard Worker     char       *hostNameBuffer;
3840*cfb92d14SAndroid Build Coastguard Worker 
3841*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUtf8(name));
3842*cfb92d14SAndroid Build Coastguard Worker 
3843*cfb92d14SAndroid Build Coastguard Worker     hostNameBuffer = otSrpClientBuffersGetHostNameString(mInstance, &size);
3844*cfb92d14SAndroid Build Coastguard Worker 
3845*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(StringLength(name, size) < size, error = OT_ERROR_INVALID_ARGS);
3846*cfb92d14SAndroid Build Coastguard Worker 
3847*cfb92d14SAndroid Build Coastguard Worker     // We first make sure we can set the name, and if so
3848*cfb92d14SAndroid Build Coastguard Worker     // we copy it to the persisted buffer and set
3849*cfb92d14SAndroid Build Coastguard Worker     // the host name again now with the persisted buffer.
3850*cfb92d14SAndroid Build Coastguard Worker     // This ensures that we do not overwrite a previous
3851*cfb92d14SAndroid Build Coastguard Worker     // buffer with a host name that cannot be set.
3852*cfb92d14SAndroid Build Coastguard Worker 
3853*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otSrpClientSetHostName(mInstance, name));
3854*cfb92d14SAndroid Build Coastguard Worker 
3855*cfb92d14SAndroid Build Coastguard Worker     strcpy(hostNameBuffer, name);
3856*cfb92d14SAndroid Build Coastguard Worker     SuccessOrAssert(error = otSrpClientSetHostName(mInstance, hostNameBuffer));
3857*cfb92d14SAndroid Build Coastguard Worker 
3858*cfb92d14SAndroid Build Coastguard Worker exit:
3859*cfb92d14SAndroid Build Coastguard Worker     return error;
3860*cfb92d14SAndroid Build Coastguard Worker }
3861*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3862*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES>(void)
3863*cfb92d14SAndroid Build Coastguard Worker {
3864*cfb92d14SAndroid Build Coastguard Worker     otError                    error    = OT_ERROR_NONE;
3865*cfb92d14SAndroid Build Coastguard Worker     const otSrpClientHostInfo *hostInfo = otSrpClientGetHostInfo(mInstance);
3866*cfb92d14SAndroid Build Coastguard Worker 
3867*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t index = 0; index < hostInfo->mNumAddresses; index++)
3868*cfb92d14SAndroid Build Coastguard Worker     {
3869*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteIp6Address(hostInfo->mAddresses[index]));
3870*cfb92d14SAndroid Build Coastguard Worker     }
3871*cfb92d14SAndroid Build Coastguard Worker 
3872*cfb92d14SAndroid Build Coastguard Worker exit:
3873*cfb92d14SAndroid Build Coastguard Worker     return error;
3874*cfb92d14SAndroid Build Coastguard Worker }
3875*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)3876*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES>(void)
3877*cfb92d14SAndroid Build Coastguard Worker {
3878*cfb92d14SAndroid Build Coastguard Worker     otError       error;
3879*cfb92d14SAndroid Build Coastguard Worker     otIp6Address  addresses[kSrpClientMaxHostAddresses];
3880*cfb92d14SAndroid Build Coastguard Worker     uint8_t       numAddresses = 0;
3881*cfb92d14SAndroid Build Coastguard Worker     otIp6Address *hostAddressArray;
3882*cfb92d14SAndroid Build Coastguard Worker     uint8_t       hostAddressArrayLength;
3883*cfb92d14SAndroid Build Coastguard Worker 
3884*cfb92d14SAndroid Build Coastguard Worker     hostAddressArray = otSrpClientBuffersGetHostAddressesArray(mInstance, &hostAddressArrayLength);
3885*cfb92d14SAndroid Build Coastguard Worker     OT_ASSERT(hostAddressArrayLength <= kSrpClientMaxHostAddresses);
3886*cfb92d14SAndroid Build Coastguard Worker 
3887*cfb92d14SAndroid Build Coastguard Worker     while (!mDecoder.IsAllReadInStruct())
3888*cfb92d14SAndroid Build Coastguard Worker     {
3889*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(numAddresses < kSrpClientMaxHostAddresses, error = OT_ERROR_NO_BUFS);
3890*cfb92d14SAndroid Build Coastguard Worker 
3891*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadIp6Address(addresses[numAddresses]));
3892*cfb92d14SAndroid Build Coastguard Worker         numAddresses++;
3893*cfb92d14SAndroid Build Coastguard Worker     }
3894*cfb92d14SAndroid Build Coastguard Worker 
3895*cfb92d14SAndroid Build Coastguard Worker     // We first make sure we can set the addresses, and if so we copy
3896*cfb92d14SAndroid Build Coastguard Worker     // the address list into `hostAddressArray` and set it again. This
3897*cfb92d14SAndroid Build Coastguard Worker     // ensures that we do not overwrite a previous list before we know
3898*cfb92d14SAndroid Build Coastguard Worker     // it is safe to set/change the address list.
3899*cfb92d14SAndroid Build Coastguard Worker 
3900*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otSrpClientSetHostAddresses(mInstance, addresses, numAddresses));
3901*cfb92d14SAndroid Build Coastguard Worker 
3902*cfb92d14SAndroid Build Coastguard Worker     memcpy(hostAddressArray, addresses, sizeof(addresses));
3903*cfb92d14SAndroid Build Coastguard Worker 
3904*cfb92d14SAndroid Build Coastguard Worker     SuccessOrAssert(error = otSrpClientSetHostAddresses(mInstance, hostAddressArray, numAddresses));
3905*cfb92d14SAndroid Build Coastguard Worker 
3906*cfb92d14SAndroid Build Coastguard Worker exit:
3907*cfb92d14SAndroid Build Coastguard Worker     return error;
3908*cfb92d14SAndroid Build Coastguard Worker }
3909*cfb92d14SAndroid Build Coastguard Worker 
EncodeSrpClientServices(const otSrpClientService * aServices)3910*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::EncodeSrpClientServices(const otSrpClientService *aServices)
3911*cfb92d14SAndroid Build Coastguard Worker {
3912*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
3913*cfb92d14SAndroid Build Coastguard Worker 
3914*cfb92d14SAndroid Build Coastguard Worker     for (; aServices != nullptr; aServices = aServices->mNext)
3915*cfb92d14SAndroid Build Coastguard Worker     {
3916*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());
3917*cfb92d14SAndroid Build Coastguard Worker 
3918*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUtf8(aServices->mName));
3919*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUtf8(aServices->mInstanceName));
3920*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(aServices->mPort));
3921*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(aServices->mPriority));
3922*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(aServices->mWeight));
3923*cfb92d14SAndroid Build Coastguard Worker 
3924*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
3925*cfb92d14SAndroid Build Coastguard Worker     }
3926*cfb92d14SAndroid Build Coastguard Worker 
3927*cfb92d14SAndroid Build Coastguard Worker exit:
3928*cfb92d14SAndroid Build Coastguard Worker     return error;
3929*cfb92d14SAndroid Build Coastguard Worker }
3930*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)3931*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_SERVICES>(void)
3932*cfb92d14SAndroid Build Coastguard Worker {
3933*cfb92d14SAndroid Build Coastguard Worker     return EncodeSrpClientServices(otSrpClientGetServices(mInstance));
3934*cfb92d14SAndroid Build Coastguard Worker }
3935*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyInsert(void)3936*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyInsert<SPINEL_PROP_SRP_CLIENT_SERVICES>(void)
3937*cfb92d14SAndroid Build Coastguard Worker {
3938*cfb92d14SAndroid Build Coastguard Worker     otError                         error = OT_ERROR_NONE;
3939*cfb92d14SAndroid Build Coastguard Worker     otSrpClientBuffersServiceEntry *entry = nullptr;
3940*cfb92d14SAndroid Build Coastguard Worker     const char                     *serviceName;
3941*cfb92d14SAndroid Build Coastguard Worker     const char                     *instanceName;
3942*cfb92d14SAndroid Build Coastguard Worker     char                           *stringBuffer;
3943*cfb92d14SAndroid Build Coastguard Worker     uint16_t                        size;
3944*cfb92d14SAndroid Build Coastguard Worker 
3945*cfb92d14SAndroid Build Coastguard Worker     entry = otSrpClientBuffersAllocateService(mInstance);
3946*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(entry != nullptr, error = OT_ERROR_NO_BUFS);
3947*cfb92d14SAndroid Build Coastguard Worker 
3948*cfb92d14SAndroid Build Coastguard Worker     stringBuffer = otSrpClientBuffersGetServiceEntryServiceNameString(entry, &size);
3949*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUtf8(serviceName));
3950*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(StringLength(serviceName, size) < size, error = OT_ERROR_INVALID_ARGS);
3951*cfb92d14SAndroid Build Coastguard Worker     strcpy(stringBuffer, serviceName);
3952*cfb92d14SAndroid Build Coastguard Worker 
3953*cfb92d14SAndroid Build Coastguard Worker     stringBuffer = otSrpClientBuffersGetServiceEntryInstanceNameString(entry, &size);
3954*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUtf8(instanceName));
3955*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(StringLength(instanceName, size) < size, error = OT_ERROR_INVALID_ARGS);
3956*cfb92d14SAndroid Build Coastguard Worker     strcpy(stringBuffer, instanceName);
3957*cfb92d14SAndroid Build Coastguard Worker 
3958*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(entry->mService.mPort));
3959*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(entry->mService.mPriority));
3960*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(entry->mService.mWeight));
3961*cfb92d14SAndroid Build Coastguard Worker 
3962*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otSrpClientAddService(mInstance, &entry->mService));
3963*cfb92d14SAndroid Build Coastguard Worker     entry = nullptr;
3964*cfb92d14SAndroid Build Coastguard Worker 
3965*cfb92d14SAndroid Build Coastguard Worker exit:
3966*cfb92d14SAndroid Build Coastguard Worker     if (entry != nullptr)
3967*cfb92d14SAndroid Build Coastguard Worker     {
3968*cfb92d14SAndroid Build Coastguard Worker         otSrpClientBuffersFreeService(mInstance, entry);
3969*cfb92d14SAndroid Build Coastguard Worker     }
3970*cfb92d14SAndroid Build Coastguard Worker 
3971*cfb92d14SAndroid Build Coastguard Worker     return error;
3972*cfb92d14SAndroid Build Coastguard Worker }
3973*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyRemove(void)3974*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyRemove<SPINEL_PROP_SRP_CLIENT_SERVICES>(void)
3975*cfb92d14SAndroid Build Coastguard Worker {
3976*cfb92d14SAndroid Build Coastguard Worker     otError                   error = OT_ERROR_NONE;
3977*cfb92d14SAndroid Build Coastguard Worker     const char               *serviceName;
3978*cfb92d14SAndroid Build Coastguard Worker     const char               *instanceName;
3979*cfb92d14SAndroid Build Coastguard Worker     bool                      toClear = false;
3980*cfb92d14SAndroid Build Coastguard Worker     const otSrpClientService *service;
3981*cfb92d14SAndroid Build Coastguard Worker 
3982*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUtf8(serviceName));
3983*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUtf8(instanceName));
3984*cfb92d14SAndroid Build Coastguard Worker 
3985*cfb92d14SAndroid Build Coastguard Worker     if (!mDecoder.IsAllReadInStruct())
3986*cfb92d14SAndroid Build Coastguard Worker     {
3987*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mDecoder.ReadBool(toClear));
3988*cfb92d14SAndroid Build Coastguard Worker     }
3989*cfb92d14SAndroid Build Coastguard Worker 
3990*cfb92d14SAndroid Build Coastguard Worker     for (service = otSrpClientGetServices(mInstance); service != nullptr; service = service->mNext)
3991*cfb92d14SAndroid Build Coastguard Worker     {
3992*cfb92d14SAndroid Build Coastguard Worker         if ((strcmp(serviceName, service->mName) == 0) || (strcmp(instanceName, service->mInstanceName) == 0))
3993*cfb92d14SAndroid Build Coastguard Worker         {
3994*cfb92d14SAndroid Build Coastguard Worker             break;
3995*cfb92d14SAndroid Build Coastguard Worker         }
3996*cfb92d14SAndroid Build Coastguard Worker     }
3997*cfb92d14SAndroid Build Coastguard Worker 
3998*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(service != nullptr, error = OT_ERROR_NOT_FOUND);
3999*cfb92d14SAndroid Build Coastguard Worker 
4000*cfb92d14SAndroid Build Coastguard Worker     if (toClear)
4001*cfb92d14SAndroid Build Coastguard Worker     {
4002*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otSrpClientClearService(mInstance, const_cast<otSrpClientService *>(service)));
4003*cfb92d14SAndroid Build Coastguard Worker         otSrpClientBuffersFreeService(
4004*cfb92d14SAndroid Build Coastguard Worker             mInstance, reinterpret_cast<otSrpClientBuffersServiceEntry *>(const_cast<otSrpClientService *>(service)));
4005*cfb92d14SAndroid Build Coastguard Worker     }
4006*cfb92d14SAndroid Build Coastguard Worker     else
4007*cfb92d14SAndroid Build Coastguard Worker     {
4008*cfb92d14SAndroid Build Coastguard Worker         error = otSrpClientRemoveService(mInstance, const_cast<otSrpClientService *>(service));
4009*cfb92d14SAndroid Build Coastguard Worker     }
4010*cfb92d14SAndroid Build Coastguard Worker 
4011*cfb92d14SAndroid Build Coastguard Worker exit:
4012*cfb92d14SAndroid Build Coastguard Worker     return error;
4013*cfb92d14SAndroid Build Coastguard Worker }
4014*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)4015*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE>(void)
4016*cfb92d14SAndroid Build Coastguard Worker {
4017*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
4018*cfb92d14SAndroid Build Coastguard Worker     bool    removeKeyLease;
4019*cfb92d14SAndroid Build Coastguard Worker     bool    sendUnregToServer;
4020*cfb92d14SAndroid Build Coastguard Worker 
4021*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(removeKeyLease));
4022*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(sendUnregToServer));
4023*cfb92d14SAndroid Build Coastguard Worker 
4024*cfb92d14SAndroid Build Coastguard Worker     error = otSrpClientRemoveHostAndServices(mInstance, removeKeyLease, sendUnregToServer);
4025*cfb92d14SAndroid Build Coastguard Worker 
4026*cfb92d14SAndroid Build Coastguard Worker exit:
4027*cfb92d14SAndroid Build Coastguard Worker     return error;
4028*cfb92d14SAndroid Build Coastguard Worker }
4029*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)4030*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR>(void)
4031*cfb92d14SAndroid Build Coastguard Worker {
4032*cfb92d14SAndroid Build Coastguard Worker     otSrpClientClearHostAndServices(mInstance);
4033*cfb92d14SAndroid Build Coastguard Worker 
4034*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
4035*cfb92d14SAndroid Build Coastguard Worker }
4036*cfb92d14SAndroid Build Coastguard Worker 
SrpClientErrorToSpinelError(otError aError)4037*cfb92d14SAndroid Build Coastguard Worker static spinel_srp_client_error_t SrpClientErrorToSpinelError(otError aError)
4038*cfb92d14SAndroid Build Coastguard Worker {
4039*cfb92d14SAndroid Build Coastguard Worker     spinel_srp_client_error_t error = SPINEL_SRP_CLIENT_ERROR_FAILED;
4040*cfb92d14SAndroid Build Coastguard Worker 
4041*cfb92d14SAndroid Build Coastguard Worker     switch (aError)
4042*cfb92d14SAndroid Build Coastguard Worker     {
4043*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_NONE:
4044*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_NONE;
4045*cfb92d14SAndroid Build Coastguard Worker         break;
4046*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_PARSE:
4047*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_PARSE;
4048*cfb92d14SAndroid Build Coastguard Worker         break;
4049*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_NOT_FOUND:
4050*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_NOT_FOUND;
4051*cfb92d14SAndroid Build Coastguard Worker         break;
4052*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_NOT_IMPLEMENTED:
4053*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_NOT_IMPLEMENTED;
4054*cfb92d14SAndroid Build Coastguard Worker         break;
4055*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_SECURITY:
4056*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_SECURITY;
4057*cfb92d14SAndroid Build Coastguard Worker         break;
4058*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_DUPLICATED:
4059*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_DUPLICATED;
4060*cfb92d14SAndroid Build Coastguard Worker         break;
4061*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_RESPONSE_TIMEOUT:
4062*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_RESPONSE_TIMEOUT;
4063*cfb92d14SAndroid Build Coastguard Worker         break;
4064*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_INVALID_ARGS:
4065*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_INVALID_ARGS;
4066*cfb92d14SAndroid Build Coastguard Worker         break;
4067*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_NO_BUFS:
4068*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_NO_BUFS;
4069*cfb92d14SAndroid Build Coastguard Worker         break;
4070*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_FAILED:
4071*cfb92d14SAndroid Build Coastguard Worker     default:
4072*cfb92d14SAndroid Build Coastguard Worker         error = SPINEL_SRP_CLIENT_ERROR_FAILED;
4073*cfb92d14SAndroid Build Coastguard Worker         break;
4074*cfb92d14SAndroid Build Coastguard Worker     }
4075*cfb92d14SAndroid Build Coastguard Worker 
4076*cfb92d14SAndroid Build Coastguard Worker     return error;
4077*cfb92d14SAndroid Build Coastguard Worker }
4078*cfb92d14SAndroid Build Coastguard Worker 
HandleSrpClientCallback(otError aError,const otSrpClientHostInfo * aHostInfo,const otSrpClientService * aServices,const otSrpClientService * aRemovedServices,void * aContext)4079*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleSrpClientCallback(otError                    aError,
4080*cfb92d14SAndroid Build Coastguard Worker                                       const otSrpClientHostInfo *aHostInfo,
4081*cfb92d14SAndroid Build Coastguard Worker                                       const otSrpClientService  *aServices,
4082*cfb92d14SAndroid Build Coastguard Worker                                       const otSrpClientService  *aRemovedServices,
4083*cfb92d14SAndroid Build Coastguard Worker                                       void                      *aContext)
4084*cfb92d14SAndroid Build Coastguard Worker {
4085*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleSrpClientCallback(aError, aHostInfo, aServices, aRemovedServices);
4086*cfb92d14SAndroid Build Coastguard Worker }
4087*cfb92d14SAndroid Build Coastguard Worker 
HandleSrpClientCallback(otError aError,const otSrpClientHostInfo * aHostInfo,const otSrpClientService * aServices,const otSrpClientService * aRemovedServices)4088*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleSrpClientCallback(otError                    aError,
4089*cfb92d14SAndroid Build Coastguard Worker                                       const otSrpClientHostInfo *aHostInfo,
4090*cfb92d14SAndroid Build Coastguard Worker                                       const otSrpClientService  *aServices,
4091*cfb92d14SAndroid Build Coastguard Worker                                       const otSrpClientService  *aRemovedServices)
4092*cfb92d14SAndroid Build Coastguard Worker {
4093*cfb92d14SAndroid Build Coastguard Worker     otError                   error = OT_ERROR_NONE;
4094*cfb92d14SAndroid Build Coastguard Worker     const otSrpClientService *service;
4095*cfb92d14SAndroid Build Coastguard Worker     const otSrpClientService *next;
4096*cfb92d14SAndroid Build Coastguard Worker 
4097*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mSrpClientCallbackEnabled);
4098*cfb92d14SAndroid Build Coastguard Worker 
4099*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
4100*cfb92d14SAndroid Build Coastguard Worker                                               SPINEL_PROP_SRP_CLIENT_EVENT));
4101*cfb92d14SAndroid Build Coastguard Worker 
4102*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(SrpClientErrorToSpinelError(aError)));
4103*cfb92d14SAndroid Build Coastguard Worker 
4104*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
4105*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = EncodeSrpClientHostInfo(*aHostInfo));
4106*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
4107*cfb92d14SAndroid Build Coastguard Worker 
4108*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
4109*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = EncodeSrpClientServices(aServices));
4110*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
4111*cfb92d14SAndroid Build Coastguard Worker 
4112*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.OpenStruct());
4113*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = EncodeSrpClientServices(aRemovedServices));
4114*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.CloseStruct());
4115*cfb92d14SAndroid Build Coastguard Worker 
4116*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.EndFrame());
4117*cfb92d14SAndroid Build Coastguard Worker 
4118*cfb92d14SAndroid Build Coastguard Worker exit:
4119*cfb92d14SAndroid Build Coastguard Worker 
4120*cfb92d14SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
4121*cfb92d14SAndroid Build Coastguard Worker     {
4122*cfb92d14SAndroid Build Coastguard Worker         // Emit a NONMEM status if we fail to send the event.
4123*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM);
4124*cfb92d14SAndroid Build Coastguard Worker         mUpdateChangedPropsTask.Post();
4125*cfb92d14SAndroid Build Coastguard Worker     }
4126*cfb92d14SAndroid Build Coastguard Worker 
4127*cfb92d14SAndroid Build Coastguard Worker     for (service = aRemovedServices; service != nullptr; service = next)
4128*cfb92d14SAndroid Build Coastguard Worker     {
4129*cfb92d14SAndroid Build Coastguard Worker         next = service->mNext;
4130*cfb92d14SAndroid Build Coastguard Worker 
4131*cfb92d14SAndroid Build Coastguard Worker         otSrpClientBuffersFreeService(
4132*cfb92d14SAndroid Build Coastguard Worker             mInstance, reinterpret_cast<otSrpClientBuffersServiceEntry *>(const_cast<otSrpClientService *>(service)));
4133*cfb92d14SAndroid Build Coastguard Worker     }
4134*cfb92d14SAndroid Build Coastguard Worker }
4135*cfb92d14SAndroid Build Coastguard Worker 
4136*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
HandlePropertyGet(void)4137*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED>(void)
4138*cfb92d14SAndroid Build Coastguard Worker {
4139*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(otSrpClientIsServiceKeyRecordEnabled(mInstance));
4140*cfb92d14SAndroid Build Coastguard Worker }
4141*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)4142*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED>(void)
4143*cfb92d14SAndroid Build Coastguard Worker {
4144*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
4145*cfb92d14SAndroid Build Coastguard Worker     bool    enabled;
4146*cfb92d14SAndroid Build Coastguard Worker 
4147*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
4148*cfb92d14SAndroid Build Coastguard Worker     otSrpClientSetServiceKeyRecordEnabled(mInstance, enabled);
4149*cfb92d14SAndroid Build Coastguard Worker 
4150*cfb92d14SAndroid Build Coastguard Worker exit:
4151*cfb92d14SAndroid Build Coastguard Worker     return error;
4152*cfb92d14SAndroid Build Coastguard Worker }
4153*cfb92d14SAndroid Build Coastguard Worker #endif
4154*cfb92d14SAndroid Build Coastguard Worker 
4155*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
4156*cfb92d14SAndroid Build Coastguard Worker 
4157*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
HandlePropertyGet(void)4158*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE>(void)
4159*cfb92d14SAndroid Build Coastguard Worker {
4160*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(!otTrelIsFilterEnabled(mInstance));
4161*cfb92d14SAndroid Build Coastguard Worker }
4162*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)4163*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE>(void)
4164*cfb92d14SAndroid Build Coastguard Worker {
4165*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
4166*cfb92d14SAndroid Build Coastguard Worker     bool    testMode;
4167*cfb92d14SAndroid Build Coastguard Worker 
4168*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(testMode));
4169*cfb92d14SAndroid Build Coastguard Worker 
4170*cfb92d14SAndroid Build Coastguard Worker     // Note that `TEST_MODE` being `true` indicates that the TREL
4171*cfb92d14SAndroid Build Coastguard Worker     // interface should be enabled and functional, so filtering
4172*cfb92d14SAndroid Build Coastguard Worker     // should be disabled.
4173*cfb92d14SAndroid Build Coastguard Worker 
4174*cfb92d14SAndroid Build Coastguard Worker     otTrelSetFilterEnabled(mInstance, !testMode);
4175*cfb92d14SAndroid Build Coastguard Worker 
4176*cfb92d14SAndroid Build Coastguard Worker exit:
4177*cfb92d14SAndroid Build Coastguard Worker     return error;
4178*cfb92d14SAndroid Build Coastguard Worker }
4179*cfb92d14SAndroid Build Coastguard Worker #endif
4180*cfb92d14SAndroid Build Coastguard Worker 
4181*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
HandlePropertyGet(void)4182*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_NETWORK_TIME>(void)
4183*cfb92d14SAndroid Build Coastguard Worker {
4184*cfb92d14SAndroid Build Coastguard Worker     otError             error = OT_ERROR_NONE;
4185*cfb92d14SAndroid Build Coastguard Worker     otNetworkTimeStatus networkTimeStatus;
4186*cfb92d14SAndroid Build Coastguard Worker     uint64_t            time;
4187*cfb92d14SAndroid Build Coastguard Worker 
4188*cfb92d14SAndroid Build Coastguard Worker     networkTimeStatus = otNetworkTimeGet(mInstance, &time);
4189*cfb92d14SAndroid Build Coastguard Worker 
4190*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint64(time));
4191*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteInt8((int8_t)networkTimeStatus));
4192*cfb92d14SAndroid Build Coastguard Worker 
4193*cfb92d14SAndroid Build Coastguard Worker exit:
4194*cfb92d14SAndroid Build Coastguard Worker     return error;
4195*cfb92d14SAndroid Build Coastguard Worker }
4196*cfb92d14SAndroid Build Coastguard Worker 
HandleTimeSyncUpdate(void * aContext)4197*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleTimeSyncUpdate(void *aContext) { static_cast<NcpBase *>(aContext)->HandleTimeSyncUpdate(); }
4198*cfb92d14SAndroid Build Coastguard Worker 
HandleTimeSyncUpdate(void)4199*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleTimeSyncUpdate(void)
4200*cfb92d14SAndroid Build Coastguard Worker {
4201*cfb92d14SAndroid Build Coastguard Worker     mChangedPropsSet.AddProperty(SPINEL_PROP_THREAD_NETWORK_TIME);
4202*cfb92d14SAndroid Build Coastguard Worker     mUpdateChangedPropsTask.Post();
4203*cfb92d14SAndroid Build Coastguard Worker }
4204*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
4205*cfb92d14SAndroid Build Coastguard Worker 
HandleActiveScanResult_Jump(otActiveScanResult * aResult,void * aContext)4206*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleActiveScanResult_Jump(otActiveScanResult *aResult, void *aContext)
4207*cfb92d14SAndroid Build Coastguard Worker {
4208*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleActiveScanResult(aResult);
4209*cfb92d14SAndroid Build Coastguard Worker }
4210*cfb92d14SAndroid Build Coastguard Worker 
4211*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4212*cfb92d14SAndroid Build Coastguard Worker // MARK: Scan Results Glue
4213*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4214*cfb92d14SAndroid Build Coastguard Worker 
HandleActiveScanResult(otActiveScanResult * aResult)4215*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleActiveScanResult(otActiveScanResult *aResult)
4216*cfb92d14SAndroid Build Coastguard Worker {
4217*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
4218*cfb92d14SAndroid Build Coastguard Worker 
4219*cfb92d14SAndroid Build Coastguard Worker     if (aResult)
4220*cfb92d14SAndroid Build Coastguard Worker     {
4221*cfb92d14SAndroid Build Coastguard Worker         uint8_t flags = static_cast<uint8_t>(aResult->mVersion << SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT);
4222*cfb92d14SAndroid Build Coastguard Worker 
4223*cfb92d14SAndroid Build Coastguard Worker         if (aResult->mIsNative)
4224*cfb92d14SAndroid Build Coastguard Worker         {
4225*cfb92d14SAndroid Build Coastguard Worker             flags |= SPINEL_BEACON_THREAD_FLAG_NATIVE;
4226*cfb92d14SAndroid Build Coastguard Worker         }
4227*cfb92d14SAndroid Build Coastguard Worker 
4228*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
4229*cfb92d14SAndroid Build Coastguard Worker                                                   SPINEL_CMD_PROP_VALUE_INSERTED, SPINEL_PROP_MAC_SCAN_BEACON));
4230*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(aResult->mChannel));
4231*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteInt8(aResult->mRssi));
4232*cfb92d14SAndroid Build Coastguard Worker 
4233*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct()); // "mac-layer data"
4234*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteEui64(aResult->mExtAddress));
4235*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(0xffff)); // short address, not given
4236*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint16(aResult->mPanId));
4237*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(aResult->mLqi));
4238*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
4239*cfb92d14SAndroid Build Coastguard Worker 
4240*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.OpenStruct());                                 // "net-layer data"
4241*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_PROTOCOL_TYPE_THREAD)); // type
4242*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(flags));
4243*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUtf8(aResult->mNetworkName.m8));
4244*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteDataWithLen(aResult->mExtendedPanId.m8, OT_EXT_PAN_ID_SIZE));
4245*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteDataWithLen(aResult->mSteeringData.m8, aResult->mSteeringData.mLength));
4246*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.CloseStruct());
4247*cfb92d14SAndroid Build Coastguard Worker 
4248*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.EndFrame());
4249*cfb92d14SAndroid Build Coastguard Worker     }
4250*cfb92d14SAndroid Build Coastguard Worker     else
4251*cfb92d14SAndroid Build Coastguard Worker     {
4252*cfb92d14SAndroid Build Coastguard Worker         // We are finished with the scan, send an unsolicited
4253*cfb92d14SAndroid Build Coastguard Worker         // scan state update.
4254*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddProperty(SPINEL_PROP_MAC_SCAN_STATE);
4255*cfb92d14SAndroid Build Coastguard Worker         mUpdateChangedPropsTask.Post();
4256*cfb92d14SAndroid Build Coastguard Worker     }
4257*cfb92d14SAndroid Build Coastguard Worker 
4258*cfb92d14SAndroid Build Coastguard Worker exit:
4259*cfb92d14SAndroid Build Coastguard Worker 
4260*cfb92d14SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
4261*cfb92d14SAndroid Build Coastguard Worker     {
4262*cfb92d14SAndroid Build Coastguard Worker         // We ran out of buffer adding a scan result so remember to send
4263*cfb92d14SAndroid Build Coastguard Worker         // an async `LAST_STATUS(NOMEM)` when buffer space becomes
4264*cfb92d14SAndroid Build Coastguard Worker         // available.
4265*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM);
4266*cfb92d14SAndroid Build Coastguard Worker         mUpdateChangedPropsTask.Post();
4267*cfb92d14SAndroid Build Coastguard Worker     }
4268*cfb92d14SAndroid Build Coastguard Worker }
4269*cfb92d14SAndroid Build Coastguard Worker 
HandleEnergyScanResult_Jump(otEnergyScanResult * aResult,void * aContext)4270*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleEnergyScanResult_Jump(otEnergyScanResult *aResult, void *aContext)
4271*cfb92d14SAndroid Build Coastguard Worker {
4272*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleEnergyScanResult(aResult);
4273*cfb92d14SAndroid Build Coastguard Worker }
4274*cfb92d14SAndroid Build Coastguard Worker 
HandleEnergyScanResult(otEnergyScanResult * aResult)4275*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleEnergyScanResult(otEnergyScanResult *aResult)
4276*cfb92d14SAndroid Build Coastguard Worker {
4277*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
4278*cfb92d14SAndroid Build Coastguard Worker 
4279*cfb92d14SAndroid Build Coastguard Worker     if (aResult)
4280*cfb92d14SAndroid Build Coastguard Worker     {
4281*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0,
4282*cfb92d14SAndroid Build Coastguard Worker                                                   SPINEL_CMD_PROP_VALUE_INSERTED, SPINEL_PROP_MAC_ENERGY_SCAN_RESULT));
4283*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteUint8(aResult->mChannel));
4284*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.WriteInt8(aResult->mMaxRssi));
4285*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = mEncoder.EndFrame());
4286*cfb92d14SAndroid Build Coastguard Worker     }
4287*cfb92d14SAndroid Build Coastguard Worker     else
4288*cfb92d14SAndroid Build Coastguard Worker     {
4289*cfb92d14SAndroid Build Coastguard Worker         // We are finished with the scan, send an unsolicited
4290*cfb92d14SAndroid Build Coastguard Worker         // scan state update.
4291*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddProperty(SPINEL_PROP_MAC_SCAN_STATE);
4292*cfb92d14SAndroid Build Coastguard Worker         mUpdateChangedPropsTask.Post();
4293*cfb92d14SAndroid Build Coastguard Worker     }
4294*cfb92d14SAndroid Build Coastguard Worker 
4295*cfb92d14SAndroid Build Coastguard Worker exit:
4296*cfb92d14SAndroid Build Coastguard Worker 
4297*cfb92d14SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
4298*cfb92d14SAndroid Build Coastguard Worker     {
4299*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_NOMEM);
4300*cfb92d14SAndroid Build Coastguard Worker         mUpdateChangedPropsTask.Post();
4301*cfb92d14SAndroid Build Coastguard Worker     }
4302*cfb92d14SAndroid Build Coastguard Worker }
4303*cfb92d14SAndroid Build Coastguard Worker 
4304*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_JOINER_ENABLE
HandleJoinerCallback_Jump(otError aError,void * aContext)4305*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleJoinerCallback_Jump(otError aError, void *aContext)
4306*cfb92d14SAndroid Build Coastguard Worker {
4307*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleJoinerCallback(aError);
4308*cfb92d14SAndroid Build Coastguard Worker }
4309*cfb92d14SAndroid Build Coastguard Worker 
HandleJoinerCallback(otError aError)4310*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleJoinerCallback(otError aError)
4311*cfb92d14SAndroid Build Coastguard Worker {
4312*cfb92d14SAndroid Build Coastguard Worker     switch (aError)
4313*cfb92d14SAndroid Build Coastguard Worker     {
4314*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_NONE:
4315*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_JOIN_SUCCESS);
4316*cfb92d14SAndroid Build Coastguard Worker         break;
4317*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_SECURITY:
4318*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_JOIN_SECURITY);
4319*cfb92d14SAndroid Build Coastguard Worker         break;
4320*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_NOT_FOUND:
4321*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_JOIN_NO_PEERS);
4322*cfb92d14SAndroid Build Coastguard Worker         break;
4323*cfb92d14SAndroid Build Coastguard Worker     case OT_ERROR_RESPONSE_TIMEOUT:
4324*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_JOIN_RSP_TIMEOUT);
4325*cfb92d14SAndroid Build Coastguard Worker         break;
4326*cfb92d14SAndroid Build Coastguard Worker     default:
4327*cfb92d14SAndroid Build Coastguard Worker         mChangedPropsSet.AddLastStatus(SPINEL_STATUS_JOIN_FAILURE);
4328*cfb92d14SAndroid Build Coastguard Worker         break;
4329*cfb92d14SAndroid Build Coastguard Worker     }
4330*cfb92d14SAndroid Build Coastguard Worker 
4331*cfb92d14SAndroid Build Coastguard Worker     mUpdateChangedPropsTask.Post();
4332*cfb92d14SAndroid Build Coastguard Worker }
4333*cfb92d14SAndroid Build Coastguard Worker #endif
4334*cfb92d14SAndroid Build Coastguard Worker 
4335*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
HandleLinkMetricsReport_Jump(const otIp6Address * aSource,const otLinkMetricsValues * aMetricsValues,otLinkMetricsStatus aStatus,void * aContext)4336*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleLinkMetricsReport_Jump(const otIp6Address        *aSource,
4337*cfb92d14SAndroid Build Coastguard Worker                                            const otLinkMetricsValues *aMetricsValues,
4338*cfb92d14SAndroid Build Coastguard Worker                                            otLinkMetricsStatus        aStatus,
4339*cfb92d14SAndroid Build Coastguard Worker                                            void                      *aContext)
4340*cfb92d14SAndroid Build Coastguard Worker {
4341*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleLinkMetricsReport(aSource, aMetricsValues, aStatus);
4342*cfb92d14SAndroid Build Coastguard Worker }
4343*cfb92d14SAndroid Build Coastguard Worker 
HandleLinkMetricsReport(const otIp6Address * aSource,const otLinkMetricsValues * aMetricsValues,otLinkMetricsStatus aStatus)4344*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleLinkMetricsReport(const otIp6Address        *aSource,
4345*cfb92d14SAndroid Build Coastguard Worker                                       const otLinkMetricsValues *aMetricsValues,
4346*cfb92d14SAndroid Build Coastguard Worker                                       otLinkMetricsStatus        aStatus)
4347*cfb92d14SAndroid Build Coastguard Worker {
4348*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
4349*cfb92d14SAndroid Build Coastguard Worker                                       SPINEL_PROP_THREAD_LINK_METRICS_QUERY_RESULT));
4350*cfb92d14SAndroid Build Coastguard Worker 
4351*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteIp6Address(*aSource));
4352*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(aStatus));
4353*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(EncodeLinkMetricsValues(aMetricsValues));
4354*cfb92d14SAndroid Build Coastguard Worker 
4355*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
4356*cfb92d14SAndroid Build Coastguard Worker 
4357*cfb92d14SAndroid Build Coastguard Worker exit:
4358*cfb92d14SAndroid Build Coastguard Worker     return;
4359*cfb92d14SAndroid Build Coastguard Worker }
4360*cfb92d14SAndroid Build Coastguard Worker 
HandleLinkMetricsMgmtResponse_Jump(const otIp6Address * aSource,otLinkMetricsStatus aStatus,void * aContext)4361*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleLinkMetricsMgmtResponse_Jump(const otIp6Address *aSource,
4362*cfb92d14SAndroid Build Coastguard Worker                                                  otLinkMetricsStatus aStatus,
4363*cfb92d14SAndroid Build Coastguard Worker                                                  void               *aContext)
4364*cfb92d14SAndroid Build Coastguard Worker {
4365*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleLinkMetricsMgmtResponse(aSource, aStatus);
4366*cfb92d14SAndroid Build Coastguard Worker }
4367*cfb92d14SAndroid Build Coastguard Worker 
HandleLinkMetricsMgmtResponse(const otIp6Address * aSource,otLinkMetricsStatus aStatus)4368*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleLinkMetricsMgmtResponse(const otIp6Address *aSource, otLinkMetricsStatus aStatus)
4369*cfb92d14SAndroid Build Coastguard Worker {
4370*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
4371*cfb92d14SAndroid Build Coastguard Worker                                       SPINEL_PROP_THREAD_LINK_METRICS_MGMT_RESPONSE));
4372*cfb92d14SAndroid Build Coastguard Worker 
4373*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteIp6Address(*aSource));
4374*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint8(aStatus));
4375*cfb92d14SAndroid Build Coastguard Worker 
4376*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
4377*cfb92d14SAndroid Build Coastguard Worker 
4378*cfb92d14SAndroid Build Coastguard Worker exit:
4379*cfb92d14SAndroid Build Coastguard Worker     return;
4380*cfb92d14SAndroid Build Coastguard Worker }
4381*cfb92d14SAndroid Build Coastguard Worker 
HandleLinkMetricsEnhAckProbingIeReport_Jump(otShortAddress aShortAddress,const otExtAddress * aExtAddress,const otLinkMetricsValues * aMetricsValues,void * aContext)4382*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleLinkMetricsEnhAckProbingIeReport_Jump(otShortAddress             aShortAddress,
4383*cfb92d14SAndroid Build Coastguard Worker                                                           const otExtAddress        *aExtAddress,
4384*cfb92d14SAndroid Build Coastguard Worker                                                           const otLinkMetricsValues *aMetricsValues,
4385*cfb92d14SAndroid Build Coastguard Worker                                                           void                      *aContext)
4386*cfb92d14SAndroid Build Coastguard Worker {
4387*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleLinkMetricsEnhAckProbingIeReport(aShortAddress, aExtAddress,
4388*cfb92d14SAndroid Build Coastguard Worker                                                                              aMetricsValues);
4389*cfb92d14SAndroid Build Coastguard Worker }
4390*cfb92d14SAndroid Build Coastguard Worker 
HandleLinkMetricsEnhAckProbingIeReport(otShortAddress aShortAddress,const otExtAddress * aExtAddress,const otLinkMetricsValues * aMetricsValues)4391*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleLinkMetricsEnhAckProbingIeReport(otShortAddress             aShortAddress,
4392*cfb92d14SAndroid Build Coastguard Worker                                                      const otExtAddress        *aExtAddress,
4393*cfb92d14SAndroid Build Coastguard Worker                                                      const otLinkMetricsValues *aMetricsValues)
4394*cfb92d14SAndroid Build Coastguard Worker {
4395*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_PROP_VALUE_IS,
4396*cfb92d14SAndroid Build Coastguard Worker                                       SPINEL_PROP_THREAD_LINK_METRICS_MGMT_ENH_ACK_IE));
4397*cfb92d14SAndroid Build Coastguard Worker 
4398*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint16(aShortAddress));
4399*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteEui64(*aExtAddress));
4400*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(EncodeLinkMetricsValues(aMetricsValues));
4401*cfb92d14SAndroid Build Coastguard Worker 
4402*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
4403*cfb92d14SAndroid Build Coastguard Worker 
4404*cfb92d14SAndroid Build Coastguard Worker exit:
4405*cfb92d14SAndroid Build Coastguard Worker     return;
4406*cfb92d14SAndroid Build Coastguard Worker }
4407*cfb92d14SAndroid Build Coastguard Worker #endif
4408*cfb92d14SAndroid Build Coastguard Worker 
4409*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4410*cfb92d14SAndroid Build Coastguard Worker // MARK: Outbound Datagram Handling
4411*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4412*cfb92d14SAndroid Build Coastguard Worker 
HandleDatagramFromStack(otMessage * aMessage,void * aContext)4413*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleDatagramFromStack(otMessage *aMessage, void *aContext)
4414*cfb92d14SAndroid Build Coastguard Worker {
4415*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleDatagramFromStack(aMessage);
4416*cfb92d14SAndroid Build Coastguard Worker }
4417*cfb92d14SAndroid Build Coastguard Worker 
HandleDatagramFromStack(otMessage * aMessage)4418*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleDatagramFromStack(otMessage *aMessage)
4419*cfb92d14SAndroid Build Coastguard Worker {
4420*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aMessage != nullptr);
4421*cfb92d14SAndroid Build Coastguard Worker 
4422*cfb92d14SAndroid Build Coastguard Worker     // Do not forward frames larger than SPINEL payload size.
4423*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(otMessageGetLength(aMessage) <= SPINEL_FRAME_MAX_COMMAND_PAYLOAD_SIZE, otMessageFree(aMessage));
4424*cfb92d14SAndroid Build Coastguard Worker 
4425*cfb92d14SAndroid Build Coastguard Worker     otMessageQueueEnqueue(&mMessageQueue, aMessage);
4426*cfb92d14SAndroid Build Coastguard Worker 
4427*cfb92d14SAndroid Build Coastguard Worker     // If there is no queued spinel command response, try to write/send
4428*cfb92d14SAndroid Build Coastguard Worker     // the datagram message immediately. If there is a queued response
4429*cfb92d14SAndroid Build Coastguard Worker     // or if currently out of buffer space, the IPv6 datagram message
4430*cfb92d14SAndroid Build Coastguard Worker     // will be sent from `HandleFrameRemovedFromNcpBuffer()` when buffer
4431*cfb92d14SAndroid Build Coastguard Worker     //  space becomes available and after any pending spinel command
4432*cfb92d14SAndroid Build Coastguard Worker     // response.
4433*cfb92d14SAndroid Build Coastguard Worker 
4434*cfb92d14SAndroid Build Coastguard Worker     if (IsResponseQueueEmpty())
4435*cfb92d14SAndroid Build Coastguard Worker     {
4436*cfb92d14SAndroid Build Coastguard Worker         IgnoreError(SendQueuedDatagramMessages());
4437*cfb92d14SAndroid Build Coastguard Worker     }
4438*cfb92d14SAndroid Build Coastguard Worker 
4439*cfb92d14SAndroid Build Coastguard Worker exit:
4440*cfb92d14SAndroid Build Coastguard Worker     return;
4441*cfb92d14SAndroid Build Coastguard Worker }
4442*cfb92d14SAndroid Build Coastguard Worker 
SendDatagramMessage(otMessage * aMessage)4443*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::SendDatagramMessage(otMessage *aMessage)
4444*cfb92d14SAndroid Build Coastguard Worker {
4445*cfb92d14SAndroid Build Coastguard Worker     otError           error    = OT_ERROR_NONE;
4446*cfb92d14SAndroid Build Coastguard Worker     uint8_t           header   = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
4447*cfb92d14SAndroid Build Coastguard Worker     bool              isSecure = otMessageIsLinkSecurityEnabled(aMessage);
4448*cfb92d14SAndroid Build Coastguard Worker     spinel_prop_key_t propKey  = isSecure ? SPINEL_PROP_STREAM_NET : SPINEL_PROP_STREAM_NET_INSECURE;
4449*cfb92d14SAndroid Build Coastguard Worker 
4450*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, propKey));
4451*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteUint16(otMessageGetLength(aMessage)));
4452*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.WriteMessage(aMessage));
4453*cfb92d14SAndroid Build Coastguard Worker 
4454*cfb92d14SAndroid Build Coastguard Worker     // Append any metadata (rssi, lqi, channel, etc) here!
4455*cfb92d14SAndroid Build Coastguard Worker 
4456*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mEncoder.EndFrame());
4457*cfb92d14SAndroid Build Coastguard Worker 
4458*cfb92d14SAndroid Build Coastguard Worker     if (isSecure)
4459*cfb92d14SAndroid Build Coastguard Worker     {
4460*cfb92d14SAndroid Build Coastguard Worker         mOutboundSecureIpFrameCounter++;
4461*cfb92d14SAndroid Build Coastguard Worker     }
4462*cfb92d14SAndroid Build Coastguard Worker     else
4463*cfb92d14SAndroid Build Coastguard Worker     {
4464*cfb92d14SAndroid Build Coastguard Worker         mOutboundInsecureIpFrameCounter++;
4465*cfb92d14SAndroid Build Coastguard Worker     }
4466*cfb92d14SAndroid Build Coastguard Worker 
4467*cfb92d14SAndroid Build Coastguard Worker exit:
4468*cfb92d14SAndroid Build Coastguard Worker     return error;
4469*cfb92d14SAndroid Build Coastguard Worker }
4470*cfb92d14SAndroid Build Coastguard Worker 
SendQueuedDatagramMessages(void)4471*cfb92d14SAndroid Build Coastguard Worker otError NcpBase::SendQueuedDatagramMessages(void)
4472*cfb92d14SAndroid Build Coastguard Worker {
4473*cfb92d14SAndroid Build Coastguard Worker     otError    error = OT_ERROR_NONE;
4474*cfb92d14SAndroid Build Coastguard Worker     otMessage *message;
4475*cfb92d14SAndroid Build Coastguard Worker 
4476*cfb92d14SAndroid Build Coastguard Worker     while ((message = otMessageQueueGetHead(&mMessageQueue)) != nullptr)
4477*cfb92d14SAndroid Build Coastguard Worker     {
4478*cfb92d14SAndroid Build Coastguard Worker         // Since an `otMessage` instance can be in one queue at a time,
4479*cfb92d14SAndroid Build Coastguard Worker         // it is first dequeued from `mMessageQueue` before attempting
4480*cfb92d14SAndroid Build Coastguard Worker         // to include it in a spinel frame by calling `SendDatagramMessage()`
4481*cfb92d14SAndroid Build Coastguard Worker         // If forming of the spinel frame fails, the message is enqueued
4482*cfb92d14SAndroid Build Coastguard Worker         // back at the front of `mMessageQueue`.
4483*cfb92d14SAndroid Build Coastguard Worker 
4484*cfb92d14SAndroid Build Coastguard Worker         otMessageQueueDequeue(&mMessageQueue, message);
4485*cfb92d14SAndroid Build Coastguard Worker 
4486*cfb92d14SAndroid Build Coastguard Worker         error = SendDatagramMessage(message);
4487*cfb92d14SAndroid Build Coastguard Worker 
4488*cfb92d14SAndroid Build Coastguard Worker         if (error != OT_ERROR_NONE)
4489*cfb92d14SAndroid Build Coastguard Worker         {
4490*cfb92d14SAndroid Build Coastguard Worker             otMessageQueueEnqueueAtHead(&mMessageQueue, message);
4491*cfb92d14SAndroid Build Coastguard Worker         }
4492*cfb92d14SAndroid Build Coastguard Worker 
4493*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error);
4494*cfb92d14SAndroid Build Coastguard Worker     }
4495*cfb92d14SAndroid Build Coastguard Worker 
4496*cfb92d14SAndroid Build Coastguard Worker exit:
4497*cfb92d14SAndroid Build Coastguard Worker     return error;
4498*cfb92d14SAndroid Build Coastguard Worker }
4499*cfb92d14SAndroid Build Coastguard Worker 
4500*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
HandlePropertySet(void)4501*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_THREAD_UDP_FORWARD_STREAM>(void)
4502*cfb92d14SAndroid Build Coastguard Worker {
4503*cfb92d14SAndroid Build Coastguard Worker     const uint8_t      *framePtr = nullptr;
4504*cfb92d14SAndroid Build Coastguard Worker     uint16_t            frameLen = 0;
4505*cfb92d14SAndroid Build Coastguard Worker     const otIp6Address *peerAddr;
4506*cfb92d14SAndroid Build Coastguard Worker     uint16_t            peerPort;
4507*cfb92d14SAndroid Build Coastguard Worker     uint16_t            sockPort;
4508*cfb92d14SAndroid Build Coastguard Worker     otMessage          *message;
4509*cfb92d14SAndroid Build Coastguard Worker     otError             error       = OT_ERROR_NONE;
4510*cfb92d14SAndroid Build Coastguard Worker     otMessageSettings   msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
4511*cfb92d14SAndroid Build Coastguard Worker 
4512*cfb92d14SAndroid Build Coastguard Worker     message = otIp6NewMessage(mInstance, &msgSettings);
4513*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
4514*cfb92d14SAndroid Build Coastguard Worker 
4515*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadDataWithLen(framePtr, frameLen));
4516*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(peerPort));
4517*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadIp6Address(peerAddr));
4518*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadUint16(sockPort));
4519*cfb92d14SAndroid Build Coastguard Worker 
4520*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otMessageAppend(message, framePtr, static_cast<uint16_t>(frameLen)));
4521*cfb92d14SAndroid Build Coastguard Worker 
4522*cfb92d14SAndroid Build Coastguard Worker     otUdpForwardReceive(mInstance, message, peerPort, peerAddr, sockPort);
4523*cfb92d14SAndroid Build Coastguard Worker 
4524*cfb92d14SAndroid Build Coastguard Worker     // `otUdpForwardReceive()` takes ownership of `message` (in both success
4525*cfb92d14SAndroid Build Coastguard Worker     // or failure cases). `message` is set to nullptr so it is not freed at
4526*cfb92d14SAndroid Build Coastguard Worker     // exit.
4527*cfb92d14SAndroid Build Coastguard Worker     message = nullptr;
4528*cfb92d14SAndroid Build Coastguard Worker 
4529*cfb92d14SAndroid Build Coastguard Worker exit:
4530*cfb92d14SAndroid Build Coastguard Worker     if (message != nullptr)
4531*cfb92d14SAndroid Build Coastguard Worker     {
4532*cfb92d14SAndroid Build Coastguard Worker         otMessageFree(message);
4533*cfb92d14SAndroid Build Coastguard Worker     }
4534*cfb92d14SAndroid Build Coastguard Worker 
4535*cfb92d14SAndroid Build Coastguard Worker     return error;
4536*cfb92d14SAndroid Build Coastguard Worker }
4537*cfb92d14SAndroid Build Coastguard Worker 
HandleUdpForwardStream(otMessage * aMessage,uint16_t aPeerPort,otIp6Address * aPeerAddr,uint16_t aSockPort,void * aContext)4538*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleUdpForwardStream(otMessage    *aMessage,
4539*cfb92d14SAndroid Build Coastguard Worker                                      uint16_t      aPeerPort,
4540*cfb92d14SAndroid Build Coastguard Worker                                      otIp6Address *aPeerAddr,
4541*cfb92d14SAndroid Build Coastguard Worker                                      uint16_t      aSockPort,
4542*cfb92d14SAndroid Build Coastguard Worker                                      void         *aContext)
4543*cfb92d14SAndroid Build Coastguard Worker {
4544*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandleUdpForwardStream(aMessage, aPeerPort, *aPeerAddr, aSockPort);
4545*cfb92d14SAndroid Build Coastguard Worker }
4546*cfb92d14SAndroid Build Coastguard Worker 
HandleUdpForwardStream(otMessage * aMessage,uint16_t aPeerPort,otIp6Address & aPeerAddr,uint16_t aPort)4547*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleUdpForwardStream(otMessage *aMessage, uint16_t aPeerPort, otIp6Address &aPeerAddr, uint16_t aPort)
4548*cfb92d14SAndroid Build Coastguard Worker {
4549*cfb92d14SAndroid Build Coastguard Worker     uint16_t length = otMessageGetLength(aMessage);
4550*cfb92d14SAndroid Build Coastguard Worker     uint8_t  header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
4551*cfb92d14SAndroid Build Coastguard Worker 
4552*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_THREAD_UDP_FORWARD_STREAM));
4553*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint16(length));
4554*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteMessage(aMessage));
4555*cfb92d14SAndroid Build Coastguard Worker 
4556*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint16(aPeerPort));
4557*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteIp6Address(aPeerAddr));
4558*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint16(aPort));
4559*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
4560*cfb92d14SAndroid Build Coastguard Worker 
4561*cfb92d14SAndroid Build Coastguard Worker     // The `aMessage` is owned by the outbound frame and NCP buffer
4562*cfb92d14SAndroid Build Coastguard Worker     // after frame was finished/ended successfully. It will be freed
4563*cfb92d14SAndroid Build Coastguard Worker     // when the frame is successfully sent and removed.
4564*cfb92d14SAndroid Build Coastguard Worker 
4565*cfb92d14SAndroid Build Coastguard Worker     aMessage = nullptr;
4566*cfb92d14SAndroid Build Coastguard Worker 
4567*cfb92d14SAndroid Build Coastguard Worker exit:
4568*cfb92d14SAndroid Build Coastguard Worker 
4569*cfb92d14SAndroid Build Coastguard Worker     if (aMessage != nullptr)
4570*cfb92d14SAndroid Build Coastguard Worker     {
4571*cfb92d14SAndroid Build Coastguard Worker         otMessageFree(aMessage);
4572*cfb92d14SAndroid Build Coastguard Worker     }
4573*cfb92d14SAndroid Build Coastguard Worker }
4574*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
4575*cfb92d14SAndroid Build Coastguard Worker 
4576*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4577*cfb92d14SAndroid Build Coastguard Worker // MARK: Pcap frame handling
4578*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4579*cfb92d14SAndroid Build Coastguard Worker 
HandlePcapFrame(const otRadioFrame * aFrame,bool aIsTx,void * aContext)4580*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandlePcapFrame(const otRadioFrame *aFrame, bool aIsTx, void *aContext)
4581*cfb92d14SAndroid Build Coastguard Worker {
4582*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->HandlePcapFrame(aFrame, aIsTx);
4583*cfb92d14SAndroid Build Coastguard Worker }
4584*cfb92d14SAndroid Build Coastguard Worker 
HandlePcapFrame(const otRadioFrame * aFrame,bool aIsTx)4585*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandlePcapFrame(const otRadioFrame *aFrame, bool aIsTx)
4586*cfb92d14SAndroid Build Coastguard Worker {
4587*cfb92d14SAndroid Build Coastguard Worker     uint16_t flags  = 0;
4588*cfb92d14SAndroid Build Coastguard Worker     uint8_t  header = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
4589*cfb92d14SAndroid Build Coastguard Worker 
4590*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mPcapEnabled);
4591*cfb92d14SAndroid Build Coastguard Worker 
4592*cfb92d14SAndroid Build Coastguard Worker     if (aIsTx)
4593*cfb92d14SAndroid Build Coastguard Worker     {
4594*cfb92d14SAndroid Build Coastguard Worker         flags |= SPINEL_MD_FLAG_TX;
4595*cfb92d14SAndroid Build Coastguard Worker     }
4596*cfb92d14SAndroid Build Coastguard Worker 
4597*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.BeginFrame(header, SPINEL_CMD_PROP_VALUE_IS, SPINEL_PROP_STREAM_RAW));
4598*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint16(aFrame->mLength));
4599*cfb92d14SAndroid Build Coastguard Worker 
4600*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteData(aFrame->mPsdu, aFrame->mLength));
4601*cfb92d14SAndroid Build Coastguard Worker 
4602*cfb92d14SAndroid Build Coastguard Worker     // Append metadata (rssi, etc)
4603*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteInt8(aFrame->mInfo.mRxInfo.mRssi)); // RSSI
4604*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteInt8(-128));                        // Noise floor (Currently unused)
4605*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.WriteUint16(flags));                     // Flags
4606*cfb92d14SAndroid Build Coastguard Worker 
4607*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.OpenStruct()); // PHY-data
4608*cfb92d14SAndroid Build Coastguard Worker     // Empty for now
4609*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.CloseStruct());
4610*cfb92d14SAndroid Build Coastguard Worker 
4611*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.OpenStruct()); // Vendor-data
4612*cfb92d14SAndroid Build Coastguard Worker     // Empty for now
4613*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.CloseStruct());
4614*cfb92d14SAndroid Build Coastguard Worker 
4615*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(mEncoder.EndFrame());
4616*cfb92d14SAndroid Build Coastguard Worker 
4617*cfb92d14SAndroid Build Coastguard Worker exit:
4618*cfb92d14SAndroid Build Coastguard Worker     return;
4619*cfb92d14SAndroid Build Coastguard Worker }
4620*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)4621*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_PHY_PCAP_ENABLED>(void)
4622*cfb92d14SAndroid Build Coastguard Worker {
4623*cfb92d14SAndroid Build Coastguard Worker     return mEncoder.WriteBool(mPcapEnabled);
4624*cfb92d14SAndroid Build Coastguard Worker }
4625*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)4626*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_PHY_PCAP_ENABLED>(void)
4627*cfb92d14SAndroid Build Coastguard Worker {
4628*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
4629*cfb92d14SAndroid Build Coastguard Worker     bool    enabled;
4630*cfb92d14SAndroid Build Coastguard Worker 
4631*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = mDecoder.ReadBool(enabled));
4632*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(enabled != mPcapEnabled);
4633*cfb92d14SAndroid Build Coastguard Worker 
4634*cfb92d14SAndroid Build Coastguard Worker     mPcapEnabled = enabled;
4635*cfb92d14SAndroid Build Coastguard Worker 
4636*cfb92d14SAndroid Build Coastguard Worker     if (mPcapEnabled)
4637*cfb92d14SAndroid Build Coastguard Worker     {
4638*cfb92d14SAndroid Build Coastguard Worker         otLinkSetPcapCallback(mInstance, &NcpBase::HandlePcapFrame, static_cast<void *>(this));
4639*cfb92d14SAndroid Build Coastguard Worker     }
4640*cfb92d14SAndroid Build Coastguard Worker     else
4641*cfb92d14SAndroid Build Coastguard Worker     {
4642*cfb92d14SAndroid Build Coastguard Worker         otLinkSetPcapCallback(mInstance, nullptr, nullptr);
4643*cfb92d14SAndroid Build Coastguard Worker     }
4644*cfb92d14SAndroid Build Coastguard Worker 
4645*cfb92d14SAndroid Build Coastguard Worker exit:
4646*cfb92d14SAndroid Build Coastguard Worker     return error;
4647*cfb92d14SAndroid Build Coastguard Worker }
4648*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertyGet(void)4649*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_LEAVE_GRACEFULLY>(void) { return OT_ERROR_NONE; }
4650*cfb92d14SAndroid Build Coastguard Worker 
HandlePropertySet(void)4651*cfb92d14SAndroid Build Coastguard Worker template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_LEAVE_GRACEFULLY>(void)
4652*cfb92d14SAndroid Build Coastguard Worker {
4653*cfb92d14SAndroid Build Coastguard Worker     return otThreadDetachGracefully(mInstance, ThreadDetachGracefullyHandler, this);
4654*cfb92d14SAndroid Build Coastguard Worker }
4655*cfb92d14SAndroid Build Coastguard Worker 
ThreadDetachGracefullyHandler(void * aContext)4656*cfb92d14SAndroid Build Coastguard Worker void NcpBase::ThreadDetachGracefullyHandler(void *aContext)
4657*cfb92d14SAndroid Build Coastguard Worker {
4658*cfb92d14SAndroid Build Coastguard Worker     static_cast<NcpBase *>(aContext)->ThreadDetachGracefullyHandler();
4659*cfb92d14SAndroid Build Coastguard Worker }
4660*cfb92d14SAndroid Build Coastguard Worker 
ThreadDetachGracefullyHandler(void)4661*cfb92d14SAndroid Build Coastguard Worker void NcpBase::ThreadDetachGracefullyHandler(void)
4662*cfb92d14SAndroid Build Coastguard Worker {
4663*cfb92d14SAndroid Build Coastguard Worker     mChangedPropsSet.AddProperty(SPINEL_PROP_NET_LEAVE_GRACEFULLY);
4664*cfb92d14SAndroid Build Coastguard Worker     mUpdateChangedPropsTask.Post();
4665*cfb92d14SAndroid Build Coastguard Worker }
4666*cfb92d14SAndroid Build Coastguard Worker 
4667*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4668*cfb92d14SAndroid Build Coastguard Worker // MARK: Property/Status Changed
4669*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
4670*cfb92d14SAndroid Build Coastguard Worker 
HandleStateChanged(otChangedFlags aFlags,void * aContext)4671*cfb92d14SAndroid Build Coastguard Worker void NcpBase::HandleStateChanged(otChangedFlags aFlags, void *aContext)
4672*cfb92d14SAndroid Build Coastguard Worker {
4673*cfb92d14SAndroid Build Coastguard Worker     NcpBase *ncp = static_cast<NcpBase *>(aContext);
4674*cfb92d14SAndroid Build Coastguard Worker 
4675*cfb92d14SAndroid Build Coastguard Worker     ncp->mThreadChangedFlags |= aFlags;
4676*cfb92d14SAndroid Build Coastguard Worker     ncp->mUpdateChangedPropsTask.Post();
4677*cfb92d14SAndroid Build Coastguard Worker }
4678*cfb92d14SAndroid Build Coastguard Worker 
ProcessThreadChangedFlags(void)4679*cfb92d14SAndroid Build Coastguard Worker void NcpBase::ProcessThreadChangedFlags(void)
4680*cfb92d14SAndroid Build Coastguard Worker {
4681*cfb92d14SAndroid Build Coastguard Worker     static const struct
4682*cfb92d14SAndroid Build Coastguard Worker     {
4683*cfb92d14SAndroid Build Coastguard Worker         otChangedFlags    mThreadFlag;
4684*cfb92d14SAndroid Build Coastguard Worker         spinel_prop_key_t mPropKey;
4685*cfb92d14SAndroid Build Coastguard Worker     } kFlags[] = {
4686*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_IP6_ADDRESS_ADDED, SPINEL_PROP_IPV6_ADDRESS_TABLE},
4687*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_IP6_ADDRESS_REMOVED, SPINEL_PROP_IPV6_ADDRESS_TABLE},
4688*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_ROLE, SPINEL_PROP_NET_ROLE},
4689*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_LL_ADDR, SPINEL_PROP_IPV6_LL_ADDR},
4690*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_ML_ADDR, SPINEL_PROP_IPV6_ML_ADDR},
4691*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_PARTITION_ID, SPINEL_PROP_NET_PARTITION_ID},
4692*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER, SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER},
4693*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_NETDATA, SPINEL_PROP_THREAD_LEADER_NETWORK_DATA},
4694*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_CHILD_ADDED, SPINEL_PROP_THREAD_CHILD_TABLE},
4695*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_CHILD_REMOVED, SPINEL_PROP_THREAD_CHILD_TABLE},
4696*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_IP6_MULTICAST_SUBSCRIBED, SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE},
4697*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_IP6_MULTICAST_UNSUBSCRIBED, SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE},
4698*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_CHANNEL, SPINEL_PROP_PHY_CHAN},
4699*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_PANID, SPINEL_PROP_MAC_15_4_PANID},
4700*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_NETWORK_NAME, SPINEL_PROP_NET_NETWORK_NAME},
4701*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_EXT_PANID, SPINEL_PROP_NET_XPANID},
4702*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_RLOC_ADDED, SPINEL_PROP_IPV6_ADDRESS_TABLE},
4703*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_THREAD_RLOC_REMOVED, SPINEL_PROP_IPV6_ADDRESS_TABLE},
4704*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_NETWORK_KEY, SPINEL_PROP_NET_NETWORK_KEY},
4705*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_PSKC, SPINEL_PROP_NET_PSKC},
4706*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_CHANNEL_MANAGER_NEW_CHANNEL, SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL},
4707*cfb92d14SAndroid Build Coastguard Worker         {OT_CHANGED_SUPPORTED_CHANNEL_MASK, SPINEL_PROP_PHY_CHAN_SUPPORTED},
4708*cfb92d14SAndroid Build Coastguard Worker     };
4709*cfb92d14SAndroid Build Coastguard Worker 
4710*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(mThreadChangedFlags != 0);
4711*cfb92d14SAndroid Build Coastguard Worker 
4712*cfb92d14SAndroid Build Coastguard Worker     // If thread role has changed, check for possible "join" error.
4713*cfb92d14SAndroid Build Coastguard Worker 
4714*cfb92d14SAndroid Build Coastguard Worker     if ((mThreadChangedFlags & OT_CHANGED_THREAD_ROLE) != 0)
4715*cfb92d14SAndroid Build Coastguard Worker     {
4716*cfb92d14SAndroid Build Coastguard Worker         if (mRequireJoinExistingNetwork)
4717*cfb92d14SAndroid Build Coastguard Worker         {
4718*cfb92d14SAndroid Build Coastguard Worker             switch (otThreadGetDeviceRole(mInstance))
4719*cfb92d14SAndroid Build Coastguard Worker             {
4720*cfb92d14SAndroid Build Coastguard Worker             case OT_DEVICE_ROLE_DETACHED:
4721*cfb92d14SAndroid Build Coastguard Worker             case OT_DEVICE_ROLE_DISABLED:
4722*cfb92d14SAndroid Build Coastguard Worker                 break;
4723*cfb92d14SAndroid Build Coastguard Worker 
4724*cfb92d14SAndroid Build Coastguard Worker             default:
4725*cfb92d14SAndroid Build Coastguard Worker                 mRequireJoinExistingNetwork = false;
4726*cfb92d14SAndroid Build Coastguard Worker                 mChangedPropsSet.AddProperty(SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING);
4727*cfb92d14SAndroid Build Coastguard Worker                 break;
4728*cfb92d14SAndroid Build Coastguard Worker             }
4729*cfb92d14SAndroid Build Coastguard Worker 
4730*cfb92d14SAndroid Build Coastguard Worker             if ((otThreadGetDeviceRole(mInstance) == OT_DEVICE_ROLE_LEADER) && otThreadIsSingleton(mInstance))
4731*cfb92d14SAndroid Build Coastguard Worker             {
4732*cfb92d14SAndroid Build Coastguard Worker                 mThreadChangedFlags &= ~static_cast<uint32_t>(OT_CHANGED_THREAD_PARTITION_ID);
4733*cfb92d14SAndroid Build Coastguard Worker                 IgnoreError(otThreadSetEnabled(mInstance, false));
4734*cfb92d14SAndroid Build Coastguard Worker 
4735*cfb92d14SAndroid Build Coastguard Worker                 mChangedPropsSet.AddProperty(SPINEL_PROP_NET_STACK_UP);
4736*cfb92d14SAndroid Build Coastguard Worker                 mChangedPropsSet.AddLastStatus(SPINEL_STATUS_JOIN_FAILURE);
4737*cfb92d14SAndroid Build Coastguard Worker             }
4738*cfb92d14SAndroid Build Coastguard Worker         }
4739*cfb92d14SAndroid Build Coastguard Worker     }
4740*cfb92d14SAndroid Build Coastguard Worker 
4741*cfb92d14SAndroid Build Coastguard Worker     // Convert OT_CHANGED flags to corresponding NCP property update.
4742*cfb92d14SAndroid Build Coastguard Worker 
4743*cfb92d14SAndroid Build Coastguard Worker     for (auto &flag : kFlags)
4744*cfb92d14SAndroid Build Coastguard Worker     {
4745*cfb92d14SAndroid Build Coastguard Worker         uint32_t threadFlag = flag.mThreadFlag;
4746*cfb92d14SAndroid Build Coastguard Worker 
4747*cfb92d14SAndroid Build Coastguard Worker         if (mThreadChangedFlags & threadFlag)
4748*cfb92d14SAndroid Build Coastguard Worker         {
4749*cfb92d14SAndroid Build Coastguard Worker             spinel_prop_key_t propKey           = flag.mPropKey;
4750*cfb92d14SAndroid Build Coastguard Worker             bool              shouldAddProperty = true;
4751*cfb92d14SAndroid Build Coastguard Worker 
4752*cfb92d14SAndroid Build Coastguard Worker             // Child table changes are reported using the `HandleChildAdded()` and
4753*cfb92d14SAndroid Build Coastguard Worker             // `HandleChildRemoved()` callbacks emitting spinel `VALUE_INSERTED` and
4754*cfb92d14SAndroid Build Coastguard Worker             // `VALUE_REMOVED` async spinel frames. If the spinel frames could not be
4755*cfb92d14SAndroid Build Coastguard Worker             // added (e.g., out of NCP buffer) from the above callbacks, the flag
4756*cfb92d14SAndroid Build Coastguard Worker             // `mShouldEmitChildTableUpdate` is set to `true` so that the entire
4757*cfb92d14SAndroid Build Coastguard Worker             // child table is emitted as an unsolicited `VALUE_IS` update.
4758*cfb92d14SAndroid Build Coastguard Worker 
4759*cfb92d14SAndroid Build Coastguard Worker             if (propKey == SPINEL_PROP_THREAD_CHILD_TABLE)
4760*cfb92d14SAndroid Build Coastguard Worker             {
4761*cfb92d14SAndroid Build Coastguard Worker                 shouldAddProperty           = mShouldEmitChildTableUpdate;
4762*cfb92d14SAndroid Build Coastguard Worker                 mShouldEmitChildTableUpdate = false;
4763*cfb92d14SAndroid Build Coastguard Worker             }
4764*cfb92d14SAndroid Build Coastguard Worker 
4765*cfb92d14SAndroid Build Coastguard Worker             if (shouldAddProperty)
4766*cfb92d14SAndroid Build Coastguard Worker             {
4767*cfb92d14SAndroid Build Coastguard Worker                 mChangedPropsSet.AddProperty(propKey);
4768*cfb92d14SAndroid Build Coastguard Worker             }
4769*cfb92d14SAndroid Build Coastguard Worker 
4770*cfb92d14SAndroid Build Coastguard Worker             if (threadFlag == OT_CHANGED_THREAD_NETDATA)
4771*cfb92d14SAndroid Build Coastguard Worker             {
4772*cfb92d14SAndroid Build Coastguard Worker                 mChangedPropsSet.AddProperty(SPINEL_PROP_THREAD_ON_MESH_NETS);
4773*cfb92d14SAndroid Build Coastguard Worker                 mChangedPropsSet.AddProperty(SPINEL_PROP_THREAD_OFF_MESH_ROUTES);
4774*cfb92d14SAndroid Build Coastguard Worker             }
4775*cfb92d14SAndroid Build Coastguard Worker 
4776*cfb92d14SAndroid Build Coastguard Worker             mThreadChangedFlags &= ~threadFlag;
4777*cfb92d14SAndroid Build Coastguard Worker             VerifyOrExit(mThreadChangedFlags != 0);
4778*cfb92d14SAndroid Build Coastguard Worker         }
4779*cfb92d14SAndroid Build Coastguard Worker     }
4780*cfb92d14SAndroid Build Coastguard Worker 
4781*cfb92d14SAndroid Build Coastguard Worker     // Clear any remaining ThreadFlag that has no matching
4782*cfb92d14SAndroid Build Coastguard Worker     // NCP property update (e.g., OT_CHANGED_SECURITY_POLICY)
4783*cfb92d14SAndroid Build Coastguard Worker 
4784*cfb92d14SAndroid Build Coastguard Worker     mThreadChangedFlags = 0;
4785*cfb92d14SAndroid Build Coastguard Worker 
4786*cfb92d14SAndroid Build Coastguard Worker exit:
4787*cfb92d14SAndroid Build Coastguard Worker     return;
4788*cfb92d14SAndroid Build Coastguard Worker }
4789*cfb92d14SAndroid Build Coastguard Worker 
4790*cfb92d14SAndroid Build Coastguard Worker } // namespace Ncp
4791*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
4792*cfb92d14SAndroid Build Coastguard Worker 
4793*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
4794