xref: /aosp_15_r20/external/openthread/src/lib/spinel/spinel.c (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *    Copyright (c) 2016, 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  *  -------------------------------------------------------------------
30*cfb92d14SAndroid Build Coastguard Worker  *
31*cfb92d14SAndroid Build Coastguard Worker  *  ## Unit Test ##
32*cfb92d14SAndroid Build Coastguard Worker  *
33*cfb92d14SAndroid Build Coastguard Worker  *  This file includes its own unit test. To compile the unit test,
34*cfb92d14SAndroid Build Coastguard Worker  *  simply compile this file with the macro SPINEL_SELF_TEST set to 1.
35*cfb92d14SAndroid Build Coastguard Worker  *  For example:
36*cfb92d14SAndroid Build Coastguard Worker  *
37*cfb92d14SAndroid Build Coastguard Worker  *      cc spinel.c -Wall -DSPINEL_SELF_TEST=1 -o spinel
38*cfb92d14SAndroid Build Coastguard Worker  *
39*cfb92d14SAndroid Build Coastguard Worker  *  -------------------------------------------------------------------
40*cfb92d14SAndroid Build Coastguard Worker  */
41*cfb92d14SAndroid Build Coastguard Worker 
42*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
43*cfb92d14SAndroid Build Coastguard Worker // MARK: -
44*cfb92d14SAndroid Build Coastguard Worker // MARK: Headers
45*cfb92d14SAndroid Build Coastguard Worker 
46*cfb92d14SAndroid Build Coastguard Worker #include "spinel.h"
47*cfb92d14SAndroid Build Coastguard Worker 
48*cfb92d14SAndroid Build Coastguard Worker #include <errno.h>
49*cfb92d14SAndroid Build Coastguard Worker 
50*cfb92d14SAndroid Build Coastguard Worker #ifndef SPINEL_PLATFORM_HEADER
51*cfb92d14SAndroid Build Coastguard Worker /* These are all already included in the spinel platform header
52*cfb92d14SAndroid Build Coastguard Worker  * if SPINEL_PLATFORM_HEADER was defined.
53*cfb92d14SAndroid Build Coastguard Worker  */
54*cfb92d14SAndroid Build Coastguard Worker #include <stdio.h>
55*cfb92d14SAndroid Build Coastguard Worker #include <stdlib.h>
56*cfb92d14SAndroid Build Coastguard Worker #include <string.h>
57*cfb92d14SAndroid Build Coastguard Worker #endif // #ifndef SPINEL_PLATFORM_HEADER
58*cfb92d14SAndroid Build Coastguard Worker 
59*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
60*cfb92d14SAndroid Build Coastguard Worker // MARK: -
61*cfb92d14SAndroid Build Coastguard Worker 
62*cfb92d14SAndroid Build Coastguard Worker // IAR's errno.h apparently doesn't define EOVERFLOW.
63*cfb92d14SAndroid Build Coastguard Worker #ifndef EOVERFLOW
64*cfb92d14SAndroid Build Coastguard Worker // There is no real good choice for what to set
65*cfb92d14SAndroid Build Coastguard Worker // errno to in this case, so we just pick the
66*cfb92d14SAndroid Build Coastguard Worker // value '1' somewhat arbitrarily.
67*cfb92d14SAndroid Build Coastguard Worker #define EOVERFLOW 1
68*cfb92d14SAndroid Build Coastguard Worker #endif
69*cfb92d14SAndroid Build Coastguard Worker 
70*cfb92d14SAndroid Build Coastguard Worker // IAR's errno.h apparently doesn't define EINVAL.
71*cfb92d14SAndroid Build Coastguard Worker #ifndef EINVAL
72*cfb92d14SAndroid Build Coastguard Worker // There is no real good choice for what to set
73*cfb92d14SAndroid Build Coastguard Worker // errno to in this case, so we just pick the
74*cfb92d14SAndroid Build Coastguard Worker // value '1' somewhat arbitrarily.
75*cfb92d14SAndroid Build Coastguard Worker #define EINVAL 1
76*cfb92d14SAndroid Build Coastguard Worker #endif
77*cfb92d14SAndroid Build Coastguard Worker 
78*cfb92d14SAndroid Build Coastguard Worker // IAR's errno.h apparently doesn't define ENOMEM.
79*cfb92d14SAndroid Build Coastguard Worker #ifndef ENOMEM
80*cfb92d14SAndroid Build Coastguard Worker // There is no real good choice for what to set
81*cfb92d14SAndroid Build Coastguard Worker // errno to in this case, so we just pick the
82*cfb92d14SAndroid Build Coastguard Worker // value '1' somewhat arbitrarily.
83*cfb92d14SAndroid Build Coastguard Worker #define ENOMEM 1
84*cfb92d14SAndroid Build Coastguard Worker #endif
85*cfb92d14SAndroid Build Coastguard Worker 
86*cfb92d14SAndroid Build Coastguard Worker #ifndef SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
87*cfb92d14SAndroid Build Coastguard Worker #define SPINEL_PLATFORM_SHOULD_LOG_ASSERTS 0
88*cfb92d14SAndroid Build Coastguard Worker #endif
89*cfb92d14SAndroid Build Coastguard Worker 
90*cfb92d14SAndroid Build Coastguard Worker #ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
91*cfb92d14SAndroid Build Coastguard Worker #define SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR 0
92*cfb92d14SAndroid Build Coastguard Worker #endif
93*cfb92d14SAndroid Build Coastguard Worker 
94*cfb92d14SAndroid Build Coastguard Worker #ifndef SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
95*cfb92d14SAndroid Build Coastguard Worker #define SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF 0
96*cfb92d14SAndroid Build Coastguard Worker #endif
97*cfb92d14SAndroid Build Coastguard Worker 
98*cfb92d14SAndroid Build Coastguard Worker #ifndef SPINEL_SELF_TEST
99*cfb92d14SAndroid Build Coastguard Worker #define SPINEL_SELF_TEST 0
100*cfb92d14SAndroid Build Coastguard Worker #endif
101*cfb92d14SAndroid Build Coastguard Worker 
102*cfb92d14SAndroid Build Coastguard Worker #if defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
103*cfb92d14SAndroid Build Coastguard Worker #error "SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR is set but errno is already defined."
104*cfb92d14SAndroid Build Coastguard Worker #endif
105*cfb92d14SAndroid Build Coastguard Worker 
106*cfb92d14SAndroid Build Coastguard Worker // Work-around for platforms that don't implement the `errno` variable.
107*cfb92d14SAndroid Build Coastguard Worker #if !defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
108*cfb92d14SAndroid Build Coastguard Worker static int spinel_errno_workaround_;
109*cfb92d14SAndroid Build Coastguard Worker #define errno spinel_errno_workaround_
110*cfb92d14SAndroid Build Coastguard Worker #endif // SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
111*cfb92d14SAndroid Build Coastguard Worker 
112*cfb92d14SAndroid Build Coastguard Worker #ifndef assert_printf
113*cfb92d14SAndroid Build Coastguard Worker #if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
114*cfb92d14SAndroid Build Coastguard Worker #define assert_printf(fmt, ...) printf(__FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
115*cfb92d14SAndroid Build Coastguard Worker #else // if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
116*cfb92d14SAndroid Build Coastguard Worker #define assert_printf(fmt, ...) fprintf(stderr, __FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
117*cfb92d14SAndroid Build Coastguard Worker #endif // else SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
118*cfb92d14SAndroid Build Coastguard Worker #endif
119*cfb92d14SAndroid Build Coastguard Worker 
120*cfb92d14SAndroid Build Coastguard Worker #ifndef require_action
121*cfb92d14SAndroid Build Coastguard Worker #if SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
122*cfb92d14SAndroid Build Coastguard Worker #define require_action(c, l, a)                           \
123*cfb92d14SAndroid Build Coastguard Worker     do                                                    \
124*cfb92d14SAndroid Build Coastguard Worker     {                                                     \
125*cfb92d14SAndroid Build Coastguard Worker         if (!(c))                                         \
126*cfb92d14SAndroid Build Coastguard Worker         {                                                 \
127*cfb92d14SAndroid Build Coastguard Worker             assert_printf("Requirement Failed (%s)", #c); \
128*cfb92d14SAndroid Build Coastguard Worker             a;                                            \
129*cfb92d14SAndroid Build Coastguard Worker             goto l;                                       \
130*cfb92d14SAndroid Build Coastguard Worker         }                                                 \
131*cfb92d14SAndroid Build Coastguard Worker     } while (0)
132*cfb92d14SAndroid Build Coastguard Worker #else // if DEBUG
133*cfb92d14SAndroid Build Coastguard Worker #define require_action(c, l, a) \
134*cfb92d14SAndroid Build Coastguard Worker     do                          \
135*cfb92d14SAndroid Build Coastguard Worker     {                           \
136*cfb92d14SAndroid Build Coastguard Worker         if (!(c))               \
137*cfb92d14SAndroid Build Coastguard Worker         {                       \
138*cfb92d14SAndroid Build Coastguard Worker             a;                  \
139*cfb92d14SAndroid Build Coastguard Worker             goto l;             \
140*cfb92d14SAndroid Build Coastguard Worker         }                       \
141*cfb92d14SAndroid Build Coastguard Worker     } while (0)
142*cfb92d14SAndroid Build Coastguard Worker #endif // else DEBUG
143*cfb92d14SAndroid Build Coastguard Worker #endif // ifndef require_action
144*cfb92d14SAndroid Build Coastguard Worker 
145*cfb92d14SAndroid Build Coastguard Worker #ifndef require
146*cfb92d14SAndroid Build Coastguard Worker #define require(c, l) require_action(c, l, {})
147*cfb92d14SAndroid Build Coastguard Worker #endif
148*cfb92d14SAndroid Build Coastguard Worker 
149*cfb92d14SAndroid Build Coastguard Worker #ifndef strnlen
spinel_strnlen(const char * s,size_t maxlen)150*cfb92d14SAndroid Build Coastguard Worker static size_t spinel_strnlen(const char *s, size_t maxlen)
151*cfb92d14SAndroid Build Coastguard Worker {
152*cfb92d14SAndroid Build Coastguard Worker     size_t ret;
153*cfb92d14SAndroid Build Coastguard Worker 
154*cfb92d14SAndroid Build Coastguard Worker     for (ret = 0; (ret < maxlen) && (s[ret] != 0); ret++)
155*cfb92d14SAndroid Build Coastguard Worker     {
156*cfb92d14SAndroid Build Coastguard Worker         // Empty loop.
157*cfb92d14SAndroid Build Coastguard Worker     }
158*cfb92d14SAndroid Build Coastguard Worker 
159*cfb92d14SAndroid Build Coastguard Worker     return ret;
160*cfb92d14SAndroid Build Coastguard Worker }
161*cfb92d14SAndroid Build Coastguard Worker #else
162*cfb92d14SAndroid Build Coastguard Worker #define spinel_strnlen strnlen
163*cfb92d14SAndroid Build Coastguard Worker #endif
164*cfb92d14SAndroid Build Coastguard Worker 
165*cfb92d14SAndroid Build Coastguard Worker typedef struct
166*cfb92d14SAndroid Build Coastguard Worker {
167*cfb92d14SAndroid Build Coastguard Worker     va_list obj;
168*cfb92d14SAndroid Build Coastguard Worker } va_list_obj;
169*cfb92d14SAndroid Build Coastguard Worker 
170*cfb92d14SAndroid Build Coastguard Worker #define SPINEL_MAX_PACK_LENGTH 32767
171*cfb92d14SAndroid Build Coastguard Worker 
172*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
173*cfb92d14SAndroid Build Coastguard Worker 
174*cfb92d14SAndroid Build Coastguard Worker // This function validates whether a given byte sequence (string) follows UTF8 encoding.
spinel_validate_utf8(const uint8_t * string)175*cfb92d14SAndroid Build Coastguard Worker static bool spinel_validate_utf8(const uint8_t *string)
176*cfb92d14SAndroid Build Coastguard Worker {
177*cfb92d14SAndroid Build Coastguard Worker     bool    ret = true;
178*cfb92d14SAndroid Build Coastguard Worker     uint8_t byte;
179*cfb92d14SAndroid Build Coastguard Worker     uint8_t continuation_bytes = 0;
180*cfb92d14SAndroid Build Coastguard Worker 
181*cfb92d14SAndroid Build Coastguard Worker     while ((byte = *string++) != 0)
182*cfb92d14SAndroid Build Coastguard Worker     {
183*cfb92d14SAndroid Build Coastguard Worker         if ((byte & 0x80) == 0)
184*cfb92d14SAndroid Build Coastguard Worker         {
185*cfb92d14SAndroid Build Coastguard Worker             continue;
186*cfb92d14SAndroid Build Coastguard Worker         }
187*cfb92d14SAndroid Build Coastguard Worker 
188*cfb92d14SAndroid Build Coastguard Worker         // This is a leading byte 1xxx-xxxx.
189*cfb92d14SAndroid Build Coastguard Worker 
190*cfb92d14SAndroid Build Coastguard Worker         if ((byte & 0x40) == 0) // 10xx-xxxx
191*cfb92d14SAndroid Build Coastguard Worker         {
192*cfb92d14SAndroid Build Coastguard Worker             // We got a continuation byte pattern without seeing a leading byte earlier.
193*cfb92d14SAndroid Build Coastguard Worker             ret = false;
194*cfb92d14SAndroid Build Coastguard Worker             goto bail;
195*cfb92d14SAndroid Build Coastguard Worker         }
196*cfb92d14SAndroid Build Coastguard Worker         else if ((byte & 0x20) == 0) // 110x-xxxx
197*cfb92d14SAndroid Build Coastguard Worker         {
198*cfb92d14SAndroid Build Coastguard Worker             continuation_bytes = 1;
199*cfb92d14SAndroid Build Coastguard Worker         }
200*cfb92d14SAndroid Build Coastguard Worker         else if ((byte & 0x10) == 0) // 1110-xxxx
201*cfb92d14SAndroid Build Coastguard Worker         {
202*cfb92d14SAndroid Build Coastguard Worker             continuation_bytes = 2;
203*cfb92d14SAndroid Build Coastguard Worker         }
204*cfb92d14SAndroid Build Coastguard Worker         else if ((byte & 0x08) == 0) // 1111-0xxx
205*cfb92d14SAndroid Build Coastguard Worker         {
206*cfb92d14SAndroid Build Coastguard Worker             continuation_bytes = 3;
207*cfb92d14SAndroid Build Coastguard Worker         }
208*cfb92d14SAndroid Build Coastguard Worker         else // 1111-1xxx  (invalid pattern).
209*cfb92d14SAndroid Build Coastguard Worker         {
210*cfb92d14SAndroid Build Coastguard Worker             ret = false;
211*cfb92d14SAndroid Build Coastguard Worker             goto bail;
212*cfb92d14SAndroid Build Coastguard Worker         }
213*cfb92d14SAndroid Build Coastguard Worker 
214*cfb92d14SAndroid Build Coastguard Worker         while (continuation_bytes-- != 0)
215*cfb92d14SAndroid Build Coastguard Worker         {
216*cfb92d14SAndroid Build Coastguard Worker             byte = *string++;
217*cfb92d14SAndroid Build Coastguard Worker 
218*cfb92d14SAndroid Build Coastguard Worker             // Verify the continuation byte pattern 10xx-xxxx
219*cfb92d14SAndroid Build Coastguard Worker             if ((byte & 0xc0) != 0x80)
220*cfb92d14SAndroid Build Coastguard Worker             {
221*cfb92d14SAndroid Build Coastguard Worker                 ret = false;
222*cfb92d14SAndroid Build Coastguard Worker                 goto bail;
223*cfb92d14SAndroid Build Coastguard Worker             }
224*cfb92d14SAndroid Build Coastguard Worker         }
225*cfb92d14SAndroid Build Coastguard Worker     }
226*cfb92d14SAndroid Build Coastguard Worker 
227*cfb92d14SAndroid Build Coastguard Worker bail:
228*cfb92d14SAndroid Build Coastguard Worker     return ret;
229*cfb92d14SAndroid Build Coastguard Worker }
230*cfb92d14SAndroid Build Coastguard Worker 
231*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
232*cfb92d14SAndroid Build Coastguard Worker // MARK: -
233*cfb92d14SAndroid Build Coastguard Worker 
spinel_packed_uint_decode(const uint8_t * bytes,spinel_size_t len,unsigned int * value_ptr)234*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_packed_uint_decode(const uint8_t *bytes, spinel_size_t len, unsigned int *value_ptr)
235*cfb92d14SAndroid Build Coastguard Worker {
236*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret   = 0;
237*cfb92d14SAndroid Build Coastguard Worker     unsigned int   value = 0;
238*cfb92d14SAndroid Build Coastguard Worker 
239*cfb92d14SAndroid Build Coastguard Worker     unsigned int i = 0;
240*cfb92d14SAndroid Build Coastguard Worker 
241*cfb92d14SAndroid Build Coastguard Worker     do
242*cfb92d14SAndroid Build Coastguard Worker     {
243*cfb92d14SAndroid Build Coastguard Worker         if ((len < sizeof(uint8_t)) || (i >= sizeof(unsigned int) * SPINEL_BITS_PER_BYTE))
244*cfb92d14SAndroid Build Coastguard Worker         {
245*cfb92d14SAndroid Build Coastguard Worker             ret = -1;
246*cfb92d14SAndroid Build Coastguard Worker             break;
247*cfb92d14SAndroid Build Coastguard Worker         }
248*cfb92d14SAndroid Build Coastguard Worker 
249*cfb92d14SAndroid Build Coastguard Worker         value |= (unsigned int)(bytes[0] & 0x7F) << i;
250*cfb92d14SAndroid Build Coastguard Worker         i += 7;
251*cfb92d14SAndroid Build Coastguard Worker         ret += sizeof(uint8_t);
252*cfb92d14SAndroid Build Coastguard Worker         bytes += sizeof(uint8_t);
253*cfb92d14SAndroid Build Coastguard Worker         len -= sizeof(uint8_t);
254*cfb92d14SAndroid Build Coastguard Worker     } while ((bytes[-1] & 0x80) == 0x80);
255*cfb92d14SAndroid Build Coastguard Worker 
256*cfb92d14SAndroid Build Coastguard Worker     if ((ret > 0) && (value_ptr != NULL))
257*cfb92d14SAndroid Build Coastguard Worker     {
258*cfb92d14SAndroid Build Coastguard Worker         *value_ptr = value;
259*cfb92d14SAndroid Build Coastguard Worker     }
260*cfb92d14SAndroid Build Coastguard Worker 
261*cfb92d14SAndroid Build Coastguard Worker     return ret;
262*cfb92d14SAndroid Build Coastguard Worker }
263*cfb92d14SAndroid Build Coastguard Worker 
spinel_packed_uint_size(unsigned int value)264*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_packed_uint_size(unsigned int value)
265*cfb92d14SAndroid Build Coastguard Worker {
266*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret;
267*cfb92d14SAndroid Build Coastguard Worker 
268*cfb92d14SAndroid Build Coastguard Worker     if (value < (1 << 7))
269*cfb92d14SAndroid Build Coastguard Worker     {
270*cfb92d14SAndroid Build Coastguard Worker         ret = 1;
271*cfb92d14SAndroid Build Coastguard Worker     }
272*cfb92d14SAndroid Build Coastguard Worker     else if (value < (1 << 14))
273*cfb92d14SAndroid Build Coastguard Worker     {
274*cfb92d14SAndroid Build Coastguard Worker         ret = 2;
275*cfb92d14SAndroid Build Coastguard Worker     }
276*cfb92d14SAndroid Build Coastguard Worker     else if (value < (1 << 21))
277*cfb92d14SAndroid Build Coastguard Worker     {
278*cfb92d14SAndroid Build Coastguard Worker         ret = 3;
279*cfb92d14SAndroid Build Coastguard Worker     }
280*cfb92d14SAndroid Build Coastguard Worker     else if (value < (1 << 28))
281*cfb92d14SAndroid Build Coastguard Worker     {
282*cfb92d14SAndroid Build Coastguard Worker         ret = 4;
283*cfb92d14SAndroid Build Coastguard Worker     }
284*cfb92d14SAndroid Build Coastguard Worker     else
285*cfb92d14SAndroid Build Coastguard Worker     {
286*cfb92d14SAndroid Build Coastguard Worker         ret = 5;
287*cfb92d14SAndroid Build Coastguard Worker     }
288*cfb92d14SAndroid Build Coastguard Worker 
289*cfb92d14SAndroid Build Coastguard Worker     return ret;
290*cfb92d14SAndroid Build Coastguard Worker }
291*cfb92d14SAndroid Build Coastguard Worker 
spinel_packed_uint_encode(uint8_t * bytes,spinel_size_t len,unsigned int value)292*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_packed_uint_encode(uint8_t *bytes, spinel_size_t len, unsigned int value)
293*cfb92d14SAndroid Build Coastguard Worker {
294*cfb92d14SAndroid Build Coastguard Worker     const spinel_ssize_t encoded_size = spinel_packed_uint_size(value);
295*cfb92d14SAndroid Build Coastguard Worker 
296*cfb92d14SAndroid Build Coastguard Worker     if ((spinel_ssize_t)len >= encoded_size)
297*cfb92d14SAndroid Build Coastguard Worker     {
298*cfb92d14SAndroid Build Coastguard Worker         spinel_ssize_t i;
299*cfb92d14SAndroid Build Coastguard Worker 
300*cfb92d14SAndroid Build Coastguard Worker         for (i = 0; i != encoded_size - 1; ++i)
301*cfb92d14SAndroid Build Coastguard Worker         {
302*cfb92d14SAndroid Build Coastguard Worker             *bytes++ = (value & 0x7F) | 0x80;
303*cfb92d14SAndroid Build Coastguard Worker             value    = (value >> 7);
304*cfb92d14SAndroid Build Coastguard Worker         }
305*cfb92d14SAndroid Build Coastguard Worker 
306*cfb92d14SAndroid Build Coastguard Worker         *bytes++ = (value & 0x7F);
307*cfb92d14SAndroid Build Coastguard Worker     }
308*cfb92d14SAndroid Build Coastguard Worker 
309*cfb92d14SAndroid Build Coastguard Worker     return encoded_size;
310*cfb92d14SAndroid Build Coastguard Worker }
311*cfb92d14SAndroid Build Coastguard Worker 
spinel_next_packed_datatype(const char * pack_format)312*cfb92d14SAndroid Build Coastguard Worker const char *spinel_next_packed_datatype(const char *pack_format)
313*cfb92d14SAndroid Build Coastguard Worker {
314*cfb92d14SAndroid Build Coastguard Worker     int depth = 0;
315*cfb92d14SAndroid Build Coastguard Worker 
316*cfb92d14SAndroid Build Coastguard Worker     do
317*cfb92d14SAndroid Build Coastguard Worker     {
318*cfb92d14SAndroid Build Coastguard Worker         switch (*++pack_format)
319*cfb92d14SAndroid Build Coastguard Worker         {
320*cfb92d14SAndroid Build Coastguard Worker         case '(':
321*cfb92d14SAndroid Build Coastguard Worker             depth++;
322*cfb92d14SAndroid Build Coastguard Worker             break;
323*cfb92d14SAndroid Build Coastguard Worker 
324*cfb92d14SAndroid Build Coastguard Worker         case ')':
325*cfb92d14SAndroid Build Coastguard Worker             depth--;
326*cfb92d14SAndroid Build Coastguard Worker 
327*cfb92d14SAndroid Build Coastguard Worker             if (depth == 0)
328*cfb92d14SAndroid Build Coastguard Worker             {
329*cfb92d14SAndroid Build Coastguard Worker                 pack_format++;
330*cfb92d14SAndroid Build Coastguard Worker             }
331*cfb92d14SAndroid Build Coastguard Worker 
332*cfb92d14SAndroid Build Coastguard Worker             break;
333*cfb92d14SAndroid Build Coastguard Worker         }
334*cfb92d14SAndroid Build Coastguard Worker     } while ((depth > 0) && *pack_format != 0);
335*cfb92d14SAndroid Build Coastguard Worker 
336*cfb92d14SAndroid Build Coastguard Worker     return pack_format;
337*cfb92d14SAndroid Build Coastguard Worker }
338*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_vunpack_(bool in_place,const uint8_t * data_in,spinel_size_t data_len,const char * pack_format,va_list_obj * args)339*cfb92d14SAndroid Build Coastguard Worker static spinel_ssize_t spinel_datatype_vunpack_(bool           in_place,
340*cfb92d14SAndroid Build Coastguard Worker                                                const uint8_t *data_in,
341*cfb92d14SAndroid Build Coastguard Worker                                                spinel_size_t  data_len,
342*cfb92d14SAndroid Build Coastguard Worker                                                const char    *pack_format,
343*cfb92d14SAndroid Build Coastguard Worker                                                va_list_obj   *args)
344*cfb92d14SAndroid Build Coastguard Worker {
345*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret = 0;
346*cfb92d14SAndroid Build Coastguard Worker 
347*cfb92d14SAndroid Build Coastguard Worker     // Buffer length sanity check
348*cfb92d14SAndroid Build Coastguard Worker     require_action(data_len <= SPINEL_MAX_PACK_LENGTH, bail, (ret = -1, errno = EINVAL));
349*cfb92d14SAndroid Build Coastguard Worker 
350*cfb92d14SAndroid Build Coastguard Worker     for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
351*cfb92d14SAndroid Build Coastguard Worker     {
352*cfb92d14SAndroid Build Coastguard Worker         if (*pack_format == ')')
353*cfb92d14SAndroid Build Coastguard Worker         {
354*cfb92d14SAndroid Build Coastguard Worker             // Don't go past the end of a struct.
355*cfb92d14SAndroid Build Coastguard Worker             break;
356*cfb92d14SAndroid Build Coastguard Worker         }
357*cfb92d14SAndroid Build Coastguard Worker 
358*cfb92d14SAndroid Build Coastguard Worker         switch ((spinel_datatype_t)pack_format[0])
359*cfb92d14SAndroid Build Coastguard Worker         {
360*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_BOOL_C:
361*cfb92d14SAndroid Build Coastguard Worker         {
362*cfb92d14SAndroid Build Coastguard Worker             bool *arg_ptr = va_arg(args->obj, bool *);
363*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
364*cfb92d14SAndroid Build Coastguard Worker 
365*cfb92d14SAndroid Build Coastguard Worker             if (arg_ptr)
366*cfb92d14SAndroid Build Coastguard Worker             {
367*cfb92d14SAndroid Build Coastguard Worker                 *arg_ptr = data_in[0] != 0;
368*cfb92d14SAndroid Build Coastguard Worker             }
369*cfb92d14SAndroid Build Coastguard Worker 
370*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint8_t);
371*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(uint8_t);
372*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(uint8_t);
373*cfb92d14SAndroid Build Coastguard Worker             break;
374*cfb92d14SAndroid Build Coastguard Worker         }
375*cfb92d14SAndroid Build Coastguard Worker 
376*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT8_C:
377*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT8_C:
378*cfb92d14SAndroid Build Coastguard Worker         {
379*cfb92d14SAndroid Build Coastguard Worker             uint8_t *arg_ptr = va_arg(args->obj, uint8_t *);
380*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
381*cfb92d14SAndroid Build Coastguard Worker 
382*cfb92d14SAndroid Build Coastguard Worker             if (arg_ptr)
383*cfb92d14SAndroid Build Coastguard Worker             {
384*cfb92d14SAndroid Build Coastguard Worker                 *arg_ptr = data_in[0];
385*cfb92d14SAndroid Build Coastguard Worker             }
386*cfb92d14SAndroid Build Coastguard Worker 
387*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint8_t);
388*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(uint8_t);
389*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(uint8_t);
390*cfb92d14SAndroid Build Coastguard Worker             break;
391*cfb92d14SAndroid Build Coastguard Worker         }
392*cfb92d14SAndroid Build Coastguard Worker 
393*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT16_C:
394*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT16_C:
395*cfb92d14SAndroid Build Coastguard Worker         {
396*cfb92d14SAndroid Build Coastguard Worker             uint16_t *arg_ptr = va_arg(args->obj, uint16_t *);
397*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(uint16_t), bail, (ret = -1, errno = EOVERFLOW));
398*cfb92d14SAndroid Build Coastguard Worker 
399*cfb92d14SAndroid Build Coastguard Worker             if (arg_ptr)
400*cfb92d14SAndroid Build Coastguard Worker             {
401*cfb92d14SAndroid Build Coastguard Worker                 *arg_ptr = (uint16_t)((data_in[1] << 8) | data_in[0]);
402*cfb92d14SAndroid Build Coastguard Worker             }
403*cfb92d14SAndroid Build Coastguard Worker 
404*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint16_t);
405*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(uint16_t);
406*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(uint16_t);
407*cfb92d14SAndroid Build Coastguard Worker             break;
408*cfb92d14SAndroid Build Coastguard Worker         }
409*cfb92d14SAndroid Build Coastguard Worker 
410*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT32_C:
411*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT32_C:
412*cfb92d14SAndroid Build Coastguard Worker         {
413*cfb92d14SAndroid Build Coastguard Worker             uint32_t *arg_ptr = va_arg(args->obj, uint32_t *);
414*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(uint32_t), bail, (ret = -1, errno = EOVERFLOW));
415*cfb92d14SAndroid Build Coastguard Worker 
416*cfb92d14SAndroid Build Coastguard Worker             if (arg_ptr)
417*cfb92d14SAndroid Build Coastguard Worker             {
418*cfb92d14SAndroid Build Coastguard Worker                 *arg_ptr = (uint32_t)((data_in[3] << 24) | (data_in[2] << 16) | (data_in[1] << 8) | data_in[0]);
419*cfb92d14SAndroid Build Coastguard Worker             }
420*cfb92d14SAndroid Build Coastguard Worker 
421*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint32_t);
422*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(uint32_t);
423*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(uint32_t);
424*cfb92d14SAndroid Build Coastguard Worker             break;
425*cfb92d14SAndroid Build Coastguard Worker         }
426*cfb92d14SAndroid Build Coastguard Worker 
427*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT64_C:
428*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT64_C:
429*cfb92d14SAndroid Build Coastguard Worker         {
430*cfb92d14SAndroid Build Coastguard Worker             uint64_t *arg_ptr = va_arg(args->obj, uint64_t *);
431*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(uint64_t), bail, (ret = -1, errno = EOVERFLOW));
432*cfb92d14SAndroid Build Coastguard Worker 
433*cfb92d14SAndroid Build Coastguard Worker             if (arg_ptr)
434*cfb92d14SAndroid Build Coastguard Worker             {
435*cfb92d14SAndroid Build Coastguard Worker                 uint32_t l32 = (uint32_t)((data_in[3] << 24) | (data_in[2] << 16) | (data_in[1] << 8) | data_in[0]);
436*cfb92d14SAndroid Build Coastguard Worker                 uint32_t h32 = (uint32_t)((data_in[7] << 24) | (data_in[6] << 16) | (data_in[5] << 8) | data_in[4]);
437*cfb92d14SAndroid Build Coastguard Worker 
438*cfb92d14SAndroid Build Coastguard Worker                 *arg_ptr = ((uint64_t)l32) | (((uint64_t)h32) << 32);
439*cfb92d14SAndroid Build Coastguard Worker             }
440*cfb92d14SAndroid Build Coastguard Worker 
441*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint64_t);
442*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(uint64_t);
443*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(uint64_t);
444*cfb92d14SAndroid Build Coastguard Worker             break;
445*cfb92d14SAndroid Build Coastguard Worker         }
446*cfb92d14SAndroid Build Coastguard Worker 
447*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_IPv6ADDR_C:
448*cfb92d14SAndroid Build Coastguard Worker         {
449*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(spinel_ipv6addr_t), bail, (ret = -1, errno = EOVERFLOW));
450*cfb92d14SAndroid Build Coastguard Worker 
451*cfb92d14SAndroid Build Coastguard Worker             if (in_place)
452*cfb92d14SAndroid Build Coastguard Worker             {
453*cfb92d14SAndroid Build Coastguard Worker                 spinel_ipv6addr_t *arg = va_arg(args->obj, spinel_ipv6addr_t *);
454*cfb92d14SAndroid Build Coastguard Worker                 if (arg)
455*cfb92d14SAndroid Build Coastguard Worker                 {
456*cfb92d14SAndroid Build Coastguard Worker                     memcpy(arg, data_in, sizeof(spinel_ipv6addr_t));
457*cfb92d14SAndroid Build Coastguard Worker                 }
458*cfb92d14SAndroid Build Coastguard Worker             }
459*cfb92d14SAndroid Build Coastguard Worker             else
460*cfb92d14SAndroid Build Coastguard Worker             {
461*cfb92d14SAndroid Build Coastguard Worker                 const spinel_ipv6addr_t **arg_ptr = va_arg(args->obj, const spinel_ipv6addr_t **);
462*cfb92d14SAndroid Build Coastguard Worker                 if (arg_ptr)
463*cfb92d14SAndroid Build Coastguard Worker                 {
464*cfb92d14SAndroid Build Coastguard Worker                     *arg_ptr = (const spinel_ipv6addr_t *)data_in;
465*cfb92d14SAndroid Build Coastguard Worker                 }
466*cfb92d14SAndroid Build Coastguard Worker             }
467*cfb92d14SAndroid Build Coastguard Worker 
468*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(spinel_ipv6addr_t);
469*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(spinel_ipv6addr_t);
470*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(spinel_ipv6addr_t);
471*cfb92d14SAndroid Build Coastguard Worker             break;
472*cfb92d14SAndroid Build Coastguard Worker         }
473*cfb92d14SAndroid Build Coastguard Worker 
474*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_EUI64_C:
475*cfb92d14SAndroid Build Coastguard Worker         {
476*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(spinel_eui64_t), bail, (ret = -1, errno = EOVERFLOW));
477*cfb92d14SAndroid Build Coastguard Worker 
478*cfb92d14SAndroid Build Coastguard Worker             if (in_place)
479*cfb92d14SAndroid Build Coastguard Worker             {
480*cfb92d14SAndroid Build Coastguard Worker                 spinel_eui64_t *arg = va_arg(args->obj, spinel_eui64_t *);
481*cfb92d14SAndroid Build Coastguard Worker                 if (arg)
482*cfb92d14SAndroid Build Coastguard Worker                 {
483*cfb92d14SAndroid Build Coastguard Worker                     memcpy(arg, data_in, sizeof(spinel_eui64_t));
484*cfb92d14SAndroid Build Coastguard Worker                 }
485*cfb92d14SAndroid Build Coastguard Worker             }
486*cfb92d14SAndroid Build Coastguard Worker             else
487*cfb92d14SAndroid Build Coastguard Worker             {
488*cfb92d14SAndroid Build Coastguard Worker                 const spinel_eui64_t **arg_ptr = va_arg(args->obj, const spinel_eui64_t **);
489*cfb92d14SAndroid Build Coastguard Worker                 if (arg_ptr)
490*cfb92d14SAndroid Build Coastguard Worker                 {
491*cfb92d14SAndroid Build Coastguard Worker                     *arg_ptr = (const spinel_eui64_t *)data_in;
492*cfb92d14SAndroid Build Coastguard Worker                 }
493*cfb92d14SAndroid Build Coastguard Worker             }
494*cfb92d14SAndroid Build Coastguard Worker 
495*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(spinel_eui64_t);
496*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(spinel_eui64_t);
497*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(spinel_eui64_t);
498*cfb92d14SAndroid Build Coastguard Worker             break;
499*cfb92d14SAndroid Build Coastguard Worker         }
500*cfb92d14SAndroid Build Coastguard Worker 
501*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_EUI48_C:
502*cfb92d14SAndroid Build Coastguard Worker         {
503*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len >= sizeof(spinel_eui48_t), bail, (ret = -1, errno = EOVERFLOW));
504*cfb92d14SAndroid Build Coastguard Worker 
505*cfb92d14SAndroid Build Coastguard Worker             if (in_place)
506*cfb92d14SAndroid Build Coastguard Worker             {
507*cfb92d14SAndroid Build Coastguard Worker                 spinel_eui48_t *arg = va_arg(args->obj, spinel_eui48_t *);
508*cfb92d14SAndroid Build Coastguard Worker                 if (arg)
509*cfb92d14SAndroid Build Coastguard Worker                 {
510*cfb92d14SAndroid Build Coastguard Worker                     memcpy(arg, data_in, sizeof(spinel_eui48_t));
511*cfb92d14SAndroid Build Coastguard Worker                 }
512*cfb92d14SAndroid Build Coastguard Worker             }
513*cfb92d14SAndroid Build Coastguard Worker             else
514*cfb92d14SAndroid Build Coastguard Worker             {
515*cfb92d14SAndroid Build Coastguard Worker                 const spinel_eui48_t **arg_ptr = va_arg(args->obj, const spinel_eui48_t **);
516*cfb92d14SAndroid Build Coastguard Worker                 if (arg_ptr)
517*cfb92d14SAndroid Build Coastguard Worker                 {
518*cfb92d14SAndroid Build Coastguard Worker                     *arg_ptr = (const spinel_eui48_t *)data_in;
519*cfb92d14SAndroid Build Coastguard Worker                 }
520*cfb92d14SAndroid Build Coastguard Worker             }
521*cfb92d14SAndroid Build Coastguard Worker 
522*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(spinel_eui48_t);
523*cfb92d14SAndroid Build Coastguard Worker             data_in += sizeof(spinel_eui48_t);
524*cfb92d14SAndroid Build Coastguard Worker             data_len -= sizeof(spinel_eui48_t);
525*cfb92d14SAndroid Build Coastguard Worker             break;
526*cfb92d14SAndroid Build Coastguard Worker         }
527*cfb92d14SAndroid Build Coastguard Worker 
528*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT_PACKED_C:
529*cfb92d14SAndroid Build Coastguard Worker         {
530*cfb92d14SAndroid Build Coastguard Worker             unsigned int  *arg_ptr = va_arg(args->obj, unsigned int *);
531*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t pui_len = spinel_packed_uint_decode(data_in, data_len, arg_ptr);
532*cfb92d14SAndroid Build Coastguard Worker 
533*cfb92d14SAndroid Build Coastguard Worker             // Range check
534*cfb92d14SAndroid Build Coastguard Worker             require_action(NULL == arg_ptr || (*arg_ptr < SPINEL_MAX_UINT_PACKED), bail, (ret = -1, errno = ERANGE));
535*cfb92d14SAndroid Build Coastguard Worker 
536*cfb92d14SAndroid Build Coastguard Worker             require(pui_len > 0, bail);
537*cfb92d14SAndroid Build Coastguard Worker 
538*cfb92d14SAndroid Build Coastguard Worker             require(pui_len <= (spinel_ssize_t)data_len, bail);
539*cfb92d14SAndroid Build Coastguard Worker 
540*cfb92d14SAndroid Build Coastguard Worker             ret += pui_len;
541*cfb92d14SAndroid Build Coastguard Worker             data_in += pui_len;
542*cfb92d14SAndroid Build Coastguard Worker             data_len -= (spinel_size_t)pui_len;
543*cfb92d14SAndroid Build Coastguard Worker             break;
544*cfb92d14SAndroid Build Coastguard Worker         }
545*cfb92d14SAndroid Build Coastguard Worker 
546*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UTF8_C:
547*cfb92d14SAndroid Build Coastguard Worker         {
548*cfb92d14SAndroid Build Coastguard Worker             size_t len;
549*cfb92d14SAndroid Build Coastguard Worker 
550*cfb92d14SAndroid Build Coastguard Worker             // Make sure we have at least one byte.
551*cfb92d14SAndroid Build Coastguard Worker             require_action(data_len > 0, bail, (ret = -1, errno = EOVERFLOW));
552*cfb92d14SAndroid Build Coastguard Worker 
553*cfb92d14SAndroid Build Coastguard Worker             // Add 1 for zero termination. If not zero terminated,
554*cfb92d14SAndroid Build Coastguard Worker             // len will then be data_len+1, which we will detect
555*cfb92d14SAndroid Build Coastguard Worker             // in the next check.
556*cfb92d14SAndroid Build Coastguard Worker             len = spinel_strnlen((const char *)data_in, data_len) + 1;
557*cfb92d14SAndroid Build Coastguard Worker 
558*cfb92d14SAndroid Build Coastguard Worker             // Verify that the string is zero terminated.
559*cfb92d14SAndroid Build Coastguard Worker             require_action(len <= data_len, bail, (ret = -1, errno = EOVERFLOW));
560*cfb92d14SAndroid Build Coastguard Worker 
561*cfb92d14SAndroid Build Coastguard Worker             // Verify the string follows valid UTF8 encoding.
562*cfb92d14SAndroid Build Coastguard Worker             require_action(spinel_validate_utf8(data_in), bail, (ret = -1, errno = EINVAL));
563*cfb92d14SAndroid Build Coastguard Worker 
564*cfb92d14SAndroid Build Coastguard Worker             if (in_place)
565*cfb92d14SAndroid Build Coastguard Worker             {
566*cfb92d14SAndroid Build Coastguard Worker                 char  *arg     = va_arg(args->obj, char *);
567*cfb92d14SAndroid Build Coastguard Worker                 size_t len_arg = va_arg(args->obj, size_t);
568*cfb92d14SAndroid Build Coastguard Worker                 if (arg)
569*cfb92d14SAndroid Build Coastguard Worker                 {
570*cfb92d14SAndroid Build Coastguard Worker                     require_action(len_arg >= len, bail, (ret = -1, errno = ENOMEM));
571*cfb92d14SAndroid Build Coastguard Worker                     memcpy(arg, data_in, len);
572*cfb92d14SAndroid Build Coastguard Worker                 }
573*cfb92d14SAndroid Build Coastguard Worker             }
574*cfb92d14SAndroid Build Coastguard Worker             else
575*cfb92d14SAndroid Build Coastguard Worker             {
576*cfb92d14SAndroid Build Coastguard Worker                 const char **arg_ptr = va_arg(args->obj, const char **);
577*cfb92d14SAndroid Build Coastguard Worker                 if (arg_ptr)
578*cfb92d14SAndroid Build Coastguard Worker                 {
579*cfb92d14SAndroid Build Coastguard Worker                     *arg_ptr = (const char *)data_in;
580*cfb92d14SAndroid Build Coastguard Worker                 }
581*cfb92d14SAndroid Build Coastguard Worker             }
582*cfb92d14SAndroid Build Coastguard Worker 
583*cfb92d14SAndroid Build Coastguard Worker             ret += (spinel_size_t)len;
584*cfb92d14SAndroid Build Coastguard Worker             data_in += len;
585*cfb92d14SAndroid Build Coastguard Worker             data_len -= (spinel_size_t)len;
586*cfb92d14SAndroid Build Coastguard Worker             break;
587*cfb92d14SAndroid Build Coastguard Worker         }
588*cfb92d14SAndroid Build Coastguard Worker 
589*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_DATA_C:
590*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_DATA_WLEN_C:
591*cfb92d14SAndroid Build Coastguard Worker         {
592*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t pui_len       = 0;
593*cfb92d14SAndroid Build Coastguard Worker             uint16_t       block_len     = 0;
594*cfb92d14SAndroid Build Coastguard Worker             const uint8_t *block_ptr     = data_in;
595*cfb92d14SAndroid Build Coastguard Worker             void          *arg_ptr       = va_arg(args->obj, void *);
596*cfb92d14SAndroid Build Coastguard Worker             unsigned int  *block_len_ptr = va_arg(args->obj, unsigned int *);
597*cfb92d14SAndroid Build Coastguard Worker             char           nextformat    = *spinel_next_packed_datatype(pack_format);
598*cfb92d14SAndroid Build Coastguard Worker 
599*cfb92d14SAndroid Build Coastguard Worker             if ((pack_format[0] == SPINEL_DATATYPE_DATA_WLEN_C) || ((nextformat != 0) && (nextformat != ')')))
600*cfb92d14SAndroid Build Coastguard Worker             {
601*cfb92d14SAndroid Build Coastguard Worker                 pui_len = spinel_datatype_unpack(data_in, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
602*cfb92d14SAndroid Build Coastguard Worker                 block_ptr += pui_len;
603*cfb92d14SAndroid Build Coastguard Worker 
604*cfb92d14SAndroid Build Coastguard Worker                 require(pui_len > 0, bail);
605*cfb92d14SAndroid Build Coastguard Worker                 require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
606*cfb92d14SAndroid Build Coastguard Worker             }
607*cfb92d14SAndroid Build Coastguard Worker             else
608*cfb92d14SAndroid Build Coastguard Worker             {
609*cfb92d14SAndroid Build Coastguard Worker                 block_len = (uint16_t)data_len;
610*cfb92d14SAndroid Build Coastguard Worker                 pui_len   = 0;
611*cfb92d14SAndroid Build Coastguard Worker             }
612*cfb92d14SAndroid Build Coastguard Worker 
613*cfb92d14SAndroid Build Coastguard Worker             require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
614*cfb92d14SAndroid Build Coastguard Worker 
615*cfb92d14SAndroid Build Coastguard Worker             if (in_place)
616*cfb92d14SAndroid Build Coastguard Worker             {
617*cfb92d14SAndroid Build Coastguard Worker                 require_action(NULL != block_len_ptr && *block_len_ptr >= block_len, bail, (ret = -1, errno = EINVAL));
618*cfb92d14SAndroid Build Coastguard Worker                 memcpy(arg_ptr, block_ptr, block_len);
619*cfb92d14SAndroid Build Coastguard Worker             }
620*cfb92d14SAndroid Build Coastguard Worker             else
621*cfb92d14SAndroid Build Coastguard Worker             {
622*cfb92d14SAndroid Build Coastguard Worker                 const uint8_t **block_ptr_ptr = (const uint8_t **)arg_ptr;
623*cfb92d14SAndroid Build Coastguard Worker                 if (NULL != block_ptr_ptr)
624*cfb92d14SAndroid Build Coastguard Worker                 {
625*cfb92d14SAndroid Build Coastguard Worker                     *block_ptr_ptr = block_ptr;
626*cfb92d14SAndroid Build Coastguard Worker                 }
627*cfb92d14SAndroid Build Coastguard Worker             }
628*cfb92d14SAndroid Build Coastguard Worker 
629*cfb92d14SAndroid Build Coastguard Worker             if (NULL != block_len_ptr)
630*cfb92d14SAndroid Build Coastguard Worker             {
631*cfb92d14SAndroid Build Coastguard Worker                 *block_len_ptr = block_len;
632*cfb92d14SAndroid Build Coastguard Worker             }
633*cfb92d14SAndroid Build Coastguard Worker 
634*cfb92d14SAndroid Build Coastguard Worker             block_len += (uint16_t)pui_len;
635*cfb92d14SAndroid Build Coastguard Worker             ret += block_len;
636*cfb92d14SAndroid Build Coastguard Worker             data_in += block_len;
637*cfb92d14SAndroid Build Coastguard Worker             data_len -= block_len;
638*cfb92d14SAndroid Build Coastguard Worker             break;
639*cfb92d14SAndroid Build Coastguard Worker         }
640*cfb92d14SAndroid Build Coastguard Worker 
641*cfb92d14SAndroid Build Coastguard Worker         case 'T':
642*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_STRUCT_C:
643*cfb92d14SAndroid Build Coastguard Worker         {
644*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t pui_len    = 0;
645*cfb92d14SAndroid Build Coastguard Worker             uint16_t       block_len  = 0;
646*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t actual_len = 0;
647*cfb92d14SAndroid Build Coastguard Worker             const uint8_t *block_ptr  = data_in;
648*cfb92d14SAndroid Build Coastguard Worker             char           nextformat = *spinel_next_packed_datatype(pack_format);
649*cfb92d14SAndroid Build Coastguard Worker 
650*cfb92d14SAndroid Build Coastguard Worker             if ((pack_format[0] == SPINEL_DATATYPE_STRUCT_C) || ((nextformat != 0) && (nextformat != ')')))
651*cfb92d14SAndroid Build Coastguard Worker             {
652*cfb92d14SAndroid Build Coastguard Worker                 pui_len = spinel_datatype_unpack(data_in, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
653*cfb92d14SAndroid Build Coastguard Worker                 block_ptr += pui_len;
654*cfb92d14SAndroid Build Coastguard Worker 
655*cfb92d14SAndroid Build Coastguard Worker                 require(pui_len > 0, bail);
656*cfb92d14SAndroid Build Coastguard Worker                 require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
657*cfb92d14SAndroid Build Coastguard Worker             }
658*cfb92d14SAndroid Build Coastguard Worker             else
659*cfb92d14SAndroid Build Coastguard Worker             {
660*cfb92d14SAndroid Build Coastguard Worker                 block_len = (uint16_t)data_len;
661*cfb92d14SAndroid Build Coastguard Worker                 pui_len   = 0;
662*cfb92d14SAndroid Build Coastguard Worker             }
663*cfb92d14SAndroid Build Coastguard Worker 
664*cfb92d14SAndroid Build Coastguard Worker             require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
665*cfb92d14SAndroid Build Coastguard Worker 
666*cfb92d14SAndroid Build Coastguard Worker             actual_len = spinel_datatype_vunpack_(false, block_ptr, block_len, pack_format + 2, args);
667*cfb92d14SAndroid Build Coastguard Worker 
668*cfb92d14SAndroid Build Coastguard Worker             require_action(actual_len > -1, bail, (ret = -1, errno = EOVERFLOW));
669*cfb92d14SAndroid Build Coastguard Worker 
670*cfb92d14SAndroid Build Coastguard Worker             if (pui_len)
671*cfb92d14SAndroid Build Coastguard Worker             {
672*cfb92d14SAndroid Build Coastguard Worker                 block_len += (uint16_t)pui_len;
673*cfb92d14SAndroid Build Coastguard Worker             }
674*cfb92d14SAndroid Build Coastguard Worker             else
675*cfb92d14SAndroid Build Coastguard Worker             {
676*cfb92d14SAndroid Build Coastguard Worker                 block_len = (uint16_t)actual_len;
677*cfb92d14SAndroid Build Coastguard Worker             }
678*cfb92d14SAndroid Build Coastguard Worker 
679*cfb92d14SAndroid Build Coastguard Worker             ret += block_len;
680*cfb92d14SAndroid Build Coastguard Worker             data_in += block_len;
681*cfb92d14SAndroid Build Coastguard Worker             data_len -= block_len;
682*cfb92d14SAndroid Build Coastguard Worker             break;
683*cfb92d14SAndroid Build Coastguard Worker         }
684*cfb92d14SAndroid Build Coastguard Worker 
685*cfb92d14SAndroid Build Coastguard Worker         case '.':
686*cfb92d14SAndroid Build Coastguard Worker             // Skip.
687*cfb92d14SAndroid Build Coastguard Worker             break;
688*cfb92d14SAndroid Build Coastguard Worker 
689*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_ARRAY_C:
690*cfb92d14SAndroid Build Coastguard Worker         default:
691*cfb92d14SAndroid Build Coastguard Worker             // Unsupported Type!
692*cfb92d14SAndroid Build Coastguard Worker             ret   = -1;
693*cfb92d14SAndroid Build Coastguard Worker             errno = EINVAL;
694*cfb92d14SAndroid Build Coastguard Worker             goto bail;
695*cfb92d14SAndroid Build Coastguard Worker         }
696*cfb92d14SAndroid Build Coastguard Worker     }
697*cfb92d14SAndroid Build Coastguard Worker 
698*cfb92d14SAndroid Build Coastguard Worker     return ret;
699*cfb92d14SAndroid Build Coastguard Worker 
700*cfb92d14SAndroid Build Coastguard Worker bail:
701*cfb92d14SAndroid Build Coastguard Worker     return ret;
702*cfb92d14SAndroid Build Coastguard Worker }
703*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_unpack_in_place(const uint8_t * data_in,spinel_size_t data_len,const char * pack_format,...)704*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_datatype_unpack_in_place(const uint8_t *data_in,
705*cfb92d14SAndroid Build Coastguard Worker                                                spinel_size_t  data_len,
706*cfb92d14SAndroid Build Coastguard Worker                                                const char    *pack_format,
707*cfb92d14SAndroid Build Coastguard Worker                                                ...)
708*cfb92d14SAndroid Build Coastguard Worker {
709*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret;
710*cfb92d14SAndroid Build Coastguard Worker     va_list_obj    args;
711*cfb92d14SAndroid Build Coastguard Worker     va_start(args.obj, pack_format);
712*cfb92d14SAndroid Build Coastguard Worker 
713*cfb92d14SAndroid Build Coastguard Worker     ret = spinel_datatype_vunpack_(true, data_in, data_len, pack_format, &args);
714*cfb92d14SAndroid Build Coastguard Worker 
715*cfb92d14SAndroid Build Coastguard Worker     va_end(args.obj);
716*cfb92d14SAndroid Build Coastguard Worker     return ret;
717*cfb92d14SAndroid Build Coastguard Worker }
718*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_unpack(const uint8_t * data_in,spinel_size_t data_len,const char * pack_format,...)719*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_datatype_unpack(const uint8_t *data_in, spinel_size_t data_len, const char *pack_format, ...)
720*cfb92d14SAndroid Build Coastguard Worker {
721*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret;
722*cfb92d14SAndroid Build Coastguard Worker     va_list_obj    args;
723*cfb92d14SAndroid Build Coastguard Worker     va_start(args.obj, pack_format);
724*cfb92d14SAndroid Build Coastguard Worker 
725*cfb92d14SAndroid Build Coastguard Worker     ret = spinel_datatype_vunpack_(false, data_in, data_len, pack_format, &args);
726*cfb92d14SAndroid Build Coastguard Worker 
727*cfb92d14SAndroid Build Coastguard Worker     va_end(args.obj);
728*cfb92d14SAndroid Build Coastguard Worker     return ret;
729*cfb92d14SAndroid Build Coastguard Worker }
730*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_vunpack_in_place(const uint8_t * data_in,spinel_size_t data_len,const char * pack_format,va_list args)731*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_datatype_vunpack_in_place(const uint8_t *data_in,
732*cfb92d14SAndroid Build Coastguard Worker                                                 spinel_size_t  data_len,
733*cfb92d14SAndroid Build Coastguard Worker                                                 const char    *pack_format,
734*cfb92d14SAndroid Build Coastguard Worker                                                 va_list        args)
735*cfb92d14SAndroid Build Coastguard Worker {
736*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret;
737*cfb92d14SAndroid Build Coastguard Worker     va_list_obj    args_obj;
738*cfb92d14SAndroid Build Coastguard Worker     va_copy(args_obj.obj, args);
739*cfb92d14SAndroid Build Coastguard Worker 
740*cfb92d14SAndroid Build Coastguard Worker     ret = spinel_datatype_vunpack_(true, data_in, data_len, pack_format, &args_obj);
741*cfb92d14SAndroid Build Coastguard Worker 
742*cfb92d14SAndroid Build Coastguard Worker     va_end(args_obj.obj);
743*cfb92d14SAndroid Build Coastguard Worker     return ret;
744*cfb92d14SAndroid Build Coastguard Worker }
745*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_vunpack(const uint8_t * data_in,spinel_size_t data_len,const char * pack_format,va_list args)746*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_datatype_vunpack(const uint8_t *data_in,
747*cfb92d14SAndroid Build Coastguard Worker                                        spinel_size_t  data_len,
748*cfb92d14SAndroid Build Coastguard Worker                                        const char    *pack_format,
749*cfb92d14SAndroid Build Coastguard Worker                                        va_list        args)
750*cfb92d14SAndroid Build Coastguard Worker {
751*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret;
752*cfb92d14SAndroid Build Coastguard Worker     va_list_obj    args_obj;
753*cfb92d14SAndroid Build Coastguard Worker     va_copy(args_obj.obj, args);
754*cfb92d14SAndroid Build Coastguard Worker 
755*cfb92d14SAndroid Build Coastguard Worker     ret = spinel_datatype_vunpack_(false, data_in, data_len, pack_format, &args_obj);
756*cfb92d14SAndroid Build Coastguard Worker 
757*cfb92d14SAndroid Build Coastguard Worker     va_end(args_obj.obj);
758*cfb92d14SAndroid Build Coastguard Worker     return ret;
759*cfb92d14SAndroid Build Coastguard Worker }
760*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_vpack_(uint8_t * data_out,spinel_size_t data_len_max,const char * pack_format,va_list_obj * args)761*cfb92d14SAndroid Build Coastguard Worker static spinel_ssize_t spinel_datatype_vpack_(uint8_t      *data_out,
762*cfb92d14SAndroid Build Coastguard Worker                                              spinel_size_t data_len_max,
763*cfb92d14SAndroid Build Coastguard Worker                                              const char   *pack_format,
764*cfb92d14SAndroid Build Coastguard Worker                                              va_list_obj  *args)
765*cfb92d14SAndroid Build Coastguard Worker {
766*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t ret = 0;
767*cfb92d14SAndroid Build Coastguard Worker 
768*cfb92d14SAndroid Build Coastguard Worker     // Buffer length sanity check
769*cfb92d14SAndroid Build Coastguard Worker     require_action(data_len_max <= SPINEL_MAX_PACK_LENGTH, bail, (ret = -1, errno = EINVAL));
770*cfb92d14SAndroid Build Coastguard Worker 
771*cfb92d14SAndroid Build Coastguard Worker     if (data_out == NULL)
772*cfb92d14SAndroid Build Coastguard Worker     {
773*cfb92d14SAndroid Build Coastguard Worker         data_len_max = 0;
774*cfb92d14SAndroid Build Coastguard Worker     }
775*cfb92d14SAndroid Build Coastguard Worker 
776*cfb92d14SAndroid Build Coastguard Worker     for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
777*cfb92d14SAndroid Build Coastguard Worker     {
778*cfb92d14SAndroid Build Coastguard Worker         if (*pack_format == ')')
779*cfb92d14SAndroid Build Coastguard Worker         {
780*cfb92d14SAndroid Build Coastguard Worker             // Don't go past the end of a struct.
781*cfb92d14SAndroid Build Coastguard Worker             break;
782*cfb92d14SAndroid Build Coastguard Worker         }
783*cfb92d14SAndroid Build Coastguard Worker 
784*cfb92d14SAndroid Build Coastguard Worker         switch ((spinel_datatype_t)*pack_format)
785*cfb92d14SAndroid Build Coastguard Worker         {
786*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_BOOL_C:
787*cfb92d14SAndroid Build Coastguard Worker         {
788*cfb92d14SAndroid Build Coastguard Worker             bool arg = (bool)va_arg(args->obj, int);
789*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint8_t);
790*cfb92d14SAndroid Build Coastguard Worker 
791*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(uint8_t))
792*cfb92d14SAndroid Build Coastguard Worker             {
793*cfb92d14SAndroid Build Coastguard Worker                 data_out[0] = (arg != false);
794*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(uint8_t);
795*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(uint8_t);
796*cfb92d14SAndroid Build Coastguard Worker             }
797*cfb92d14SAndroid Build Coastguard Worker             else
798*cfb92d14SAndroid Build Coastguard Worker             {
799*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
800*cfb92d14SAndroid Build Coastguard Worker             }
801*cfb92d14SAndroid Build Coastguard Worker 
802*cfb92d14SAndroid Build Coastguard Worker             break;
803*cfb92d14SAndroid Build Coastguard Worker         }
804*cfb92d14SAndroid Build Coastguard Worker 
805*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT8_C:
806*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT8_C:
807*cfb92d14SAndroid Build Coastguard Worker         {
808*cfb92d14SAndroid Build Coastguard Worker             uint8_t arg = (uint8_t)va_arg(args->obj, int);
809*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint8_t);
810*cfb92d14SAndroid Build Coastguard Worker 
811*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(uint8_t))
812*cfb92d14SAndroid Build Coastguard Worker             {
813*cfb92d14SAndroid Build Coastguard Worker                 data_out[0] = arg;
814*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(uint8_t);
815*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(uint8_t);
816*cfb92d14SAndroid Build Coastguard Worker             }
817*cfb92d14SAndroid Build Coastguard Worker             else
818*cfb92d14SAndroid Build Coastguard Worker             {
819*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
820*cfb92d14SAndroid Build Coastguard Worker             }
821*cfb92d14SAndroid Build Coastguard Worker 
822*cfb92d14SAndroid Build Coastguard Worker             break;
823*cfb92d14SAndroid Build Coastguard Worker         }
824*cfb92d14SAndroid Build Coastguard Worker 
825*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT16_C:
826*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT16_C:
827*cfb92d14SAndroid Build Coastguard Worker         {
828*cfb92d14SAndroid Build Coastguard Worker             uint16_t arg = (uint16_t)va_arg(args->obj, int);
829*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint16_t);
830*cfb92d14SAndroid Build Coastguard Worker 
831*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(uint16_t))
832*cfb92d14SAndroid Build Coastguard Worker             {
833*cfb92d14SAndroid Build Coastguard Worker                 data_out[1] = (arg >> 8) & 0xff;
834*cfb92d14SAndroid Build Coastguard Worker                 data_out[0] = (arg >> 0) & 0xff;
835*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(uint16_t);
836*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(uint16_t);
837*cfb92d14SAndroid Build Coastguard Worker             }
838*cfb92d14SAndroid Build Coastguard Worker             else
839*cfb92d14SAndroid Build Coastguard Worker             {
840*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
841*cfb92d14SAndroid Build Coastguard Worker             }
842*cfb92d14SAndroid Build Coastguard Worker 
843*cfb92d14SAndroid Build Coastguard Worker             break;
844*cfb92d14SAndroid Build Coastguard Worker         }
845*cfb92d14SAndroid Build Coastguard Worker 
846*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT32_C:
847*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT32_C:
848*cfb92d14SAndroid Build Coastguard Worker         {
849*cfb92d14SAndroid Build Coastguard Worker             uint32_t arg = (uint32_t)va_arg(args->obj, int);
850*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint32_t);
851*cfb92d14SAndroid Build Coastguard Worker 
852*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(uint32_t))
853*cfb92d14SAndroid Build Coastguard Worker             {
854*cfb92d14SAndroid Build Coastguard Worker                 data_out[3] = (arg >> 24) & 0xff;
855*cfb92d14SAndroid Build Coastguard Worker                 data_out[2] = (arg >> 16) & 0xff;
856*cfb92d14SAndroid Build Coastguard Worker                 data_out[1] = (arg >> 8) & 0xff;
857*cfb92d14SAndroid Build Coastguard Worker                 data_out[0] = (arg >> 0) & 0xff;
858*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(uint32_t);
859*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(uint32_t);
860*cfb92d14SAndroid Build Coastguard Worker             }
861*cfb92d14SAndroid Build Coastguard Worker             else
862*cfb92d14SAndroid Build Coastguard Worker             {
863*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
864*cfb92d14SAndroid Build Coastguard Worker             }
865*cfb92d14SAndroid Build Coastguard Worker 
866*cfb92d14SAndroid Build Coastguard Worker             break;
867*cfb92d14SAndroid Build Coastguard Worker         }
868*cfb92d14SAndroid Build Coastguard Worker 
869*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_INT64_C:
870*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT64_C:
871*cfb92d14SAndroid Build Coastguard Worker         {
872*cfb92d14SAndroid Build Coastguard Worker             uint64_t arg = va_arg(args->obj, uint64_t);
873*cfb92d14SAndroid Build Coastguard Worker 
874*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(uint64_t);
875*cfb92d14SAndroid Build Coastguard Worker 
876*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(uint64_t))
877*cfb92d14SAndroid Build Coastguard Worker             {
878*cfb92d14SAndroid Build Coastguard Worker                 data_out[7] = (arg >> 56) & 0xff;
879*cfb92d14SAndroid Build Coastguard Worker                 data_out[6] = (arg >> 48) & 0xff;
880*cfb92d14SAndroid Build Coastguard Worker                 data_out[5] = (arg >> 40) & 0xff;
881*cfb92d14SAndroid Build Coastguard Worker                 data_out[4] = (arg >> 32) & 0xff;
882*cfb92d14SAndroid Build Coastguard Worker                 data_out[3] = (arg >> 24) & 0xff;
883*cfb92d14SAndroid Build Coastguard Worker                 data_out[2] = (arg >> 16) & 0xff;
884*cfb92d14SAndroid Build Coastguard Worker                 data_out[1] = (arg >> 8) & 0xff;
885*cfb92d14SAndroid Build Coastguard Worker                 data_out[0] = (arg >> 0) & 0xff;
886*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(uint64_t);
887*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(uint64_t);
888*cfb92d14SAndroid Build Coastguard Worker             }
889*cfb92d14SAndroid Build Coastguard Worker             else
890*cfb92d14SAndroid Build Coastguard Worker             {
891*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
892*cfb92d14SAndroid Build Coastguard Worker             }
893*cfb92d14SAndroid Build Coastguard Worker 
894*cfb92d14SAndroid Build Coastguard Worker             break;
895*cfb92d14SAndroid Build Coastguard Worker         }
896*cfb92d14SAndroid Build Coastguard Worker 
897*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_IPv6ADDR_C:
898*cfb92d14SAndroid Build Coastguard Worker         {
899*cfb92d14SAndroid Build Coastguard Worker             spinel_ipv6addr_t *arg = va_arg(args->obj, spinel_ipv6addr_t *);
900*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(spinel_ipv6addr_t);
901*cfb92d14SAndroid Build Coastguard Worker 
902*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(spinel_ipv6addr_t))
903*cfb92d14SAndroid Build Coastguard Worker             {
904*cfb92d14SAndroid Build Coastguard Worker                 *(spinel_ipv6addr_t *)data_out = *arg;
905*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(spinel_ipv6addr_t);
906*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(spinel_ipv6addr_t);
907*cfb92d14SAndroid Build Coastguard Worker             }
908*cfb92d14SAndroid Build Coastguard Worker             else
909*cfb92d14SAndroid Build Coastguard Worker             {
910*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
911*cfb92d14SAndroid Build Coastguard Worker             }
912*cfb92d14SAndroid Build Coastguard Worker 
913*cfb92d14SAndroid Build Coastguard Worker             break;
914*cfb92d14SAndroid Build Coastguard Worker         }
915*cfb92d14SAndroid Build Coastguard Worker 
916*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_EUI48_C:
917*cfb92d14SAndroid Build Coastguard Worker         {
918*cfb92d14SAndroid Build Coastguard Worker             spinel_eui48_t *arg = va_arg(args->obj, spinel_eui48_t *);
919*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(spinel_eui48_t);
920*cfb92d14SAndroid Build Coastguard Worker 
921*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(spinel_eui48_t))
922*cfb92d14SAndroid Build Coastguard Worker             {
923*cfb92d14SAndroid Build Coastguard Worker                 *(spinel_eui48_t *)data_out = *arg;
924*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(spinel_eui48_t);
925*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(spinel_eui48_t);
926*cfb92d14SAndroid Build Coastguard Worker             }
927*cfb92d14SAndroid Build Coastguard Worker             else
928*cfb92d14SAndroid Build Coastguard Worker             {
929*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
930*cfb92d14SAndroid Build Coastguard Worker             }
931*cfb92d14SAndroid Build Coastguard Worker 
932*cfb92d14SAndroid Build Coastguard Worker             break;
933*cfb92d14SAndroid Build Coastguard Worker         }
934*cfb92d14SAndroid Build Coastguard Worker 
935*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_EUI64_C:
936*cfb92d14SAndroid Build Coastguard Worker         {
937*cfb92d14SAndroid Build Coastguard Worker             spinel_eui64_t *arg = va_arg(args->obj, spinel_eui64_t *);
938*cfb92d14SAndroid Build Coastguard Worker             ret += sizeof(spinel_eui64_t);
939*cfb92d14SAndroid Build Coastguard Worker 
940*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= sizeof(spinel_eui64_t))
941*cfb92d14SAndroid Build Coastguard Worker             {
942*cfb92d14SAndroid Build Coastguard Worker                 *(spinel_eui64_t *)data_out = *arg;
943*cfb92d14SAndroid Build Coastguard Worker                 data_out += sizeof(spinel_eui64_t);
944*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= sizeof(spinel_eui64_t);
945*cfb92d14SAndroid Build Coastguard Worker             }
946*cfb92d14SAndroid Build Coastguard Worker             else
947*cfb92d14SAndroid Build Coastguard Worker             {
948*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
949*cfb92d14SAndroid Build Coastguard Worker             }
950*cfb92d14SAndroid Build Coastguard Worker 
951*cfb92d14SAndroid Build Coastguard Worker             break;
952*cfb92d14SAndroid Build Coastguard Worker         }
953*cfb92d14SAndroid Build Coastguard Worker 
954*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UINT_PACKED_C:
955*cfb92d14SAndroid Build Coastguard Worker         {
956*cfb92d14SAndroid Build Coastguard Worker             uint32_t       arg = va_arg(args->obj, uint32_t);
957*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t encoded_size;
958*cfb92d14SAndroid Build Coastguard Worker 
959*cfb92d14SAndroid Build Coastguard Worker             // Range Check
960*cfb92d14SAndroid Build Coastguard Worker             require_action(arg < SPINEL_MAX_UINT_PACKED, bail, {
961*cfb92d14SAndroid Build Coastguard Worker                 ret   = -1;
962*cfb92d14SAndroid Build Coastguard Worker                 errno = EINVAL;
963*cfb92d14SAndroid Build Coastguard Worker             });
964*cfb92d14SAndroid Build Coastguard Worker 
965*cfb92d14SAndroid Build Coastguard Worker             encoded_size = spinel_packed_uint_encode(data_out, data_len_max, arg);
966*cfb92d14SAndroid Build Coastguard Worker             ret += encoded_size;
967*cfb92d14SAndroid Build Coastguard Worker 
968*cfb92d14SAndroid Build Coastguard Worker             if ((spinel_ssize_t)data_len_max >= encoded_size)
969*cfb92d14SAndroid Build Coastguard Worker             {
970*cfb92d14SAndroid Build Coastguard Worker                 data_out += encoded_size;
971*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= (spinel_size_t)encoded_size;
972*cfb92d14SAndroid Build Coastguard Worker             }
973*cfb92d14SAndroid Build Coastguard Worker             else
974*cfb92d14SAndroid Build Coastguard Worker             {
975*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
976*cfb92d14SAndroid Build Coastguard Worker             }
977*cfb92d14SAndroid Build Coastguard Worker 
978*cfb92d14SAndroid Build Coastguard Worker             break;
979*cfb92d14SAndroid Build Coastguard Worker         }
980*cfb92d14SAndroid Build Coastguard Worker 
981*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_UTF8_C:
982*cfb92d14SAndroid Build Coastguard Worker         {
983*cfb92d14SAndroid Build Coastguard Worker             const char *string_arg     = va_arg(args->obj, const char *);
984*cfb92d14SAndroid Build Coastguard Worker             size_t      string_arg_len = 0;
985*cfb92d14SAndroid Build Coastguard Worker 
986*cfb92d14SAndroid Build Coastguard Worker             if (string_arg)
987*cfb92d14SAndroid Build Coastguard Worker             {
988*cfb92d14SAndroid Build Coastguard Worker                 string_arg_len = strlen(string_arg) + 1;
989*cfb92d14SAndroid Build Coastguard Worker             }
990*cfb92d14SAndroid Build Coastguard Worker             else
991*cfb92d14SAndroid Build Coastguard Worker             {
992*cfb92d14SAndroid Build Coastguard Worker                 string_arg     = "";
993*cfb92d14SAndroid Build Coastguard Worker                 string_arg_len = 1;
994*cfb92d14SAndroid Build Coastguard Worker             }
995*cfb92d14SAndroid Build Coastguard Worker 
996*cfb92d14SAndroid Build Coastguard Worker             ret += (spinel_size_t)string_arg_len;
997*cfb92d14SAndroid Build Coastguard Worker 
998*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= string_arg_len)
999*cfb92d14SAndroid Build Coastguard Worker             {
1000*cfb92d14SAndroid Build Coastguard Worker                 memcpy(data_out, string_arg, string_arg_len);
1001*cfb92d14SAndroid Build Coastguard Worker 
1002*cfb92d14SAndroid Build Coastguard Worker                 data_out += string_arg_len;
1003*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= (spinel_size_t)string_arg_len;
1004*cfb92d14SAndroid Build Coastguard Worker             }
1005*cfb92d14SAndroid Build Coastguard Worker             else
1006*cfb92d14SAndroid Build Coastguard Worker             {
1007*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
1008*cfb92d14SAndroid Build Coastguard Worker             }
1009*cfb92d14SAndroid Build Coastguard Worker 
1010*cfb92d14SAndroid Build Coastguard Worker             break;
1011*cfb92d14SAndroid Build Coastguard Worker         }
1012*cfb92d14SAndroid Build Coastguard Worker 
1013*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_DATA_WLEN_C:
1014*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_DATA_C:
1015*cfb92d14SAndroid Build Coastguard Worker         {
1016*cfb92d14SAndroid Build Coastguard Worker             const uint8_t *arg           = va_arg(args->obj, const uint8_t *);
1017*cfb92d14SAndroid Build Coastguard Worker             uint32_t       data_size_arg = va_arg(args->obj, uint32_t);
1018*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t size_len      = 0;
1019*cfb92d14SAndroid Build Coastguard Worker             char           nextformat    = *spinel_next_packed_datatype(pack_format);
1020*cfb92d14SAndroid Build Coastguard Worker 
1021*cfb92d14SAndroid Build Coastguard Worker             if ((pack_format[0] == SPINEL_DATATYPE_DATA_WLEN_C) || ((nextformat != 0) && (nextformat != ')')))
1022*cfb92d14SAndroid Build Coastguard Worker             {
1023*cfb92d14SAndroid Build Coastguard Worker                 size_len = spinel_datatype_pack(data_out, data_len_max, SPINEL_DATATYPE_UINT16_S, data_size_arg);
1024*cfb92d14SAndroid Build Coastguard Worker                 require_action(size_len > 0, bail, {
1025*cfb92d14SAndroid Build Coastguard Worker                     ret   = -1;
1026*cfb92d14SAndroid Build Coastguard Worker                     errno = EINVAL;
1027*cfb92d14SAndroid Build Coastguard Worker                 });
1028*cfb92d14SAndroid Build Coastguard Worker             }
1029*cfb92d14SAndroid Build Coastguard Worker 
1030*cfb92d14SAndroid Build Coastguard Worker             ret += (spinel_size_t)size_len + data_size_arg;
1031*cfb92d14SAndroid Build Coastguard Worker 
1032*cfb92d14SAndroid Build Coastguard Worker             if (data_len_max >= (spinel_size_t)size_len + data_size_arg)
1033*cfb92d14SAndroid Build Coastguard Worker             {
1034*cfb92d14SAndroid Build Coastguard Worker                 data_out += size_len;
1035*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= (spinel_size_t)size_len;
1036*cfb92d14SAndroid Build Coastguard Worker 
1037*cfb92d14SAndroid Build Coastguard Worker                 if (data_out && arg)
1038*cfb92d14SAndroid Build Coastguard Worker                 {
1039*cfb92d14SAndroid Build Coastguard Worker                     memcpy(data_out, arg, data_size_arg);
1040*cfb92d14SAndroid Build Coastguard Worker                 }
1041*cfb92d14SAndroid Build Coastguard Worker 
1042*cfb92d14SAndroid Build Coastguard Worker                 data_out += data_size_arg;
1043*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= data_size_arg;
1044*cfb92d14SAndroid Build Coastguard Worker             }
1045*cfb92d14SAndroid Build Coastguard Worker             else
1046*cfb92d14SAndroid Build Coastguard Worker             {
1047*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
1048*cfb92d14SAndroid Build Coastguard Worker             }
1049*cfb92d14SAndroid Build Coastguard Worker 
1050*cfb92d14SAndroid Build Coastguard Worker             break;
1051*cfb92d14SAndroid Build Coastguard Worker         }
1052*cfb92d14SAndroid Build Coastguard Worker 
1053*cfb92d14SAndroid Build Coastguard Worker         case 'T':
1054*cfb92d14SAndroid Build Coastguard Worker         case SPINEL_DATATYPE_STRUCT_C:
1055*cfb92d14SAndroid Build Coastguard Worker         {
1056*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t struct_len = 0;
1057*cfb92d14SAndroid Build Coastguard Worker             spinel_ssize_t size_len   = 0;
1058*cfb92d14SAndroid Build Coastguard Worker             char           nextformat = *spinel_next_packed_datatype(pack_format);
1059*cfb92d14SAndroid Build Coastguard Worker 
1060*cfb92d14SAndroid Build Coastguard Worker             require_action(pack_format[1] == '(', bail, {
1061*cfb92d14SAndroid Build Coastguard Worker                 ret   = -1;
1062*cfb92d14SAndroid Build Coastguard Worker                 errno = EINVAL;
1063*cfb92d14SAndroid Build Coastguard Worker             });
1064*cfb92d14SAndroid Build Coastguard Worker 
1065*cfb92d14SAndroid Build Coastguard Worker             // First we figure out the size of the struct
1066*cfb92d14SAndroid Build Coastguard Worker             {
1067*cfb92d14SAndroid Build Coastguard Worker                 va_list_obj subargs;
1068*cfb92d14SAndroid Build Coastguard Worker                 va_copy(subargs.obj, args->obj);
1069*cfb92d14SAndroid Build Coastguard Worker                 struct_len = spinel_datatype_vpack_(NULL, 0, pack_format + 2, &subargs);
1070*cfb92d14SAndroid Build Coastguard Worker                 va_end(subargs.obj);
1071*cfb92d14SAndroid Build Coastguard Worker             }
1072*cfb92d14SAndroid Build Coastguard Worker 
1073*cfb92d14SAndroid Build Coastguard Worker             if ((pack_format[0] == SPINEL_DATATYPE_STRUCT_C) || ((nextformat != 0) && (nextformat != ')')))
1074*cfb92d14SAndroid Build Coastguard Worker             {
1075*cfb92d14SAndroid Build Coastguard Worker                 size_len = spinel_datatype_pack(data_out, data_len_max, SPINEL_DATATYPE_UINT16_S, struct_len);
1076*cfb92d14SAndroid Build Coastguard Worker                 require_action(size_len > 0, bail, {
1077*cfb92d14SAndroid Build Coastguard Worker                     ret   = -1;
1078*cfb92d14SAndroid Build Coastguard Worker                     errno = EINVAL;
1079*cfb92d14SAndroid Build Coastguard Worker                 });
1080*cfb92d14SAndroid Build Coastguard Worker             }
1081*cfb92d14SAndroid Build Coastguard Worker 
1082*cfb92d14SAndroid Build Coastguard Worker             ret += size_len + struct_len;
1083*cfb92d14SAndroid Build Coastguard Worker 
1084*cfb92d14SAndroid Build Coastguard Worker             if (struct_len + size_len <= (spinel_ssize_t)data_len_max)
1085*cfb92d14SAndroid Build Coastguard Worker             {
1086*cfb92d14SAndroid Build Coastguard Worker                 data_out += size_len;
1087*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= (spinel_size_t)size_len;
1088*cfb92d14SAndroid Build Coastguard Worker 
1089*cfb92d14SAndroid Build Coastguard Worker                 struct_len = spinel_datatype_vpack_(data_out, data_len_max, pack_format + 2, args);
1090*cfb92d14SAndroid Build Coastguard Worker 
1091*cfb92d14SAndroid Build Coastguard Worker                 data_out += struct_len;
1092*cfb92d14SAndroid Build Coastguard Worker                 data_len_max -= (spinel_size_t)struct_len;
1093*cfb92d14SAndroid Build Coastguard Worker             }
1094*cfb92d14SAndroid Build Coastguard Worker             else
1095*cfb92d14SAndroid Build Coastguard Worker             {
1096*cfb92d14SAndroid Build Coastguard Worker                 data_len_max = 0;
1097*cfb92d14SAndroid Build Coastguard Worker             }
1098*cfb92d14SAndroid Build Coastguard Worker 
1099*cfb92d14SAndroid Build Coastguard Worker             break;
1100*cfb92d14SAndroid Build Coastguard Worker         }
1101*cfb92d14SAndroid Build Coastguard Worker 
1102*cfb92d14SAndroid Build Coastguard Worker         case '.':
1103*cfb92d14SAndroid Build Coastguard Worker             // Skip.
1104*cfb92d14SAndroid Build Coastguard Worker             break;
1105*cfb92d14SAndroid Build Coastguard Worker 
1106*cfb92d14SAndroid Build Coastguard Worker         default:
1107*cfb92d14SAndroid Build Coastguard Worker             // Unsupported Type!
1108*cfb92d14SAndroid Build Coastguard Worker             ret   = -1;
1109*cfb92d14SAndroid Build Coastguard Worker             errno = EINVAL;
1110*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1111*cfb92d14SAndroid Build Coastguard Worker         }
1112*cfb92d14SAndroid Build Coastguard Worker     }
1113*cfb92d14SAndroid Build Coastguard Worker 
1114*cfb92d14SAndroid Build Coastguard Worker bail:
1115*cfb92d14SAndroid Build Coastguard Worker     return ret;
1116*cfb92d14SAndroid Build Coastguard Worker }
1117*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_pack(uint8_t * data_out,spinel_size_t data_len_max,const char * pack_format,...)1118*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_datatype_pack(uint8_t *data_out, spinel_size_t data_len_max, const char *pack_format, ...)
1119*cfb92d14SAndroid Build Coastguard Worker {
1120*cfb92d14SAndroid Build Coastguard Worker     int         ret;
1121*cfb92d14SAndroid Build Coastguard Worker     va_list_obj args;
1122*cfb92d14SAndroid Build Coastguard Worker     va_start(args.obj, pack_format);
1123*cfb92d14SAndroid Build Coastguard Worker 
1124*cfb92d14SAndroid Build Coastguard Worker     ret = spinel_datatype_vpack_(data_out, data_len_max, pack_format, &args);
1125*cfb92d14SAndroid Build Coastguard Worker 
1126*cfb92d14SAndroid Build Coastguard Worker     va_end(args.obj);
1127*cfb92d14SAndroid Build Coastguard Worker     return ret;
1128*cfb92d14SAndroid Build Coastguard Worker }
1129*cfb92d14SAndroid Build Coastguard Worker 
spinel_datatype_vpack(uint8_t * data_out,spinel_size_t data_len_max,const char * pack_format,va_list args)1130*cfb92d14SAndroid Build Coastguard Worker spinel_ssize_t spinel_datatype_vpack(uint8_t      *data_out,
1131*cfb92d14SAndroid Build Coastguard Worker                                      spinel_size_t data_len_max,
1132*cfb92d14SAndroid Build Coastguard Worker                                      const char   *pack_format,
1133*cfb92d14SAndroid Build Coastguard Worker                                      va_list       args)
1134*cfb92d14SAndroid Build Coastguard Worker {
1135*cfb92d14SAndroid Build Coastguard Worker     int         ret;
1136*cfb92d14SAndroid Build Coastguard Worker     va_list_obj args_obj;
1137*cfb92d14SAndroid Build Coastguard Worker     va_copy(args_obj.obj, args);
1138*cfb92d14SAndroid Build Coastguard Worker 
1139*cfb92d14SAndroid Build Coastguard Worker     ret = spinel_datatype_vpack_(data_out, data_len_max, pack_format, &args_obj);
1140*cfb92d14SAndroid Build Coastguard Worker 
1141*cfb92d14SAndroid Build Coastguard Worker     va_end(args_obj.obj);
1142*cfb92d14SAndroid Build Coastguard Worker     return ret;
1143*cfb92d14SAndroid Build Coastguard Worker }
1144*cfb92d14SAndroid Build Coastguard Worker 
1145*cfb92d14SAndroid Build Coastguard Worker // ----------------------------------------------------------------------------
1146*cfb92d14SAndroid Build Coastguard Worker // MARK: -
1147*cfb92d14SAndroid Build Coastguard Worker 
1148*cfb92d14SAndroid Build Coastguard Worker // LCOV_EXCL_START
1149*cfb92d14SAndroid Build Coastguard Worker 
1150*cfb92d14SAndroid Build Coastguard Worker struct spinel_cstr
1151*cfb92d14SAndroid Build Coastguard Worker {
1152*cfb92d14SAndroid Build Coastguard Worker     uint32_t    val;
1153*cfb92d14SAndroid Build Coastguard Worker     const char *str;
1154*cfb92d14SAndroid Build Coastguard Worker };
1155*cfb92d14SAndroid Build Coastguard Worker 
spinel_to_cstr(const struct spinel_cstr * table,uint32_t val)1156*cfb92d14SAndroid Build Coastguard Worker static const char *spinel_to_cstr(const struct spinel_cstr *table, uint32_t val)
1157*cfb92d14SAndroid Build Coastguard Worker {
1158*cfb92d14SAndroid Build Coastguard Worker     int i;
1159*cfb92d14SAndroid Build Coastguard Worker 
1160*cfb92d14SAndroid Build Coastguard Worker     for (i = 0; table[i].str; i++)
1161*cfb92d14SAndroid Build Coastguard Worker         if (val == table[i].val)
1162*cfb92d14SAndroid Build Coastguard Worker             return table[i].str;
1163*cfb92d14SAndroid Build Coastguard Worker     return "UNKNOWN";
1164*cfb92d14SAndroid Build Coastguard Worker }
1165*cfb92d14SAndroid Build Coastguard Worker 
spinel_command_to_cstr(spinel_command_t command)1166*cfb92d14SAndroid Build Coastguard Worker const char *spinel_command_to_cstr(spinel_command_t command)
1167*cfb92d14SAndroid Build Coastguard Worker {
1168*cfb92d14SAndroid Build Coastguard Worker     static const struct spinel_cstr spinel_commands_cstr[] = {
1169*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_NOOP, "NOOP"},
1170*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_RESET, "RESET"},
1171*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_GET, "PROP_VALUE_GET"},
1172*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_SET, "PROP_VALUE_SET"},
1173*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_INSERT, "PROP_VALUE_INSERT"},
1174*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_REMOVE, "PROP_VALUE_REMOVE"},
1175*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_IS, "PROP_VALUE_IS"},
1176*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_INSERTED, "PROP_VALUE_INSERTED"},
1177*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_REMOVED, "PROP_VALUE_REMOVED"},
1178*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_NET_SAVE, "NET_SAVE"},
1179*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_NET_CLEAR, "NET_CLEAR"},
1180*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_NET_RECALL, "NET_RECALL"},
1181*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_HBO_OFFLOAD, "HBO_OFFLOAD"},
1182*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_HBO_RECLAIM, "HBO_RECLAIM"},
1183*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_HBO_DROP, "HBO_DROP"},
1184*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_HBO_OFFLOADED, "HBO_OFFLOADED"},
1185*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_HBO_RECLAIMED, "HBO_RECLAIMED"},
1186*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_HBO_DROPPED, "HBO_DROPPED"},
1187*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PEEK, "PEEK"},
1188*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PEEK_RET, "PEEK_RET"},
1189*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_POKE, "POKE"},
1190*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_MULTI_GET, "PROP_VALUE_MULTI_GET"},
1191*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUE_MULTI_SET, "PROP_VALUE_MULTI_SET"},
1192*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CMD_PROP_VALUES_ARE, "PROP_VALUES_ARE"},
1193*cfb92d14SAndroid Build Coastguard Worker         {0, NULL},
1194*cfb92d14SAndroid Build Coastguard Worker     };
1195*cfb92d14SAndroid Build Coastguard Worker 
1196*cfb92d14SAndroid Build Coastguard Worker     return spinel_to_cstr(spinel_commands_cstr, command);
1197*cfb92d14SAndroid Build Coastguard Worker }
1198*cfb92d14SAndroid Build Coastguard Worker 
spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)1199*cfb92d14SAndroid Build Coastguard Worker const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
1200*cfb92d14SAndroid Build Coastguard Worker {
1201*cfb92d14SAndroid Build Coastguard Worker     static const struct spinel_cstr spinel_prop_cstr[] = {
1202*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_LAST_STATUS, "LAST_STATUS"},
1203*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PROTOCOL_VERSION, "PROTOCOL_VERSION"},
1204*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NCP_VERSION, "NCP_VERSION"},
1205*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_INTERFACE_TYPE, "INTERFACE_TYPE"},
1206*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_VENDOR_ID, "VENDOR_ID"},
1207*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CAPS, "CAPS"},
1208*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_INTERFACE_COUNT, "INTERFACE_COUNT"},
1209*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_POWER_STATE, "POWER_STATE"},
1210*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_HWADDR, "HWADDR"},
1211*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_LOCK, "LOCK"},
1212*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_HBO_MEM_MAX, "HBO_MEM_MAX"},
1213*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_HBO_BLOCK_MAX, "HBO_BLOCK_MAX"},
1214*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_HOST_POWER_STATE, "HOST_POWER_STATE"},
1215*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MCU_POWER_STATE, "MCU_POWER_STATE"},
1216*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_GPIO_CONFIG, "GPIO_CONFIG"},
1217*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_GPIO_STATE, "GPIO_STATE"},
1218*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_GPIO_STATE_SET, "GPIO_STATE_SET"},
1219*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_GPIO_STATE_CLEAR, "GPIO_STATE_CLEAR"},
1220*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_TRNG_32, "TRNG_32"},
1221*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_TRNG_128, "TRNG_128"},
1222*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_TRNG_RAW_32, "TRNG_RAW_32"},
1223*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_UNSOL_UPDATE_FILTER, "UNSOL_UPDATE_FILTER"},
1224*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_UNSOL_UPDATE_LIST, "UNSOL_UPDATE_LIST"},
1225*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_ENABLED, "PHY_ENABLED"},
1226*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_CHAN, "PHY_CHAN"},
1227*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_CHAN_SUPPORTED, "PHY_CHAN_SUPPORTED"},
1228*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_FREQ, "PHY_FREQ"},
1229*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_CCA_THRESHOLD, "PHY_CCA_THRESHOLD"},
1230*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_TX_POWER, "PHY_TX_POWER"},
1231*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_FEM_LNA_GAIN, "PHY_FEM_LNA_GAIN"},
1232*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_RSSI, "PHY_RSSI"},
1233*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_RX_SENSITIVITY, "PHY_RX_SENSITIVITY"},
1234*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_PCAP_ENABLED, "PHY_PCAP_ENABLED"},
1235*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_CHAN_PREFERRED, "PHY_CHAN_PREFERRED"},
1236*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_CHAN_MAX_POWER, "PHY_CHAN_MAX_POWER"},
1237*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_REGION_CODE, "PHY_REGION_CODE"},
1238*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_CALIBRATED_POWER, "PHY_CALIBRATED_POWER"},
1239*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PHY_CHAN_TARGET_POWER, "PHY_CHAN_TARGET_POWER"},
1240*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_JAM_DETECT_ENABLE, "JAM_DETECT_ENABLE"},
1241*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_JAM_DETECTED, "JAM_DETECTED"},
1242*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD, "JAM_DETECT_RSSI_THRESHOLD"},
1243*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_JAM_DETECT_WINDOW, "JAM_DETECT_WINDOW"},
1244*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_JAM_DETECT_BUSY, "JAM_DETECT_BUSY"},
1245*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP, "JAM_DETECT_HISTORY_BITMAP"},
1246*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL, "CHANNEL_MONITOR_SAMPLE_INTERVAL"},
1247*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD, "CHANNEL_MONITOR_RSSI_THRESHOLD"},
1248*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW, "CHANNEL_MONITOR_SAMPLE_WINDOW"},
1249*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT, "CHANNEL_MONITOR_SAMPLE_COUNT"},
1250*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_OCCUPANCY, "CHANNEL_MONITOR_CHANNEL_OCCUPANCY"},
1251*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RADIO_CAPS, "RADIO_CAPS"},
1252*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RADIO_COEX_METRICS, "RADIO_COEX_METRICS"},
1253*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RADIO_COEX_ENABLE, "RADIO_COEX_ENABLE"},
1254*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_SCAN_STATE, "MAC_SCAN_STATE"},
1255*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_SCAN_MASK, "MAC_SCAN_MASK"},
1256*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_SCAN_PERIOD, "MAC_SCAN_PERIOD"},
1257*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_SCAN_BEACON, "MAC_SCAN_BEACON"},
1258*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_15_4_LADDR, "MAC_15_4_LADDR"},
1259*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_15_4_SADDR, "MAC_15_4_SADDR"},
1260*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_15_4_PANID, "MAC_15_4_PANID"},
1261*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_RAW_STREAM_ENABLED, "MAC_RAW_STREAM_ENABLED"},
1262*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_PROMISCUOUS_MODE, "MAC_PROMISCUOUS_MODE"},
1263*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_ENERGY_SCAN_RESULT, "MAC_ENERGY_SCAN_RESULT"},
1264*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_DATA_POLL_PERIOD, "MAC_DATA_POLL_PERIOD"},
1265*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_RX_ON_WHEN_IDLE_MODE, "MAC_RX_ON_WHEN_IDLE_MODE"},
1266*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_ALLOWLIST, "MAC_ALLOWLIST"},
1267*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_ALLOWLIST_ENABLED, "MAC_ALLOWLIST_ENABLED"},
1268*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_EXTENDED_ADDR, "MAC_EXTENDED_ADDR"},
1269*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_SRC_MATCH_ENABLED, "MAC_SRC_MATCH_ENABLED"},
1270*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, "MAC_SRC_MATCH_SHORT_ADDRESSES"},
1271*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, "MAC_SRC_MATCH_EXTENDED_ADDRESSES"},
1272*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_DENYLIST, "MAC_DENYLIST"},
1273*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_DENYLIST_ENABLED, "MAC_DENYLIST_ENABLED"},
1274*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_FIXED_RSS, "MAC_FIXED_RSS"},
1275*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_CCA_FAILURE_RATE, "MAC_CCA_FAILURE_RATE"},
1276*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT, "MAC_MAX_RETRY_NUMBER_DIRECT"},
1277*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT, "MAC_MAX_RETRY_NUMBER_INDIRECT"},
1278*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_SAVED, "NET_SAVED"},
1279*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_IF_UP, "NET_IF_UP"},
1280*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_STACK_UP, "NET_STACK_UP"},
1281*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_ROLE, "NET_ROLE"},
1282*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_NETWORK_NAME, "NET_NETWORK_NAME"},
1283*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_XPANID, "NET_XPANID"},
1284*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_NETWORK_KEY, "NET_NETWORK_KEY"},
1285*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, "NET_KEY_SEQUENCE_COUNTER"},
1286*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_PARTITION_ID, "NET_PARTITION_ID"},
1287*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING, "NET_REQUIRE_JOIN_EXISTING"},
1288*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME, "NET_KEY_SWITCH_GUARDTIME"},
1289*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_PSKC, "NET_PSKC"},
1290*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NET_LEAVE_GRACEFULLY, "NET_LEAVE_GRACEFULLY"},
1291*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LEADER_ADDR, "THREAD_LEADER_ADDR"},
1292*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_PARENT, "THREAD_PARENT"},
1293*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CHILD_TABLE, "THREAD_CHILD_TABLE"},
1294*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LEADER_RID, "THREAD_LEADER_RID"},
1295*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LEADER_WEIGHT, "THREAD_LEADER_WEIGHT"},
1296*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT, "THREAD_LOCAL_LEADER_WEIGHT"},
1297*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_NETWORK_DATA, "THREAD_NETWORK_DATA"},
1298*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_NETWORK_DATA_VERSION, "THREAD_NETWORK_DATA_VERSION"},
1299*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_STABLE_NETWORK_DATA, "THREAD_STABLE_NETWORK_DATA"},
1300*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION, "THREAD_STABLE_NETWORK_DATA_VERSION"},
1301*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ON_MESH_NETS, "THREAD_ON_MESH_NETS"},
1302*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_OFF_MESH_ROUTES, "THREAD_OFF_MESH_ROUTES"},
1303*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ASSISTING_PORTS, "THREAD_ASSISTING_PORTS"},
1304*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE, "THREAD_ALLOW_LOCAL_NET_DATA_CHANGE"},
1305*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MODE, "THREAD_MODE"},
1306*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CHILD_TIMEOUT, "THREAD_CHILD_TIMEOUT"},
1307*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_RLOC16, "THREAD_RLOC16"},
1308*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD, "THREAD_ROUTER_UPGRADE_THRESHOLD"},
1309*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY, "THREAD_CONTEXT_REUSE_DELAY"},
1310*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT, "THREAD_NETWORK_ID_TIMEOUT"},
1311*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS, "THREAD_ACTIVE_ROUTER_IDS"},
1312*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU, "THREAD_RLOC16_DEBUG_PASSTHRU"},
1313*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED, "THREAD_ROUTER_ROLE_ENABLED"},
1314*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD, "THREAD_ROUTER_DOWNGRADE_THRESHOLD"},
1315*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER, "THREAD_ROUTER_SELECTION_JITTER"},
1316*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID, "THREAD_PREFERRED_ROUTER_ID"},
1317*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_NEIGHBOR_TABLE, "THREAD_NEIGHBOR_TABLE"},
1318*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CHILD_COUNT_MAX, "THREAD_CHILD_COUNT_MAX"},
1319*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LEADER_NETWORK_DATA, "THREAD_LEADER_NETWORK_DATA"},
1320*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA, "THREAD_STABLE_LEADER_NETWORK_DATA"},
1321*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_JOINERS, "THREAD_JOINERS"},
1322*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_COMMISSIONER_ENABLED, "THREAD_COMMISSIONER_ENABLED"},
1323*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_TMF_PROXY_ENABLED, "THREAD_TMF_PROXY_ENABLED"},
1324*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_TMF_PROXY_STREAM, "THREAD_TMF_PROXY_STREAM"},
1325*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_UDP_FORWARD_STREAM, "THREAD_UDP_FORWARD_STREAM"},
1326*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG, "THREAD_DISCOVERY_SCAN_JOINER_FLAG"},
1327*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING, "THREAD_DISCOVERY_SCAN_ENABLE_FILTERING"},
1328*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID, "THREAD_DISCOVERY_SCAN_PANID"},
1329*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_STEERING_DATA, "THREAD_STEERING_DATA"},
1330*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ROUTER_TABLE, "THREAD_ROUTER_TABLE"},
1331*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ACTIVE_DATASET, "THREAD_ACTIVE_DATASET"},
1332*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_PENDING_DATASET, "THREAD_PENDING_DATASET"},
1333*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET, "THREAD_MGMT_SET_ACTIVE_DATASET"},
1334*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET, "THREAD_MGMT_SET_PENDING_DATASET"},
1335*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DATASET_ACTIVE_TIMESTAMP, "DATASET_ACTIVE_TIMESTAMP"},
1336*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DATASET_PENDING_TIMESTAMP, "DATASET_PENDING_TIMESTAMP"},
1337*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DATASET_DELAY_TIMER, "DATASET_DELAY_TIMER"},
1338*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DATASET_SECURITY_POLICY, "DATASET_SECURITY_POLICY"},
1339*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DATASET_RAW_TLVS, "DATASET_RAW_TLVS"},
1340*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES, "THREAD_CHILD_TABLE_ADDRESSES"},
1341*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_NEIGHBOR_TABLE_ERROR_RATES, "THREAD_NEIGHBOR_TABLE_ERROR_RATES"},
1342*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE, "THREAD_ADDRESS_CACHE_TABLE"},
1343*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET, "THREAD_MGMT_GET_ACTIVE_DATASET"},
1344*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET, "THREAD_MGMT_GET_PENDING_DATASET"},
1345*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DATASET_DEST_ADDRESS, "DATASET_DEST_ADDRESS"},
1346*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_NEW_DATASET, "THREAD_NEW_DATASET"},
1347*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CSL_PERIOD, "THREAD_CSL_PERIOD"},
1348*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CSL_TIMEOUT, "THREAD_CSL_TIMEOUT"},
1349*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_CSL_CHANNEL, "THREAD_CSL_CHANNEL"},
1350*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_DOMAIN_NAME, "THREAD_DOMAIN_NAME"},
1351*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LINK_METRICS_QUERY, "THREAD_LINK_METRICS_QUERY"},
1352*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LINK_METRICS_QUERY_RESULT, "THREAD_LINK_METRICS_QUERY_RESULT"},
1353*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LINK_METRICS_PROBE, "THREAD_LINK_METRICS_PROBE"},
1354*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LINK_METRICS_MGMT_ENH_ACK, "THREAD_LINK_METRICS_MGMT_ENH_ACK"},
1355*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LINK_METRICS_MGMT_ENH_ACK_IE, "THREAD_LINK_METRICS_MGMT_ENH_ACK_IE"},
1356*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LINK_METRICS_MGMT_FORWARD, "THREAD_LINK_METRICS_MGMT_FORWARD"},
1357*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_LINK_METRICS_MGMT_RESPONSE, "THREAD_LINK_METRICS_MGMT_RESPONSE"},
1358*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MLR_REQUEST, "THREAD_MLR_REQUEST"},
1359*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MLR_RESPONSE, "THREAD_MLR_RESPONSE"},
1360*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_BACKBONE_ROUTER_PRIMARY, "THREAD_BACKBONE_ROUTER_PRIMARY"},
1361*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE, "THREAD_BACKBONE_ROUTER_LOCAL_STATE"},
1362*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_CONFIG, "THREAD_BACKBONE_ROUTER_LOCAL_CONFIG"},
1363*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTER, "THREAD_BACKBONE_ROUTER_LOCAL_REGISTER"},
1364*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER,
1365*cfb92d14SAndroid Build Coastguard Worker          "THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER"},
1366*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET_TLVS, "THREAD_MGMT_SET_PENDING_DATASET_TLVS"},
1367*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_JOINER_STATE, "MESHCOP_JOINER_STATE"},
1368*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING, "MESHCOP_JOINER_COMMISSIONING"},
1369*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_LL_ADDR, "IPV6_LL_ADDR"},
1370*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_ML_ADDR, "IPV6_ML_ADDR"},
1371*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_ML_PREFIX, "IPV6_ML_PREFIX"},
1372*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_ADDRESS_TABLE, "IPV6_ADDRESS_TABLE"},
1373*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_ROUTE_TABLE, "IPV6_ROUTE_TABLE"},
1374*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD, "IPV6_ICMP_PING_OFFLOAD"},
1375*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE, "IPV6_MULTICAST_ADDRESS_TABLE"},
1376*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE, "IPV6_ICMP_PING_OFFLOAD_MODE"},
1377*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_STREAM_DEBUG, "STREAM_DEBUG"},
1378*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_STREAM_RAW, "STREAM_RAW"},
1379*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_STREAM_NET, "STREAM_NET"},
1380*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_STREAM_NET_INSECURE, "STREAM_NET_INSECURE"},
1381*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_STREAM_LOG, "STREAM_LOG"},
1382*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_STATE, "MESHCOP_COMMISSIONER_STATE"},
1383*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS, "MESHCOP_COMMISSIONER_JOINERS"},
1384*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL, "MESHCOP_COMMISSIONER_PROVISIONING_URL"},
1385*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID, "MESHCOP_COMMISSIONER_SESSION_ID"},
1386*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_JOINER_DISCERNER, "MESHCOP_JOINER_DISCERNER"},
1387*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN, "MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN"},
1388*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN, "MESHCOP_COMMISSIONER_ENERGY_SCAN"},
1389*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT, "MESHCOP_COMMISSIONER_ENERGY_SCAN_RESULT"},
1390*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY, "MESHCOP_COMMISSIONER_PAN_ID_QUERY"},
1391*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT, "MESHCOP_COMMISSIONER_PAN_ID_CONFLICT_RESULT"},
1392*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_GET, "MESHCOP_COMMISSIONER_MGMT_GET"},
1393*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_SET, "MESHCOP_COMMISSIONER_MGMT_SET"},
1394*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MESHCOP_COMMISSIONER_GENERATE_PSKC, "MESHCOP_COMMISSIONER_GENERATE_PSKC"},
1395*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL, "CHANNEL_MANAGER_NEW_CHANNEL"},
1396*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MANAGER_DELAY, "CHANNEL_MANAGER_DELAY"},
1397*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS, "CHANNEL_MANAGER_SUPPORTED_CHANNELS"},
1398*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS, "CHANNEL_MANAGER_FAVORED_CHANNELS"},
1399*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT, "CHANNEL_MANAGER_CHANNEL_SELECT"},
1400*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED, "CHANNEL_MANAGER_AUTO_SELECT_ENABLED"},
1401*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL, "CHANNEL_MANAGER_AUTO_SELECT_INTERVAL"},
1402*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_THREAD_NETWORK_TIME, "THREAD_NETWORK_TIME"},
1403*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_TIME_SYNC_PERIOD, "TIME_SYNC_PERIOD"},
1404*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD, "TIME_SYNC_XTAL_THRESHOLD"},
1405*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHILD_SUPERVISION_INTERVAL, "CHILD_SUPERVISION_INTERVAL"},
1406*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT, "CHILD_SUPERVISION_CHECK_TIMEOUT"},
1407*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_VERSION, "RCP_VERSION"},
1408*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_TIMESTAMP, "TIMESTAMP"},
1409*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_ENH_ACK_PROBING, "ENH_ACK_PROBING"},
1410*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_CSL_ACCURACY, "CSL_ACCURACY"},
1411*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_CSL_UNCERTAINTY, "CSL_UNCERTAINTY"},
1412*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_PARENT_RESPONSE_INFO, "PARENT_RESPONSE_INFO"},
1413*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SLAAC_ENABLED, "SLAAC_ENABLED"},
1414*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SUPPORTED_RADIO_LINKS, "SUPPORTED_RADIO_LINKS"},
1415*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO, "NEIGHBOR_TABLE_MULTI_RADIO_INFO"},
1416*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_START, "SRP_CLIENT_START"},
1417*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL, "SRP_CLIENT_LEASE_INTERVAL"},
1418*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL, "SRP_CLIENT_KEY_LEASE_INTERVAL"},
1419*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_HOST_INFO, "SRP_CLIENT_HOST_INFO"},
1420*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_HOST_NAME, "SRP_CLIENT_HOST_NAME"},
1421*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES, "SRP_CLIENT_HOST_ADDRESSES"},
1422*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_SERVICES, "SRP_CLIENT_SERVICES"},
1423*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE, "SRP_CLIENT_HOST_SERVICES_REMOVE"},
1424*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR, "SRP_CLIENT_HOST_SERVICES_CLEAR"},
1425*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_EVENT, "SRP_CLIENT_EVENT"},
1426*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED, "SRP_CLIENT_SERVICE_KEY_ENABLED"},
1427*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE, "SERVER_ALLOW_LOCAL_DATA_CHANGE"},
1428*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SERVER_SERVICES, "SERVER_SERVICES"},
1429*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_SERVER_LEADER_SERVICES, "SERVER_LEADER_SERVICES"},
1430*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_API_VERSION, "RCP_API_VERSION"},
1431*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_MIN_HOST_API_VERSION, "RCP_MIN_HOST_API_VERSION"},
1432*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_LOG_CRASH_DUMP, "RCP_LOG_CRASH_DUMP"},
1433*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_UART_BITRATE, "UART_BITRATE"},
1434*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_UART_XON_XOFF, "UART_XON_XOFF"},
1435*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_15_4_PIB_PHY_CHANNELS_SUPPORTED, "15_4_PIB_PHY_CHANNELS_SUPPORTED"},
1436*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_15_4_PIB_MAC_PROMISCUOUS_MODE, "15_4_PIB_MAC_PROMISCUOUS_MODE"},
1437*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_15_4_PIB_MAC_SECURITY_ENABLED, "15_4_PIB_MAC_SECURITY_ENABLED"},
1438*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RESET, "CNTR_RESET"},
1439*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_TOTAL, "CNTR_TX_PKT_TOTAL"},
1440*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_ACK_REQ, "CNTR_TX_PKT_ACK_REQ"},
1441*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_ACKED, "CNTR_TX_PKT_ACKED"},
1442*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ, "CNTR_TX_PKT_NO_ACK_REQ"},
1443*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_DATA, "CNTR_TX_PKT_DATA"},
1444*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_DATA_POLL, "CNTR_TX_PKT_DATA_POLL"},
1445*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_BEACON, "CNTR_TX_PKT_BEACON"},
1446*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ, "CNTR_TX_PKT_BEACON_REQ"},
1447*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_OTHER, "CNTR_TX_PKT_OTHER"},
1448*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_RETRY, "CNTR_TX_PKT_RETRY"},
1449*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_ERR_CCA, "CNTR_TX_ERR_CCA"},
1450*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_UNICAST, "CNTR_TX_PKT_UNICAST"},
1451*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_PKT_BROADCAST, "CNTR_TX_PKT_BROADCAST"},
1452*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_ERR_ABORT, "CNTR_TX_ERR_ABORT"},
1453*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_TOTAL, "CNTR_RX_PKT_TOTAL"},
1454*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_DATA, "CNTR_RX_PKT_DATA"},
1455*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_DATA_POLL, "CNTR_RX_PKT_DATA_POLL"},
1456*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_BEACON, "CNTR_RX_PKT_BEACON"},
1457*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ, "CNTR_RX_PKT_BEACON_REQ"},
1458*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_OTHER, "CNTR_RX_PKT_OTHER"},
1459*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_FILT_WL, "CNTR_RX_PKT_FILT_WL"},
1460*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_FILT_DA, "CNTR_RX_PKT_FILT_DA"},
1461*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_ERR_EMPTY, "CNTR_RX_ERR_EMPTY"},
1462*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR, "CNTR_RX_ERR_UKWN_NBR"},
1463*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR, "CNTR_RX_ERR_NVLD_SADDR"},
1464*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_ERR_SECURITY, "CNTR_RX_ERR_SECURITY"},
1465*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_ERR_BAD_FCS, "CNTR_RX_ERR_BAD_FCS"},
1466*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_ERR_OTHER, "CNTR_RX_ERR_OTHER"},
1467*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_DUP, "CNTR_RX_PKT_DUP"},
1468*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_UNICAST, "CNTR_RX_PKT_UNICAST"},
1469*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_PKT_BROADCAST, "CNTR_RX_PKT_BROADCAST"},
1470*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL, "CNTR_TX_IP_SEC_TOTAL"},
1471*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL, "CNTR_TX_IP_INSEC_TOTAL"},
1472*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_IP_DROPPED, "CNTR_TX_IP_DROPPED"},
1473*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL, "CNTR_RX_IP_SEC_TOTAL"},
1474*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL, "CNTR_RX_IP_INSEC_TOTAL"},
1475*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_IP_DROPPED, "CNTR_RX_IP_DROPPED"},
1476*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_TX_SPINEL_TOTAL, "CNTR_TX_SPINEL_TOTAL"},
1477*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_SPINEL_TOTAL, "CNTR_RX_SPINEL_TOTAL"},
1478*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_SPINEL_ERR, "CNTR_RX_SPINEL_ERR"},
1479*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_RX_SPINEL_OUT_OF_ORDER_TID, "CNTR_RX_SPINEL_OUT_OF_ORDER_TID"},
1480*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_IP_TX_SUCCESS, "CNTR_IP_TX_SUCCESS"},
1481*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_IP_RX_SUCCESS, "CNTR_IP_RX_SUCCESS"},
1482*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_IP_TX_FAILURE, "CNTR_IP_TX_FAILURE"},
1483*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_IP_RX_FAILURE, "CNTR_IP_RX_FAILURE"},
1484*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_MSG_BUFFER_COUNTERS, "MSG_BUFFER_COUNTERS"},
1485*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_ALL_MAC_COUNTERS, "CNTR_ALL_MAC_COUNTERS"},
1486*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_MLE_COUNTERS, "CNTR_MLE_COUNTERS"},
1487*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_ALL_IP_COUNTERS, "CNTR_ALL_IP_COUNTERS"},
1488*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM, "CNTR_MAC_RETRY_HISTOGRAM"},
1489*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_NEST_STREAM_MFG, "NEST_STREAM_MFG"},
1490*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DEBUG_TEST_ASSERT, "DEBUG_TEST_ASSERT"},
1491*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DEBUG_NCP_LOG_LEVEL, "DEBUG_NCP_LOG_LEVEL"},
1492*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DEBUG_TEST_WATCHDOG, "DEBUG_TEST_WATCHDOG"},
1493*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_MAC_FRAME_COUNTER, "RCP_MAC_FRAME_COUNTER"},
1494*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_RCP_MAC_KEY, "RCP_MAC_KEY"},
1495*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE, "DEBUG_LOG_TIMESTAMP_BASE"},
1496*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE, "DEBUG_TREL_TEST_MODE_ENABLE"},
1497*cfb92d14SAndroid Build Coastguard Worker         {0, NULL},
1498*cfb92d14SAndroid Build Coastguard Worker     };
1499*cfb92d14SAndroid Build Coastguard Worker 
1500*cfb92d14SAndroid Build Coastguard Worker     return spinel_to_cstr(spinel_prop_cstr, prop_key);
1501*cfb92d14SAndroid Build Coastguard Worker }
1502*cfb92d14SAndroid Build Coastguard Worker 
spinel_net_role_to_cstr(uint8_t net_role)1503*cfb92d14SAndroid Build Coastguard Worker const char *spinel_net_role_to_cstr(uint8_t net_role)
1504*cfb92d14SAndroid Build Coastguard Worker {
1505*cfb92d14SAndroid Build Coastguard Worker     static const struct spinel_cstr spinel_net_cstr[] = {
1506*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_NET_ROLE_DETACHED, "NET_ROLE_DETACHED"}, {SPINEL_NET_ROLE_CHILD, "NET_ROLE_CHILD"},
1507*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_NET_ROLE_ROUTER, "NET_ROLE_ROUTER"},     {SPINEL_NET_ROLE_LEADER, "NET_ROLE_LEADER"},
1508*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_NET_ROLE_DISABLED, "NET_ROLE_DISABLED"}, {0, NULL},
1509*cfb92d14SAndroid Build Coastguard Worker     };
1510*cfb92d14SAndroid Build Coastguard Worker 
1511*cfb92d14SAndroid Build Coastguard Worker     return spinel_to_cstr(spinel_net_cstr, net_role);
1512*cfb92d14SAndroid Build Coastguard Worker }
1513*cfb92d14SAndroid Build Coastguard Worker 
spinel_mcu_power_state_to_cstr(uint8_t mcu_power_state)1514*cfb92d14SAndroid Build Coastguard Worker const char *spinel_mcu_power_state_to_cstr(uint8_t mcu_power_state)
1515*cfb92d14SAndroid Build Coastguard Worker {
1516*cfb92d14SAndroid Build Coastguard Worker     static const struct spinel_cstr spinel_mcu_power_state_cstr[] = {
1517*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_MCU_POWER_STATE_ON, "MCU_POWER_STATE_ON"},
1518*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_MCU_POWER_STATE_LOW_POWER, "MCU_POWER_STATE_LOW_POWER"},
1519*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_MCU_POWER_STATE_OFF, "MCU_POWER_STATE_OFF"},
1520*cfb92d14SAndroid Build Coastguard Worker         {0, NULL},
1521*cfb92d14SAndroid Build Coastguard Worker     };
1522*cfb92d14SAndroid Build Coastguard Worker 
1523*cfb92d14SAndroid Build Coastguard Worker     return spinel_to_cstr(spinel_mcu_power_state_cstr, mcu_power_state);
1524*cfb92d14SAndroid Build Coastguard Worker }
1525*cfb92d14SAndroid Build Coastguard Worker 
spinel_status_to_cstr(spinel_status_t status)1526*cfb92d14SAndroid Build Coastguard Worker const char *spinel_status_to_cstr(spinel_status_t status)
1527*cfb92d14SAndroid Build Coastguard Worker {
1528*cfb92d14SAndroid Build Coastguard Worker     static const struct spinel_cstr spinel_status_cstr[] = {
1529*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_OK, "OK"},
1530*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_FAILURE, "FAILURE"},
1531*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_UNIMPLEMENTED, "UNIMPLEMENTED"},
1532*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_INVALID_ARGUMENT, "INVALID_ARGUMENT"},
1533*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_INVALID_STATE, "INVALID_STATE"},
1534*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_INVALID_COMMAND, "INVALID_COMMAND"},
1535*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_INVALID_INTERFACE, "INVALID_INTERFACE"},
1536*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_INTERNAL_ERROR, "INTERNAL_ERROR"},
1537*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_SECURITY_ERROR, "SECURITY_ERROR"},
1538*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_PARSE_ERROR, "PARSE_ERROR"},
1539*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_IN_PROGRESS, "IN_PROGRESS"},
1540*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_NOMEM, "NOMEM"},
1541*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_BUSY, "BUSY"},
1542*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_PROP_NOT_FOUND, "PROP_NOT_FOUND"},
1543*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_DROPPED, "DROPPED"},
1544*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_EMPTY, "EMPTY"},
1545*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_CMD_TOO_BIG, "CMD_TOO_BIG"},
1546*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_NO_ACK, "NO_ACK"},
1547*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_CCA_FAILURE, "CCA_FAILURE"},
1548*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_ALREADY, "ALREADY"},
1549*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_ITEM_NOT_FOUND, "ITEM_NOT_FOUND"},
1550*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_INVALID_COMMAND_FOR_PROP, "INVALID_COMMAND_FOR_PROP"},
1551*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESPONSE_TIMEOUT, "RESPONSE_TIMEOUT"},
1552*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_SWITCHOVER_DONE, "SWITCHOVER_DONE"},
1553*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_SWITCHOVER_FAILED, "SWITCHOVER_FAILED"},
1554*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_JOIN_FAILURE, "JOIN_FAILURE"},
1555*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_JOIN_SECURITY, "JOIN_SECURITY"},
1556*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_JOIN_NO_PEERS, "JOIN_NO_PEERS"},
1557*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_JOIN_INCOMPATIBLE, "JOIN_INCOMPATIBLE"},
1558*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_JOIN_RSP_TIMEOUT, "JOIN_RSP_TIMEOUT"},
1559*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_JOIN_SUCCESS, "JOIN_SUCCESS"},
1560*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_POWER_ON, "RESET_POWER_ON"},
1561*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_EXTERNAL, "RESET_EXTERNAL"},
1562*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_SOFTWARE, "RESET_SOFTWARE"},
1563*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_FAULT, "RESET_FAULT"},
1564*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_CRASH, "RESET_CRASH"},
1565*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_ASSERT, "RESET_ASSERT"},
1566*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_OTHER, "RESET_OTHER"},
1567*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_UNKNOWN, "RESET_UNKNOWN"},
1568*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_STATUS_RESET_WATCHDOG, "RESET_WATCHDOG"},
1569*cfb92d14SAndroid Build Coastguard Worker         {0, NULL},
1570*cfb92d14SAndroid Build Coastguard Worker     };
1571*cfb92d14SAndroid Build Coastguard Worker 
1572*cfb92d14SAndroid Build Coastguard Worker     return spinel_to_cstr(spinel_status_cstr, status);
1573*cfb92d14SAndroid Build Coastguard Worker }
1574*cfb92d14SAndroid Build Coastguard Worker 
spinel_capability_to_cstr(spinel_capability_t capability)1575*cfb92d14SAndroid Build Coastguard Worker const char *spinel_capability_to_cstr(spinel_capability_t capability)
1576*cfb92d14SAndroid Build Coastguard Worker {
1577*cfb92d14SAndroid Build Coastguard Worker     static const struct spinel_cstr spinel_cap_cstr[] = {
1578*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_LOCK, "LOCK"},
1579*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_NET_SAVE, "NET_SAVE"},
1580*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_HBO, "HBO"},
1581*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_POWER_SAVE, "POWER_SAVE"},
1582*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_COUNTERS, "COUNTERS"},
1583*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_JAM_DETECT, "JAM_DETECT"},
1584*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_PEEK_POKE, "PEEK_POKE"},
1585*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_WRITABLE_RAW_STREAM, "WRITABLE_RAW_STREAM"},
1586*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_GPIO, "GPIO"},
1587*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_TRNG, "TRNG"},
1588*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_CMD_MULTI, "CMD_MULTI"},
1589*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_UNSOL_UPDATE_FILTER, "UNSOL_UPDATE_FILTER"},
1590*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_MCU_POWER_STATE, "MCU_POWER_STATE"},
1591*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_PCAP, "PCAP"},
1592*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_2003, "802_15_4_2003"},
1593*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_2006, "802_15_4_2006"},
1594*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_2011, "802_15_4_2011"},
1595*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_PIB, "802_15_4_PIB"},
1596*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_2450MHZ_OQPSK, "802_15_4_2450MHZ_OQPSK"},
1597*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_915MHZ_OQPSK, "802_15_4_915MHZ_OQPSK"},
1598*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_868MHZ_OQPSK, "802_15_4_868MHZ_OQPSK"},
1599*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_915MHZ_BPSK, "802_15_4_915MHZ_BPSK"},
1600*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_868MHZ_BPSK, "802_15_4_868MHZ_BPSK"},
1601*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_915MHZ_ASK, "802_15_4_915MHZ_ASK"},
1602*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_802_15_4_868MHZ_ASK, "802_15_4_868MHZ_ASK"},
1603*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_CONFIG_FTD, "CONFIG_FTD"},
1604*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_CONFIG_MTD, "CONFIG_MTD"},
1605*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_CONFIG_RADIO, "CONFIG_RADIO"},
1606*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_ROLE_ROUTER, "ROLE_ROUTER"},
1607*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_ROLE_SLEEPY, "ROLE_SLEEPY"},
1608*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_NET_THREAD_1_0, "NET_THREAD_1_0"},
1609*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_NET_THREAD_1_1, "NET_THREAD_1_1"},
1610*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_NET_THREAD_1_2, "NET_THREAD_1_2"},
1611*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_RCP_API_VERSION, "RCP_API_VERSION"},
1612*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_RCP_MIN_HOST_API_VERSION, "RCP_MIN_HOST_API_VERSION"},
1613*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_RCP_RESET_TO_BOOTLOADER, "RCP_RESET_TO_BOOTLOADER"},
1614*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_RCP_LOG_CRASH_DUMP, "RCP_LOG_CRASH_DUMP"},
1615*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_MAC_ALLOWLIST, "MAC_ALLOWLIST"},
1616*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_MAC_RAW, "MAC_RAW"},
1617*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_OOB_STEERING_DATA, "OOB_STEERING_DATA"},
1618*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_CHANNEL_MONITOR, "CHANNEL_MONITOR"},
1619*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_CHANNEL_MANAGER, "CHANNEL_MANAGER"},
1620*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_OPENTHREAD_LOG_METADATA, "OPENTHREAD_LOG_METADATA"},
1621*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_TIME_SYNC, "TIME_SYNC"},
1622*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_CHILD_SUPERVISION, "CHILD_SUPERVISION"},
1623*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_POSIX, "POSIX"},
1624*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_SLAAC, "SLAAC"},
1625*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_RADIO_COEX, "RADIO_COEX"},
1626*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_MAC_RETRY_HISTOGRAM, "MAC_RETRY_HISTOGRAM"},
1627*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_MULTI_RADIO, "MULTI_RADIO"},
1628*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_SRP_CLIENT, "SRP_CLIENT"},
1629*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_DUA, "DUA"},
1630*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_REFERENCE_DEVICE, "REFERENCE_DEVICE"},
1631*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_ERROR_RATE_TRACKING, "ERROR_RATE_TRACKING"},
1632*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_COMMISSIONER, "THREAD_COMMISSIONER"},
1633*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_TMF_PROXY, "THREAD_TMF_PROXY"},
1634*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_UDP_FORWARD, "THREAD_UDP_FORWARD"},
1635*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_JOINER, "THREAD_JOINER"},
1636*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_BORDER_ROUTER, "THREAD_BORDER_ROUTER"},
1637*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_SERVICE, "THREAD_SERVICE"},
1638*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_CSL_RECEIVER, "THREAD_CSL_RECEIVER"},
1639*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_THREAD_BACKBONE_ROUTER, "THREAD_BACKBONE_ROUTER"},
1640*cfb92d14SAndroid Build Coastguard Worker         {SPINEL_CAP_NEST_TRANSMIT_HOOK, "NEST_TRANSMIT_HOOK"},
1641*cfb92d14SAndroid Build Coastguard Worker         {0, NULL},
1642*cfb92d14SAndroid Build Coastguard Worker     };
1643*cfb92d14SAndroid Build Coastguard Worker 
1644*cfb92d14SAndroid Build Coastguard Worker     return spinel_to_cstr(spinel_cap_cstr, capability);
1645*cfb92d14SAndroid Build Coastguard Worker }
1646*cfb92d14SAndroid Build Coastguard Worker 
1647*cfb92d14SAndroid Build Coastguard Worker // LCOV_EXCL_STOP
1648*cfb92d14SAndroid Build Coastguard Worker 
1649*cfb92d14SAndroid Build Coastguard Worker /* -------------------------------------------------------------------------- */
1650*cfb92d14SAndroid Build Coastguard Worker 
1651*cfb92d14SAndroid Build Coastguard Worker #if SPINEL_SELF_TEST
1652*cfb92d14SAndroid Build Coastguard Worker 
main(void)1653*cfb92d14SAndroid Build Coastguard Worker int main(void)
1654*cfb92d14SAndroid Build Coastguard Worker {
1655*cfb92d14SAndroid Build Coastguard Worker     int                  ret             = -1;
1656*cfb92d14SAndroid Build Coastguard Worker     const spinel_eui64_t static_eui64    = {{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}};
1657*cfb92d14SAndroid Build Coastguard Worker     const char           static_string[] = "static_string";
1658*cfb92d14SAndroid Build Coastguard Worker     uint8_t              buffer[1024];
1659*cfb92d14SAndroid Build Coastguard Worker     ssize_t              len;
1660*cfb92d14SAndroid Build Coastguard Worker 
1661*cfb92d14SAndroid Build Coastguard Worker     len =
1662*cfb92d14SAndroid Build Coastguard Worker         spinel_datatype_pack(buffer, sizeof(buffer), "CiiLUE", 0x88, 9, 0xA3, 0xDEADBEEF, static_string, &static_eui64);
1663*cfb92d14SAndroid Build Coastguard Worker 
1664*cfb92d14SAndroid Build Coastguard Worker     if (len != 30)
1665*cfb92d14SAndroid Build Coastguard Worker     {
1666*cfb92d14SAndroid Build Coastguard Worker         printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
1667*cfb92d14SAndroid Build Coastguard Worker         goto bail;
1668*cfb92d14SAndroid Build Coastguard Worker     }
1669*cfb92d14SAndroid Build Coastguard Worker 
1670*cfb92d14SAndroid Build Coastguard Worker     {
1671*cfb92d14SAndroid Build Coastguard Worker         const char *str = NULL;
1672*cfb92d14SAndroid Build Coastguard Worker 
1673*cfb92d14SAndroid Build Coastguard Worker         // Length ends right before the string.
1674*cfb92d14SAndroid Build Coastguard Worker         len = spinel_datatype_unpack(buffer, 8, "CiiLU", NULL, NULL, NULL, NULL, &str);
1675*cfb92d14SAndroid Build Coastguard Worker 
1676*cfb92d14SAndroid Build Coastguard Worker         if (len != -1)
1677*cfb92d14SAndroid Build Coastguard Worker         {
1678*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: len != -1; (%d)\n", __LINE__, (int)len);
1679*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1680*cfb92d14SAndroid Build Coastguard Worker         }
1681*cfb92d14SAndroid Build Coastguard Worker 
1682*cfb92d14SAndroid Build Coastguard Worker         if (str != NULL)
1683*cfb92d14SAndroid Build Coastguard Worker         {
1684*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: str != NULL\n", __LINE__);
1685*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1686*cfb92d14SAndroid Build Coastguard Worker         }
1687*cfb92d14SAndroid Build Coastguard Worker     }
1688*cfb92d14SAndroid Build Coastguard Worker 
1689*cfb92d14SAndroid Build Coastguard Worker     len = 30;
1690*cfb92d14SAndroid Build Coastguard Worker 
1691*cfb92d14SAndroid Build Coastguard Worker     {
1692*cfb92d14SAndroid Build Coastguard Worker         uint8_t               c     = 0;
1693*cfb92d14SAndroid Build Coastguard Worker         unsigned int          i1    = 0;
1694*cfb92d14SAndroid Build Coastguard Worker         unsigned int          i2    = 0;
1695*cfb92d14SAndroid Build Coastguard Worker         uint32_t              l     = 0;
1696*cfb92d14SAndroid Build Coastguard Worker         const char           *str   = NULL;
1697*cfb92d14SAndroid Build Coastguard Worker         const spinel_eui64_t *eui64 = NULL;
1698*cfb92d14SAndroid Build Coastguard Worker 
1699*cfb92d14SAndroid Build Coastguard Worker         len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "CiiLUE", &c, &i1, &i2, &l, &str, &eui64);
1700*cfb92d14SAndroid Build Coastguard Worker 
1701*cfb92d14SAndroid Build Coastguard Worker         if (len != 30)
1702*cfb92d14SAndroid Build Coastguard Worker         {
1703*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
1704*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1705*cfb92d14SAndroid Build Coastguard Worker         }
1706*cfb92d14SAndroid Build Coastguard Worker 
1707*cfb92d14SAndroid Build Coastguard Worker         if (c != 0x88)
1708*cfb92d14SAndroid Build Coastguard Worker         {
1709*cfb92d14SAndroid Build Coastguard Worker             printf("error: x != 0x88; (%d)\n", c);
1710*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1711*cfb92d14SAndroid Build Coastguard Worker         }
1712*cfb92d14SAndroid Build Coastguard Worker 
1713*cfb92d14SAndroid Build Coastguard Worker         if (i1 != 9)
1714*cfb92d14SAndroid Build Coastguard Worker         {
1715*cfb92d14SAndroid Build Coastguard Worker             printf("error: i1 != 9; (%d)\n", i1);
1716*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1717*cfb92d14SAndroid Build Coastguard Worker         }
1718*cfb92d14SAndroid Build Coastguard Worker 
1719*cfb92d14SAndroid Build Coastguard Worker         if (i2 != 0xA3)
1720*cfb92d14SAndroid Build Coastguard Worker         {
1721*cfb92d14SAndroid Build Coastguard Worker             printf("error: i2 != 0xA3; (0x%02X)\n", i2);
1722*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1723*cfb92d14SAndroid Build Coastguard Worker         }
1724*cfb92d14SAndroid Build Coastguard Worker 
1725*cfb92d14SAndroid Build Coastguard Worker         if (l != 0xDEADBEEF)
1726*cfb92d14SAndroid Build Coastguard Worker         {
1727*cfb92d14SAndroid Build Coastguard Worker             printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
1728*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1729*cfb92d14SAndroid Build Coastguard Worker         }
1730*cfb92d14SAndroid Build Coastguard Worker 
1731*cfb92d14SAndroid Build Coastguard Worker         if (strcmp(str, static_string) != 0)
1732*cfb92d14SAndroid Build Coastguard Worker         {
1733*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
1734*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1735*cfb92d14SAndroid Build Coastguard Worker         }
1736*cfb92d14SAndroid Build Coastguard Worker 
1737*cfb92d14SAndroid Build Coastguard Worker         if (memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
1738*cfb92d14SAndroid Build Coastguard Worker         {
1739*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: memcmp(eui64, &eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
1740*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1741*cfb92d14SAndroid Build Coastguard Worker         }
1742*cfb92d14SAndroid Build Coastguard Worker     }
1743*cfb92d14SAndroid Build Coastguard Worker 
1744*cfb92d14SAndroid Build Coastguard Worker     {
1745*cfb92d14SAndroid Build Coastguard Worker         uint8_t        c  = 0;
1746*cfb92d14SAndroid Build Coastguard Worker         unsigned int   i1 = 0;
1747*cfb92d14SAndroid Build Coastguard Worker         unsigned int   i2 = 0;
1748*cfb92d14SAndroid Build Coastguard Worker         uint32_t       l  = 0;
1749*cfb92d14SAndroid Build Coastguard Worker         char           str[sizeof(static_string)];
1750*cfb92d14SAndroid Build Coastguard Worker         spinel_eui64_t eui64 = {{0}};
1751*cfb92d14SAndroid Build Coastguard Worker 
1752*cfb92d14SAndroid Build Coastguard Worker         len = spinel_datatype_unpack_in_place(buffer, (spinel_size_t)len, "CiiLUE", &c, &i1, &i2, &l, &str, sizeof(str),
1753*cfb92d14SAndroid Build Coastguard Worker                                               &eui64);
1754*cfb92d14SAndroid Build Coastguard Worker 
1755*cfb92d14SAndroid Build Coastguard Worker         if (len != 30)
1756*cfb92d14SAndroid Build Coastguard Worker         {
1757*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: len != 30; (%d)\n", __LINE__, (int)len);
1758*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1759*cfb92d14SAndroid Build Coastguard Worker         }
1760*cfb92d14SAndroid Build Coastguard Worker 
1761*cfb92d14SAndroid Build Coastguard Worker         if (c != 0x88)
1762*cfb92d14SAndroid Build Coastguard Worker         {
1763*cfb92d14SAndroid Build Coastguard Worker             printf("error: x != 0x88; (%d)\n", c);
1764*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1765*cfb92d14SAndroid Build Coastguard Worker         }
1766*cfb92d14SAndroid Build Coastguard Worker 
1767*cfb92d14SAndroid Build Coastguard Worker         if (i1 != 9)
1768*cfb92d14SAndroid Build Coastguard Worker         {
1769*cfb92d14SAndroid Build Coastguard Worker             printf("error: i1 != 9; (%d)\n", i1);
1770*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1771*cfb92d14SAndroid Build Coastguard Worker         }
1772*cfb92d14SAndroid Build Coastguard Worker 
1773*cfb92d14SAndroid Build Coastguard Worker         if (i2 != 0xA3)
1774*cfb92d14SAndroid Build Coastguard Worker         {
1775*cfb92d14SAndroid Build Coastguard Worker             printf("error: i2 != 0xA3; (0x%02X)\n", i2);
1776*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1777*cfb92d14SAndroid Build Coastguard Worker         }
1778*cfb92d14SAndroid Build Coastguard Worker 
1779*cfb92d14SAndroid Build Coastguard Worker         if (l != 0xDEADBEEF)
1780*cfb92d14SAndroid Build Coastguard Worker         {
1781*cfb92d14SAndroid Build Coastguard Worker             printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
1782*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1783*cfb92d14SAndroid Build Coastguard Worker         }
1784*cfb92d14SAndroid Build Coastguard Worker 
1785*cfb92d14SAndroid Build Coastguard Worker         if (strcmp(str, static_string) != 0)
1786*cfb92d14SAndroid Build Coastguard Worker         {
1787*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
1788*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1789*cfb92d14SAndroid Build Coastguard Worker         }
1790*cfb92d14SAndroid Build Coastguard Worker 
1791*cfb92d14SAndroid Build Coastguard Worker         if (memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
1792*cfb92d14SAndroid Build Coastguard Worker         {
1793*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
1794*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1795*cfb92d14SAndroid Build Coastguard Worker         }
1796*cfb92d14SAndroid Build Coastguard Worker     }
1797*cfb92d14SAndroid Build Coastguard Worker 
1798*cfb92d14SAndroid Build Coastguard Worker     // -----------------------------------
1799*cfb92d14SAndroid Build Coastguard Worker 
1800*cfb92d14SAndroid Build Coastguard Worker     memset(buffer, 0xAA, sizeof(buffer));
1801*cfb92d14SAndroid Build Coastguard Worker 
1802*cfb92d14SAndroid Build Coastguard Worker     len = spinel_datatype_pack(buffer, sizeof(buffer), "Cit(iL)UE", 0x88, 9, 0xA3, 0xDEADBEEF, static_string,
1803*cfb92d14SAndroid Build Coastguard Worker                                &static_eui64);
1804*cfb92d14SAndroid Build Coastguard Worker 
1805*cfb92d14SAndroid Build Coastguard Worker     if (len != 32)
1806*cfb92d14SAndroid Build Coastguard Worker     {
1807*cfb92d14SAndroid Build Coastguard Worker         printf("error:%d: len != 32; (%d)\n", __LINE__, (int)len);
1808*cfb92d14SAndroid Build Coastguard Worker         goto bail;
1809*cfb92d14SAndroid Build Coastguard Worker     }
1810*cfb92d14SAndroid Build Coastguard Worker 
1811*cfb92d14SAndroid Build Coastguard Worker     {
1812*cfb92d14SAndroid Build Coastguard Worker         uint8_t         c     = 0;
1813*cfb92d14SAndroid Build Coastguard Worker         unsigned int    i1    = 0;
1814*cfb92d14SAndroid Build Coastguard Worker         unsigned int    i2    = 0;
1815*cfb92d14SAndroid Build Coastguard Worker         uint32_t        l     = 0;
1816*cfb92d14SAndroid Build Coastguard Worker         const char     *str   = NULL;
1817*cfb92d14SAndroid Build Coastguard Worker         spinel_eui64_t *eui64 = NULL;
1818*cfb92d14SAndroid Build Coastguard Worker 
1819*cfb92d14SAndroid Build Coastguard Worker         len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "Cit(iL)UE", &c, &i1, &i2, &l, &str, &eui64);
1820*cfb92d14SAndroid Build Coastguard Worker 
1821*cfb92d14SAndroid Build Coastguard Worker         if (len != 32)
1822*cfb92d14SAndroid Build Coastguard Worker         {
1823*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
1824*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1825*cfb92d14SAndroid Build Coastguard Worker         }
1826*cfb92d14SAndroid Build Coastguard Worker 
1827*cfb92d14SAndroid Build Coastguard Worker         if (c != 0x88)
1828*cfb92d14SAndroid Build Coastguard Worker         {
1829*cfb92d14SAndroid Build Coastguard Worker             printf("error: x != 0x88; (%d)\n", c);
1830*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1831*cfb92d14SAndroid Build Coastguard Worker         }
1832*cfb92d14SAndroid Build Coastguard Worker 
1833*cfb92d14SAndroid Build Coastguard Worker         if (i1 != 9)
1834*cfb92d14SAndroid Build Coastguard Worker         {
1835*cfb92d14SAndroid Build Coastguard Worker             printf("error: i1 != 9; (%d)\n", i1);
1836*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1837*cfb92d14SAndroid Build Coastguard Worker         }
1838*cfb92d14SAndroid Build Coastguard Worker 
1839*cfb92d14SAndroid Build Coastguard Worker         if (i2 != 0xA3)
1840*cfb92d14SAndroid Build Coastguard Worker         {
1841*cfb92d14SAndroid Build Coastguard Worker             printf("error: i2 != 0xA3; (0x%02X)\n", i2);
1842*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1843*cfb92d14SAndroid Build Coastguard Worker         }
1844*cfb92d14SAndroid Build Coastguard Worker 
1845*cfb92d14SAndroid Build Coastguard Worker         if (l != 0xDEADBEEF)
1846*cfb92d14SAndroid Build Coastguard Worker         {
1847*cfb92d14SAndroid Build Coastguard Worker             printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
1848*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1849*cfb92d14SAndroid Build Coastguard Worker         }
1850*cfb92d14SAndroid Build Coastguard Worker 
1851*cfb92d14SAndroid Build Coastguard Worker         if (strcmp(str, static_string) != 0)
1852*cfb92d14SAndroid Build Coastguard Worker         {
1853*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
1854*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1855*cfb92d14SAndroid Build Coastguard Worker         }
1856*cfb92d14SAndroid Build Coastguard Worker 
1857*cfb92d14SAndroid Build Coastguard Worker         if (memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
1858*cfb92d14SAndroid Build Coastguard Worker         {
1859*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: memcmp(eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
1860*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1861*cfb92d14SAndroid Build Coastguard Worker         }
1862*cfb92d14SAndroid Build Coastguard Worker     }
1863*cfb92d14SAndroid Build Coastguard Worker 
1864*cfb92d14SAndroid Build Coastguard Worker     {
1865*cfb92d14SAndroid Build Coastguard Worker         uint8_t        c  = 0;
1866*cfb92d14SAndroid Build Coastguard Worker         unsigned int   i1 = 0;
1867*cfb92d14SAndroid Build Coastguard Worker         unsigned int   i2 = 0;
1868*cfb92d14SAndroid Build Coastguard Worker         uint32_t       l  = 0;
1869*cfb92d14SAndroid Build Coastguard Worker         char           str[sizeof(static_string)];
1870*cfb92d14SAndroid Build Coastguard Worker         spinel_eui64_t eui64 = {{0}};
1871*cfb92d14SAndroid Build Coastguard Worker 
1872*cfb92d14SAndroid Build Coastguard Worker         len = spinel_datatype_unpack_in_place(buffer, (spinel_size_t)len, "Cit(iL)UE", &c, &i1, &i2, &l, &str,
1873*cfb92d14SAndroid Build Coastguard Worker                                               sizeof(str), &eui64);
1874*cfb92d14SAndroid Build Coastguard Worker 
1875*cfb92d14SAndroid Build Coastguard Worker         if (len != 32)
1876*cfb92d14SAndroid Build Coastguard Worker         {
1877*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
1878*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1879*cfb92d14SAndroid Build Coastguard Worker         }
1880*cfb92d14SAndroid Build Coastguard Worker 
1881*cfb92d14SAndroid Build Coastguard Worker         if (c != 0x88)
1882*cfb92d14SAndroid Build Coastguard Worker         {
1883*cfb92d14SAndroid Build Coastguard Worker             printf("error: x != 0x88; (%d)\n", c);
1884*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1885*cfb92d14SAndroid Build Coastguard Worker         }
1886*cfb92d14SAndroid Build Coastguard Worker 
1887*cfb92d14SAndroid Build Coastguard Worker         if (i1 != 9)
1888*cfb92d14SAndroid Build Coastguard Worker         {
1889*cfb92d14SAndroid Build Coastguard Worker             printf("error: i1 != 9; (%d)\n", i1);
1890*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1891*cfb92d14SAndroid Build Coastguard Worker         }
1892*cfb92d14SAndroid Build Coastguard Worker 
1893*cfb92d14SAndroid Build Coastguard Worker         if (i2 != 0xA3)
1894*cfb92d14SAndroid Build Coastguard Worker         {
1895*cfb92d14SAndroid Build Coastguard Worker             printf("error: i2 != 0xA3; (0x%02X)\n", i2);
1896*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1897*cfb92d14SAndroid Build Coastguard Worker         }
1898*cfb92d14SAndroid Build Coastguard Worker 
1899*cfb92d14SAndroid Build Coastguard Worker         if (l != 0xDEADBEEF)
1900*cfb92d14SAndroid Build Coastguard Worker         {
1901*cfb92d14SAndroid Build Coastguard Worker             printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
1902*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1903*cfb92d14SAndroid Build Coastguard Worker         }
1904*cfb92d14SAndroid Build Coastguard Worker 
1905*cfb92d14SAndroid Build Coastguard Worker         if (strcmp(str, static_string) != 0)
1906*cfb92d14SAndroid Build Coastguard Worker         {
1907*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
1908*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1909*cfb92d14SAndroid Build Coastguard Worker         }
1910*cfb92d14SAndroid Build Coastguard Worker 
1911*cfb92d14SAndroid Build Coastguard Worker         if (memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0)
1912*cfb92d14SAndroid Build Coastguard Worker         {
1913*cfb92d14SAndroid Build Coastguard Worker             printf("error:%d: memcmp(&eui64, &static_eui64, sizeof(spinel_eui64_t)) != 0\n", __LINE__);
1914*cfb92d14SAndroid Build Coastguard Worker             goto bail;
1915*cfb92d14SAndroid Build Coastguard Worker         }
1916*cfb92d14SAndroid Build Coastguard Worker     }
1917*cfb92d14SAndroid Build Coastguard Worker 
1918*cfb92d14SAndroid Build Coastguard Worker     {
1919*cfb92d14SAndroid Build Coastguard Worker         // Test UTF8 validation - Good/Valid strings
1920*cfb92d14SAndroid Build Coastguard Worker 
1921*cfb92d14SAndroid Build Coastguard Worker         // Single symbols
1922*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single1[] = {0};                            // 0000
1923*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single2[] = {0x7F, 0x00};                   // 007F
1924*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single3[] = {0xC2, 0x80, 0x00};             // 080
1925*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single4[] = {0xDF, 0xBF, 0x00};             // 07FF
1926*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single5[] = {0xE0, 0xA0, 0x80, 0x00};       // 0800
1927*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single6[] = {0xEF, 0xBF, 0xBF, 0x00};       // FFFF
1928*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single7[] = {0xF0, 0x90, 0x80, 0x80, 0x00}; // 010000
1929*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single8[] = {0xF4, 0x8F, 0xBF, 0xBF, 0x00}; // 10FFFF
1930*cfb92d14SAndroid Build Coastguard Worker 
1931*cfb92d14SAndroid Build Coastguard Worker         // Strings
1932*cfb92d14SAndroid Build Coastguard Worker         const uint8_t str1[] = "spinel";
1933*cfb92d14SAndroid Build Coastguard Worker         const uint8_t str2[] = "OpenThread";
1934*cfb92d14SAndroid Build Coastguard Worker         const uint8_t str3[] = {0x41, 0x7F, 0xEF, 0xBF, 0xBF, 0xC2, 0x80, 0x21, 0x33, 0x00};
1935*cfb92d14SAndroid Build Coastguard Worker         const uint8_t str4[] = {0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xB5, 0x00}; // κόσμε
1936*cfb92d14SAndroid Build Coastguard Worker         const uint8_t str5[] = {0x3D, 0xF4, 0x8F, 0xBF, 0xBF, 0x01, 0xE0, 0xA0, 0x83, 0x22, 0xEF, 0xBF, 0xBF, 0x00};
1937*cfb92d14SAndroid Build Coastguard Worker         const uint8_t str6[] = {0xE5, 0xA2, 0x82, 0xE0, 0xA0, 0x80, 0xC2, 0x83, 0xC2, 0x80, 0xF4,
1938*cfb92d14SAndroid Build Coastguard Worker                                 0x8F, 0xBF, 0xBF, 0xF4, 0x8F, 0xBF, 0xBF, 0xDF, 0xBF, 0x21, 0x00};
1939*cfb92d14SAndroid Build Coastguard Worker 
1940*cfb92d14SAndroid Build Coastguard Worker         const uint8_t  *good_strings[] = {single1, single2, single3, single4, single5, single6, single7, single8,
1941*cfb92d14SAndroid Build Coastguard Worker                                           str1,    str2,    str3,    str4,    str5,    str6,    NULL};
1942*cfb92d14SAndroid Build Coastguard Worker         const uint8_t **str_ptr;
1943*cfb92d14SAndroid Build Coastguard Worker 
1944*cfb92d14SAndroid Build Coastguard Worker         for (str_ptr = &good_strings[0]; *str_ptr != NULL; str_ptr++)
1945*cfb92d14SAndroid Build Coastguard Worker         {
1946*cfb92d14SAndroid Build Coastguard Worker             if (!spinel_validate_utf8(*str_ptr))
1947*cfb92d14SAndroid Build Coastguard Worker             {
1948*cfb92d14SAndroid Build Coastguard Worker                 printf("error: spinel_validate_utf8() did not correctly detect a valid UTF8 sequence!\n");
1949*cfb92d14SAndroid Build Coastguard Worker                 goto bail;
1950*cfb92d14SAndroid Build Coastguard Worker             }
1951*cfb92d14SAndroid Build Coastguard Worker         }
1952*cfb92d14SAndroid Build Coastguard Worker     }
1953*cfb92d14SAndroid Build Coastguard Worker 
1954*cfb92d14SAndroid Build Coastguard Worker     {
1955*cfb92d14SAndroid Build Coastguard Worker         // Test UTF8 validation - Bad/Invalid strings
1956*cfb92d14SAndroid Build Coastguard Worker 
1957*cfb92d14SAndroid Build Coastguard Worker         // Single symbols (invalid)
1958*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single1[] = {0xF8, 0x00};
1959*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single2[] = {0xF9, 0x00};
1960*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single3[] = {0xFA, 0x00};
1961*cfb92d14SAndroid Build Coastguard Worker         const uint8_t single4[] = {0xFF, 0x00};
1962*cfb92d14SAndroid Build Coastguard Worker 
1963*cfb92d14SAndroid Build Coastguard Worker         // Bad continuations
1964*cfb92d14SAndroid Build Coastguard Worker         const uint8_t bad1[] = {0xDF, 0x0F, 0x00};
1965*cfb92d14SAndroid Build Coastguard Worker         const uint8_t bad2[] = {0xE0, 0xA0, 0x10, 0x00};
1966*cfb92d14SAndroid Build Coastguard Worker         const uint8_t bad3[] = {0xF0, 0x90, 0x80, 0x60, 0x00};
1967*cfb92d14SAndroid Build Coastguard Worker         const uint8_t bad4[] = {0xF4, 0x8F, 0xBF, 0x0F, 0x00};
1968*cfb92d14SAndroid Build Coastguard Worker         const uint8_t bad5[] = {0x21, 0xA0, 0x00};
1969*cfb92d14SAndroid Build Coastguard Worker         const uint8_t bad6[] = {0xCE, 0xBA, 0xE1, 0xBD, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0x00};
1970*cfb92d14SAndroid Build Coastguard Worker 
1971*cfb92d14SAndroid Build Coastguard Worker         const uint8_t  *bad_strings[] = {single1, single2, single3, single4, bad1, bad2, bad3, bad4, bad5, bad6, NULL};
1972*cfb92d14SAndroid Build Coastguard Worker         const uint8_t **str_ptr;
1973*cfb92d14SAndroid Build Coastguard Worker 
1974*cfb92d14SAndroid Build Coastguard Worker         for (str_ptr = &bad_strings[0]; *str_ptr != NULL; str_ptr++)
1975*cfb92d14SAndroid Build Coastguard Worker         {
1976*cfb92d14SAndroid Build Coastguard Worker             if (spinel_validate_utf8(*str_ptr))
1977*cfb92d14SAndroid Build Coastguard Worker             {
1978*cfb92d14SAndroid Build Coastguard Worker                 printf("error: spinel_validate_utf8() did not correctly detect an invalid UTF8 sequence\n");
1979*cfb92d14SAndroid Build Coastguard Worker                 goto bail;
1980*cfb92d14SAndroid Build Coastguard Worker             }
1981*cfb92d14SAndroid Build Coastguard Worker         }
1982*cfb92d14SAndroid Build Coastguard Worker     }
1983*cfb92d14SAndroid Build Coastguard Worker 
1984*cfb92d14SAndroid Build Coastguard Worker     printf("OK\n");
1985*cfb92d14SAndroid Build Coastguard Worker     ret = 0;
1986*cfb92d14SAndroid Build Coastguard Worker     return ret;
1987*cfb92d14SAndroid Build Coastguard Worker 
1988*cfb92d14SAndroid Build Coastguard Worker bail:
1989*cfb92d14SAndroid Build Coastguard Worker     printf("FAILURE\n");
1990*cfb92d14SAndroid Build Coastguard Worker     return ret;
1991*cfb92d14SAndroid Build Coastguard Worker }
1992*cfb92d14SAndroid Build Coastguard Worker 
1993*cfb92d14SAndroid Build Coastguard Worker #endif // #if SPINEL_SELF_TEST
1994