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 "common/appender.hpp"
30*cfb92d14SAndroid Build Coastguard Worker #include "common/debug.hpp"
31*cfb92d14SAndroid Build Coastguard Worker #include "common/message.hpp"
32*cfb92d14SAndroid Build Coastguard Worker #include "common/random.hpp"
33*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
34*cfb92d14SAndroid Build Coastguard Worker
35*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
36*cfb92d14SAndroid Build Coastguard Worker #include "test_util.hpp"
37*cfb92d14SAndroid Build Coastguard Worker
38*cfb92d14SAndroid Build Coastguard Worker namespace ot {
39*cfb92d14SAndroid Build Coastguard Worker
TestMessage(void)40*cfb92d14SAndroid Build Coastguard Worker void TestMessage(void)
41*cfb92d14SAndroid Build Coastguard Worker {
42*cfb92d14SAndroid Build Coastguard Worker enum : uint16_t
43*cfb92d14SAndroid Build Coastguard Worker {
44*cfb92d14SAndroid Build Coastguard Worker kMaxSize = (kBufferSize * 3 + 24),
45*cfb92d14SAndroid Build Coastguard Worker kOffsetStep = 101,
46*cfb92d14SAndroid Build Coastguard Worker kLengthStep = 21,
47*cfb92d14SAndroid Build Coastguard Worker };
48*cfb92d14SAndroid Build Coastguard Worker
49*cfb92d14SAndroid Build Coastguard Worker Instance *instance;
50*cfb92d14SAndroid Build Coastguard Worker MessagePool *messagePool;
51*cfb92d14SAndroid Build Coastguard Worker Message *message;
52*cfb92d14SAndroid Build Coastguard Worker Message *message2;
53*cfb92d14SAndroid Build Coastguard Worker Message *messageCopy;
54*cfb92d14SAndroid Build Coastguard Worker uint8_t writeBuffer[kMaxSize];
55*cfb92d14SAndroid Build Coastguard Worker uint8_t readBuffer[kMaxSize];
56*cfb92d14SAndroid Build Coastguard Worker uint8_t zeroBuffer[kMaxSize];
57*cfb92d14SAndroid Build Coastguard Worker
58*cfb92d14SAndroid Build Coastguard Worker printf("TestMessage\n");
59*cfb92d14SAndroid Build Coastguard Worker
60*cfb92d14SAndroid Build Coastguard Worker memset(zeroBuffer, 0, sizeof(zeroBuffer));
61*cfb92d14SAndroid Build Coastguard Worker
62*cfb92d14SAndroid Build Coastguard Worker instance = static_cast<Instance *>(testInitInstance());
63*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr);
64*cfb92d14SAndroid Build Coastguard Worker
65*cfb92d14SAndroid Build Coastguard Worker messagePool = &instance->Get<MessagePool>();
66*cfb92d14SAndroid Build Coastguard Worker
67*cfb92d14SAndroid Build Coastguard Worker Random::NonCrypto::FillBuffer(writeBuffer, kMaxSize);
68*cfb92d14SAndroid Build Coastguard Worker
69*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
70*cfb92d14SAndroid Build Coastguard Worker message->SetLinkSecurityEnabled(Message::kWithLinkSecurity);
71*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetPriority(Message::Priority::kPriorityNet));
72*cfb92d14SAndroid Build Coastguard Worker message->SetType(Message::Type::kType6lowpan);
73*cfb92d14SAndroid Build Coastguard Worker message->SetSubType(Message::SubType::kSubTypeMleChildIdRequest);
74*cfb92d14SAndroid Build Coastguard Worker message->SetLoopbackToHostAllowed(true);
75*cfb92d14SAndroid Build Coastguard Worker message->SetOrigin(Message::kOriginHostUntrusted);
76*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->SetLength(kMaxSize));
77*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(0, writeBuffer, kMaxSize);
78*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, readBuffer, kMaxSize));
79*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(writeBuffer, readBuffer, kMaxSize) == 0);
80*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->CompareBytes(0, readBuffer, kMaxSize));
81*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(0, readBuffer));
82*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->GetLength() == kMaxSize);
83*cfb92d14SAndroid Build Coastguard Worker
84*cfb92d14SAndroid Build Coastguard Worker // Verify `Clone()` behavior
85*cfb92d14SAndroid Build Coastguard Worker message->SetOffset(15);
86*cfb92d14SAndroid Build Coastguard Worker messageCopy = message->Clone();
87*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->GetOffset() == message->GetOffset());
88*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(messageCopy->Read(0, readBuffer, kMaxSize));
89*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(writeBuffer, readBuffer, kMaxSize) == 0);
90*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->CompareBytes(0, readBuffer, kMaxSize));
91*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->Compare(0, readBuffer));
92*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->GetLength() == kMaxSize);
93*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->GetType() == message->GetType());
94*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->GetSubType() == message->GetSubType());
95*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->IsLinkSecurityEnabled() == message->IsLinkSecurityEnabled());
96*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->GetPriority() == message->GetPriority());
97*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->IsLoopbackToHostAllowed() == message->IsLoopbackToHostAllowed());
98*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->GetOrigin() == message->GetOrigin());
99*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(messageCopy->Compare(0, readBuffer));
100*cfb92d14SAndroid Build Coastguard Worker message->SetOffset(0);
101*cfb92d14SAndroid Build Coastguard Worker
102*cfb92d14SAndroid Build Coastguard Worker messageCopy->Free();
103*cfb92d14SAndroid Build Coastguard Worker
104*cfb92d14SAndroid Build Coastguard Worker for (uint16_t offset = 0; offset < kMaxSize; offset++)
105*cfb92d14SAndroid Build Coastguard Worker {
106*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = 0; length <= kMaxSize - offset; length++)
107*cfb92d14SAndroid Build Coastguard Worker {
108*cfb92d14SAndroid Build Coastguard Worker for (uint16_t i = 0; i < length; i++)
109*cfb92d14SAndroid Build Coastguard Worker {
110*cfb92d14SAndroid Build Coastguard Worker writeBuffer[offset + i]++;
111*cfb92d14SAndroid Build Coastguard Worker }
112*cfb92d14SAndroid Build Coastguard Worker
113*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(offset, &writeBuffer[offset], length);
114*cfb92d14SAndroid Build Coastguard Worker
115*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, readBuffer, kMaxSize));
116*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(writeBuffer, readBuffer, kMaxSize) == 0);
117*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(0, writeBuffer));
118*cfb92d14SAndroid Build Coastguard Worker
119*cfb92d14SAndroid Build Coastguard Worker memset(readBuffer, 0, sizeof(readBuffer));
120*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(offset, readBuffer, length));
121*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(readBuffer, &writeBuffer[offset], length) == 0);
122*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[length], zeroBuffer, kMaxSize - length) == 0, "read after length");
123*cfb92d14SAndroid Build Coastguard Worker
124*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->CompareBytes(offset, &writeBuffer[offset], length));
125*cfb92d14SAndroid Build Coastguard Worker
126*cfb92d14SAndroid Build Coastguard Worker if (length == 0)
127*cfb92d14SAndroid Build Coastguard Worker {
128*cfb92d14SAndroid Build Coastguard Worker continue;
129*cfb92d14SAndroid Build Coastguard Worker }
130*cfb92d14SAndroid Build Coastguard Worker
131*cfb92d14SAndroid Build Coastguard Worker // Change the first byte, and then last byte, and verify that
132*cfb92d14SAndroid Build Coastguard Worker // `CompareBytes()` correctly fails.
133*cfb92d14SAndroid Build Coastguard Worker
134*cfb92d14SAndroid Build Coastguard Worker writeBuffer[offset]++;
135*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!message->CompareBytes(offset, &writeBuffer[offset], length));
136*cfb92d14SAndroid Build Coastguard Worker writeBuffer[offset]--;
137*cfb92d14SAndroid Build Coastguard Worker
138*cfb92d14SAndroid Build Coastguard Worker writeBuffer[offset + length - 1]++;
139*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!message->CompareBytes(offset, &writeBuffer[offset], length));
140*cfb92d14SAndroid Build Coastguard Worker writeBuffer[offset + length - 1]--;
141*cfb92d14SAndroid Build Coastguard Worker }
142*cfb92d14SAndroid Build Coastguard Worker
143*cfb92d14SAndroid Build Coastguard Worker // Verify `ReadBytes()` behavior when requested read length goes beyond available bytes in the message.
144*cfb92d14SAndroid Build Coastguard Worker
145*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = kMaxSize - offset + 1; length <= kMaxSize + 1; length++)
146*cfb92d14SAndroid Build Coastguard Worker {
147*cfb92d14SAndroid Build Coastguard Worker uint16_t readLength;
148*cfb92d14SAndroid Build Coastguard Worker
149*cfb92d14SAndroid Build Coastguard Worker memset(readBuffer, 0, sizeof(readBuffer));
150*cfb92d14SAndroid Build Coastguard Worker readLength = message->ReadBytes(offset, readBuffer, length);
151*cfb92d14SAndroid Build Coastguard Worker
152*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(readLength < length, "Message::ReadBytes() returned longer length");
153*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(readLength == kMaxSize - offset);
154*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(readBuffer, &writeBuffer[offset], readLength) == 0);
155*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[readLength], zeroBuffer, kMaxSize - readLength) == 0, "read after length");
156*cfb92d14SAndroid Build Coastguard Worker
157*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!message->CompareBytes(offset, readBuffer, length));
158*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->CompareBytes(offset, readBuffer, readLength));
159*cfb92d14SAndroid Build Coastguard Worker }
160*cfb92d14SAndroid Build Coastguard Worker }
161*cfb92d14SAndroid Build Coastguard Worker
162*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->GetLength() == kMaxSize);
163*cfb92d14SAndroid Build Coastguard Worker
164*cfb92d14SAndroid Build Coastguard Worker // Test `WriteBytesFromMessage()` behavior copying between different
165*cfb92d14SAndroid Build Coastguard Worker // messages.
166*cfb92d14SAndroid Build Coastguard Worker
167*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message2 = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
168*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message2->SetLength(kMaxSize));
169*cfb92d14SAndroid Build Coastguard Worker
170*cfb92d14SAndroid Build Coastguard Worker for (uint16_t readOffset = 0; readOffset < kMaxSize; readOffset += kOffsetStep)
171*cfb92d14SAndroid Build Coastguard Worker {
172*cfb92d14SAndroid Build Coastguard Worker for (uint16_t writeOffset = 0; writeOffset < kMaxSize; writeOffset += kOffsetStep)
173*cfb92d14SAndroid Build Coastguard Worker {
174*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = 0; length <= kMaxSize - Max(writeOffset, readOffset); length += kLengthStep)
175*cfb92d14SAndroid Build Coastguard Worker {
176*cfb92d14SAndroid Build Coastguard Worker message2->WriteBytes(0, zeroBuffer, kMaxSize);
177*cfb92d14SAndroid Build Coastguard Worker
178*cfb92d14SAndroid Build Coastguard Worker message2->WriteBytesFromMessage(writeOffset, *message, readOffset, length);
179*cfb92d14SAndroid Build Coastguard Worker
180*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message2->Read(0, readBuffer, kMaxSize));
181*cfb92d14SAndroid Build Coastguard Worker
182*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[0], zeroBuffer, writeOffset) == 0);
183*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[writeOffset], &writeBuffer[readOffset], length) == 0);
184*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[writeOffset + length], zeroBuffer, kMaxSize - length - writeOffset) ==
185*cfb92d14SAndroid Build Coastguard Worker 0);
186*cfb92d14SAndroid Build Coastguard Worker
187*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->CompareBytes(readOffset, *message2, writeOffset, length));
188*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message2->CompareBytes(writeOffset, *message, readOffset, length));
189*cfb92d14SAndroid Build Coastguard Worker }
190*cfb92d14SAndroid Build Coastguard Worker }
191*cfb92d14SAndroid Build Coastguard Worker }
192*cfb92d14SAndroid Build Coastguard Worker
193*cfb92d14SAndroid Build Coastguard Worker // Verify `WriteBytesFromMessage()` behavior copying backwards within
194*cfb92d14SAndroid Build Coastguard Worker // same message.
195*cfb92d14SAndroid Build Coastguard Worker
196*cfb92d14SAndroid Build Coastguard Worker for (uint16_t readOffset = 0; readOffset < kMaxSize; readOffset++)
197*cfb92d14SAndroid Build Coastguard Worker {
198*cfb92d14SAndroid Build Coastguard Worker uint16_t length = kMaxSize - readOffset;
199*cfb92d14SAndroid Build Coastguard Worker
200*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(0, writeBuffer, kMaxSize);
201*cfb92d14SAndroid Build Coastguard Worker
202*cfb92d14SAndroid Build Coastguard Worker message->WriteBytesFromMessage(0, *message, readOffset, length);
203*cfb92d14SAndroid Build Coastguard Worker
204*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, readBuffer, kMaxSize));
205*cfb92d14SAndroid Build Coastguard Worker
206*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[0], &writeBuffer[readOffset], length) == 0);
207*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[length], &writeBuffer[length], kMaxSize - length) == 0);
208*cfb92d14SAndroid Build Coastguard Worker }
209*cfb92d14SAndroid Build Coastguard Worker
210*cfb92d14SAndroid Build Coastguard Worker // Verify `WriteBytesFromMessage()` behavior copying forward within
211*cfb92d14SAndroid Build Coastguard Worker // same message.
212*cfb92d14SAndroid Build Coastguard Worker
213*cfb92d14SAndroid Build Coastguard Worker for (uint16_t writeOffset = 0; writeOffset < kMaxSize; writeOffset++)
214*cfb92d14SAndroid Build Coastguard Worker {
215*cfb92d14SAndroid Build Coastguard Worker uint16_t length = kMaxSize - writeOffset;
216*cfb92d14SAndroid Build Coastguard Worker
217*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(0, writeBuffer, kMaxSize);
218*cfb92d14SAndroid Build Coastguard Worker
219*cfb92d14SAndroid Build Coastguard Worker message->WriteBytesFromMessage(writeOffset, *message, 0, length);
220*cfb92d14SAndroid Build Coastguard Worker
221*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, readBuffer, kMaxSize));
222*cfb92d14SAndroid Build Coastguard Worker
223*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[0], &writeBuffer[0], writeOffset) == 0);
224*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[writeOffset], &writeBuffer[0], length) == 0);
225*cfb92d14SAndroid Build Coastguard Worker }
226*cfb92d14SAndroid Build Coastguard Worker
227*cfb92d14SAndroid Build Coastguard Worker // Test `WriteBytesFromMessage()` behavior copying within same
228*cfb92d14SAndroid Build Coastguard Worker // message at different read and write offsets and lengths.
229*cfb92d14SAndroid Build Coastguard Worker
230*cfb92d14SAndroid Build Coastguard Worker for (uint16_t readOffset = 0; readOffset < kMaxSize; readOffset += kOffsetStep)
231*cfb92d14SAndroid Build Coastguard Worker {
232*cfb92d14SAndroid Build Coastguard Worker for (uint16_t writeOffset = 0; writeOffset < kMaxSize; writeOffset += kOffsetStep)
233*cfb92d14SAndroid Build Coastguard Worker {
234*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = 0; length <= kMaxSize - Max(writeOffset, readOffset); length += kLengthStep)
235*cfb92d14SAndroid Build Coastguard Worker {
236*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(0, writeBuffer, kMaxSize);
237*cfb92d14SAndroid Build Coastguard Worker
238*cfb92d14SAndroid Build Coastguard Worker message->WriteBytesFromMessage(writeOffset, *message, readOffset, length);
239*cfb92d14SAndroid Build Coastguard Worker
240*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, readBuffer, kMaxSize));
241*cfb92d14SAndroid Build Coastguard Worker
242*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[0], writeBuffer, writeOffset) == 0);
243*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[writeOffset], &writeBuffer[readOffset], length) == 0);
244*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[writeOffset + length], &writeBuffer[writeOffset + length],
245*cfb92d14SAndroid Build Coastguard Worker kMaxSize - length - writeOffset) == 0);
246*cfb92d14SAndroid Build Coastguard Worker }
247*cfb92d14SAndroid Build Coastguard Worker }
248*cfb92d14SAndroid Build Coastguard Worker }
249*cfb92d14SAndroid Build Coastguard Worker
250*cfb92d14SAndroid Build Coastguard Worker // Verify `AppendBytesFromMessage()` with two different messages as source and destination.
251*cfb92d14SAndroid Build Coastguard Worker
252*cfb92d14SAndroid Build Coastguard Worker message->WriteBytes(0, writeBuffer, kMaxSize);
253*cfb92d14SAndroid Build Coastguard Worker
254*cfb92d14SAndroid Build Coastguard Worker for (uint16_t srcOffset = 0; srcOffset < kMaxSize; srcOffset += kOffsetStep)
255*cfb92d14SAndroid Build Coastguard Worker {
256*cfb92d14SAndroid Build Coastguard Worker for (uint16_t dstOffset = 0; dstOffset < kMaxSize; dstOffset += kOffsetStep)
257*cfb92d14SAndroid Build Coastguard Worker {
258*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = 0; length <= kMaxSize - srcOffset; length += kLengthStep)
259*cfb92d14SAndroid Build Coastguard Worker {
260*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message2->SetLength(0));
261*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message2->AppendBytes(zeroBuffer, dstOffset));
262*cfb92d14SAndroid Build Coastguard Worker
263*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message2->AppendBytesFromMessage(*message, srcOffset, length));
264*cfb92d14SAndroid Build Coastguard Worker
265*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message2->CompareBytes(dstOffset, *message, srcOffset, length));
266*cfb92d14SAndroid Build Coastguard Worker }
267*cfb92d14SAndroid Build Coastguard Worker
268*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message2->AppendBytesFromMessage(*message, srcOffset, kMaxSize - srcOffset + 1) ==
269*cfb92d14SAndroid Build Coastguard Worker kErrorParse);
270*cfb92d14SAndroid Build Coastguard Worker }
271*cfb92d14SAndroid Build Coastguard Worker }
272*cfb92d14SAndroid Build Coastguard Worker
273*cfb92d14SAndroid Build Coastguard Worker // Verify `AppendBytesFromMessage()` with the same message as source and destination.
274*cfb92d14SAndroid Build Coastguard Worker
275*cfb92d14SAndroid Build Coastguard Worker for (uint16_t srcOffset = 0; srcOffset < kMaxSize; srcOffset += kOffsetStep)
276*cfb92d14SAndroid Build Coastguard Worker {
277*cfb92d14SAndroid Build Coastguard Worker uint16_t size = kMaxSize;
278*cfb92d14SAndroid Build Coastguard Worker
279*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = 0; length <= kMaxSize - srcOffset; length++)
280*cfb92d14SAndroid Build Coastguard Worker {
281*cfb92d14SAndroid Build Coastguard Worker // Reset the `message` to its original size.
282*cfb92d14SAndroid Build Coastguard Worker IgnoreError(message->SetLength(size));
283*cfb92d14SAndroid Build Coastguard Worker
284*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->AppendBytesFromMessage(*message, srcOffset, length));
285*cfb92d14SAndroid Build Coastguard Worker
286*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->CompareBytes(size, *message, srcOffset, length));
287*cfb92d14SAndroid Build Coastguard Worker }
288*cfb92d14SAndroid Build Coastguard Worker }
289*cfb92d14SAndroid Build Coastguard Worker
290*cfb92d14SAndroid Build Coastguard Worker message->Free();
291*cfb92d14SAndroid Build Coastguard Worker message2->Free();
292*cfb92d14SAndroid Build Coastguard Worker
293*cfb92d14SAndroid Build Coastguard Worker // Verify `RemoveHeader()`
294*cfb92d14SAndroid Build Coastguard Worker
295*cfb92d14SAndroid Build Coastguard Worker for (uint16_t offset = 0; offset < kMaxSize; offset += kOffsetStep)
296*cfb92d14SAndroid Build Coastguard Worker {
297*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = 0; length <= kMaxSize - offset; length += kLengthStep)
298*cfb92d14SAndroid Build Coastguard Worker {
299*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
300*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->AppendBytes(writeBuffer, kMaxSize));
301*cfb92d14SAndroid Build Coastguard Worker
302*cfb92d14SAndroid Build Coastguard Worker message->RemoveHeader(offset, length);
303*cfb92d14SAndroid Build Coastguard Worker
304*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->GetLength() == kMaxSize - length);
305*cfb92d14SAndroid Build Coastguard Worker
306*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, readBuffer, kMaxSize - length));
307*cfb92d14SAndroid Build Coastguard Worker
308*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[0], &writeBuffer[0], offset) == 0);
309*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[offset], &writeBuffer[offset + length], kMaxSize - length - offset) == 0);
310*cfb92d14SAndroid Build Coastguard Worker message->Free();
311*cfb92d14SAndroid Build Coastguard Worker }
312*cfb92d14SAndroid Build Coastguard Worker }
313*cfb92d14SAndroid Build Coastguard Worker
314*cfb92d14SAndroid Build Coastguard Worker // Verify `InsertHeader()`
315*cfb92d14SAndroid Build Coastguard Worker
316*cfb92d14SAndroid Build Coastguard Worker for (uint16_t offset = 0; offset < kMaxSize; offset += kOffsetStep)
317*cfb92d14SAndroid Build Coastguard Worker {
318*cfb92d14SAndroid Build Coastguard Worker for (uint16_t length = 0; length <= kMaxSize; length += kLengthStep)
319*cfb92d14SAndroid Build Coastguard Worker {
320*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
321*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->AppendBytes(writeBuffer, kMaxSize));
322*cfb92d14SAndroid Build Coastguard Worker
323*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->InsertHeader(offset, length));
324*cfb92d14SAndroid Build Coastguard Worker
325*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->GetLength() == kMaxSize + length);
326*cfb92d14SAndroid Build Coastguard Worker
327*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(0, readBuffer, offset));
328*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[0], &writeBuffer[0], offset) == 0);
329*cfb92d14SAndroid Build Coastguard Worker
330*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Read(offset + length, readBuffer, kMaxSize - offset));
331*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(&readBuffer[0], &writeBuffer[offset], kMaxSize - offset) == 0);
332*cfb92d14SAndroid Build Coastguard Worker message->Free();
333*cfb92d14SAndroid Build Coastguard Worker }
334*cfb92d14SAndroid Build Coastguard Worker }
335*cfb92d14SAndroid Build Coastguard Worker
336*cfb92d14SAndroid Build Coastguard Worker testFreeInstance(instance);
337*cfb92d14SAndroid Build Coastguard Worker }
338*cfb92d14SAndroid Build Coastguard Worker
TestAppender(void)339*cfb92d14SAndroid Build Coastguard Worker void TestAppender(void)
340*cfb92d14SAndroid Build Coastguard Worker {
341*cfb92d14SAndroid Build Coastguard Worker const uint8_t kData1[] = {0x01, 0x02, 0x03, 0x04};
342*cfb92d14SAndroid Build Coastguard Worker const uint8_t kData2[] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa};
343*cfb92d14SAndroid Build Coastguard Worker
344*cfb92d14SAndroid Build Coastguard Worker static constexpr uint16_t kMaxBufferSize = sizeof(kData1) * 2 + sizeof(kData2);
345*cfb92d14SAndroid Build Coastguard Worker
346*cfb92d14SAndroid Build Coastguard Worker Instance *instance;
347*cfb92d14SAndroid Build Coastguard Worker Message *message;
348*cfb92d14SAndroid Build Coastguard Worker uint8_t buffer[kMaxBufferSize];
349*cfb92d14SAndroid Build Coastguard Worker uint8_t zeroBuffer[kMaxBufferSize];
350*cfb92d14SAndroid Build Coastguard Worker Appender bufAppender(buffer, sizeof(buffer));
351*cfb92d14SAndroid Build Coastguard Worker Data<kWithUint16Length> data;
352*cfb92d14SAndroid Build Coastguard Worker
353*cfb92d14SAndroid Build Coastguard Worker printf("TestAppender\n");
354*cfb92d14SAndroid Build Coastguard Worker
355*cfb92d14SAndroid Build Coastguard Worker instance = static_cast<Instance *>(testInitInstance());
356*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(instance != nullptr);
357*cfb92d14SAndroid Build Coastguard Worker
358*cfb92d14SAndroid Build Coastguard Worker message = instance->Get<MessagePool>().Allocate(Message::kTypeIp6);
359*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message != nullptr);
360*cfb92d14SAndroid Build Coastguard Worker
361*cfb92d14SAndroid Build Coastguard Worker memset(buffer, 0, sizeof(buffer));
362*cfb92d14SAndroid Build Coastguard Worker memset(zeroBuffer, 0, sizeof(zeroBuffer));
363*cfb92d14SAndroid Build Coastguard Worker
364*cfb92d14SAndroid Build Coastguard Worker // Test Buffer Appender
365*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetType() == Appender::kBuffer);
366*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetBufferStart() == buffer);
367*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetAppendedLength() == 0);
368*cfb92d14SAndroid Build Coastguard Worker
369*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(bufAppender.AppendBytes(kData1, sizeof(kData1)));
370*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("Data1", buffer, sizeof(buffer));
371*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetAppendedLength() == sizeof(kData1));
372*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetBufferStart() == buffer);
373*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
374*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer + sizeof(kData1), zeroBuffer, sizeof(buffer) - sizeof(kData1)) == 0);
375*cfb92d14SAndroid Build Coastguard Worker
376*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(bufAppender.AppendBytes(kData2, sizeof(kData2)));
377*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("Data1+Data2", buffer, sizeof(buffer));
378*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetAppendedLength() == sizeof(kData1) + sizeof(kData2));
379*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetBufferStart() == buffer);
380*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
381*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData2, sizeof(kData2)) == 0);
382*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer + sizeof(kData1) + sizeof(kData2), zeroBuffer,
383*cfb92d14SAndroid Build Coastguard Worker sizeof(buffer) - sizeof(kData1) - sizeof(kData2)) == 0);
384*cfb92d14SAndroid Build Coastguard Worker
385*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.Append(kData2) == kErrorNoBufs);
386*cfb92d14SAndroid Build Coastguard Worker
387*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(bufAppender.AppendBytes(kData1, sizeof(kData1)));
388*cfb92d14SAndroid Build Coastguard Worker DumpBuffer("Data1+Data2+Data1", buffer, sizeof(buffer));
389*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetAppendedLength() == sizeof(kData1) + sizeof(kData2) + sizeof(kData1));
390*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.GetBufferStart() == buffer);
391*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
392*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData2, sizeof(kData2)) == 0);
393*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(memcmp(buffer + sizeof(kData1) + sizeof(kData2), kData1, sizeof(kData1)) == 0);
394*cfb92d14SAndroid Build Coastguard Worker
395*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(bufAppender.Append<uint8_t>(0) == kErrorNoBufs);
396*cfb92d14SAndroid Build Coastguard Worker
397*cfb92d14SAndroid Build Coastguard Worker bufAppender.GetAsData(data);
398*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(data.GetBytes() == buffer);
399*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(data.GetLength() == sizeof(buffer));
400*cfb92d14SAndroid Build Coastguard Worker
401*cfb92d14SAndroid Build Coastguard Worker // Test Message Appender
402*cfb92d14SAndroid Build Coastguard Worker
403*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(message->Append(kData2));
404*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(0, kData2));
405*cfb92d14SAndroid Build Coastguard Worker
406*cfb92d14SAndroid Build Coastguard Worker {
407*cfb92d14SAndroid Build Coastguard Worker Appender msgAppender(*message);
408*cfb92d14SAndroid Build Coastguard Worker uint16_t offset = message->GetLength();
409*cfb92d14SAndroid Build Coastguard Worker
410*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(msgAppender.GetType() == Appender::kMessage);
411*cfb92d14SAndroid Build Coastguard Worker
412*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(msgAppender.AppendBytes(kData1, sizeof(kData1)));
413*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(msgAppender.GetAppendedLength() == sizeof(kData1));
414*cfb92d14SAndroid Build Coastguard Worker
415*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->GetLength() == sizeof(kData2) + sizeof(kData1));
416*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(offset, kData1));
417*cfb92d14SAndroid Build Coastguard Worker
418*cfb92d14SAndroid Build Coastguard Worker SuccessOrQuit(msgAppender.AppendBytes(kData2, sizeof(kData2)));
419*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(msgAppender.GetAppendedLength() == sizeof(kData1) + sizeof(kData2));
420*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(offset, kData1));
421*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(message->Compare(offset + sizeof(kData1), kData2));
422*cfb92d14SAndroid Build Coastguard Worker }
423*cfb92d14SAndroid Build Coastguard Worker
424*cfb92d14SAndroid Build Coastguard Worker message->Free();
425*cfb92d14SAndroid Build Coastguard Worker testFreeInstance(instance);
426*cfb92d14SAndroid Build Coastguard Worker }
427*cfb92d14SAndroid Build Coastguard Worker
428*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
429*cfb92d14SAndroid Build Coastguard Worker
main(void)430*cfb92d14SAndroid Build Coastguard Worker int main(void)
431*cfb92d14SAndroid Build Coastguard Worker {
432*cfb92d14SAndroid Build Coastguard Worker ot::TestMessage();
433*cfb92d14SAndroid Build Coastguard Worker ot::TestAppender();
434*cfb92d14SAndroid Build Coastguard Worker printf("All tests passed\n");
435*cfb92d14SAndroid Build Coastguard Worker return 0;
436*cfb92d14SAndroid Build Coastguard Worker }
437