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