xref: /aosp_15_r20/external/openthread/tests/unit/test_spinel_buffer.cpp (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"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include <ctype.h>
30*cfb92d14SAndroid Build Coastguard Worker 
31*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
32*cfb92d14SAndroid Build Coastguard Worker #include "common/message.hpp"
33*cfb92d14SAndroid Build Coastguard Worker #include "common/random.hpp"
34*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
35*cfb92d14SAndroid Build Coastguard Worker #include "lib/spinel/spinel_buffer.hpp"
36*cfb92d14SAndroid Build Coastguard Worker 
37*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
38*cfb92d14SAndroid Build Coastguard Worker #include "test_util.hpp"
39*cfb92d14SAndroid Build Coastguard Worker 
40*cfb92d14SAndroid Build Coastguard Worker namespace ot {
41*cfb92d14SAndroid Build Coastguard Worker namespace Spinel {
42*cfb92d14SAndroid Build Coastguard Worker 
43*cfb92d14SAndroid Build Coastguard Worker // This module implements unit-test for Spinel::Buffer class.
44*cfb92d14SAndroid Build Coastguard Worker 
45*cfb92d14SAndroid Build Coastguard Worker // Test related constants:
46*cfb92d14SAndroid Build Coastguard Worker enum
47*cfb92d14SAndroid Build Coastguard Worker {
48*cfb92d14SAndroid Build Coastguard Worker     kTestBufferSize       = 800,
49*cfb92d14SAndroid Build Coastguard Worker     kTestIterationAttemps = 10000,
50*cfb92d14SAndroid Build Coastguard Worker     kTagArraySize         = 1000,
51*cfb92d14SAndroid Build Coastguard Worker };
52*cfb92d14SAndroid Build Coastguard Worker 
53*cfb92d14SAndroid Build Coastguard Worker //  Messages used for building frames...
54*cfb92d14SAndroid Build Coastguard Worker static const uint8_t sOpenThreadText[] = "OpenThread Rocks";
55*cfb92d14SAndroid Build Coastguard Worker static const uint8_t sHelloText[]      = "Hello there!";
56*cfb92d14SAndroid Build Coastguard Worker static const uint8_t sMottoText[]      = "Think good thoughts, say good words, do good deeds!";
57*cfb92d14SAndroid Build Coastguard Worker static const uint8_t sMysteryText[]    = "4871(\\):|(3$}{4|/4/2%14(\\)";
58*cfb92d14SAndroid Build Coastguard Worker static const uint8_t sHexText[]        = "0123456789abcdef";
59*cfb92d14SAndroid Build Coastguard Worker 
60*cfb92d14SAndroid Build Coastguard Worker static Instance    *sInstance;
61*cfb92d14SAndroid Build Coastguard Worker static MessagePool *sMessagePool;
62*cfb92d14SAndroid Build Coastguard Worker 
63*cfb92d14SAndroid Build Coastguard Worker struct CallbackContext
64*cfb92d14SAndroid Build Coastguard Worker {
65*cfb92d14SAndroid Build Coastguard Worker     uint32_t mFrameAddedCount;   // Number of times FrameAddedCallback is invoked.
66*cfb92d14SAndroid Build Coastguard Worker     uint32_t mFrameRemovedCount; // Number of times FrameRemovedCallback is invoked.
67*cfb92d14SAndroid Build Coastguard Worker };
68*cfb92d14SAndroid Build Coastguard Worker 
69*cfb92d14SAndroid Build Coastguard Worker CallbackContext sContext;
70*cfb92d14SAndroid Build Coastguard Worker 
71*cfb92d14SAndroid Build Coastguard Worker enum
72*cfb92d14SAndroid Build Coastguard Worker {
73*cfb92d14SAndroid Build Coastguard Worker     kNumPrios = 2, // Number of priority levels.
74*cfb92d14SAndroid Build Coastguard Worker 
75*cfb92d14SAndroid Build Coastguard Worker     kTestFrame1Size = sizeof(sMottoText) + sizeof(sMysteryText) + sizeof(sMottoText) + sizeof(sHelloText),
76*cfb92d14SAndroid Build Coastguard Worker     kTestFrame2Size = sizeof(sMysteryText) + sizeof(sHelloText) + sizeof(sOpenThreadText),
77*cfb92d14SAndroid Build Coastguard Worker     kTestFrame3Size = sizeof(sMysteryText),
78*cfb92d14SAndroid Build Coastguard Worker     kTestFrame4Size = sizeof(sOpenThreadText),
79*cfb92d14SAndroid Build Coastguard Worker };
80*cfb92d14SAndroid Build Coastguard Worker 
81*cfb92d14SAndroid Build Coastguard Worker Spinel::Buffer::FrameTag sTagHistoryArray[kNumPrios][kTagArraySize];
82*cfb92d14SAndroid Build Coastguard Worker uint32_t                 sTagHistoryHead[kNumPrios] = {0};
83*cfb92d14SAndroid Build Coastguard Worker uint32_t                 sTagHistoryTail[kNumPrios] = {0};
84*cfb92d14SAndroid Build Coastguard Worker Spinel::Buffer::FrameTag sExpectedRemovedTag        = Spinel::Buffer::kInvalidTag;
85*cfb92d14SAndroid Build Coastguard Worker 
ClearTagHistory(void)86*cfb92d14SAndroid Build Coastguard Worker void ClearTagHistory(void)
87*cfb92d14SAndroid Build Coastguard Worker {
88*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t priority = 0; priority < kNumPrios; priority++)
89*cfb92d14SAndroid Build Coastguard Worker     {
90*cfb92d14SAndroid Build Coastguard Worker         sTagHistoryHead[priority] = sTagHistoryTail[priority];
91*cfb92d14SAndroid Build Coastguard Worker     }
92*cfb92d14SAndroid Build Coastguard Worker }
93*cfb92d14SAndroid Build Coastguard Worker 
AddTagToHistory(Spinel::Buffer::FrameTag aTag,Spinel::Buffer::Priority aPriority)94*cfb92d14SAndroid Build Coastguard Worker void AddTagToHistory(Spinel::Buffer::FrameTag aTag, Spinel::Buffer::Priority aPriority)
95*cfb92d14SAndroid Build Coastguard Worker {
96*cfb92d14SAndroid Build Coastguard Worker     uint8_t priority = static_cast<uint8_t>(aPriority);
97*cfb92d14SAndroid Build Coastguard Worker 
98*cfb92d14SAndroid Build Coastguard Worker     sTagHistoryArray[priority][sTagHistoryTail[priority]] = aTag;
99*cfb92d14SAndroid Build Coastguard Worker 
100*cfb92d14SAndroid Build Coastguard Worker     if (++sTagHistoryTail[priority] == kTagArraySize)
101*cfb92d14SAndroid Build Coastguard Worker     {
102*cfb92d14SAndroid Build Coastguard Worker         sTagHistoryTail[priority] = 0;
103*cfb92d14SAndroid Build Coastguard Worker     }
104*cfb92d14SAndroid Build Coastguard Worker 
105*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTagHistoryTail[priority] != sTagHistoryHead[priority],
106*cfb92d14SAndroid Build Coastguard Worker                  "Ran out of space in `TagHistoryArray`, increase its size.");
107*cfb92d14SAndroid Build Coastguard Worker }
108*cfb92d14SAndroid Build Coastguard Worker 
VerifyAndRemoveTagFromHistory(Spinel::Buffer::FrameTag aTag,Spinel::Buffer::Priority aPriority)109*cfb92d14SAndroid Build Coastguard Worker void VerifyAndRemoveTagFromHistory(Spinel::Buffer::FrameTag aTag, Spinel::Buffer::Priority aPriority)
110*cfb92d14SAndroid Build Coastguard Worker {
111*cfb92d14SAndroid Build Coastguard Worker     uint8_t priority = static_cast<uint8_t>(aPriority);
112*cfb92d14SAndroid Build Coastguard Worker 
113*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sTagHistoryHead[priority] != sTagHistoryTail[priority], "Tag history is empty,");
114*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aTag == sTagHistoryArray[priority][sTagHistoryHead[priority]],
115*cfb92d14SAndroid Build Coastguard Worker                  "Removed tag does not match the added one");
116*cfb92d14SAndroid Build Coastguard Worker 
117*cfb92d14SAndroid Build Coastguard Worker     if (++sTagHistoryHead[priority] == kTagArraySize)
118*cfb92d14SAndroid Build Coastguard Worker     {
119*cfb92d14SAndroid Build Coastguard Worker         sTagHistoryHead[priority] = 0;
120*cfb92d14SAndroid Build Coastguard Worker     }
121*cfb92d14SAndroid Build Coastguard Worker 
122*cfb92d14SAndroid Build Coastguard Worker     if (sExpectedRemovedTag != Spinel::Buffer::kInvalidTag)
123*cfb92d14SAndroid Build Coastguard Worker     {
124*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(sExpectedRemovedTag == aTag, "Removed tag does match the previous OutFrameGetTag()");
125*cfb92d14SAndroid Build Coastguard Worker         sExpectedRemovedTag = Spinel::Buffer::kInvalidTag;
126*cfb92d14SAndroid Build Coastguard Worker     }
127*cfb92d14SAndroid Build Coastguard Worker }
128*cfb92d14SAndroid Build Coastguard Worker 
FrameAddedCallback(void * aContext,Spinel::Buffer::FrameTag aTag,Spinel::Buffer::Priority aPriority,Spinel::Buffer * aNcpBuffer)129*cfb92d14SAndroid Build Coastguard Worker void FrameAddedCallback(void                    *aContext,
130*cfb92d14SAndroid Build Coastguard Worker                         Spinel::Buffer::FrameTag aTag,
131*cfb92d14SAndroid Build Coastguard Worker                         Spinel::Buffer::Priority aPriority,
132*cfb92d14SAndroid Build Coastguard Worker                         Spinel::Buffer          *aNcpBuffer)
133*cfb92d14SAndroid Build Coastguard Worker {
134*cfb92d14SAndroid Build Coastguard Worker     CallbackContext *callbackContext = reinterpret_cast<CallbackContext *>(aContext);
135*cfb92d14SAndroid Build Coastguard Worker 
136*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer != nullptr, "Null Spinel::Buffer in the callback");
137*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(callbackContext != nullptr, "Null context in the callback");
138*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aTag != Spinel::Buffer::kInvalidTag, "Invalid tag in the callback");
139*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aTag == aNcpBuffer->InFrameGetLastTag(), "InFrameGetLastTag() does not match the tag from callback");
140*cfb92d14SAndroid Build Coastguard Worker 
141*cfb92d14SAndroid Build Coastguard Worker     AddTagToHistory(aTag, aPriority);
142*cfb92d14SAndroid Build Coastguard Worker 
143*cfb92d14SAndroid Build Coastguard Worker     callbackContext->mFrameAddedCount++;
144*cfb92d14SAndroid Build Coastguard Worker }
145*cfb92d14SAndroid Build Coastguard Worker 
FrameRemovedCallback(void * aContext,Spinel::Buffer::FrameTag aTag,Spinel::Buffer::Priority aPriority,Spinel::Buffer * aNcpBuffer)146*cfb92d14SAndroid Build Coastguard Worker void FrameRemovedCallback(void                    *aContext,
147*cfb92d14SAndroid Build Coastguard Worker                           Spinel::Buffer::FrameTag aTag,
148*cfb92d14SAndroid Build Coastguard Worker                           Spinel::Buffer::Priority aPriority,
149*cfb92d14SAndroid Build Coastguard Worker                           Spinel::Buffer          *aNcpBuffer)
150*cfb92d14SAndroid Build Coastguard Worker {
151*cfb92d14SAndroid Build Coastguard Worker     CallbackContext *callbackContext = reinterpret_cast<CallbackContext *>(aContext);
152*cfb92d14SAndroid Build Coastguard Worker 
153*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer != nullptr, "Null Spinel::Buffer in the callback");
154*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(callbackContext != nullptr, "Null context in the callback");
155*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aTag != Spinel::Buffer::kInvalidTag, "Invalid tag in the callback");
156*cfb92d14SAndroid Build Coastguard Worker 
157*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveTagFromHistory(aTag, aPriority);
158*cfb92d14SAndroid Build Coastguard Worker 
159*cfb92d14SAndroid Build Coastguard Worker     callbackContext->mFrameRemovedCount++;
160*cfb92d14SAndroid Build Coastguard Worker }
161*cfb92d14SAndroid Build Coastguard Worker 
162*cfb92d14SAndroid Build Coastguard Worker // Reads bytes from the ncp buffer, and verifies that it matches with the given content buffer.
ReadAndVerifyContent(Spinel::Buffer & aNcpBuffer,const uint8_t * aContentBuffer,uint16_t aBufferLength)163*cfb92d14SAndroid Build Coastguard Worker void ReadAndVerifyContent(Spinel::Buffer &aNcpBuffer, const uint8_t *aContentBuffer, uint16_t aBufferLength)
164*cfb92d14SAndroid Build Coastguard Worker {
165*cfb92d14SAndroid Build Coastguard Worker     while (aBufferLength--)
166*cfb92d14SAndroid Build Coastguard Worker     {
167*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(aNcpBuffer.OutFrameHasEnded() == false, "Out frame ended before end of expected content.");
168*cfb92d14SAndroid Build Coastguard Worker 
169*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == *aContentBuffer++,
170*cfb92d14SAndroid Build Coastguard Worker                      "Out frame read byte does not match expected content");
171*cfb92d14SAndroid Build Coastguard Worker     }
172*cfb92d14SAndroid Build Coastguard Worker }
173*cfb92d14SAndroid Build Coastguard Worker 
WriteTestFrame1(Spinel::Buffer & aNcpBuffer,Spinel::Buffer::Priority aPriority)174*cfb92d14SAndroid Build Coastguard Worker void WriteTestFrame1(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
175*cfb92d14SAndroid Build Coastguard Worker {
176*cfb92d14SAndroid Build Coastguard Worker     Message        *message;
177*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext;
178*cfb92d14SAndroid Build Coastguard Worker 
179*cfb92d14SAndroid Build Coastguard Worker     message = sMessagePool->Allocate(Message::kTypeIp6);
180*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr, "Null Message");
181*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->SetLength(sizeof(sMottoText)));
182*cfb92d14SAndroid Build Coastguard Worker     message->Write(0, sMottoText);
183*cfb92d14SAndroid Build Coastguard Worker 
184*cfb92d14SAndroid Build Coastguard Worker     oldContext = sContext;
185*cfb92d14SAndroid Build Coastguard Worker     aNcpBuffer.InFrameBegin(aPriority);
186*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMottoText, sizeof(sMottoText)));
187*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMysteryText, sizeof(sMysteryText)));
188*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message));
189*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)));
190*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameEnd());
191*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
192*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
193*cfb92d14SAndroid Build Coastguard Worker }
194*cfb92d14SAndroid Build Coastguard Worker 
VerifyAndRemoveFrame1(Spinel::Buffer & aNcpBuffer)195*cfb92d14SAndroid Build Coastguard Worker void VerifyAndRemoveFrame1(Spinel::Buffer &aNcpBuffer)
196*cfb92d14SAndroid Build Coastguard Worker {
197*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
198*cfb92d14SAndroid Build Coastguard Worker 
199*cfb92d14SAndroid Build Coastguard Worker     sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
200*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size);
201*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameBegin());
202*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sExpectedRemovedTag == aNcpBuffer.OutFrameGetTag());
203*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size);
204*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sMottoText, sizeof(sMottoText));
205*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
206*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sMottoText, sizeof(sMottoText));
207*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sHelloText, sizeof(sHelloText));
208*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameHasEnded(), "Frame longer than expected.");
209*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
210*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(sExpectedRemovedTag == aNcpBuffer.OutFrameGetTag());
211*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame1Size);
212*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameRemove());
213*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
214*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
215*cfb92d14SAndroid Build Coastguard Worker }
216*cfb92d14SAndroid Build Coastguard Worker 
WriteTestFrame2(Spinel::Buffer & aNcpBuffer,Spinel::Buffer::Priority aPriority)217*cfb92d14SAndroid Build Coastguard Worker void WriteTestFrame2(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
218*cfb92d14SAndroid Build Coastguard Worker {
219*cfb92d14SAndroid Build Coastguard Worker     Message        *message1;
220*cfb92d14SAndroid Build Coastguard Worker     Message        *message2;
221*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
222*cfb92d14SAndroid Build Coastguard Worker 
223*cfb92d14SAndroid Build Coastguard Worker     message1 = sMessagePool->Allocate(Message::kTypeIp6);
224*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message1 != nullptr, "Null Message");
225*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message1->SetLength(sizeof(sMysteryText)));
226*cfb92d14SAndroid Build Coastguard Worker     message1->Write(0, sMysteryText);
227*cfb92d14SAndroid Build Coastguard Worker 
228*cfb92d14SAndroid Build Coastguard Worker     message2 = sMessagePool->Allocate(Message::kTypeIp6);
229*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message2 != nullptr, "Null Message");
230*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message2->SetLength(sizeof(sHelloText)));
231*cfb92d14SAndroid Build Coastguard Worker     message2->Write(0, sHelloText);
232*cfb92d14SAndroid Build Coastguard Worker 
233*cfb92d14SAndroid Build Coastguard Worker     aNcpBuffer.InFrameBegin(aPriority);
234*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message1));
235*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)));
236*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message2));
237*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameEnd());
238*cfb92d14SAndroid Build Coastguard Worker 
239*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
240*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
241*cfb92d14SAndroid Build Coastguard Worker }
242*cfb92d14SAndroid Build Coastguard Worker 
VerifyAndRemoveFrame2(Spinel::Buffer & aNcpBuffer)243*cfb92d14SAndroid Build Coastguard Worker void VerifyAndRemoveFrame2(Spinel::Buffer &aNcpBuffer)
244*cfb92d14SAndroid Build Coastguard Worker {
245*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
246*cfb92d14SAndroid Build Coastguard Worker 
247*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size);
248*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameBegin());
249*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size);
250*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
251*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sOpenThreadText, sizeof(sOpenThreadText));
252*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sHelloText, sizeof(sHelloText));
253*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameHasEnded(), "Frame longer than expected.");
254*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
255*cfb92d14SAndroid Build Coastguard Worker     sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
256*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == kTestFrame2Size);
257*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameRemove());
258*cfb92d14SAndroid Build Coastguard Worker 
259*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
260*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
261*cfb92d14SAndroid Build Coastguard Worker }
262*cfb92d14SAndroid Build Coastguard Worker 
WriteTestFrame3(Spinel::Buffer & aNcpBuffer,Spinel::Buffer::Priority aPriority)263*cfb92d14SAndroid Build Coastguard Worker void WriteTestFrame3(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
264*cfb92d14SAndroid Build Coastguard Worker {
265*cfb92d14SAndroid Build Coastguard Worker     Message        *message1;
266*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
267*cfb92d14SAndroid Build Coastguard Worker 
268*cfb92d14SAndroid Build Coastguard Worker     message1 = sMessagePool->Allocate(Message::kTypeIp6);
269*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message1 != nullptr, "Null Message");
270*cfb92d14SAndroid Build Coastguard Worker 
271*cfb92d14SAndroid Build Coastguard Worker     // An empty message with no content.
272*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message1->SetLength(0));
273*cfb92d14SAndroid Build Coastguard Worker 
274*cfb92d14SAndroid Build Coastguard Worker     aNcpBuffer.InFrameBegin(aPriority);
275*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedMessage(message1));
276*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedData(sMysteryText, sizeof(sMysteryText)));
277*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameEnd());
278*cfb92d14SAndroid Build Coastguard Worker 
279*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
280*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
281*cfb92d14SAndroid Build Coastguard Worker }
282*cfb92d14SAndroid Build Coastguard Worker 
VerifyAndRemoveFrame3(Spinel::Buffer & aNcpBuffer)283*cfb92d14SAndroid Build Coastguard Worker void VerifyAndRemoveFrame3(Spinel::Buffer &aNcpBuffer)
284*cfb92d14SAndroid Build Coastguard Worker {
285*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
286*cfb92d14SAndroid Build Coastguard Worker 
287*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText));
288*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameBegin());
289*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText));
290*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sMysteryText, sizeof(sMysteryText));
291*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameHasEnded(), "Frame longer than expected.");
292*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
293*cfb92d14SAndroid Build Coastguard Worker     sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
294*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sMysteryText));
295*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameRemove());
296*cfb92d14SAndroid Build Coastguard Worker 
297*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
298*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
299*cfb92d14SAndroid Build Coastguard Worker }
300*cfb92d14SAndroid Build Coastguard Worker 
WriteTestFrame4(Spinel::Buffer & aNcpBuffer,Spinel::Buffer::Priority aPriority)301*cfb92d14SAndroid Build Coastguard Worker void WriteTestFrame4(Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
302*cfb92d14SAndroid Build Coastguard Worker {
303*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
304*cfb92d14SAndroid Build Coastguard Worker 
305*cfb92d14SAndroid Build Coastguard Worker     aNcpBuffer.InFrameBegin(aPriority);
306*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)));
307*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.InFrameEnd());
308*cfb92d14SAndroid Build Coastguard Worker 
309*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
310*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
311*cfb92d14SAndroid Build Coastguard Worker }
312*cfb92d14SAndroid Build Coastguard Worker 
VerifyAndRemoveFrame4(Spinel::Buffer & aNcpBuffer)313*cfb92d14SAndroid Build Coastguard Worker void VerifyAndRemoveFrame4(Spinel::Buffer &aNcpBuffer)
314*cfb92d14SAndroid Build Coastguard Worker {
315*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
316*cfb92d14SAndroid Build Coastguard Worker 
317*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText));
318*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameBegin());
319*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText));
320*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sOpenThreadText, sizeof(sOpenThreadText));
321*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameHasEnded(), "Frame longer than expected.");
322*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameReadByte() == 0, "ReadByte() returned non-zero after end of frame.");
323*cfb92d14SAndroid Build Coastguard Worker     sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
324*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == sizeof(sOpenThreadText));
325*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameRemove());
326*cfb92d14SAndroid Build Coastguard Worker 
327*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
328*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
329*cfb92d14SAndroid Build Coastguard Worker }
330*cfb92d14SAndroid Build Coastguard Worker 
331*cfb92d14SAndroid Build Coastguard Worker // This function implements the Spinel::Buffer tests
TestBuffer(void)332*cfb92d14SAndroid Build Coastguard Worker void TestBuffer(void)
333*cfb92d14SAndroid Build Coastguard Worker {
334*cfb92d14SAndroid Build Coastguard Worker     unsigned       i, j;
335*cfb92d14SAndroid Build Coastguard Worker     uint8_t        buffer[kTestBufferSize];
336*cfb92d14SAndroid Build Coastguard Worker     Spinel::Buffer ncpBuffer(buffer, kTestBufferSize);
337*cfb92d14SAndroid Build Coastguard Worker 
338*cfb92d14SAndroid Build Coastguard Worker     Message                      *message;
339*cfb92d14SAndroid Build Coastguard Worker     uint8_t                       readBuffer[16];
340*cfb92d14SAndroid Build Coastguard Worker     uint16_t                      readLen, readOffset;
341*cfb92d14SAndroid Build Coastguard Worker     Spinel::Buffer::WritePosition pos1, pos2;
342*cfb92d14SAndroid Build Coastguard Worker 
343*cfb92d14SAndroid Build Coastguard Worker     sInstance    = testInitInstance();
344*cfb92d14SAndroid Build Coastguard Worker     sMessagePool = &sInstance->Get<MessagePool>();
345*cfb92d14SAndroid Build Coastguard Worker 
346*cfb92d14SAndroid Build Coastguard Worker     for (i = 0; i < sizeof(buffer); i++)
347*cfb92d14SAndroid Build Coastguard Worker     {
348*cfb92d14SAndroid Build Coastguard Worker         buffer[i] = 0;
349*cfb92d14SAndroid Build Coastguard Worker     }
350*cfb92d14SAndroid Build Coastguard Worker 
351*cfb92d14SAndroid Build Coastguard Worker     sContext.mFrameAddedCount   = 0;
352*cfb92d14SAndroid Build Coastguard Worker     sContext.mFrameRemovedCount = 0;
353*cfb92d14SAndroid Build Coastguard Worker     ClearTagHistory();
354*cfb92d14SAndroid Build Coastguard Worker 
355*cfb92d14SAndroid Build Coastguard Worker     // Set the callbacks.
356*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.SetFrameAddedCallback(FrameAddedCallback, &sContext);
357*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.SetFrameRemovedCallback(FrameRemovedCallback, &sContext);
358*cfb92d14SAndroid Build Coastguard Worker 
359*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
360*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 1: Check initial buffer state");
361*cfb92d14SAndroid Build Coastguard Worker 
362*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty(), "Not empty after init.");
363*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameGetLastTag() == Spinel::Buffer::kInvalidTag, "Incorrect tag after init.");
364*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetTag() == Spinel::Buffer::kInvalidTag, "Incorrect OutFrameTag after init.");
365*cfb92d14SAndroid Build Coastguard Worker 
366*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
367*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 2: Write and read a single frame");
368*cfb92d14SAndroid Build Coastguard Worker 
369*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
370*cfb92d14SAndroid Build Coastguard Worker     DumpBuffer("\nBuffer after frame1 (low priority)", buffer, kTestBufferSize);
371*cfb92d14SAndroid Build Coastguard Worker     printf("\nFrameLen is %u", ncpBuffer.OutFrameGetLength());
372*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
373*cfb92d14SAndroid Build Coastguard Worker 
374*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
375*cfb92d14SAndroid Build Coastguard Worker     DumpBuffer("\nBuffer after frame1 (high priority)", buffer, kTestBufferSize);
376*cfb92d14SAndroid Build Coastguard Worker     printf("\nFrameLen is %u", ncpBuffer.OutFrameGetLength());
377*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
378*cfb92d14SAndroid Build Coastguard Worker 
379*cfb92d14SAndroid Build Coastguard Worker     printf("\nIterations: ");
380*cfb92d14SAndroid Build Coastguard Worker 
381*cfb92d14SAndroid Build Coastguard Worker     // Always add as low priority.
382*cfb92d14SAndroid Build Coastguard Worker     for (j = 0; j < kTestIterationAttemps; j++)
383*cfb92d14SAndroid Build Coastguard Worker     {
384*cfb92d14SAndroid Build Coastguard Worker         printf("*");
385*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
386*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
387*cfb92d14SAndroid Build Coastguard Worker 
388*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame1(ncpBuffer);
389*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() is incorrect when buffer is empty.");
390*cfb92d14SAndroid Build Coastguard Worker     }
391*cfb92d14SAndroid Build Coastguard Worker 
392*cfb92d14SAndroid Build Coastguard Worker     // Always add as high priority.
393*cfb92d14SAndroid Build Coastguard Worker     for (j = 0; j < kTestIterationAttemps; j++)
394*cfb92d14SAndroid Build Coastguard Worker     {
395*cfb92d14SAndroid Build Coastguard Worker         printf("*");
396*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
397*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
398*cfb92d14SAndroid Build Coastguard Worker 
399*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame1(ncpBuffer);
400*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() is incorrect when buffer is empty.");
401*cfb92d14SAndroid Build Coastguard Worker     }
402*cfb92d14SAndroid Build Coastguard Worker 
403*cfb92d14SAndroid Build Coastguard Worker     // Every 5th add as high priority.
404*cfb92d14SAndroid Build Coastguard Worker     for (j = 0; j < kTestIterationAttemps; j++)
405*cfb92d14SAndroid Build Coastguard Worker     {
406*cfb92d14SAndroid Build Coastguard Worker         printf("*");
407*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame1(ncpBuffer, ((j % 5) == 0) ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow);
408*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty() == false, "IsEmpty() is incorrect when buffer is non-empty");
409*cfb92d14SAndroid Build Coastguard Worker 
410*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame1(ncpBuffer);
411*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() is incorrect when buffer is empty.");
412*cfb92d14SAndroid Build Coastguard Worker     }
413*cfb92d14SAndroid Build Coastguard Worker 
414*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
415*cfb92d14SAndroid Build Coastguard Worker 
416*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
417*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 3: Multiple frames write and read (same priority)");
418*cfb92d14SAndroid Build Coastguard Worker 
419*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
420*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
421*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
422*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
423*cfb92d14SAndroid Build Coastguard Worker 
424*cfb92d14SAndroid Build Coastguard Worker     DumpBuffer("\nBuffer after multiple frames", buffer, kTestBufferSize);
425*cfb92d14SAndroid Build Coastguard Worker 
426*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
427*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
428*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
429*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
430*cfb92d14SAndroid Build Coastguard Worker 
431*cfb92d14SAndroid Build Coastguard Worker     printf("\nIterations: ");
432*cfb92d14SAndroid Build Coastguard Worker 
433*cfb92d14SAndroid Build Coastguard Worker     // Repeat this multiple times.
434*cfb92d14SAndroid Build Coastguard Worker     for (j = 0; j < kTestIterationAttemps; j++)
435*cfb92d14SAndroid Build Coastguard Worker     {
436*cfb92d14SAndroid Build Coastguard Worker         printf("*");
437*cfb92d14SAndroid Build Coastguard Worker 
438*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
439*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
440*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
441*cfb92d14SAndroid Build Coastguard Worker 
442*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame2(ncpBuffer);
443*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame3(ncpBuffer);
444*cfb92d14SAndroid Build Coastguard Worker 
445*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
446*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
447*cfb92d14SAndroid Build Coastguard Worker 
448*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame2(ncpBuffer);
449*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame2(ncpBuffer);
450*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame3(ncpBuffer);
451*cfb92d14SAndroid Build Coastguard Worker 
452*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() is incorrect when buffer is empty.");
453*cfb92d14SAndroid Build Coastguard Worker     }
454*cfb92d14SAndroid Build Coastguard Worker 
455*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
456*cfb92d14SAndroid Build Coastguard Worker 
457*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
458*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 4: Multiple frames write and read (mixed priority)");
459*cfb92d14SAndroid Build Coastguard Worker 
460*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
461*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
462*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
463*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
464*cfb92d14SAndroid Build Coastguard Worker 
465*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
466*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
467*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
468*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
469*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
470*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
471*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
472*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
473*cfb92d14SAndroid Build Coastguard Worker 
474*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
475*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
476*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
477*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
478*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
479*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
480*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
481*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
482*cfb92d14SAndroid Build Coastguard Worker 
483*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
484*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
485*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
486*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
487*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
488*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
489*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
490*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
491*cfb92d14SAndroid Build Coastguard Worker 
492*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
493*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
494*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityLow);
495*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityLow);
496*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
497*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
498*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
499*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
500*cfb92d14SAndroid Build Coastguard Worker 
501*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
502*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
503*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
504*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
505*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityHigh);
506*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
507*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
508*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
509*cfb92d14SAndroid Build Coastguard Worker 
510*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
511*cfb92d14SAndroid Build Coastguard Worker 
512*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
513*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 5: Frame discard when buffer full and partial read restart");
514*cfb92d14SAndroid Build Coastguard Worker 
515*cfb92d14SAndroid Build Coastguard Worker     printf("\nIterations: ");
516*cfb92d14SAndroid Build Coastguard Worker 
517*cfb92d14SAndroid Build Coastguard Worker     for (j = 0; j < kTestIterationAttemps; j++)
518*cfb92d14SAndroid Build Coastguard Worker     {
519*cfb92d14SAndroid Build Coastguard Worker         bool frame1IsHighPriority = ((j % 3) == 0);
520*cfb92d14SAndroid Build Coastguard Worker 
521*cfb92d14SAndroid Build Coastguard Worker         printf("*");
522*cfb92d14SAndroid Build Coastguard Worker 
523*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
524*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
525*cfb92d14SAndroid Build Coastguard Worker 
526*cfb92d14SAndroid Build Coastguard Worker         ncpBuffer.InFrameBegin((j % 2) == 0 ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow);
527*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)));
528*cfb92d14SAndroid Build Coastguard Worker 
529*cfb92d14SAndroid Build Coastguard Worker         message = sMessagePool->Allocate(Message::kTypeIp6);
530*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(message != nullptr, "Null Message");
531*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(message->SetLength(sizeof(sMysteryText)));
532*cfb92d14SAndroid Build Coastguard Worker         message->Write(0, sMysteryText);
533*cfb92d14SAndroid Build Coastguard Worker 
534*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameFeedMessage(message));
535*cfb92d14SAndroid Build Coastguard Worker 
536*cfb92d14SAndroid Build Coastguard Worker         // Start writing a new frame in middle of an unfinished frame. Ensure the first one is discarded.
537*cfb92d14SAndroid Build Coastguard Worker         WriteTestFrame1(ncpBuffer, frame1IsHighPriority ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow);
538*cfb92d14SAndroid Build Coastguard Worker 
539*cfb92d14SAndroid Build Coastguard Worker         // Note that message will not be freed by the NCP buffer since the frame associated with it was discarded and
540*cfb92d14SAndroid Build Coastguard Worker         // not yet finished/ended.
541*cfb92d14SAndroid Build Coastguard Worker         otMessageFree(message);
542*cfb92d14SAndroid Build Coastguard Worker 
543*cfb92d14SAndroid Build Coastguard Worker         VerifyAndRemoveFrame3(ncpBuffer);
544*cfb92d14SAndroid Build Coastguard Worker 
545*cfb92d14SAndroid Build Coastguard Worker         // Start reading few bytes from the frame
546*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.OutFrameBegin());
547*cfb92d14SAndroid Build Coastguard Worker         ncpBuffer.OutFrameReadByte();
548*cfb92d14SAndroid Build Coastguard Worker         ncpBuffer.OutFrameReadByte();
549*cfb92d14SAndroid Build Coastguard Worker         ncpBuffer.OutFrameReadByte();
550*cfb92d14SAndroid Build Coastguard Worker 
551*cfb92d14SAndroid Build Coastguard Worker         // Now reset the read pointer and read/verify the frame from start.
552*cfb92d14SAndroid Build Coastguard Worker         if (frame1IsHighPriority)
553*cfb92d14SAndroid Build Coastguard Worker         {
554*cfb92d14SAndroid Build Coastguard Worker             VerifyAndRemoveFrame1(ncpBuffer);
555*cfb92d14SAndroid Build Coastguard Worker             VerifyAndRemoveFrame2(ncpBuffer);
556*cfb92d14SAndroid Build Coastguard Worker         }
557*cfb92d14SAndroid Build Coastguard Worker         else
558*cfb92d14SAndroid Build Coastguard Worker         {
559*cfb92d14SAndroid Build Coastguard Worker             VerifyAndRemoveFrame2(ncpBuffer);
560*cfb92d14SAndroid Build Coastguard Worker             VerifyAndRemoveFrame1(ncpBuffer);
561*cfb92d14SAndroid Build Coastguard Worker         }
562*cfb92d14SAndroid Build Coastguard Worker 
563*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() is incorrect when buffer is empty.");
564*cfb92d14SAndroid Build Coastguard Worker     }
565*cfb92d14SAndroid Build Coastguard Worker 
566*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
567*cfb92d14SAndroid Build Coastguard Worker 
568*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
569*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 6: Clear() and empty buffer method tests");
570*cfb92d14SAndroid Build Coastguard Worker 
571*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
572*cfb92d14SAndroid Build Coastguard Worker 
573*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.Clear();
574*cfb92d14SAndroid Build Coastguard Worker     ClearTagHistory();
575*cfb92d14SAndroid Build Coastguard Worker 
576*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameGetLastTag() == Spinel::Buffer::kInvalidTag, "Incorrect last tag after Clear().");
577*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetTag() == Spinel::Buffer::kInvalidTag, "Incorrect OutFrameTag after Clear().");
578*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() is incorrect when buffer is empty.");
579*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameHasEnded(), "OutFrameHasEnded() is incorrect when no data in buffer.");
580*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameRemove() == OT_ERROR_NOT_FOUND,
581*cfb92d14SAndroid Build Coastguard Worker                  "Remove() returned incorrect error status when buffer is empty.");
582*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == 0,
583*cfb92d14SAndroid Build Coastguard Worker                  "OutFrameGetLength() returned non-zero length when buffer is empty.");
584*cfb92d14SAndroid Build Coastguard Worker 
585*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
586*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
587*cfb92d14SAndroid Build Coastguard Worker 
588*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty(), "IsEmpty() is incorrect when buffer is empty.");
589*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameHasEnded(), "OutFrameHasEnded() is incorrect when no data in buffer.");
590*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameRemove() == OT_ERROR_NOT_FOUND,
591*cfb92d14SAndroid Build Coastguard Worker                  "Remove() returned incorrect error status when buffer is empty.");
592*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == 0,
593*cfb92d14SAndroid Build Coastguard Worker                  "OutFrameGetLength() returned non-zero length when buffer is empty.");
594*cfb92d14SAndroid Build Coastguard Worker 
595*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
596*cfb92d14SAndroid Build Coastguard Worker 
597*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
598*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 7: OutFrameRead() in parts\n");
599*cfb92d14SAndroid Build Coastguard Worker 
600*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityLow);
601*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameFeedData(sMottoText, sizeof(sMottoText)));
602*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameEnd());
603*cfb92d14SAndroid Build Coastguard Worker 
604*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameBegin());
605*cfb92d14SAndroid Build Coastguard Worker     readOffset = 0;
606*cfb92d14SAndroid Build Coastguard Worker 
607*cfb92d14SAndroid Build Coastguard Worker     while ((readLen = ncpBuffer.OutFrameRead(sizeof(readBuffer), readBuffer)) != 0)
608*cfb92d14SAndroid Build Coastguard Worker     {
609*cfb92d14SAndroid Build Coastguard Worker         DumpBuffer("Read() returned", readBuffer, readLen);
610*cfb92d14SAndroid Build Coastguard Worker 
611*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(memcmp(readBuffer, sMottoText + readOffset, readLen) == 0,
612*cfb92d14SAndroid Build Coastguard Worker                      "Read() does not match expected content.");
613*cfb92d14SAndroid Build Coastguard Worker 
614*cfb92d14SAndroid Build Coastguard Worker         readOffset += readLen;
615*cfb92d14SAndroid Build Coastguard Worker     }
616*cfb92d14SAndroid Build Coastguard Worker 
617*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(readOffset == sizeof(sMottoText), "Read len does not match expected length.");
618*cfb92d14SAndroid Build Coastguard Worker 
619*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameRemove());
620*cfb92d14SAndroid Build Coastguard Worker 
621*cfb92d14SAndroid Build Coastguard Worker     printf("\n -- PASS\n");
622*cfb92d14SAndroid Build Coastguard Worker 
623*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
624*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 8: Remove a frame without reading it first");
625*cfb92d14SAndroid Build Coastguard Worker 
626*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
627*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
628*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
629*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameRemove());
630*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
631*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
632*cfb92d14SAndroid Build Coastguard Worker 
633*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
634*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 9: Check length when front frame gets changed (a higher priority frame is added)");
635*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
636*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
637*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
638*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame3Size);
639*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
640*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
641*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
642*cfb92d14SAndroid Build Coastguard Worker 
643*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
644*cfb92d14SAndroid Build Coastguard Worker     printf("\nTest 10: Active out frame remaining unchanged when a higher priority frame is written while reading it");
645*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
646*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
647*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameBegin());
648*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
649*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
650*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
651*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
652*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
653*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameBegin());
654*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
655*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
656*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
657*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
658*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
659*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameHasEnded(), "Frame longer than expected.");
660*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
661*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityLow);
662*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
663*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
664*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
665*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
666*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
667*cfb92d14SAndroid Build Coastguard Worker     // Repeat test reversing frame priority orders.
668*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
669*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
670*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameBegin());
671*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
672*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
673*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
674*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
675*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
676*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameBegin());
677*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
678*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
679*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMysteryText, sizeof(sMysteryText));
680*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sMottoText, sizeof(sMottoText));
681*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
682*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameHasEnded(), "Frame longer than expected.");
683*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame3(ncpBuffer, Spinel::Buffer::kPriorityHigh);
684*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame4(ncpBuffer, Spinel::Buffer::kPriorityLow);
685*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameGetLength() == kTestFrame1Size);
686*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
687*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame3(ncpBuffer);
688*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
689*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
690*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
691*cfb92d14SAndroid Build Coastguard Worker 
692*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
693*cfb92d14SAndroid Build Coastguard Worker     printf("\n Test 11: Read and remove in middle of an active input frame write");
694*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
695*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
696*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)));
697*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
698*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty());
699*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameEnd());
700*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
701*cfb92d14SAndroid Build Coastguard Worker     // Repeat the test reversing priorities
702*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
703*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityLow);
704*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)));
705*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
706*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty());
707*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameEnd());
708*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
709*cfb92d14SAndroid Build Coastguard Worker     // Repeat the test with same priorities
710*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
711*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
712*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, sizeof(sOpenThreadText)));
713*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
714*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty());
715*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameEnd());
716*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame4(ncpBuffer);
717*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
718*cfb92d14SAndroid Build Coastguard Worker 
719*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
720*cfb92d14SAndroid Build Coastguard Worker     printf("\n Test 12: Check returned error status");
721*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
722*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
723*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer)) == OT_ERROR_NO_BUFS);
724*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
725*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty());
726*cfb92d14SAndroid Build Coastguard Worker 
727*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityLow);
728*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityHigh);
729*cfb92d14SAndroid Build Coastguard Worker     // Ensure writes with starting `InFrameBegin()` fail
730*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 1) == OT_ERROR_INVALID_STATE);
731*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 0) == OT_ERROR_INVALID_STATE);
732*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameFeedData(sOpenThreadText, 0) == OT_ERROR_INVALID_STATE);
733*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameEnd() == OT_ERROR_INVALID_STATE);
734*cfb92d14SAndroid Build Coastguard Worker     message = sMessagePool->Allocate(Message::kTypeIp6);
735*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(message != nullptr, "Null Message");
736*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(message->SetLength(sizeof(sMysteryText)));
737*cfb92d14SAndroid Build Coastguard Worker     message->Write(0, sMysteryText);
738*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameFeedMessage(message) == OT_ERROR_INVALID_STATE);
739*cfb92d14SAndroid Build Coastguard Worker     message->Free();
740*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.InFrameEnd() == OT_ERROR_INVALID_STATE);
741*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
742*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
743*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty());
744*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.OutFrameBegin() == OT_ERROR_NOT_FOUND, "OutFrameBegin() failed on empty queue");
745*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
746*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
747*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ncpBuffer.IsEmpty());
748*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
749*cfb92d14SAndroid Build Coastguard Worker 
750*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
751*cfb92d14SAndroid Build Coastguard Worker     printf("\n Test 13: Ensure we can utilize the full buffer size when frames removed during write");
752*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
753*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
754*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityHigh);
755*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
756*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
757*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer) - 4));
758*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameEnd());
759*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameRemove());
760*cfb92d14SAndroid Build Coastguard Worker     // Repeat the test with a low priority buffer write
761*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame1(ncpBuffer, Spinel::Buffer::kPriorityHigh);
762*cfb92d14SAndroid Build Coastguard Worker     WriteTestFrame2(ncpBuffer, Spinel::Buffer::kPriorityLow);
763*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.InFrameBegin(Spinel::Buffer::kPriorityLow);
764*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame1(ncpBuffer);
765*cfb92d14SAndroid Build Coastguard Worker     VerifyAndRemoveFrame2(ncpBuffer);
766*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameFeedData(buffer, sizeof(buffer) - 4));
767*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.InFrameEnd());
768*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ncpBuffer.OutFrameRemove());
769*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
770*cfb92d14SAndroid Build Coastguard Worker 
771*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
772*cfb92d14SAndroid Build Coastguard Worker     printf("\n Test 14: Test InFrameOverwrite ");
773*cfb92d14SAndroid Build Coastguard Worker     printf("\nIterations: ");
774*cfb92d14SAndroid Build Coastguard Worker 
775*cfb92d14SAndroid Build Coastguard Worker     for (j = 0; j < kTestIterationAttemps; j++)
776*cfb92d14SAndroid Build Coastguard Worker     {
777*cfb92d14SAndroid Build Coastguard Worker         uint16_t                 index;
778*cfb92d14SAndroid Build Coastguard Worker         bool                     addExtra = ((j % 7) != 0);
779*cfb92d14SAndroid Build Coastguard Worker         Spinel::Buffer::Priority priority;
780*cfb92d14SAndroid Build Coastguard Worker 
781*cfb92d14SAndroid Build Coastguard Worker         printf("*");
782*cfb92d14SAndroid Build Coastguard Worker         priority = ((j % 3) == 0) ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow;
783*cfb92d14SAndroid Build Coastguard Worker         index    = static_cast<uint16_t>(j % sizeof(sHexText));
784*cfb92d14SAndroid Build Coastguard Worker         ncpBuffer.InFrameBegin(priority);
785*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText, index));
786*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameGetPosition(pos1));
787*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameFeedData(sMysteryText, sizeof(sHexText) - index));
788*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index);
789*cfb92d14SAndroid Build Coastguard Worker 
790*cfb92d14SAndroid Build Coastguard Worker         if (addExtra)
791*cfb92d14SAndroid Build Coastguard Worker         {
792*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)));
793*cfb92d14SAndroid Build Coastguard Worker         }
794*cfb92d14SAndroid Build Coastguard Worker 
795*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameOverwrite(pos1, sHexText + index, sizeof(sHexText) - index),
796*cfb92d14SAndroid Build Coastguard Worker                       "InFrameOverwrite() failed.");
797*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) ==
798*cfb92d14SAndroid Build Coastguard Worker                          sizeof(sHexText) - index + (addExtra ? sizeof(sHelloText) : 0),
799*cfb92d14SAndroid Build Coastguard Worker                      "InFrameGetDistance() failed");
800*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameEnd());
801*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.InFrameGetPosition(pos2) == OT_ERROR_INVALID_STATE);
802*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.InFrameOverwrite(pos1, sHexText, 0) != OT_ERROR_NONE);
803*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.OutFrameBegin());
804*cfb92d14SAndroid Build Coastguard Worker         ReadAndVerifyContent(ncpBuffer, sHexText, sizeof(sHexText));
805*cfb92d14SAndroid Build Coastguard Worker 
806*cfb92d14SAndroid Build Coastguard Worker         if (addExtra)
807*cfb92d14SAndroid Build Coastguard Worker         {
808*cfb92d14SAndroid Build Coastguard Worker             ReadAndVerifyContent(ncpBuffer, sHelloText, sizeof(sHelloText));
809*cfb92d14SAndroid Build Coastguard Worker         }
810*cfb92d14SAndroid Build Coastguard Worker 
811*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.OutFrameRemove());
812*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.InFrameGetPosition(pos2) == OT_ERROR_INVALID_STATE);
813*cfb92d14SAndroid Build Coastguard Worker     }
814*cfb92d14SAndroid Build Coastguard Worker 
815*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
816*cfb92d14SAndroid Build Coastguard Worker 
817*cfb92d14SAndroid Build Coastguard Worker     printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
818*cfb92d14SAndroid Build Coastguard Worker     printf("\n Test 15: Test InFrameReset()");
819*cfb92d14SAndroid Build Coastguard Worker     printf("\nIterations: ");
820*cfb92d14SAndroid Build Coastguard Worker 
821*cfb92d14SAndroid Build Coastguard Worker     for (j = 0; j < kTestIterationAttemps; j++)
822*cfb92d14SAndroid Build Coastguard Worker     {
823*cfb92d14SAndroid Build Coastguard Worker         uint16_t                 index;
824*cfb92d14SAndroid Build Coastguard Worker         bool                     addExtra = ((j % 7) != 0);
825*cfb92d14SAndroid Build Coastguard Worker         Spinel::Buffer::Priority priority;
826*cfb92d14SAndroid Build Coastguard Worker 
827*cfb92d14SAndroid Build Coastguard Worker         printf("*");
828*cfb92d14SAndroid Build Coastguard Worker         priority = ((j % 3) == 0) ? Spinel::Buffer::kPriorityHigh : Spinel::Buffer::kPriorityLow;
829*cfb92d14SAndroid Build Coastguard Worker         index    = static_cast<uint16_t>(j % sizeof(sHexText));
830*cfb92d14SAndroid Build Coastguard Worker         ncpBuffer.InFrameBegin(priority);
831*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText, index));
832*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameGetPosition(pos1));
833*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameFeedData(sMysteryText, sizeof(sHexText) - index));
834*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index);
835*cfb92d14SAndroid Build Coastguard Worker 
836*cfb92d14SAndroid Build Coastguard Worker         if (addExtra)
837*cfb92d14SAndroid Build Coastguard Worker         {
838*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(ncpBuffer.InFrameFeedData(sHelloText, sizeof(sHelloText)));
839*cfb92d14SAndroid Build Coastguard Worker         }
840*cfb92d14SAndroid Build Coastguard Worker 
841*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameReset(pos1));
842*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText + index, sizeof(sHexText) - index));
843*cfb92d14SAndroid Build Coastguard Worker 
844*cfb92d14SAndroid Build Coastguard Worker         if (addExtra)
845*cfb92d14SAndroid Build Coastguard Worker         {
846*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(ncpBuffer.InFrameReset(pos1));
847*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(ncpBuffer.InFrameFeedData(sHexText + index, sizeof(sHexText) - index));
848*cfb92d14SAndroid Build Coastguard Worker         }
849*cfb92d14SAndroid Build Coastguard Worker 
850*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ncpBuffer.InFrameGetDistance(pos1) == sizeof(sHexText) - index);
851*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.InFrameEnd());
852*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.OutFrameBegin());
853*cfb92d14SAndroid Build Coastguard Worker         ReadAndVerifyContent(ncpBuffer, sHexText, sizeof(sHexText));
854*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ncpBuffer.OutFrameRemove());
855*cfb92d14SAndroid Build Coastguard Worker     }
856*cfb92d14SAndroid Build Coastguard Worker 
857*cfb92d14SAndroid Build Coastguard Worker     printf(" -- PASS\n");
858*cfb92d14SAndroid Build Coastguard Worker 
859*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
860*cfb92d14SAndroid Build Coastguard Worker }
861*cfb92d14SAndroid Build Coastguard Worker 
862*cfb92d14SAndroid Build Coastguard Worker /**
863*cfb92d14SAndroid Build Coastguard Worker  * NCP Buffer Fuzz testing
864*cfb92d14SAndroid Build Coastguard Worker  *
865*cfb92d14SAndroid Build Coastguard Worker  * Randomly decide if to read or write a frame to the NCP buffer (use `kReadProbability` in percent to control the
866*cfb92d14SAndroid Build Coastguard Worker  * behavior).
867*cfb92d14SAndroid Build Coastguard Worker  *
868*cfb92d14SAndroid Build Coastguard Worker  * When writing a frame, use a random length (1 up to `kMaxFrameLen`) and generate random byte sequences.
869*cfb92d14SAndroid Build Coastguard Worker  * When reading a frame ensure the length and the content matches what was written earlier.
870*cfb92d14SAndroid Build Coastguard Worker  * Handle the cases where buffer gets full or empty.
871*cfb92d14SAndroid Build Coastguard Worker  *
872*cfb92d14SAndroid Build Coastguard Worker  */
873*cfb92d14SAndroid Build Coastguard Worker 
874*cfb92d14SAndroid Build Coastguard Worker enum
875*cfb92d14SAndroid Build Coastguard Worker {
876*cfb92d14SAndroid Build Coastguard Worker     kFuzTestBufferSize            = 2000,   // Size of the buffer used during fuzz testing
877*cfb92d14SAndroid Build Coastguard Worker     kFuzTestIterationAttempts     = 500000, // Number of iterations  to run
878*cfb92d14SAndroid Build Coastguard Worker     kLensArraySize                = 500,    // Size of "Lengths" array.
879*cfb92d14SAndroid Build Coastguard Worker     kMaxFrameLen                  = 400,    // Maximum frame length
880*cfb92d14SAndroid Build Coastguard Worker     kReadProbability              = 50,     // Probability (in percent) to randomly choose to read vs write frame
881*cfb92d14SAndroid Build Coastguard Worker     kHighPriorityProbability      = 20,     // Probability (in percent) to write a high priority frame
882*cfb92d14SAndroid Build Coastguard Worker     kUseTrueRandomNumberGenerator = 1,      // To use true random number generator or not.
883*cfb92d14SAndroid Build Coastguard Worker };
884*cfb92d14SAndroid Build Coastguard Worker 
885*cfb92d14SAndroid Build Coastguard Worker uint8_t  sFrameBuffer[kNumPrios][kFuzTestBufferSize];
886*cfb92d14SAndroid Build Coastguard Worker uint32_t sFrameBufferTailIndex[kNumPrios] = {0};
887*cfb92d14SAndroid Build Coastguard Worker 
GetRandom(uint32_t max)888*cfb92d14SAndroid Build Coastguard Worker uint32_t GetRandom(uint32_t max)
889*cfb92d14SAndroid Build Coastguard Worker {
890*cfb92d14SAndroid Build Coastguard Worker     uint32_t value;
891*cfb92d14SAndroid Build Coastguard Worker 
892*cfb92d14SAndroid Build Coastguard Worker     if (kUseTrueRandomNumberGenerator)
893*cfb92d14SAndroid Build Coastguard Worker     {
894*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(Random::Crypto::Fill(value));
895*cfb92d14SAndroid Build Coastguard Worker     }
896*cfb92d14SAndroid Build Coastguard Worker     else
897*cfb92d14SAndroid Build Coastguard Worker     {
898*cfb92d14SAndroid Build Coastguard Worker         value = Random::NonCrypto::GetUint32();
899*cfb92d14SAndroid Build Coastguard Worker     }
900*cfb92d14SAndroid Build Coastguard Worker 
901*cfb92d14SAndroid Build Coastguard Worker     return value % max;
902*cfb92d14SAndroid Build Coastguard Worker }
903*cfb92d14SAndroid Build Coastguard Worker 
WriteRandomFrame(uint32_t aLength,Spinel::Buffer & aNcpBuffer,Spinel::Buffer::Priority aPriority)904*cfb92d14SAndroid Build Coastguard Worker otError WriteRandomFrame(uint32_t aLength, Spinel::Buffer &aNcpBuffer, Spinel::Buffer::Priority aPriority)
905*cfb92d14SAndroid Build Coastguard Worker {
906*cfb92d14SAndroid Build Coastguard Worker     otError         error;
907*cfb92d14SAndroid Build Coastguard Worker     uint8_t         byte;
908*cfb92d14SAndroid Build Coastguard Worker     uint8_t         priority   = static_cast<uint8_t>(aPriority);
909*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
910*cfb92d14SAndroid Build Coastguard Worker     uint32_t        tail       = sFrameBufferTailIndex[priority];
911*cfb92d14SAndroid Build Coastguard Worker 
912*cfb92d14SAndroid Build Coastguard Worker     aNcpBuffer.InFrameBegin(aPriority);
913*cfb92d14SAndroid Build Coastguard Worker 
914*cfb92d14SAndroid Build Coastguard Worker     while (aLength--)
915*cfb92d14SAndroid Build Coastguard Worker     {
916*cfb92d14SAndroid Build Coastguard Worker         byte = static_cast<uint8_t>(GetRandom(256));
917*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aNcpBuffer.InFrameFeedData(&byte, sizeof(byte)));
918*cfb92d14SAndroid Build Coastguard Worker         sFrameBuffer[priority][tail++] = byte;
919*cfb92d14SAndroid Build Coastguard Worker     }
920*cfb92d14SAndroid Build Coastguard Worker 
921*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aNcpBuffer.InFrameEnd());
922*cfb92d14SAndroid Build Coastguard Worker 
923*cfb92d14SAndroid Build Coastguard Worker     sFrameBufferTailIndex[priority] = tail;
924*cfb92d14SAndroid Build Coastguard Worker 
925*cfb92d14SAndroid Build Coastguard Worker     // check the callbacks
926*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount + 1 == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
927*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
928*cfb92d14SAndroid Build Coastguard Worker 
929*cfb92d14SAndroid Build Coastguard Worker exit:
930*cfb92d14SAndroid Build Coastguard Worker     return error;
931*cfb92d14SAndroid Build Coastguard Worker }
932*cfb92d14SAndroid Build Coastguard Worker 
ReadRandomFrame(uint32_t aLength,Spinel::Buffer & aNcpBuffer,uint8_t priority)933*cfb92d14SAndroid Build Coastguard Worker otError ReadRandomFrame(uint32_t aLength, Spinel::Buffer &aNcpBuffer, uint8_t priority)
934*cfb92d14SAndroid Build Coastguard Worker {
935*cfb92d14SAndroid Build Coastguard Worker     CallbackContext oldContext = sContext;
936*cfb92d14SAndroid Build Coastguard Worker 
937*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameBegin());
938*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(aNcpBuffer.OutFrameGetLength() == aLength);
939*cfb92d14SAndroid Build Coastguard Worker 
940*cfb92d14SAndroid Build Coastguard Worker     // Read and verify that the content is same as sFrameBuffer values...
941*cfb92d14SAndroid Build Coastguard Worker     ReadAndVerifyContent(aNcpBuffer, sFrameBuffer[priority], static_cast<uint16_t>(aLength));
942*cfb92d14SAndroid Build Coastguard Worker     sExpectedRemovedTag = aNcpBuffer.OutFrameGetTag();
943*cfb92d14SAndroid Build Coastguard Worker 
944*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(aNcpBuffer.OutFrameRemove());
945*cfb92d14SAndroid Build Coastguard Worker 
946*cfb92d14SAndroid Build Coastguard Worker     sFrameBufferTailIndex[priority] -= aLength;
947*cfb92d14SAndroid Build Coastguard Worker     memmove(sFrameBuffer[priority], sFrameBuffer[priority] + aLength, sFrameBufferTailIndex[priority]);
948*cfb92d14SAndroid Build Coastguard Worker 
949*cfb92d14SAndroid Build Coastguard Worker     // If successful check the callbacks
950*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameAddedCount == sContext.mFrameAddedCount, "FrameAddedCallback failed.");
951*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(oldContext.mFrameRemovedCount + 1 == sContext.mFrameRemovedCount, "FrameRemovedCallback failed.");
952*cfb92d14SAndroid Build Coastguard Worker 
953*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
954*cfb92d14SAndroid Build Coastguard Worker }
955*cfb92d14SAndroid Build Coastguard Worker 
956*cfb92d14SAndroid Build Coastguard Worker // This runs a fuzz test of NCP buffer
TestFuzzBuffer(void)957*cfb92d14SAndroid Build Coastguard Worker void TestFuzzBuffer(void)
958*cfb92d14SAndroid Build Coastguard Worker {
959*cfb92d14SAndroid Build Coastguard Worker     uint8_t        buffer[kFuzTestBufferSize];
960*cfb92d14SAndroid Build Coastguard Worker     Spinel::Buffer ncpBuffer(buffer, kFuzTestBufferSize);
961*cfb92d14SAndroid Build Coastguard Worker 
962*cfb92d14SAndroid Build Coastguard Worker     uint32_t lensArray[kNumPrios][kLensArraySize]; // Keeps track of length of written frames so far
963*cfb92d14SAndroid Build Coastguard Worker     uint32_t lensArrayStart[kNumPrios];
964*cfb92d14SAndroid Build Coastguard Worker     uint32_t lensArrayCount[kNumPrios];
965*cfb92d14SAndroid Build Coastguard Worker 
966*cfb92d14SAndroid Build Coastguard Worker     sInstance    = testInitInstance();
967*cfb92d14SAndroid Build Coastguard Worker     sMessagePool = &sInstance->Get<MessagePool>();
968*cfb92d14SAndroid Build Coastguard Worker 
969*cfb92d14SAndroid Build Coastguard Worker     memset(buffer, 0, sizeof(buffer));
970*cfb92d14SAndroid Build Coastguard Worker 
971*cfb92d14SAndroid Build Coastguard Worker     memset(lensArray, 0, sizeof(lensArray));
972*cfb92d14SAndroid Build Coastguard Worker     memset(lensArrayStart, 0, sizeof(lensArrayStart));
973*cfb92d14SAndroid Build Coastguard Worker     memset(lensArrayCount, 0, sizeof(lensArrayCount));
974*cfb92d14SAndroid Build Coastguard Worker 
975*cfb92d14SAndroid Build Coastguard Worker     sContext.mFrameAddedCount   = 0;
976*cfb92d14SAndroid Build Coastguard Worker     sContext.mFrameRemovedCount = 0;
977*cfb92d14SAndroid Build Coastguard Worker     ClearTagHistory();
978*cfb92d14SAndroid Build Coastguard Worker 
979*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.SetFrameAddedCallback(FrameAddedCallback, &sContext);
980*cfb92d14SAndroid Build Coastguard Worker     ncpBuffer.SetFrameRemovedCallback(FrameRemovedCallback, &sContext);
981*cfb92d14SAndroid Build Coastguard Worker 
982*cfb92d14SAndroid Build Coastguard Worker     for (uint32_t iter = 0; iter < kFuzTestIterationAttempts; iter++)
983*cfb92d14SAndroid Build Coastguard Worker     {
984*cfb92d14SAndroid Build Coastguard Worker         bool shouldRead;
985*cfb92d14SAndroid Build Coastguard Worker 
986*cfb92d14SAndroid Build Coastguard Worker         if (lensArrayCount[0] == 0 && lensArrayCount[1] == 0)
987*cfb92d14SAndroid Build Coastguard Worker         {
988*cfb92d14SAndroid Build Coastguard Worker             shouldRead = false;
989*cfb92d14SAndroid Build Coastguard Worker         }
990*cfb92d14SAndroid Build Coastguard Worker         else if (lensArrayCount[0] == kLensArraySize - 1 || lensArrayCount[1] == kLensArraySize - 1)
991*cfb92d14SAndroid Build Coastguard Worker         {
992*cfb92d14SAndroid Build Coastguard Worker             shouldRead = true;
993*cfb92d14SAndroid Build Coastguard Worker         }
994*cfb92d14SAndroid Build Coastguard Worker         else
995*cfb92d14SAndroid Build Coastguard Worker         {
996*cfb92d14SAndroid Build Coastguard Worker             // Randomly decide to read or write.
997*cfb92d14SAndroid Build Coastguard Worker             shouldRead = (GetRandom(100) < kReadProbability);
998*cfb92d14SAndroid Build Coastguard Worker         }
999*cfb92d14SAndroid Build Coastguard Worker 
1000*cfb92d14SAndroid Build Coastguard Worker         if (shouldRead)
1001*cfb92d14SAndroid Build Coastguard Worker         {
1002*cfb92d14SAndroid Build Coastguard Worker             uint32_t len;
1003*cfb92d14SAndroid Build Coastguard Worker             uint8_t  priority;
1004*cfb92d14SAndroid Build Coastguard Worker 
1005*cfb92d14SAndroid Build Coastguard Worker             priority = (lensArrayCount[Spinel::Buffer::kPriorityHigh] != 0) ? Spinel::Buffer::kPriorityHigh
1006*cfb92d14SAndroid Build Coastguard Worker                                                                             : Spinel::Buffer::kPriorityLow;
1007*cfb92d14SAndroid Build Coastguard Worker 
1008*cfb92d14SAndroid Build Coastguard Worker             len                      = lensArray[priority][lensArrayStart[priority]];
1009*cfb92d14SAndroid Build Coastguard Worker             lensArrayStart[priority] = (lensArrayStart[priority] + 1) % kLensArraySize;
1010*cfb92d14SAndroid Build Coastguard Worker             lensArrayCount[priority]--;
1011*cfb92d14SAndroid Build Coastguard Worker 
1012*cfb92d14SAndroid Build Coastguard Worker             printf("R%c%d ", priority == Spinel::Buffer::kPriorityHigh ? 'H' : 'L', len);
1013*cfb92d14SAndroid Build Coastguard Worker 
1014*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(ReadRandomFrame(len, ncpBuffer, priority), "Failed to read random frame.");
1015*cfb92d14SAndroid Build Coastguard Worker         }
1016*cfb92d14SAndroid Build Coastguard Worker         else
1017*cfb92d14SAndroid Build Coastguard Worker         {
1018*cfb92d14SAndroid Build Coastguard Worker             uint32_t                 len = GetRandom(kMaxFrameLen) + 1;
1019*cfb92d14SAndroid Build Coastguard Worker             Spinel::Buffer::Priority priority;
1020*cfb92d14SAndroid Build Coastguard Worker 
1021*cfb92d14SAndroid Build Coastguard Worker             if (GetRandom(100) < kHighPriorityProbability)
1022*cfb92d14SAndroid Build Coastguard Worker             {
1023*cfb92d14SAndroid Build Coastguard Worker                 priority = Spinel::Buffer::kPriorityHigh;
1024*cfb92d14SAndroid Build Coastguard Worker             }
1025*cfb92d14SAndroid Build Coastguard Worker             else
1026*cfb92d14SAndroid Build Coastguard Worker             {
1027*cfb92d14SAndroid Build Coastguard Worker                 priority = Spinel::Buffer::kPriorityLow;
1028*cfb92d14SAndroid Build Coastguard Worker             }
1029*cfb92d14SAndroid Build Coastguard Worker 
1030*cfb92d14SAndroid Build Coastguard Worker             if (WriteRandomFrame(len, ncpBuffer, priority) == OT_ERROR_NONE)
1031*cfb92d14SAndroid Build Coastguard Worker             {
1032*cfb92d14SAndroid Build Coastguard Worker                 lensArray[priority][(lensArrayStart[priority] + lensArrayCount[priority]) % kLensArraySize] = len;
1033*cfb92d14SAndroid Build Coastguard Worker                 lensArrayCount[priority]++;
1034*cfb92d14SAndroid Build Coastguard Worker 
1035*cfb92d14SAndroid Build Coastguard Worker                 printf("W%c%d ", priority == Spinel::Buffer::kPriorityHigh ? 'H' : 'L', len);
1036*cfb92d14SAndroid Build Coastguard Worker             }
1037*cfb92d14SAndroid Build Coastguard Worker             else
1038*cfb92d14SAndroid Build Coastguard Worker             {
1039*cfb92d14SAndroid Build Coastguard Worker                 printf("FULL ");
1040*cfb92d14SAndroid Build Coastguard Worker             }
1041*cfb92d14SAndroid Build Coastguard Worker         }
1042*cfb92d14SAndroid Build Coastguard Worker 
1043*cfb92d14SAndroid Build Coastguard Worker         if (lensArrayCount[0] == 0 && lensArrayCount[1] == 0)
1044*cfb92d14SAndroid Build Coastguard Worker         {
1045*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(ncpBuffer.IsEmpty());
1046*cfb92d14SAndroid Build Coastguard Worker             printf("EMPTY ");
1047*cfb92d14SAndroid Build Coastguard Worker         }
1048*cfb92d14SAndroid Build Coastguard Worker     }
1049*cfb92d14SAndroid Build Coastguard Worker 
1050*cfb92d14SAndroid Build Coastguard Worker     printf("\n -- PASS\n");
1051*cfb92d14SAndroid Build Coastguard Worker 
1052*cfb92d14SAndroid Build Coastguard Worker     testFreeInstance(sInstance);
1053*cfb92d14SAndroid Build Coastguard Worker }
1054*cfb92d14SAndroid Build Coastguard Worker 
1055*cfb92d14SAndroid Build Coastguard Worker } // namespace Spinel
1056*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
1057*cfb92d14SAndroid Build Coastguard Worker 
main(void)1058*cfb92d14SAndroid Build Coastguard Worker int main(void)
1059*cfb92d14SAndroid Build Coastguard Worker {
1060*cfb92d14SAndroid Build Coastguard Worker     ot::Spinel::TestBuffer();
1061*cfb92d14SAndroid Build Coastguard Worker     ot::Spinel::TestFuzzBuffer();
1062*cfb92d14SAndroid Build Coastguard Worker     printf("\nAll tests passed.\n");
1063*cfb92d14SAndroid Build Coastguard Worker     return 0;
1064*cfb92d14SAndroid Build Coastguard Worker }
1065