xref: /aosp_15_r20/external/openthread/src/lib/spinel/logger.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2024, 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"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include "logger.hpp"
30*cfb92d14SAndroid Build Coastguard Worker 
31*cfb92d14SAndroid Build Coastguard Worker #include "openthread-spinel-config.h"
32*cfb92d14SAndroid Build Coastguard Worker 
33*cfb92d14SAndroid Build Coastguard Worker #include <assert.h>
34*cfb92d14SAndroid Build Coastguard Worker #include <stdio.h>
35*cfb92d14SAndroid Build Coastguard Worker #include <stdlib.h>
36*cfb92d14SAndroid Build Coastguard Worker 
37*cfb92d14SAndroid Build Coastguard Worker #include <openthread/error.h>
38*cfb92d14SAndroid Build Coastguard Worker #include <openthread/logging.h>
39*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/radio.h>
40*cfb92d14SAndroid Build Coastguard Worker 
41*cfb92d14SAndroid Build Coastguard Worker #include "lib/spinel/spinel.h"
42*cfb92d14SAndroid Build Coastguard Worker #include "lib/utils/math.hpp"
43*cfb92d14SAndroid Build Coastguard Worker #include "lib/utils/utils.hpp"
44*cfb92d14SAndroid Build Coastguard Worker 
45*cfb92d14SAndroid Build Coastguard Worker namespace ot {
46*cfb92d14SAndroid Build Coastguard Worker namespace Spinel {
47*cfb92d14SAndroid Build Coastguard Worker 
48*cfb92d14SAndroid Build Coastguard Worker using Lib::Utils::Min;
49*cfb92d14SAndroid Build Coastguard Worker using Lib::Utils::ToUlong;
50*cfb92d14SAndroid Build Coastguard Worker 
Logger(const char * aModuleName)51*cfb92d14SAndroid Build Coastguard Worker Logger::Logger(const char *aModuleName)
52*cfb92d14SAndroid Build Coastguard Worker     : mModuleName(aModuleName)
53*cfb92d14SAndroid Build Coastguard Worker {
54*cfb92d14SAndroid Build Coastguard Worker }
55*cfb92d14SAndroid Build Coastguard Worker 
LogIfFail(const char * aText,otError aError)56*cfb92d14SAndroid Build Coastguard Worker void Logger::LogIfFail(const char *aText, otError aError)
57*cfb92d14SAndroid Build Coastguard Worker {
58*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aText);
59*cfb92d14SAndroid Build Coastguard Worker 
60*cfb92d14SAndroid Build Coastguard Worker     if (aError != OT_ERROR_NONE && aError != OT_ERROR_NO_ACK)
61*cfb92d14SAndroid Build Coastguard Worker     {
62*cfb92d14SAndroid Build Coastguard Worker         LogWarn("%s: %s", aText, otThreadErrorToString(aError));
63*cfb92d14SAndroid Build Coastguard Worker     }
64*cfb92d14SAndroid Build Coastguard Worker }
65*cfb92d14SAndroid Build Coastguard Worker 
LogCrit(const char * aFormat,...)66*cfb92d14SAndroid Build Coastguard Worker void Logger::LogCrit(const char *aFormat, ...)
67*cfb92d14SAndroid Build Coastguard Worker {
68*cfb92d14SAndroid Build Coastguard Worker     va_list args;
69*cfb92d14SAndroid Build Coastguard Worker 
70*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
71*cfb92d14SAndroid Build Coastguard Worker     otLogPlatArgs(OT_LOG_LEVEL_CRIT, mModuleName, aFormat, args);
72*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
73*cfb92d14SAndroid Build Coastguard Worker }
74*cfb92d14SAndroid Build Coastguard Worker 
LogWarn(const char * aFormat,...)75*cfb92d14SAndroid Build Coastguard Worker void Logger::LogWarn(const char *aFormat, ...)
76*cfb92d14SAndroid Build Coastguard Worker {
77*cfb92d14SAndroid Build Coastguard Worker     va_list args;
78*cfb92d14SAndroid Build Coastguard Worker 
79*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
80*cfb92d14SAndroid Build Coastguard Worker     otLogPlatArgs(OT_LOG_LEVEL_WARN, mModuleName, aFormat, args);
81*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
82*cfb92d14SAndroid Build Coastguard Worker }
83*cfb92d14SAndroid Build Coastguard Worker 
LogNote(const char * aFormat,...)84*cfb92d14SAndroid Build Coastguard Worker void Logger::LogNote(const char *aFormat, ...)
85*cfb92d14SAndroid Build Coastguard Worker {
86*cfb92d14SAndroid Build Coastguard Worker     va_list args;
87*cfb92d14SAndroid Build Coastguard Worker 
88*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
89*cfb92d14SAndroid Build Coastguard Worker     otLogPlatArgs(OT_LOG_LEVEL_NOTE, mModuleName, aFormat, args);
90*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
91*cfb92d14SAndroid Build Coastguard Worker }
92*cfb92d14SAndroid Build Coastguard Worker 
LogInfo(const char * aFormat,...)93*cfb92d14SAndroid Build Coastguard Worker void Logger::LogInfo(const char *aFormat, ...)
94*cfb92d14SAndroid Build Coastguard Worker {
95*cfb92d14SAndroid Build Coastguard Worker     va_list args;
96*cfb92d14SAndroid Build Coastguard Worker 
97*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
98*cfb92d14SAndroid Build Coastguard Worker     otLogPlatArgs(OT_LOG_LEVEL_INFO, mModuleName, aFormat, args);
99*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
100*cfb92d14SAndroid Build Coastguard Worker }
101*cfb92d14SAndroid Build Coastguard Worker 
LogDebg(const char * aFormat,...)102*cfb92d14SAndroid Build Coastguard Worker void Logger::LogDebg(const char *aFormat, ...)
103*cfb92d14SAndroid Build Coastguard Worker {
104*cfb92d14SAndroid Build Coastguard Worker     va_list args;
105*cfb92d14SAndroid Build Coastguard Worker 
106*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
107*cfb92d14SAndroid Build Coastguard Worker     otLogPlatArgs(OT_LOG_LEVEL_DEBG, mModuleName, aFormat, args);
108*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
109*cfb92d14SAndroid Build Coastguard Worker }
110*cfb92d14SAndroid Build Coastguard Worker 
Snprintf(char * aDest,uint32_t aSize,const char * aFormat,...)111*cfb92d14SAndroid Build Coastguard Worker uint32_t Logger::Snprintf(char *aDest, uint32_t aSize, const char *aFormat, ...)
112*cfb92d14SAndroid Build Coastguard Worker {
113*cfb92d14SAndroid Build Coastguard Worker     int     len;
114*cfb92d14SAndroid Build Coastguard Worker     va_list args;
115*cfb92d14SAndroid Build Coastguard Worker 
116*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aFormat);
117*cfb92d14SAndroid Build Coastguard Worker     len = vsnprintf(aDest, static_cast<size_t>(aSize), aFormat, args);
118*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
119*cfb92d14SAndroid Build Coastguard Worker 
120*cfb92d14SAndroid Build Coastguard Worker     return (len < 0) ? 0 : Min(static_cast<uint32_t>(len), aSize - 1);
121*cfb92d14SAndroid Build Coastguard Worker }
122*cfb92d14SAndroid Build Coastguard Worker 
LogSpinelFrame(const uint8_t * aFrame,uint16_t aLength,bool aTx)123*cfb92d14SAndroid Build Coastguard Worker void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
124*cfb92d14SAndroid Build Coastguard Worker {
125*cfb92d14SAndroid Build Coastguard Worker     otError           error                                   = OT_ERROR_NONE;
126*cfb92d14SAndroid Build Coastguard Worker     char              buf[OPENTHREAD_LIB_SPINEL_LOG_MAX_SIZE] = {0};
127*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t    unpacked;
128*cfb92d14SAndroid Build Coastguard Worker     uint8_t           header;
129*cfb92d14SAndroid Build Coastguard Worker     uint32_t          cmd;
130*cfb92d14SAndroid Build Coastguard Worker     spinel_prop_key_t key;
131*cfb92d14SAndroid Build Coastguard Worker     uint8_t          *data;
132*cfb92d14SAndroid Build Coastguard Worker     spinel_size_t     len;
133*cfb92d14SAndroid Build Coastguard Worker     const char       *prefix = nullptr;
134*cfb92d14SAndroid Build Coastguard Worker     char             *start  = buf;
135*cfb92d14SAndroid Build Coastguard Worker     char             *end    = buf + sizeof(buf);
136*cfb92d14SAndroid Build Coastguard Worker 
137*cfb92d14SAndroid Build Coastguard Worker     EXPECT(otLoggingGetLevel() >= OT_LOG_LEVEL_DEBG, NO_ACTION);
138*cfb92d14SAndroid Build Coastguard Worker 
139*cfb92d14SAndroid Build Coastguard Worker     prefix   = aTx ? "Sent spinel frame" : "Received spinel frame";
140*cfb92d14SAndroid Build Coastguard Worker     unpacked = spinel_datatype_unpack(aFrame, aLength, "CiiD", &header, &cmd, &key, &data, &len);
141*cfb92d14SAndroid Build Coastguard Worker     EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
142*cfb92d14SAndroid Build Coastguard Worker 
143*cfb92d14SAndroid Build Coastguard Worker     start += Snprintf(start, static_cast<uint32_t>(end - start), "%s, flg:0x%x, iid:%d, tid:%u, cmd:%s", prefix,
144*cfb92d14SAndroid Build Coastguard Worker                       SPINEL_HEADER_GET_FLAG(header), SPINEL_HEADER_GET_IID(header), SPINEL_HEADER_GET_TID(header),
145*cfb92d14SAndroid Build Coastguard Worker                       spinel_command_to_cstr(cmd));
146*cfb92d14SAndroid Build Coastguard Worker     EXPECT(cmd != SPINEL_CMD_RESET, NO_ACTION);
147*cfb92d14SAndroid Build Coastguard Worker 
148*cfb92d14SAndroid Build Coastguard Worker     start += Snprintf(start, static_cast<uint32_t>(end - start), ", key:%s", spinel_prop_key_to_cstr(key));
149*cfb92d14SAndroid Build Coastguard Worker     EXPECT(cmd != SPINEL_CMD_PROP_VALUE_GET, NO_ACTION);
150*cfb92d14SAndroid Build Coastguard Worker 
151*cfb92d14SAndroid Build Coastguard Worker     switch (key)
152*cfb92d14SAndroid Build Coastguard Worker     {
153*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_LAST_STATUS:
154*cfb92d14SAndroid Build Coastguard Worker     {
155*cfb92d14SAndroid Build Coastguard Worker         spinel_status_t status;
156*cfb92d14SAndroid Build Coastguard Worker 
157*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT_PACKED_S, &status);
158*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
159*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", status:%s", spinel_status_to_cstr(status));
160*cfb92d14SAndroid Build Coastguard Worker     }
161*cfb92d14SAndroid Build Coastguard Worker     break;
162*cfb92d14SAndroid Build Coastguard Worker 
163*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_RAW_STREAM_ENABLED:
164*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_SRC_MATCH_ENABLED:
165*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_ENABLED:
166*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RADIO_COEX_ENABLE:
167*cfb92d14SAndroid Build Coastguard Worker     {
168*cfb92d14SAndroid Build Coastguard Worker         bool enabled;
169*cfb92d14SAndroid Build Coastguard Worker 
170*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_BOOL_S, &enabled);
171*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
172*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", enabled:%u", enabled);
173*cfb92d14SAndroid Build Coastguard Worker     }
174*cfb92d14SAndroid Build Coastguard Worker     break;
175*cfb92d14SAndroid Build Coastguard Worker 
176*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_CCA_THRESHOLD:
177*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_FEM_LNA_GAIN:
178*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_RX_SENSITIVITY:
179*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_RSSI:
180*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_TX_POWER:
181*cfb92d14SAndroid Build Coastguard Worker     {
182*cfb92d14SAndroid Build Coastguard Worker         const char *name = nullptr;
183*cfb92d14SAndroid Build Coastguard Worker         int8_t      value;
184*cfb92d14SAndroid Build Coastguard Worker 
185*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_INT8_S, &value);
186*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
187*cfb92d14SAndroid Build Coastguard Worker 
188*cfb92d14SAndroid Build Coastguard Worker         switch (key)
189*cfb92d14SAndroid Build Coastguard Worker         {
190*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_TX_POWER:
191*cfb92d14SAndroid Build Coastguard Worker             name = "power";
192*cfb92d14SAndroid Build Coastguard Worker             break;
193*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_CCA_THRESHOLD:
194*cfb92d14SAndroid Build Coastguard Worker             name = "threshold";
195*cfb92d14SAndroid Build Coastguard Worker             break;
196*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_FEM_LNA_GAIN:
197*cfb92d14SAndroid Build Coastguard Worker             name = "gain";
198*cfb92d14SAndroid Build Coastguard Worker             break;
199*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_RX_SENSITIVITY:
200*cfb92d14SAndroid Build Coastguard Worker             name = "sensitivity";
201*cfb92d14SAndroid Build Coastguard Worker             break;
202*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_RSSI:
203*cfb92d14SAndroid Build Coastguard Worker             name = "rssi";
204*cfb92d14SAndroid Build Coastguard Worker             break;
205*cfb92d14SAndroid Build Coastguard Worker         }
206*cfb92d14SAndroid Build Coastguard Worker 
207*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s:%d", name, value);
208*cfb92d14SAndroid Build Coastguard Worker     }
209*cfb92d14SAndroid Build Coastguard Worker     break;
210*cfb92d14SAndroid Build Coastguard Worker 
211*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_PROMISCUOUS_MODE:
212*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_SCAN_STATE:
213*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_CHAN:
214*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_CSL_ACCURACY:
215*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_CSL_UNCERTAINTY:
216*cfb92d14SAndroid Build Coastguard Worker     {
217*cfb92d14SAndroid Build Coastguard Worker         const char *name = nullptr;
218*cfb92d14SAndroid Build Coastguard Worker         uint8_t     value;
219*cfb92d14SAndroid Build Coastguard Worker 
220*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT8_S, &value);
221*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
222*cfb92d14SAndroid Build Coastguard Worker 
223*cfb92d14SAndroid Build Coastguard Worker         switch (key)
224*cfb92d14SAndroid Build Coastguard Worker         {
225*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_MAC_SCAN_STATE:
226*cfb92d14SAndroid Build Coastguard Worker             name = "state";
227*cfb92d14SAndroid Build Coastguard Worker             break;
228*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_RCP_CSL_ACCURACY:
229*cfb92d14SAndroid Build Coastguard Worker             name = "accuracy";
230*cfb92d14SAndroid Build Coastguard Worker             break;
231*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_RCP_CSL_UNCERTAINTY:
232*cfb92d14SAndroid Build Coastguard Worker             name = "uncertainty";
233*cfb92d14SAndroid Build Coastguard Worker             break;
234*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_MAC_PROMISCUOUS_MODE:
235*cfb92d14SAndroid Build Coastguard Worker             name = "mode";
236*cfb92d14SAndroid Build Coastguard Worker             break;
237*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_CHAN:
238*cfb92d14SAndroid Build Coastguard Worker             name = "channel";
239*cfb92d14SAndroid Build Coastguard Worker             break;
240*cfb92d14SAndroid Build Coastguard Worker         }
241*cfb92d14SAndroid Build Coastguard Worker 
242*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s:%u", name, value);
243*cfb92d14SAndroid Build Coastguard Worker     }
244*cfb92d14SAndroid Build Coastguard Worker     break;
245*cfb92d14SAndroid Build Coastguard Worker 
246*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_15_4_PANID:
247*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_15_4_SADDR:
248*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_SCAN_PERIOD:
249*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_REGION_CODE:
250*cfb92d14SAndroid Build Coastguard Worker     {
251*cfb92d14SAndroid Build Coastguard Worker         const char *name = nullptr;
252*cfb92d14SAndroid Build Coastguard Worker         uint16_t    value;
253*cfb92d14SAndroid Build Coastguard Worker 
254*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT16_S, &value);
255*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
256*cfb92d14SAndroid Build Coastguard Worker 
257*cfb92d14SAndroid Build Coastguard Worker         switch (key)
258*cfb92d14SAndroid Build Coastguard Worker         {
259*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_MAC_SCAN_PERIOD:
260*cfb92d14SAndroid Build Coastguard Worker             name = "period";
261*cfb92d14SAndroid Build Coastguard Worker             break;
262*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_PHY_REGION_CODE:
263*cfb92d14SAndroid Build Coastguard Worker             name = "region";
264*cfb92d14SAndroid Build Coastguard Worker             break;
265*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_MAC_15_4_SADDR:
266*cfb92d14SAndroid Build Coastguard Worker             name = "saddr";
267*cfb92d14SAndroid Build Coastguard Worker             break;
268*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES:
269*cfb92d14SAndroid Build Coastguard Worker             name = "saddr";
270*cfb92d14SAndroid Build Coastguard Worker             break;
271*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_MAC_15_4_PANID:
272*cfb92d14SAndroid Build Coastguard Worker             name = "panid";
273*cfb92d14SAndroid Build Coastguard Worker             break;
274*cfb92d14SAndroid Build Coastguard Worker         }
275*cfb92d14SAndroid Build Coastguard Worker 
276*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s:0x%04x", name, value);
277*cfb92d14SAndroid Build Coastguard Worker     }
278*cfb92d14SAndroid Build Coastguard Worker     break;
279*cfb92d14SAndroid Build Coastguard Worker 
280*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES:
281*cfb92d14SAndroid Build Coastguard Worker     {
282*cfb92d14SAndroid Build Coastguard Worker         uint16_t saddr;
283*cfb92d14SAndroid Build Coastguard Worker 
284*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", saddr:");
285*cfb92d14SAndroid Build Coastguard Worker 
286*cfb92d14SAndroid Build Coastguard Worker         if (len < sizeof(saddr))
287*cfb92d14SAndroid Build Coastguard Worker         {
288*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start), "none");
289*cfb92d14SAndroid Build Coastguard Worker         }
290*cfb92d14SAndroid Build Coastguard Worker         else
291*cfb92d14SAndroid Build Coastguard Worker         {
292*cfb92d14SAndroid Build Coastguard Worker             while (len >= sizeof(saddr))
293*cfb92d14SAndroid Build Coastguard Worker             {
294*cfb92d14SAndroid Build Coastguard Worker                 unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT16_S, &saddr);
295*cfb92d14SAndroid Build Coastguard Worker                 EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
296*cfb92d14SAndroid Build Coastguard Worker                 data += unpacked;
297*cfb92d14SAndroid Build Coastguard Worker                 len -= static_cast<spinel_size_t>(unpacked);
298*cfb92d14SAndroid Build Coastguard Worker                 start += Snprintf(start, static_cast<uint32_t>(end - start), "0x%04x ", saddr);
299*cfb92d14SAndroid Build Coastguard Worker             }
300*cfb92d14SAndroid Build Coastguard Worker         }
301*cfb92d14SAndroid Build Coastguard Worker     }
302*cfb92d14SAndroid Build Coastguard Worker     break;
303*cfb92d14SAndroid Build Coastguard Worker 
304*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_MAC_FRAME_COUNTER:
305*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_TIMESTAMP:
306*cfb92d14SAndroid Build Coastguard Worker     {
307*cfb92d14SAndroid Build Coastguard Worker         const char *name;
308*cfb92d14SAndroid Build Coastguard Worker         uint32_t    value;
309*cfb92d14SAndroid Build Coastguard Worker 
310*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT32_S, &value);
311*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
312*cfb92d14SAndroid Build Coastguard Worker 
313*cfb92d14SAndroid Build Coastguard Worker         name = (key == SPINEL_PROP_RCP_TIMESTAMP) ? "timestamp" : "counter";
314*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s:%u", name, value);
315*cfb92d14SAndroid Build Coastguard Worker     }
316*cfb92d14SAndroid Build Coastguard Worker     break;
317*cfb92d14SAndroid Build Coastguard Worker 
318*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RADIO_CAPS:
319*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_API_VERSION:
320*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_MIN_HOST_API_VERSION:
321*cfb92d14SAndroid Build Coastguard Worker     {
322*cfb92d14SAndroid Build Coastguard Worker         const char  *name;
323*cfb92d14SAndroid Build Coastguard Worker         unsigned int value;
324*cfb92d14SAndroid Build Coastguard Worker 
325*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT_PACKED_S, &value);
326*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
327*cfb92d14SAndroid Build Coastguard Worker 
328*cfb92d14SAndroid Build Coastguard Worker         switch (key)
329*cfb92d14SAndroid Build Coastguard Worker         {
330*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_RADIO_CAPS:
331*cfb92d14SAndroid Build Coastguard Worker             name = "caps";
332*cfb92d14SAndroid Build Coastguard Worker             break;
333*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_RCP_API_VERSION:
334*cfb92d14SAndroid Build Coastguard Worker             name = "version";
335*cfb92d14SAndroid Build Coastguard Worker             break;
336*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_PROP_RCP_MIN_HOST_API_VERSION:
337*cfb92d14SAndroid Build Coastguard Worker             name = "min-host-version";
338*cfb92d14SAndroid Build Coastguard Worker             break;
339*cfb92d14SAndroid Build Coastguard Worker         default:
340*cfb92d14SAndroid Build Coastguard Worker             name = "";
341*cfb92d14SAndroid Build Coastguard Worker             break;
342*cfb92d14SAndroid Build Coastguard Worker         }
343*cfb92d14SAndroid Build Coastguard Worker 
344*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s:%u", name, value);
345*cfb92d14SAndroid Build Coastguard Worker     }
346*cfb92d14SAndroid Build Coastguard Worker     break;
347*cfb92d14SAndroid Build Coastguard Worker 
348*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_LOG_CRASH_DUMP:
349*cfb92d14SAndroid Build Coastguard Worker     {
350*cfb92d14SAndroid Build Coastguard Worker         const char *name;
351*cfb92d14SAndroid Build Coastguard Worker         name = "log-crash-dump";
352*cfb92d14SAndroid Build Coastguard Worker 
353*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s", name);
354*cfb92d14SAndroid Build Coastguard Worker     }
355*cfb92d14SAndroid Build Coastguard Worker     break;
356*cfb92d14SAndroid Build Coastguard Worker 
357*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_ENERGY_SCAN_RESULT:
358*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_CHAN_MAX_POWER:
359*cfb92d14SAndroid Build Coastguard Worker     {
360*cfb92d14SAndroid Build Coastguard Worker         const char *name;
361*cfb92d14SAndroid Build Coastguard Worker         uint8_t     channel;
362*cfb92d14SAndroid Build Coastguard Worker         int8_t      value;
363*cfb92d14SAndroid Build Coastguard Worker 
364*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_INT8_S, &channel, &value);
365*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
366*cfb92d14SAndroid Build Coastguard Worker 
367*cfb92d14SAndroid Build Coastguard Worker         name = (key == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT) ? "rssi" : "power";
368*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", channel:%u, %s:%d", channel, name, value);
369*cfb92d14SAndroid Build Coastguard Worker     }
370*cfb92d14SAndroid Build Coastguard Worker     break;
371*cfb92d14SAndroid Build Coastguard Worker 
372*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_CAPS:
373*cfb92d14SAndroid Build Coastguard Worker     {
374*cfb92d14SAndroid Build Coastguard Worker         unsigned int capability;
375*cfb92d14SAndroid Build Coastguard Worker 
376*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", caps:");
377*cfb92d14SAndroid Build Coastguard Worker 
378*cfb92d14SAndroid Build Coastguard Worker         while (len > 0)
379*cfb92d14SAndroid Build Coastguard Worker         {
380*cfb92d14SAndroid Build Coastguard Worker             unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT_PACKED_S, &capability);
381*cfb92d14SAndroid Build Coastguard Worker             EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
382*cfb92d14SAndroid Build Coastguard Worker             data += unpacked;
383*cfb92d14SAndroid Build Coastguard Worker             len -= static_cast<spinel_size_t>(unpacked);
384*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start), "%s ", spinel_capability_to_cstr(capability));
385*cfb92d14SAndroid Build Coastguard Worker         }
386*cfb92d14SAndroid Build Coastguard Worker     }
387*cfb92d14SAndroid Build Coastguard Worker     break;
388*cfb92d14SAndroid Build Coastguard Worker 
389*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PROTOCOL_VERSION:
390*cfb92d14SAndroid Build Coastguard Worker     {
391*cfb92d14SAndroid Build Coastguard Worker         unsigned int major;
392*cfb92d14SAndroid Build Coastguard Worker         unsigned int minor;
393*cfb92d14SAndroid Build Coastguard Worker 
394*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT_PACKED_S SPINEL_DATATYPE_UINT_PACKED_S,
395*cfb92d14SAndroid Build Coastguard Worker                                           &major, &minor);
396*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
397*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", major:%u, minor:%u", major, minor);
398*cfb92d14SAndroid Build Coastguard Worker     }
399*cfb92d14SAndroid Build Coastguard Worker     break;
400*cfb92d14SAndroid Build Coastguard Worker 
401*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_CHAN_PREFERRED:
402*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_CHAN_SUPPORTED:
403*cfb92d14SAndroid Build Coastguard Worker     {
404*cfb92d14SAndroid Build Coastguard Worker         uint8_t        maskBuffer[kChannelMaskBufferSize];
405*cfb92d14SAndroid Build Coastguard Worker         uint32_t       channelMask = 0;
406*cfb92d14SAndroid Build Coastguard Worker         const uint8_t *maskData    = maskBuffer;
407*cfb92d14SAndroid Build Coastguard Worker         spinel_size_t  maskLength  = sizeof(maskBuffer);
408*cfb92d14SAndroid Build Coastguard Worker 
409*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack_in_place(data, len, SPINEL_DATATYPE_DATA_S, maskBuffer, &maskLength);
410*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
411*cfb92d14SAndroid Build Coastguard Worker 
412*cfb92d14SAndroid Build Coastguard Worker         while (maskLength > 0)
413*cfb92d14SAndroid Build Coastguard Worker         {
414*cfb92d14SAndroid Build Coastguard Worker             uint8_t channel;
415*cfb92d14SAndroid Build Coastguard Worker 
416*cfb92d14SAndroid Build Coastguard Worker             unpacked = spinel_datatype_unpack(maskData, maskLength, SPINEL_DATATYPE_UINT8_S, &channel);
417*cfb92d14SAndroid Build Coastguard Worker             EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
418*cfb92d14SAndroid Build Coastguard Worker             EXPECT(channel < kChannelMaskBufferSize, error = OT_ERROR_PARSE);
419*cfb92d14SAndroid Build Coastguard Worker             channelMask |= (1UL << channel);
420*cfb92d14SAndroid Build Coastguard Worker 
421*cfb92d14SAndroid Build Coastguard Worker             maskData += unpacked;
422*cfb92d14SAndroid Build Coastguard Worker             maskLength -= static_cast<spinel_size_t>(unpacked);
423*cfb92d14SAndroid Build Coastguard Worker         }
424*cfb92d14SAndroid Build Coastguard Worker 
425*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", channelMask:0x%08x", channelMask);
426*cfb92d14SAndroid Build Coastguard Worker     }
427*cfb92d14SAndroid Build Coastguard Worker     break;
428*cfb92d14SAndroid Build Coastguard Worker 
429*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_NCP_VERSION:
430*cfb92d14SAndroid Build Coastguard Worker     {
431*cfb92d14SAndroid Build Coastguard Worker         const char *version;
432*cfb92d14SAndroid Build Coastguard Worker 
433*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UTF8_S, &version);
434*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked >= 0, error = OT_ERROR_PARSE);
435*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", version:%s", version);
436*cfb92d14SAndroid Build Coastguard Worker     }
437*cfb92d14SAndroid Build Coastguard Worker     break;
438*cfb92d14SAndroid Build Coastguard Worker 
439*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_STREAM_RAW:
440*cfb92d14SAndroid Build Coastguard Worker     {
441*cfb92d14SAndroid Build Coastguard Worker         otRadioFrame frame;
442*cfb92d14SAndroid Build Coastguard Worker 
443*cfb92d14SAndroid Build Coastguard Worker         if (cmd == SPINEL_CMD_PROP_VALUE_IS)
444*cfb92d14SAndroid Build Coastguard Worker         {
445*cfb92d14SAndroid Build Coastguard Worker             uint16_t     flags;
446*cfb92d14SAndroid Build Coastguard Worker             int8_t       noiseFloor;
447*cfb92d14SAndroid Build Coastguard Worker             unsigned int receiveError;
448*cfb92d14SAndroid Build Coastguard Worker 
449*cfb92d14SAndroid Build Coastguard Worker             unpacked = spinel_datatype_unpack(data, len,
450*cfb92d14SAndroid Build Coastguard Worker                                               SPINEL_DATATYPE_DATA_WLEN_S                          // Frame
451*cfb92d14SAndroid Build Coastguard Worker                                                   SPINEL_DATATYPE_INT8_S                           // RSSI
452*cfb92d14SAndroid Build Coastguard Worker                                                       SPINEL_DATATYPE_INT8_S                       // Noise Floor
453*cfb92d14SAndroid Build Coastguard Worker                                                           SPINEL_DATATYPE_UINT16_S                 // Flags
454*cfb92d14SAndroid Build Coastguard Worker                                                               SPINEL_DATATYPE_STRUCT_S(            // PHY-data
455*cfb92d14SAndroid Build Coastguard Worker                                                                   SPINEL_DATATYPE_UINT8_S          // 802.15.4 channel
456*cfb92d14SAndroid Build Coastguard Worker                                                                       SPINEL_DATATYPE_UINT8_S      // 802.15.4 LQI
457*cfb92d14SAndroid Build Coastguard Worker                                                                           SPINEL_DATATYPE_UINT64_S // Timestamp (us).
458*cfb92d14SAndroid Build Coastguard Worker                                                                   ) SPINEL_DATATYPE_STRUCT_S(      // Vendor-data
459*cfb92d14SAndroid Build Coastguard Worker                                                                   SPINEL_DATATYPE_UINT_PACKED_S    // Receive error
460*cfb92d14SAndroid Build Coastguard Worker                                                                   ),
461*cfb92d14SAndroid Build Coastguard Worker                                               &frame.mPsdu, &frame.mLength, &frame.mInfo.mRxInfo.mRssi, &noiseFloor,
462*cfb92d14SAndroid Build Coastguard Worker                                               &flags, &frame.mChannel, &frame.mInfo.mRxInfo.mLqi,
463*cfb92d14SAndroid Build Coastguard Worker                                               &frame.mInfo.mRxInfo.mTimestamp, &receiveError);
464*cfb92d14SAndroid Build Coastguard Worker             EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
465*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start), ", len:%u, rssi:%d ...", frame.mLength,
466*cfb92d14SAndroid Build Coastguard Worker                               frame.mInfo.mRxInfo.mRssi);
467*cfb92d14SAndroid Build Coastguard Worker             OT_UNUSED_VARIABLE(start); // Avoid static analysis error
468*cfb92d14SAndroid Build Coastguard Worker             LogDebg("%s", buf);
469*cfb92d14SAndroid Build Coastguard Worker 
470*cfb92d14SAndroid Build Coastguard Worker             start = buf;
471*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start),
472*cfb92d14SAndroid Build Coastguard Worker                               "... noise:%d, flags:0x%04x, channel:%u, lqi:%u, timestamp:%lu, rxerr:%u", noiseFloor,
473*cfb92d14SAndroid Build Coastguard Worker                               flags, frame.mChannel, frame.mInfo.mRxInfo.mLqi,
474*cfb92d14SAndroid Build Coastguard Worker                               static_cast<unsigned long>(frame.mInfo.mRxInfo.mTimestamp), receiveError);
475*cfb92d14SAndroid Build Coastguard Worker         }
476*cfb92d14SAndroid Build Coastguard Worker         else if (cmd == SPINEL_CMD_PROP_VALUE_SET)
477*cfb92d14SAndroid Build Coastguard Worker         {
478*cfb92d14SAndroid Build Coastguard Worker             bool csmaCaEnabled;
479*cfb92d14SAndroid Build Coastguard Worker             bool isHeaderUpdated;
480*cfb92d14SAndroid Build Coastguard Worker             bool isARetx;
481*cfb92d14SAndroid Build Coastguard Worker             bool skipAes;
482*cfb92d14SAndroid Build Coastguard Worker 
483*cfb92d14SAndroid Build Coastguard Worker             unpacked = spinel_datatype_unpack(
484*cfb92d14SAndroid Build Coastguard Worker                 data, len,
485*cfb92d14SAndroid Build Coastguard Worker                 SPINEL_DATATYPE_DATA_WLEN_S                                   // Frame data
486*cfb92d14SAndroid Build Coastguard Worker                     SPINEL_DATATYPE_UINT8_S                                   // Channel
487*cfb92d14SAndroid Build Coastguard Worker                         SPINEL_DATATYPE_UINT8_S                               // MaxCsmaBackoffs
488*cfb92d14SAndroid Build Coastguard Worker                             SPINEL_DATATYPE_UINT8_S                           // MaxFrameRetries
489*cfb92d14SAndroid Build Coastguard Worker                                 SPINEL_DATATYPE_BOOL_S                        // CsmaCaEnabled
490*cfb92d14SAndroid Build Coastguard Worker                                     SPINEL_DATATYPE_BOOL_S                    // IsHeaderUpdated
491*cfb92d14SAndroid Build Coastguard Worker                                         SPINEL_DATATYPE_BOOL_S                // IsARetx
492*cfb92d14SAndroid Build Coastguard Worker                                             SPINEL_DATATYPE_BOOL_S            // SkipAes
493*cfb92d14SAndroid Build Coastguard Worker                                                 SPINEL_DATATYPE_UINT32_S      // TxDelay
494*cfb92d14SAndroid Build Coastguard Worker                                                     SPINEL_DATATYPE_UINT32_S, // TxDelayBaseTime
495*cfb92d14SAndroid Build Coastguard Worker                 &frame.mPsdu, &frame.mLength, &frame.mChannel, &frame.mInfo.mTxInfo.mMaxCsmaBackoffs,
496*cfb92d14SAndroid Build Coastguard Worker                 &frame.mInfo.mTxInfo.mMaxFrameRetries, &csmaCaEnabled, &isHeaderUpdated, &isARetx, &skipAes,
497*cfb92d14SAndroid Build Coastguard Worker                 &frame.mInfo.mTxInfo.mTxDelay, &frame.mInfo.mTxInfo.mTxDelayBaseTime);
498*cfb92d14SAndroid Build Coastguard Worker 
499*cfb92d14SAndroid Build Coastguard Worker             EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
500*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start),
501*cfb92d14SAndroid Build Coastguard Worker                               ", len:%u, channel:%u, maxbackoffs:%u, maxretries:%u ...", frame.mLength, frame.mChannel,
502*cfb92d14SAndroid Build Coastguard Worker                               frame.mInfo.mTxInfo.mMaxCsmaBackoffs, frame.mInfo.mTxInfo.mMaxFrameRetries);
503*cfb92d14SAndroid Build Coastguard Worker             OT_UNUSED_VARIABLE(start); // Avoid static analysis error
504*cfb92d14SAndroid Build Coastguard Worker             LogDebg("%s", buf);
505*cfb92d14SAndroid Build Coastguard Worker 
506*cfb92d14SAndroid Build Coastguard Worker             start = buf;
507*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start),
508*cfb92d14SAndroid Build Coastguard Worker                               "... csmaCaEnabled:%u, isHeaderUpdated:%u, isARetx:%u, skipAes:%u"
509*cfb92d14SAndroid Build Coastguard Worker                               ", txDelay:%u, txDelayBase:%u",
510*cfb92d14SAndroid Build Coastguard Worker                               csmaCaEnabled, isHeaderUpdated, isARetx, skipAes, frame.mInfo.mTxInfo.mTxDelay,
511*cfb92d14SAndroid Build Coastguard Worker                               frame.mInfo.mTxInfo.mTxDelayBaseTime);
512*cfb92d14SAndroid Build Coastguard Worker         }
513*cfb92d14SAndroid Build Coastguard Worker     }
514*cfb92d14SAndroid Build Coastguard Worker     break;
515*cfb92d14SAndroid Build Coastguard Worker 
516*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_STREAM_DEBUG:
517*cfb92d14SAndroid Build Coastguard Worker     {
518*cfb92d14SAndroid Build Coastguard Worker         char          debugString[OPENTHREAD_LIB_SPINEL_NCP_LOG_MAX_SIZE + 1];
519*cfb92d14SAndroid Build Coastguard Worker         spinel_size_t stringLength = sizeof(debugString);
520*cfb92d14SAndroid Build Coastguard Worker 
521*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack_in_place(data, len, SPINEL_DATATYPE_DATA_S, debugString, &stringLength);
522*cfb92d14SAndroid Build Coastguard Worker         assert(stringLength < sizeof(debugString));
523*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
524*cfb92d14SAndroid Build Coastguard Worker         debugString[stringLength] = '\0';
525*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", debug:%s", debugString);
526*cfb92d14SAndroid Build Coastguard Worker     }
527*cfb92d14SAndroid Build Coastguard Worker     break;
528*cfb92d14SAndroid Build Coastguard Worker 
529*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_STREAM_LOG:
530*cfb92d14SAndroid Build Coastguard Worker     {
531*cfb92d14SAndroid Build Coastguard Worker         const char *logString;
532*cfb92d14SAndroid Build Coastguard Worker         uint8_t     logLevel;
533*cfb92d14SAndroid Build Coastguard Worker 
534*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UTF8_S, &logString);
535*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked >= 0, error = OT_ERROR_PARSE);
536*cfb92d14SAndroid Build Coastguard Worker         data += unpacked;
537*cfb92d14SAndroid Build Coastguard Worker         len -= static_cast<spinel_size_t>(unpacked);
538*cfb92d14SAndroid Build Coastguard Worker 
539*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT8_S, &logLevel);
540*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
541*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", level:%u, log:%s", logLevel, logString);
542*cfb92d14SAndroid Build Coastguard Worker     }
543*cfb92d14SAndroid Build Coastguard Worker     break;
544*cfb92d14SAndroid Build Coastguard Worker 
545*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_NEST_STREAM_MFG:
546*cfb92d14SAndroid Build Coastguard Worker     {
547*cfb92d14SAndroid Build Coastguard Worker         const char *output;
548*cfb92d14SAndroid Build Coastguard Worker         size_t      outputLen;
549*cfb92d14SAndroid Build Coastguard Worker 
550*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UTF8_S, &output, &outputLen);
551*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
552*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", diag:%s", output);
553*cfb92d14SAndroid Build Coastguard Worker     }
554*cfb92d14SAndroid Build Coastguard Worker     break;
555*cfb92d14SAndroid Build Coastguard Worker 
556*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_MAC_KEY:
557*cfb92d14SAndroid Build Coastguard Worker     {
558*cfb92d14SAndroid Build Coastguard Worker         uint8_t      keyIdMode;
559*cfb92d14SAndroid Build Coastguard Worker         uint8_t      keyId;
560*cfb92d14SAndroid Build Coastguard Worker         otMacKey     prevKey;
561*cfb92d14SAndroid Build Coastguard Worker         unsigned int prevKeyLen = sizeof(otMacKey);
562*cfb92d14SAndroid Build Coastguard Worker         otMacKey     currKey;
563*cfb92d14SAndroid Build Coastguard Worker         unsigned int currKeyLen = sizeof(otMacKey);
564*cfb92d14SAndroid Build Coastguard Worker         otMacKey     nextKey;
565*cfb92d14SAndroid Build Coastguard Worker         unsigned int nextKeyLen = sizeof(otMacKey);
566*cfb92d14SAndroid Build Coastguard Worker 
567*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len,
568*cfb92d14SAndroid Build Coastguard Worker                                           SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_DATA_WLEN_S
569*cfb92d14SAndroid Build Coastguard Worker                                               SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_DATA_WLEN_S,
570*cfb92d14SAndroid Build Coastguard Worker                                           &keyIdMode, &keyId, prevKey.m8, &prevKeyLen, currKey.m8, &currKeyLen,
571*cfb92d14SAndroid Build Coastguard Worker                                           nextKey.m8, &nextKeyLen);
572*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
573*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start),
574*cfb92d14SAndroid Build Coastguard Worker                           ", keyIdMode:%u, keyId:%u, prevKey:***, currKey:***, nextKey:***", keyIdMode, keyId);
575*cfb92d14SAndroid Build Coastguard Worker     }
576*cfb92d14SAndroid Build Coastguard Worker     break;
577*cfb92d14SAndroid Build Coastguard Worker 
578*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_HWADDR:
579*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_15_4_LADDR:
580*cfb92d14SAndroid Build Coastguard Worker     {
581*cfb92d14SAndroid Build Coastguard Worker         const char *name                    = nullptr;
582*cfb92d14SAndroid Build Coastguard Worker         uint8_t     m8[OT_EXT_ADDRESS_SIZE] = {0};
583*cfb92d14SAndroid Build Coastguard Worker 
584*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack_in_place(data, len, SPINEL_DATATYPE_EUI64_S, &m8[0]);
585*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
586*cfb92d14SAndroid Build Coastguard Worker 
587*cfb92d14SAndroid Build Coastguard Worker         name = (key == SPINEL_PROP_HWADDR) ? "eui64" : "laddr";
588*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s:%02x%02x%02x%02x%02x%02x%02x%02x", name,
589*cfb92d14SAndroid Build Coastguard Worker                           m8[0], m8[1], m8[2], m8[3], m8[4], m8[5], m8[6], m8[7]);
590*cfb92d14SAndroid Build Coastguard Worker     }
591*cfb92d14SAndroid Build Coastguard Worker     break;
592*cfb92d14SAndroid Build Coastguard Worker 
593*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES:
594*cfb92d14SAndroid Build Coastguard Worker     {
595*cfb92d14SAndroid Build Coastguard Worker         uint8_t m8[OT_EXT_ADDRESS_SIZE];
596*cfb92d14SAndroid Build Coastguard Worker 
597*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", extaddr:");
598*cfb92d14SAndroid Build Coastguard Worker 
599*cfb92d14SAndroid Build Coastguard Worker         if (len < sizeof(m8))
600*cfb92d14SAndroid Build Coastguard Worker         {
601*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start), "none");
602*cfb92d14SAndroid Build Coastguard Worker         }
603*cfb92d14SAndroid Build Coastguard Worker         else
604*cfb92d14SAndroid Build Coastguard Worker         {
605*cfb92d14SAndroid Build Coastguard Worker             while (len >= sizeof(m8))
606*cfb92d14SAndroid Build Coastguard Worker             {
607*cfb92d14SAndroid Build Coastguard Worker                 unpacked = spinel_datatype_unpack_in_place(data, len, SPINEL_DATATYPE_EUI64_S, m8);
608*cfb92d14SAndroid Build Coastguard Worker                 EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
609*cfb92d14SAndroid Build Coastguard Worker                 data += unpacked;
610*cfb92d14SAndroid Build Coastguard Worker                 len -= static_cast<spinel_size_t>(unpacked);
611*cfb92d14SAndroid Build Coastguard Worker                 start += Snprintf(start, static_cast<uint32_t>(end - start), "%02x%02x%02x%02x%02x%02x%02x%02x ", m8[0],
612*cfb92d14SAndroid Build Coastguard Worker                                   m8[1], m8[2], m8[3], m8[4], m8[5], m8[6], m8[7]);
613*cfb92d14SAndroid Build Coastguard Worker             }
614*cfb92d14SAndroid Build Coastguard Worker         }
615*cfb92d14SAndroid Build Coastguard Worker     }
616*cfb92d14SAndroid Build Coastguard Worker     break;
617*cfb92d14SAndroid Build Coastguard Worker 
618*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RADIO_COEX_METRICS:
619*cfb92d14SAndroid Build Coastguard Worker     {
620*cfb92d14SAndroid Build Coastguard Worker         otRadioCoexMetrics metrics;
621*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(
622*cfb92d14SAndroid Build Coastguard Worker             data, len,
623*cfb92d14SAndroid Build Coastguard Worker             SPINEL_DATATYPE_STRUCT_S(                                    // Tx Coex Metrics Structure
624*cfb92d14SAndroid Build Coastguard Worker                 SPINEL_DATATYPE_UINT32_S                                 // NumTxRequest
625*cfb92d14SAndroid Build Coastguard Worker                     SPINEL_DATATYPE_UINT32_S                             // NumTxGrantImmediate
626*cfb92d14SAndroid Build Coastguard Worker                         SPINEL_DATATYPE_UINT32_S                         // NumTxGrantWait
627*cfb92d14SAndroid Build Coastguard Worker                             SPINEL_DATATYPE_UINT32_S                     // NumTxGrantWaitActivated
628*cfb92d14SAndroid Build Coastguard Worker                                 SPINEL_DATATYPE_UINT32_S                 // NumTxGrantWaitTimeout
629*cfb92d14SAndroid Build Coastguard Worker                                     SPINEL_DATATYPE_UINT32_S             // NumTxGrantDeactivatedDuringRequest
630*cfb92d14SAndroid Build Coastguard Worker                                         SPINEL_DATATYPE_UINT32_S         // NumTxDelayedGrant
631*cfb92d14SAndroid Build Coastguard Worker                                             SPINEL_DATATYPE_UINT32_S     // AvgTxRequestToGrantTime
632*cfb92d14SAndroid Build Coastguard Worker                 ) SPINEL_DATATYPE_STRUCT_S(                              // Rx Coex Metrics Structure
633*cfb92d14SAndroid Build Coastguard Worker                 SPINEL_DATATYPE_UINT32_S                                 // NumRxRequest
634*cfb92d14SAndroid Build Coastguard Worker                     SPINEL_DATATYPE_UINT32_S                             // NumRxGrantImmediate
635*cfb92d14SAndroid Build Coastguard Worker                         SPINEL_DATATYPE_UINT32_S                         // NumRxGrantWait
636*cfb92d14SAndroid Build Coastguard Worker                             SPINEL_DATATYPE_UINT32_S                     // NumRxGrantWaitActivated
637*cfb92d14SAndroid Build Coastguard Worker                                 SPINEL_DATATYPE_UINT32_S                 // NumRxGrantWaitTimeout
638*cfb92d14SAndroid Build Coastguard Worker                                     SPINEL_DATATYPE_UINT32_S             // NumRxGrantDeactivatedDuringRequest
639*cfb92d14SAndroid Build Coastguard Worker                                         SPINEL_DATATYPE_UINT32_S         // NumRxDelayedGrant
640*cfb92d14SAndroid Build Coastguard Worker                                             SPINEL_DATATYPE_UINT32_S     // AvgRxRequestToGrantTime
641*cfb92d14SAndroid Build Coastguard Worker                                                 SPINEL_DATATYPE_UINT32_S // NumRxGrantNone
642*cfb92d14SAndroid Build Coastguard Worker                 ) SPINEL_DATATYPE_BOOL_S                                 // Stopped
643*cfb92d14SAndroid Build Coastguard Worker                 SPINEL_DATATYPE_UINT32_S,                                // NumGrantGlitch
644*cfb92d14SAndroid Build Coastguard Worker             &metrics.mNumTxRequest, &metrics.mNumTxGrantImmediate, &metrics.mNumTxGrantWait,
645*cfb92d14SAndroid Build Coastguard Worker             &metrics.mNumTxGrantWaitActivated, &metrics.mNumTxGrantWaitTimeout,
646*cfb92d14SAndroid Build Coastguard Worker             &metrics.mNumTxGrantDeactivatedDuringRequest, &metrics.mNumTxDelayedGrant,
647*cfb92d14SAndroid Build Coastguard Worker             &metrics.mAvgTxRequestToGrantTime, &metrics.mNumRxRequest, &metrics.mNumRxGrantImmediate,
648*cfb92d14SAndroid Build Coastguard Worker             &metrics.mNumRxGrantWait, &metrics.mNumRxGrantWaitActivated, &metrics.mNumRxGrantWaitTimeout,
649*cfb92d14SAndroid Build Coastguard Worker             &metrics.mNumRxGrantDeactivatedDuringRequest, &metrics.mNumRxDelayedGrant,
650*cfb92d14SAndroid Build Coastguard Worker             &metrics.mAvgRxRequestToGrantTime, &metrics.mNumRxGrantNone, &metrics.mStopped, &metrics.mNumGrantGlitch);
651*cfb92d14SAndroid Build Coastguard Worker 
652*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
653*cfb92d14SAndroid Build Coastguard Worker 
654*cfb92d14SAndroid Build Coastguard Worker         LogDebg("%s ...", buf);
655*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" txRequest:%lu", ToUlong(metrics.mNumTxRequest));
656*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" txGrantImmediate:%lu", ToUlong(metrics.mNumTxGrantImmediate));
657*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" txGrantWait:%lu", ToUlong(metrics.mNumTxGrantWait));
658*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" txGrantWaitActivated:%lu", ToUlong(metrics.mNumTxGrantWaitActivated));
659*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" txGrantWaitTimeout:%lu", ToUlong(metrics.mNumTxGrantWaitTimeout));
660*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" txGrantDeactivatedDuringRequest:%lu", ToUlong(metrics.mNumTxGrantDeactivatedDuringRequest));
661*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" txDelayedGrant:%lu", ToUlong(metrics.mNumTxDelayedGrant));
662*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" avgTxRequestToGrantTime:%lu", ToUlong(metrics.mAvgTxRequestToGrantTime));
663*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxRequest:%lu", ToUlong(metrics.mNumRxRequest));
664*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxGrantImmediate:%lu", ToUlong(metrics.mNumRxGrantImmediate));
665*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxGrantWait:%lu", ToUlong(metrics.mNumRxGrantWait));
666*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxGrantWaitActivated:%lu", ToUlong(metrics.mNumRxGrantWaitActivated));
667*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxGrantWaitTimeout:%lu", ToUlong(metrics.mNumRxGrantWaitTimeout));
668*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxGrantDeactivatedDuringRequest:%lu", ToUlong(metrics.mNumRxGrantDeactivatedDuringRequest));
669*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxDelayedGrant:%lu", ToUlong(metrics.mNumRxDelayedGrant));
670*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" avgRxRequestToGrantTime:%lu", ToUlong(metrics.mAvgRxRequestToGrantTime));
671*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" rxGrantNone:%lu", ToUlong(metrics.mNumRxGrantNone));
672*cfb92d14SAndroid Build Coastguard Worker         LogDebg(" stopped:%u", metrics.mStopped);
673*cfb92d14SAndroid Build Coastguard Worker 
674*cfb92d14SAndroid Build Coastguard Worker         start = buf;
675*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), " grantGlitch:%u", metrics.mNumGrantGlitch);
676*cfb92d14SAndroid Build Coastguard Worker     }
677*cfb92d14SAndroid Build Coastguard Worker     break;
678*cfb92d14SAndroid Build Coastguard Worker 
679*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_MAC_SCAN_MASK:
680*cfb92d14SAndroid Build Coastguard Worker     {
681*cfb92d14SAndroid Build Coastguard Worker         constexpr uint8_t kNumChannels = 16;
682*cfb92d14SAndroid Build Coastguard Worker         uint8_t           channels[kNumChannels];
683*cfb92d14SAndroid Build Coastguard Worker         spinel_size_t     size;
684*cfb92d14SAndroid Build Coastguard Worker 
685*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_DATA_S, channels, &size);
686*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
687*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", channels:");
688*cfb92d14SAndroid Build Coastguard Worker 
689*cfb92d14SAndroid Build Coastguard Worker         for (spinel_size_t i = 0; i < size; i++)
690*cfb92d14SAndroid Build Coastguard Worker         {
691*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start), "%u ", channels[i]);
692*cfb92d14SAndroid Build Coastguard Worker         }
693*cfb92d14SAndroid Build Coastguard Worker     }
694*cfb92d14SAndroid Build Coastguard Worker     break;
695*cfb92d14SAndroid Build Coastguard Worker 
696*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_RCP_ENH_ACK_PROBING:
697*cfb92d14SAndroid Build Coastguard Worker     {
698*cfb92d14SAndroid Build Coastguard Worker         uint16_t saddr;
699*cfb92d14SAndroid Build Coastguard Worker         uint8_t  m8[OT_EXT_ADDRESS_SIZE];
700*cfb92d14SAndroid Build Coastguard Worker         uint8_t  flags;
701*cfb92d14SAndroid Build Coastguard Worker 
702*cfb92d14SAndroid Build Coastguard Worker         unpacked = spinel_datatype_unpack(
703*cfb92d14SAndroid Build Coastguard Worker             data, len, SPINEL_DATATYPE_UINT16_S SPINEL_DATATYPE_EUI64_S SPINEL_DATATYPE_UINT8_S, &saddr, m8, &flags);
704*cfb92d14SAndroid Build Coastguard Worker 
705*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
706*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start),
707*cfb92d14SAndroid Build Coastguard Worker                           ", saddr:%04x, extaddr:%02x%02x%02x%02x%02x%02x%02x%02x, flags:0x%02x", saddr, m8[0], m8[1],
708*cfb92d14SAndroid Build Coastguard Worker                           m8[2], m8[3], m8[4], m8[5], m8[6], m8[7], flags);
709*cfb92d14SAndroid Build Coastguard Worker     }
710*cfb92d14SAndroid Build Coastguard Worker     break;
711*cfb92d14SAndroid Build Coastguard Worker 
712*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_CALIBRATED_POWER:
713*cfb92d14SAndroid Build Coastguard Worker     {
714*cfb92d14SAndroid Build Coastguard Worker         if (cmd == SPINEL_CMD_PROP_VALUE_INSERT)
715*cfb92d14SAndroid Build Coastguard Worker         {
716*cfb92d14SAndroid Build Coastguard Worker             uint8_t      channel;
717*cfb92d14SAndroid Build Coastguard Worker             int16_t      actualPower;
718*cfb92d14SAndroid Build Coastguard Worker             uint8_t     *rawPowerSetting;
719*cfb92d14SAndroid Build Coastguard Worker             unsigned int rawPowerSettingLength;
720*cfb92d14SAndroid Build Coastguard Worker 
721*cfb92d14SAndroid Build Coastguard Worker             unpacked = spinel_datatype_unpack(
722*cfb92d14SAndroid Build Coastguard Worker                 data, len, SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_INT16_S SPINEL_DATATYPE_DATA_WLEN_S, &channel,
723*cfb92d14SAndroid Build Coastguard Worker                 &actualPower, &rawPowerSetting, &rawPowerSettingLength);
724*cfb92d14SAndroid Build Coastguard Worker             EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
725*cfb92d14SAndroid Build Coastguard Worker 
726*cfb92d14SAndroid Build Coastguard Worker             start += Snprintf(start, static_cast<uint32_t>(end - start),
727*cfb92d14SAndroid Build Coastguard Worker                               ", ch:%u, actualPower:%d, rawPowerSetting:", channel, actualPower);
728*cfb92d14SAndroid Build Coastguard Worker             for (unsigned int i = 0; i < rawPowerSettingLength; i++)
729*cfb92d14SAndroid Build Coastguard Worker             {
730*cfb92d14SAndroid Build Coastguard Worker                 start += Snprintf(start, static_cast<uint32_t>(end - start), "%02x", rawPowerSetting[i]);
731*cfb92d14SAndroid Build Coastguard Worker             }
732*cfb92d14SAndroid Build Coastguard Worker         }
733*cfb92d14SAndroid Build Coastguard Worker     }
734*cfb92d14SAndroid Build Coastguard Worker     break;
735*cfb92d14SAndroid Build Coastguard Worker 
736*cfb92d14SAndroid Build Coastguard Worker     case SPINEL_PROP_PHY_CHAN_TARGET_POWER:
737*cfb92d14SAndroid Build Coastguard Worker     {
738*cfb92d14SAndroid Build Coastguard Worker         uint8_t channel;
739*cfb92d14SAndroid Build Coastguard Worker         int16_t targetPower;
740*cfb92d14SAndroid Build Coastguard Worker 
741*cfb92d14SAndroid Build Coastguard Worker         unpacked =
742*cfb92d14SAndroid Build Coastguard Worker             spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_INT16_S, &channel, &targetPower);
743*cfb92d14SAndroid Build Coastguard Worker         EXPECT(unpacked > 0, error = OT_ERROR_PARSE);
744*cfb92d14SAndroid Build Coastguard Worker         start += Snprintf(start, static_cast<uint32_t>(end - start), ", ch:%u, targetPower:%d", channel, targetPower);
745*cfb92d14SAndroid Build Coastguard Worker     }
746*cfb92d14SAndroid Build Coastguard Worker     break;
747*cfb92d14SAndroid Build Coastguard Worker     }
748*cfb92d14SAndroid Build Coastguard Worker 
749*cfb92d14SAndroid Build Coastguard Worker exit:
750*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(start); // Avoid static analysis error
751*cfb92d14SAndroid Build Coastguard Worker     if (error == OT_ERROR_NONE)
752*cfb92d14SAndroid Build Coastguard Worker     {
753*cfb92d14SAndroid Build Coastguard Worker         LogDebg("%s", buf);
754*cfb92d14SAndroid Build Coastguard Worker     }
755*cfb92d14SAndroid Build Coastguard Worker     else if (prefix != nullptr)
756*cfb92d14SAndroid Build Coastguard Worker     {
757*cfb92d14SAndroid Build Coastguard Worker         LogDebg("%s, failed to parse spinel frame !", prefix);
758*cfb92d14SAndroid Build Coastguard Worker     }
759*cfb92d14SAndroid Build Coastguard Worker }
760*cfb92d14SAndroid Build Coastguard Worker 
761*cfb92d14SAndroid Build Coastguard Worker } // namespace Spinel
762*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
763