1 /*
2  *  Copyright (c) 2022, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <openthread/config.h>
30 
31 #include "test_platform.h"
32 #include "test_util.hpp"
33 
34 #include "common/frame_builder.hpp"
35 
36 namespace ot {
37 
TestFrameBuilder(void)38 void TestFrameBuilder(void)
39 {
40     const uint8_t kData1[] = {0x01, 0x02, 0x03, 0x04, 0x05};
41     const uint8_t kData2[] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa};
42     const uint8_t kData3[] = {0xca, 0xfe, 0xbe, 0xef};
43 
44     static constexpr uint16_t kMaxBufferSize = sizeof(kData1) * 2 + sizeof(kData2);
45 
46     Instance    *instance;
47     Message     *message;
48     uint16_t     offset;
49     uint8_t      buffer[kMaxBufferSize];
50     uint8_t      zeroBuffer[kMaxBufferSize];
51     FrameBuilder frameBuilder;
52 
53     printf("TestFrameBuilder\n");
54 
55     instance = static_cast<Instance *>(testInitInstance());
56     VerifyOrQuit(instance != nullptr);
57 
58     message = instance->Get<MessagePool>().Allocate(Message::kTypeIp6);
59     VerifyOrQuit(message != nullptr);
60 
61     SuccessOrQuit(message->Append(kData1));
62     SuccessOrQuit(message->Append(kData2));
63 
64     memset(buffer, 0, sizeof(buffer));
65     memset(zeroBuffer, 0, sizeof(zeroBuffer));
66 
67     frameBuilder.Init(buffer, sizeof(buffer));
68 
69     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
70     VerifyOrQuit(frameBuilder.GetLength() == 0);
71     VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
72     VerifyOrQuit(memcmp(buffer, zeroBuffer, sizeof(buffer)) == 0);
73     VerifyOrQuit(frameBuilder.CanAppend(sizeof(buffer)));
74     VerifyOrQuit(!frameBuilder.CanAppend(sizeof(buffer) + 1));
75 
76     frameBuilder.SetMaxLength(sizeof(kData1));
77     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
78     VerifyOrQuit(frameBuilder.GetLength() == 0);
79     VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(kData1));
80     VerifyOrQuit(memcmp(buffer, zeroBuffer, sizeof(buffer)) == 0);
81     VerifyOrQuit(frameBuilder.CanAppend(sizeof(kData1)));
82     VerifyOrQuit(!frameBuilder.CanAppend(sizeof(kData1) + 1));
83 
84     SuccessOrQuit(frameBuilder.Append(kData1));
85     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
86     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
87     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
88     VerifyOrQuit(memcmp(buffer + sizeof(kData1), zeroBuffer, sizeof(buffer) - sizeof(kData1)) == 0);
89 
90     frameBuilder.SetMaxLength(sizeof(buffer));
91     VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
92     VerifyOrQuit(frameBuilder.CanAppend(sizeof(buffer) - sizeof(kData1)));
93     VerifyOrQuit(!frameBuilder.CanAppend(sizeof(buffer) - sizeof(kData1) + 1));
94 
95     SuccessOrQuit(frameBuilder.AppendUint8(0x01));
96     SuccessOrQuit(frameBuilder.AppendBigEndianUint16(0x0203));
97     SuccessOrQuit(frameBuilder.AppendLittleEndianUint16(0x0504));
98     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) * 2);
99     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
100     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
101     VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData1, sizeof(kData1)) == 0);
102 
103     SuccessOrQuit(frameBuilder.AppendBigEndianUint32(0x01020304));
104     SuccessOrQuit(frameBuilder.AppendUint8(0x05));
105     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) * 3);
106     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
107     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
108     VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData1, sizeof(kData1)) == 0);
109     VerifyOrQuit(memcmp(buffer + 2 * sizeof(kData1), kData1, sizeof(kData1)) == 0);
110 
111     frameBuilder.Init(buffer, sizeof(buffer));
112     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
113     VerifyOrQuit(frameBuilder.GetLength() == 0);
114     VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
115 
116     offset = sizeof(kData1);
117     SuccessOrQuit(frameBuilder.AppendBytesFromMessage(*message, offset, sizeof(kData2)));
118     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData2));
119     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
120     VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
121 
122     frameBuilder.Init(buffer, sizeof(buffer));
123     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
124     VerifyOrQuit(frameBuilder.GetLength() == 0);
125     VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
126 
127     SuccessOrQuit(frameBuilder.AppendLittleEndianUint32(0x04030201));
128     SuccessOrQuit(frameBuilder.AppendUint8(0x05));
129     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
130     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
131     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
132 
133     SuccessOrQuit(frameBuilder.AppendBytes(zeroBuffer, sizeof(kData2)));
134     SuccessOrQuit(frameBuilder.Append(kData1));
135     VerifyOrQuit(frameBuilder.GetLength() == sizeof(buffer));
136     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
137     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
138     VerifyOrQuit(memcmp(buffer + sizeof(kData1), zeroBuffer, sizeof(kData2)) == 0);
139     VerifyOrQuit(memcmp(buffer + sizeof(kData1) + sizeof(kData2), kData1, sizeof(kData1)) == 0);
140 
141     VerifyOrQuit(!frameBuilder.CanAppend(1));
142     VerifyOrQuit(frameBuilder.AppendUint8(0x00) == kErrorNoBufs);
143 
144     offset = sizeof(kData1);
145     frameBuilder.Write(offset, kData2);
146     VerifyOrQuit(frameBuilder.GetLength() == sizeof(buffer));
147     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
148     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
149     VerifyOrQuit(memcmp(buffer + sizeof(kData1), kData2, sizeof(kData2)) == 0);
150     VerifyOrQuit(memcmp(buffer + sizeof(kData1) + sizeof(kData2), kData1, sizeof(kData1)) == 0);
151 
152     frameBuilder.Init(buffer, sizeof(buffer));
153     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
154     VerifyOrQuit(frameBuilder.GetLength() == 0);
155     VerifyOrQuit(frameBuilder.GetMaxLength() == sizeof(buffer));
156 
157     offset = 0;
158     SuccessOrQuit(frameBuilder.Insert(offset, kData1));
159     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
160     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
161     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
162 
163     offset = 0;
164     SuccessOrQuit(frameBuilder.Insert(offset, kData2));
165     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2));
166     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
167     VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
168     VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData1, sizeof(kData1)) == 0);
169 
170     offset = sizeof(kData2);
171     SuccessOrQuit(frameBuilder.InsertBytes(offset, kData3, sizeof(kData3)));
172     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2) + sizeof(kData3));
173     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
174     VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
175     VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData3, sizeof(kData3)) == 0);
176     VerifyOrQuit(memcmp(buffer + sizeof(kData2) + sizeof(kData3), kData1, sizeof(kData1)) == 0);
177 
178     offset = frameBuilder.GetLength();
179     SuccessOrQuit(frameBuilder.Insert<uint8_t>(offset, 0x77));
180     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2) + sizeof(kData3) + sizeof(uint8_t));
181     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
182     VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
183     VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData3, sizeof(kData3)) == 0);
184     VerifyOrQuit(memcmp(buffer + sizeof(kData2) + sizeof(kData3), kData1, sizeof(kData1)) == 0);
185     VerifyOrQuit(buffer[sizeof(kData2) + sizeof(kData3) + sizeof(kData1)] == 0x77);
186 
187     offset = frameBuilder.GetLength() - 1;
188     frameBuilder.RemoveBytes(offset, sizeof(uint8_t));
189     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2) + sizeof(kData3));
190     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
191     VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
192     VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData3, sizeof(kData3)) == 0);
193     VerifyOrQuit(memcmp(buffer + sizeof(kData2) + sizeof(kData3), kData1, sizeof(kData1)) == 0);
194 
195     offset = sizeof(kData2);
196     frameBuilder.RemoveBytes(offset, sizeof(kData3));
197     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1) + sizeof(kData2));
198     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
199     VerifyOrQuit(memcmp(buffer, kData2, sizeof(kData2)) == 0);
200     VerifyOrQuit(memcmp(buffer + sizeof(kData2), kData1, sizeof(kData1)) == 0);
201 
202     offset = 0;
203     frameBuilder.RemoveBytes(offset, sizeof(kData2));
204     VerifyOrQuit(frameBuilder.GetLength() == sizeof(kData1));
205     VerifyOrQuit(frameBuilder.GetBytes() == buffer);
206     VerifyOrQuit(memcmp(buffer, kData1, sizeof(kData1)) == 0);
207 
208     offset = 0;
209     frameBuilder.RemoveBytes(offset, sizeof(kData1));
210     VerifyOrQuit(frameBuilder.GetLength() == 0);
211 
212     message->Free();
213     testFreeInstance(instance);
214 }
215 
216 } // namespace ot
217 
main(void)218 int main(void)
219 {
220     ot::TestFrameBuilder();
221 
222     printf("All tests passed\n");
223     return 0;
224 }
225