xref: /aosp_15_r20/external/openthread/tests/unit/test_message.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2016, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include "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