xref: /aosp_15_r20/external/openthread/src/lib/spinel/spinel_encoder.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *    Copyright (c) 2017, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *    All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17*cfb92d14SAndroid Build Coastguard Worker  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*cfb92d14SAndroid Build Coastguard Worker  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*cfb92d14SAndroid Build Coastguard Worker  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20*cfb92d14SAndroid Build Coastguard Worker  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21*cfb92d14SAndroid Build Coastguard Worker  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22*cfb92d14SAndroid Build Coastguard Worker  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23*cfb92d14SAndroid Build Coastguard Worker  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*cfb92d14SAndroid Build Coastguard Worker  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*cfb92d14SAndroid Build Coastguard Worker  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*cfb92d14SAndroid Build Coastguard Worker  */
27*cfb92d14SAndroid Build Coastguard Worker 
28*cfb92d14SAndroid Build Coastguard Worker /**
29*cfb92d14SAndroid Build Coastguard Worker  * @file
30*cfb92d14SAndroid Build Coastguard Worker  *   This file implements a spinel encoder.
31*cfb92d14SAndroid Build Coastguard Worker  */
32*cfb92d14SAndroid Build Coastguard Worker 
33*cfb92d14SAndroid Build Coastguard Worker #include "spinel_encoder.hpp"
34*cfb92d14SAndroid Build Coastguard Worker 
35*cfb92d14SAndroid Build Coastguard Worker #include <string.h>
36*cfb92d14SAndroid Build Coastguard Worker 
37*cfb92d14SAndroid Build Coastguard Worker #include "lib/utils/utils.hpp"
38*cfb92d14SAndroid Build Coastguard Worker 
39*cfb92d14SAndroid Build Coastguard Worker namespace ot {
40*cfb92d14SAndroid Build Coastguard Worker namespace Spinel {
41*cfb92d14SAndroid Build Coastguard Worker 
BeginFrame(Spinel::Buffer::Priority aPriority)42*cfb92d14SAndroid Build Coastguard Worker otError Encoder::BeginFrame(Spinel::Buffer::Priority aPriority)
43*cfb92d14SAndroid Build Coastguard Worker {
44*cfb92d14SAndroid Build Coastguard Worker     mNumOpenStructs = 0;
45*cfb92d14SAndroid Build Coastguard Worker     mNcpBuffer.InFrameBegin(aPriority);
46*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
47*cfb92d14SAndroid Build Coastguard Worker }
48*cfb92d14SAndroid Build Coastguard Worker 
BeginFrame(uint8_t aHeader,unsigned int aCommand)49*cfb92d14SAndroid Build Coastguard Worker otError Encoder::BeginFrame(uint8_t aHeader, unsigned int aCommand)
50*cfb92d14SAndroid Build Coastguard Worker {
51*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
52*cfb92d14SAndroid Build Coastguard Worker 
53*cfb92d14SAndroid Build Coastguard Worker     // Non-zero TID indicates this is a response to a spinel command.
54*cfb92d14SAndroid Build Coastguard Worker 
55*cfb92d14SAndroid Build Coastguard Worker     if (SPINEL_HEADER_GET_TID(aHeader) != 0)
56*cfb92d14SAndroid Build Coastguard Worker     {
57*cfb92d14SAndroid Build Coastguard Worker         EXPECT_NO_ERROR(error = BeginFrame(Spinel::Buffer::kPriorityHigh));
58*cfb92d14SAndroid Build Coastguard Worker     }
59*cfb92d14SAndroid Build Coastguard Worker     else
60*cfb92d14SAndroid Build Coastguard Worker     {
61*cfb92d14SAndroid Build Coastguard Worker         EXPECT_NO_ERROR(error = BeginFrame(Spinel::Buffer::kPriorityLow));
62*cfb92d14SAndroid Build Coastguard Worker     }
63*cfb92d14SAndroid Build Coastguard Worker 
64*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteUint8(aHeader));
65*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteUintPacked(aCommand));
66*cfb92d14SAndroid Build Coastguard Worker 
67*cfb92d14SAndroid Build Coastguard Worker exit:
68*cfb92d14SAndroid Build Coastguard Worker     return error;
69*cfb92d14SAndroid Build Coastguard Worker }
70*cfb92d14SAndroid Build Coastguard Worker 
BeginFrame(uint8_t aHeader,unsigned int aCommand,spinel_prop_key_t aKey)71*cfb92d14SAndroid Build Coastguard Worker otError Encoder::BeginFrame(uint8_t aHeader, unsigned int aCommand, spinel_prop_key_t aKey)
72*cfb92d14SAndroid Build Coastguard Worker {
73*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
74*cfb92d14SAndroid Build Coastguard Worker 
75*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = BeginFrame(aHeader, aCommand));
76*cfb92d14SAndroid Build Coastguard Worker 
77*cfb92d14SAndroid Build Coastguard Worker     // The write position is saved before writing the property key,
78*cfb92d14SAndroid Build Coastguard Worker     // so that if fetching the property fails and we need to
79*cfb92d14SAndroid Build Coastguard Worker     // reply with a `LAST_STATUS` error we can get back to
80*cfb92d14SAndroid Build Coastguard Worker     // this saved write position and update the property key.
81*cfb92d14SAndroid Build Coastguard Worker     // (Also see `OverwriteWithLastStatusError()`).
82*cfb92d14SAndroid Build Coastguard Worker 
83*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = SavePosition());
84*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteUintPacked(aKey));
85*cfb92d14SAndroid Build Coastguard Worker 
86*cfb92d14SAndroid Build Coastguard Worker exit:
87*cfb92d14SAndroid Build Coastguard Worker     return error;
88*cfb92d14SAndroid Build Coastguard Worker }
89*cfb92d14SAndroid Build Coastguard Worker 
OverwriteWithLastStatusError(spinel_status_t aStatus)90*cfb92d14SAndroid Build Coastguard Worker otError Encoder::OverwriteWithLastStatusError(spinel_status_t aStatus)
91*cfb92d14SAndroid Build Coastguard Worker {
92*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
93*cfb92d14SAndroid Build Coastguard Worker 
94*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = ResetToSaved());
95*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteUintPacked(SPINEL_PROP_LAST_STATUS));
96*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteUintPacked(aStatus));
97*cfb92d14SAndroid Build Coastguard Worker 
98*cfb92d14SAndroid Build Coastguard Worker exit:
99*cfb92d14SAndroid Build Coastguard Worker     return error;
100*cfb92d14SAndroid Build Coastguard Worker }
101*cfb92d14SAndroid Build Coastguard Worker 
EndFrame(void)102*cfb92d14SAndroid Build Coastguard Worker otError Encoder::EndFrame(void)
103*cfb92d14SAndroid Build Coastguard Worker {
104*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
105*cfb92d14SAndroid Build Coastguard Worker 
106*cfb92d14SAndroid Build Coastguard Worker     while (mNumOpenStructs > 0)
107*cfb92d14SAndroid Build Coastguard Worker     {
108*cfb92d14SAndroid Build Coastguard Worker         EXPECT_NO_ERROR(error = CloseStruct());
109*cfb92d14SAndroid Build Coastguard Worker     }
110*cfb92d14SAndroid Build Coastguard Worker 
111*cfb92d14SAndroid Build Coastguard Worker     error = mNcpBuffer.InFrameEnd();
112*cfb92d14SAndroid Build Coastguard Worker 
113*cfb92d14SAndroid Build Coastguard Worker exit:
114*cfb92d14SAndroid Build Coastguard Worker     return error;
115*cfb92d14SAndroid Build Coastguard Worker }
116*cfb92d14SAndroid Build Coastguard Worker 
WriteUint16(uint16_t aUint16)117*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WriteUint16(uint16_t aUint16)
118*cfb92d14SAndroid Build Coastguard Worker {
119*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
120*cfb92d14SAndroid Build Coastguard Worker 
121*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint16 >> 0) & 0xff));
122*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint16 >> 8) & 0xff));
123*cfb92d14SAndroid Build Coastguard Worker 
124*cfb92d14SAndroid Build Coastguard Worker exit:
125*cfb92d14SAndroid Build Coastguard Worker     return error;
126*cfb92d14SAndroid Build Coastguard Worker }
127*cfb92d14SAndroid Build Coastguard Worker 
WriteUint32(uint32_t aUint32)128*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WriteUint32(uint32_t aUint32)
129*cfb92d14SAndroid Build Coastguard Worker {
130*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
131*cfb92d14SAndroid Build Coastguard Worker 
132*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 0) & 0xff));
133*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 8) & 0xff));
134*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 16) & 0xff));
135*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint32 >> 24) & 0xff));
136*cfb92d14SAndroid Build Coastguard Worker 
137*cfb92d14SAndroid Build Coastguard Worker exit:
138*cfb92d14SAndroid Build Coastguard Worker     return error;
139*cfb92d14SAndroid Build Coastguard Worker }
140*cfb92d14SAndroid Build Coastguard Worker 
WriteUint64(uint64_t aUint64)141*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WriteUint64(uint64_t aUint64)
142*cfb92d14SAndroid Build Coastguard Worker {
143*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
144*cfb92d14SAndroid Build Coastguard Worker 
145*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 0) & 0xff));
146*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 8) & 0xff));
147*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 16) & 0xff));
148*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 24) & 0xff));
149*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 32) & 0xff));
150*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 40) & 0xff));
151*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 48) & 0xff));
152*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte((aUint64 >> 56) & 0xff));
153*cfb92d14SAndroid Build Coastguard Worker 
154*cfb92d14SAndroid Build Coastguard Worker exit:
155*cfb92d14SAndroid Build Coastguard Worker     return error;
156*cfb92d14SAndroid Build Coastguard Worker }
157*cfb92d14SAndroid Build Coastguard Worker 
WriteUintPacked(unsigned int aUint)158*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WriteUintPacked(unsigned int aUint)
159*cfb92d14SAndroid Build Coastguard Worker {
160*cfb92d14SAndroid Build Coastguard Worker     uint8_t        buffer[6];
161*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t len;
162*cfb92d14SAndroid Build Coastguard Worker 
163*cfb92d14SAndroid Build Coastguard Worker     len = spinel_packed_uint_encode(buffer, sizeof(buffer), aUint);
164*cfb92d14SAndroid Build Coastguard Worker 
165*cfb92d14SAndroid Build Coastguard Worker     return WriteData(buffer, static_cast<uint16_t>(len));
166*cfb92d14SAndroid Build Coastguard Worker }
167*cfb92d14SAndroid Build Coastguard Worker 
WriteDataWithLen(const uint8_t * aData,uint16_t aDataLen)168*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WriteDataWithLen(const uint8_t *aData, uint16_t aDataLen)
169*cfb92d14SAndroid Build Coastguard Worker {
170*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
171*cfb92d14SAndroid Build Coastguard Worker 
172*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteUint16(aDataLen));
173*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteData(aData, aDataLen));
174*cfb92d14SAndroid Build Coastguard Worker 
175*cfb92d14SAndroid Build Coastguard Worker exit:
176*cfb92d14SAndroid Build Coastguard Worker     return error;
177*cfb92d14SAndroid Build Coastguard Worker }
178*cfb92d14SAndroid Build Coastguard Worker 
WriteUtf8(const char * aUtf8)179*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WriteUtf8(const char *aUtf8)
180*cfb92d14SAndroid Build Coastguard Worker {
181*cfb92d14SAndroid Build Coastguard Worker     otError error;
182*cfb92d14SAndroid Build Coastguard Worker     size_t  len = strlen(aUtf8);
183*cfb92d14SAndroid Build Coastguard Worker 
184*cfb92d14SAndroid Build Coastguard Worker     if (len >= 0xffff)
185*cfb92d14SAndroid Build Coastguard Worker     {
186*cfb92d14SAndroid Build Coastguard Worker         len = 0xffff;
187*cfb92d14SAndroid Build Coastguard Worker     }
188*cfb92d14SAndroid Build Coastguard Worker 
189*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = WriteData(reinterpret_cast<const uint8_t *>(aUtf8), static_cast<uint16_t>(len)));
190*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte(0));
191*cfb92d14SAndroid Build Coastguard Worker 
192*cfb92d14SAndroid Build Coastguard Worker exit:
193*cfb92d14SAndroid Build Coastguard Worker     return error;
194*cfb92d14SAndroid Build Coastguard Worker }
195*cfb92d14SAndroid Build Coastguard Worker 
OpenStruct(void)196*cfb92d14SAndroid Build Coastguard Worker otError Encoder::OpenStruct(void)
197*cfb92d14SAndroid Build Coastguard Worker {
198*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
199*cfb92d14SAndroid Build Coastguard Worker 
200*cfb92d14SAndroid Build Coastguard Worker     EXPECT(mNumOpenStructs < kMaxNestedStructs, error = OT_ERROR_INVALID_STATE);
201*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameGetPosition(mStructPosition[mNumOpenStructs]));
202*cfb92d14SAndroid Build Coastguard Worker 
203*cfb92d14SAndroid Build Coastguard Worker     // Reserve bytes for the length to be filled when the struct gets closed.
204*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte(0));
205*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameFeedByte(0));
206*cfb92d14SAndroid Build Coastguard Worker 
207*cfb92d14SAndroid Build Coastguard Worker     mNumOpenStructs++;
208*cfb92d14SAndroid Build Coastguard Worker 
209*cfb92d14SAndroid Build Coastguard Worker exit:
210*cfb92d14SAndroid Build Coastguard Worker     return error;
211*cfb92d14SAndroid Build Coastguard Worker }
212*cfb92d14SAndroid Build Coastguard Worker 
CloseStruct(void)213*cfb92d14SAndroid Build Coastguard Worker otError Encoder::CloseStruct(void)
214*cfb92d14SAndroid Build Coastguard Worker {
215*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
216*cfb92d14SAndroid Build Coastguard Worker     uint16_t len;
217*cfb92d14SAndroid Build Coastguard Worker     uint8_t  buffer[sizeof(uint16_t)];
218*cfb92d14SAndroid Build Coastguard Worker 
219*cfb92d14SAndroid Build Coastguard Worker     EXPECT(mNumOpenStructs > 0, error = OT_ERROR_INVALID_STATE);
220*cfb92d14SAndroid Build Coastguard Worker 
221*cfb92d14SAndroid Build Coastguard Worker     mNumOpenStructs--;
222*cfb92d14SAndroid Build Coastguard Worker 
223*cfb92d14SAndroid Build Coastguard Worker     len = mNcpBuffer.InFrameGetDistance(mStructPosition[mNumOpenStructs]);
224*cfb92d14SAndroid Build Coastguard Worker     EXPECT(len >= sizeof(uint16_t), error = OT_ERROR_INVALID_STATE);
225*cfb92d14SAndroid Build Coastguard Worker 
226*cfb92d14SAndroid Build Coastguard Worker     len -= sizeof(uint16_t);
227*cfb92d14SAndroid Build Coastguard Worker 
228*cfb92d14SAndroid Build Coastguard Worker     buffer[0] = (len >> 0 & 0xff);
229*cfb92d14SAndroid Build Coastguard Worker     buffer[1] = (len >> 8 & 0xff);
230*cfb92d14SAndroid Build Coastguard Worker 
231*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameOverwrite(mStructPosition[mNumOpenStructs], buffer, sizeof(buffer)));
232*cfb92d14SAndroid Build Coastguard Worker 
233*cfb92d14SAndroid Build Coastguard Worker exit:
234*cfb92d14SAndroid Build Coastguard Worker     return error;
235*cfb92d14SAndroid Build Coastguard Worker }
236*cfb92d14SAndroid Build Coastguard Worker 
SavePosition(void)237*cfb92d14SAndroid Build Coastguard Worker otError Encoder::SavePosition(void)
238*cfb92d14SAndroid Build Coastguard Worker {
239*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
240*cfb92d14SAndroid Build Coastguard Worker 
241*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameGetPosition(mSavedPosition));
242*cfb92d14SAndroid Build Coastguard Worker     mSavedNumOpenStructs = mNumOpenStructs;
243*cfb92d14SAndroid Build Coastguard Worker 
244*cfb92d14SAndroid Build Coastguard Worker exit:
245*cfb92d14SAndroid Build Coastguard Worker     return error;
246*cfb92d14SAndroid Build Coastguard Worker }
247*cfb92d14SAndroid Build Coastguard Worker 
ResetToSaved(void)248*cfb92d14SAndroid Build Coastguard Worker otError Encoder::ResetToSaved(void)
249*cfb92d14SAndroid Build Coastguard Worker {
250*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
251*cfb92d14SAndroid Build Coastguard Worker 
252*cfb92d14SAndroid Build Coastguard Worker     EXPECT_NO_ERROR(error = mNcpBuffer.InFrameReset(mSavedPosition));
253*cfb92d14SAndroid Build Coastguard Worker     mNumOpenStructs = mSavedNumOpenStructs;
254*cfb92d14SAndroid Build Coastguard Worker 
255*cfb92d14SAndroid Build Coastguard Worker exit:
256*cfb92d14SAndroid Build Coastguard Worker     return error;
257*cfb92d14SAndroid Build Coastguard Worker }
258*cfb92d14SAndroid Build Coastguard Worker 
WritePacked(const char * aPackFormat,...)259*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WritePacked(const char *aPackFormat, ...)
260*cfb92d14SAndroid Build Coastguard Worker {
261*cfb92d14SAndroid Build Coastguard Worker     uint8_t        buf[kPackFormatBufferSize];
262*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_NONE;
263*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t packedLen;
264*cfb92d14SAndroid Build Coastguard Worker     va_list        args;
265*cfb92d14SAndroid Build Coastguard Worker 
266*cfb92d14SAndroid Build Coastguard Worker     va_start(args, aPackFormat);
267*cfb92d14SAndroid Build Coastguard Worker 
268*cfb92d14SAndroid Build Coastguard Worker     packedLen = spinel_datatype_vpack(buf, sizeof(buf), aPackFormat, args);
269*cfb92d14SAndroid Build Coastguard Worker     EXPECT((packedLen > 0) && (packedLen <= static_cast<spinel_ssize_t>(sizeof(buf))), error = OT_ERROR_NO_BUFS);
270*cfb92d14SAndroid Build Coastguard Worker 
271*cfb92d14SAndroid Build Coastguard Worker     error = mNcpBuffer.InFrameFeedData(buf, static_cast<uint16_t>(packedLen));
272*cfb92d14SAndroid Build Coastguard Worker 
273*cfb92d14SAndroid Build Coastguard Worker exit:
274*cfb92d14SAndroid Build Coastguard Worker     va_end(args);
275*cfb92d14SAndroid Build Coastguard Worker 
276*cfb92d14SAndroid Build Coastguard Worker     return error;
277*cfb92d14SAndroid Build Coastguard Worker }
278*cfb92d14SAndroid Build Coastguard Worker 
WriteVPacked(const char * aPackFormat,va_list aArgs)279*cfb92d14SAndroid Build Coastguard Worker otError Encoder::WriteVPacked(const char *aPackFormat, va_list aArgs)
280*cfb92d14SAndroid Build Coastguard Worker {
281*cfb92d14SAndroid Build Coastguard Worker     uint8_t        buf[kPackFormatBufferSize];
282*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_NONE;
283*cfb92d14SAndroid Build Coastguard Worker     spinel_ssize_t packedLen;
284*cfb92d14SAndroid Build Coastguard Worker 
285*cfb92d14SAndroid Build Coastguard Worker     packedLen = spinel_datatype_vpack(buf, sizeof(buf), aPackFormat, aArgs);
286*cfb92d14SAndroid Build Coastguard Worker     EXPECT((packedLen > 0) && (packedLen <= static_cast<spinel_ssize_t>(sizeof(buf))), error = OT_ERROR_NO_BUFS);
287*cfb92d14SAndroid Build Coastguard Worker 
288*cfb92d14SAndroid Build Coastguard Worker     error = mNcpBuffer.InFrameFeedData(buf, static_cast<uint16_t>(packedLen));
289*cfb92d14SAndroid Build Coastguard Worker 
290*cfb92d14SAndroid Build Coastguard Worker exit:
291*cfb92d14SAndroid Build Coastguard Worker     return error;
292*cfb92d14SAndroid Build Coastguard Worker }
293*cfb92d14SAndroid Build Coastguard Worker 
ClearNcpBuffer(void)294*cfb92d14SAndroid Build Coastguard Worker void Encoder::ClearNcpBuffer(void) { mNcpBuffer.Clear(); }
295*cfb92d14SAndroid Build Coastguard Worker 
296*cfb92d14SAndroid Build Coastguard Worker } // namespace Spinel
297*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
298