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