1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bluetooth_hci/uart_transport.h"
16
17 #include "gtest/gtest.h"
18 #include "pw_bluetooth_hci/packet.h"
19 #include "pw_bytes/byte_builder.h"
20 #include "pw_status/status.h"
21
22 namespace pw::bluetooth_hci {
23 namespace {
24
25 class UartTransportTest : public ::testing::Test {
26 protected:
27 constexpr static std::byte kInvalidPacketIndicator = std::byte{0x0};
28 static_assert(kInvalidPacketIndicator != kUartCommandPacketIndicator);
29 static_assert(kInvalidPacketIndicator != kUartAsyncDataPacketIndicator);
30 static_assert(kInvalidPacketIndicator != kUartSyncDataPacketIndicator);
31 static_assert(kInvalidPacketIndicator != kUartEventPacketIndicator);
32
33 constexpr static size_t kUartBufferSizeBytes = 256;
34 ByteBuffer<kUartBufferSizeBytes> uart_buffer_;
35 };
36
TEST_F(UartTransportTest,EmptyBuffer)37 TEST_F(UartTransportTest, EmptyBuffer) {
38 const StatusWithSize status_with_size =
39 DecodeHciUartData(ConstByteSpan(), [](const Packet&) { FAIL(); });
40 EXPECT_EQ(status_with_size.status(), OkStatus());
41 EXPECT_EQ(status_with_size.size(), 0u);
42 }
43
TEST_F(UartTransportTest,InvalidPacketIndicator)44 TEST_F(UartTransportTest, InvalidPacketIndicator) {
45 uart_buffer_.push_back(kInvalidPacketIndicator);
46 ASSERT_EQ(uart_buffer_.status(), OkStatus());
47
48 const StatusWithSize status_with_size =
49 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
50 EXPECT_EQ(status_with_size.status(), Status::DataLoss());
51 EXPECT_EQ(status_with_size.size(), 1u);
52 }
53
TEST_F(UartTransportTest,CommandPacketIndicatorOnly)54 TEST_F(UartTransportTest, CommandPacketIndicatorOnly) {
55 uart_buffer_.push_back(kUartCommandPacketIndicator);
56 ASSERT_EQ(uart_buffer_.status(), OkStatus());
57
58 const StatusWithSize status_with_size =
59 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
60 EXPECT_EQ(status_with_size.status(), OkStatus());
61 EXPECT_EQ(status_with_size.size(), 0u);
62 }
63
TEST_F(UartTransportTest,CommandPacketPartialPacket)64 TEST_F(UartTransportTest, CommandPacketPartialPacket) {
65 uart_buffer_.push_back(kUartCommandPacketIndicator);
66
67 std::array<std::byte, CommandPacket::kHeaderSizeBytes> packet_buffer;
68 CommandPacket packet(0u, ConstByteSpan());
69 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
70 ASSERT_EQ(result.status(), OkStatus());
71
72 uart_buffer_.append(result.value().first(result.value().size_bytes() - 1));
73 ASSERT_EQ(uart_buffer_.status(), OkStatus());
74
75 const StatusWithSize status_with_size =
76 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
77 EXPECT_EQ(status_with_size.status(), OkStatus());
78 EXPECT_EQ(status_with_size.size(), 0u);
79 }
80
TEST_F(UartTransportTest,CommandPacket)81 TEST_F(UartTransportTest, CommandPacket) {
82 uart_buffer_.push_back(kUartCommandPacketIndicator);
83
84 std::array<std::byte, CommandPacket::kHeaderSizeBytes> packet_buffer;
85 CommandPacket packet(0u, ConstByteSpan());
86 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
87 ASSERT_EQ(result.status(), OkStatus());
88
89 uart_buffer_.append(result.value());
90 ASSERT_EQ(uart_buffer_.status(), OkStatus());
91
92 size_t command_packet_count = 0;
93 const StatusWithSize status_with_size =
94 DecodeHciUartData(uart_buffer_, [&](const Packet& decoded_packet) {
95 ASSERT_EQ(decoded_packet.type(), Packet::Type::kCommandPacket);
96 ++command_packet_count;
97 });
98 EXPECT_EQ(status_with_size.status(), OkStatus());
99 EXPECT_EQ(status_with_size.size(), uart_buffer_.size());
100 EXPECT_EQ(command_packet_count, 1u);
101 }
102
TEST_F(UartTransportTest,AsyncDataPacketIndicatorOnly)103 TEST_F(UartTransportTest, AsyncDataPacketIndicatorOnly) {
104 uart_buffer_.push_back(kUartAsyncDataPacketIndicator);
105 ASSERT_EQ(uart_buffer_.status(), OkStatus());
106
107 const StatusWithSize status_with_size =
108 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
109 EXPECT_EQ(status_with_size.status(), OkStatus());
110 EXPECT_EQ(status_with_size.size(), 0u);
111 }
112
TEST_F(UartTransportTest,AsyncDataPacketPartialPacket)113 TEST_F(UartTransportTest, AsyncDataPacketPartialPacket) {
114 uart_buffer_.push_back(kUartAsyncDataPacketIndicator);
115
116 std::array<std::byte, AsyncDataPacket::kHeaderSizeBytes> packet_buffer;
117 AsyncDataPacket packet(0u, ConstByteSpan());
118 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
119 ASSERT_EQ(result.status(), OkStatus());
120
121 uart_buffer_.append(result.value().first(result.value().size_bytes() - 1));
122 ASSERT_EQ(uart_buffer_.status(), OkStatus());
123
124 const StatusWithSize status_with_size =
125 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
126 EXPECT_EQ(status_with_size.status(), OkStatus());
127 EXPECT_EQ(status_with_size.size(), 0u);
128 }
129
TEST_F(UartTransportTest,AsyncDataPacket)130 TEST_F(UartTransportTest, AsyncDataPacket) {
131 uart_buffer_.push_back(kUartAsyncDataPacketIndicator);
132
133 std::array<std::byte, AsyncDataPacket::kHeaderSizeBytes> packet_buffer;
134 AsyncDataPacket packet(0u, ConstByteSpan());
135 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
136 ASSERT_EQ(result.status(), OkStatus());
137
138 uart_buffer_.append(result.value());
139 ASSERT_EQ(uart_buffer_.status(), OkStatus());
140
141 size_t async_data_packet_count = 0;
142 const StatusWithSize status_with_size =
143 DecodeHciUartData(uart_buffer_, [&](const Packet& decoded_packet) {
144 ASSERT_EQ(decoded_packet.type(), Packet::Type::kAsyncDataPacket);
145 ++async_data_packet_count;
146 });
147 EXPECT_EQ(status_with_size.status(), OkStatus());
148 EXPECT_EQ(status_with_size.size(), uart_buffer_.size());
149 EXPECT_EQ(async_data_packet_count, 1u);
150 }
151
TEST_F(UartTransportTest,SyncDataPacketIndicatorOnly)152 TEST_F(UartTransportTest, SyncDataPacketIndicatorOnly) {
153 uart_buffer_.push_back(kUartSyncDataPacketIndicator);
154 ASSERT_EQ(uart_buffer_.status(), OkStatus());
155
156 const StatusWithSize status_with_size =
157 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
158 EXPECT_EQ(status_with_size.status(), OkStatus());
159 EXPECT_EQ(status_with_size.size(), 0u);
160 }
161
TEST_F(UartTransportTest,SyncDataPacketPartialPacket)162 TEST_F(UartTransportTest, SyncDataPacketPartialPacket) {
163 uart_buffer_.push_back(kUartSyncDataPacketIndicator);
164
165 std::array<std::byte, SyncDataPacket::kHeaderSizeBytes> packet_buffer;
166 SyncDataPacket packet(0u, ConstByteSpan());
167 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
168 ASSERT_EQ(result.status(), OkStatus());
169
170 uart_buffer_.append(result.value().first(result.value().size_bytes() - 1));
171 ASSERT_EQ(uart_buffer_.status(), OkStatus());
172
173 const StatusWithSize status_with_size =
174 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
175 EXPECT_EQ(status_with_size.status(), OkStatus());
176 EXPECT_EQ(status_with_size.size(), 0u);
177 }
178
TEST_F(UartTransportTest,SyncDataPacket)179 TEST_F(UartTransportTest, SyncDataPacket) {
180 uart_buffer_.push_back(kUartSyncDataPacketIndicator);
181
182 std::array<std::byte, SyncDataPacket::kHeaderSizeBytes> packet_buffer;
183 SyncDataPacket packet(0u, ConstByteSpan());
184 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
185 ASSERT_EQ(result.status(), OkStatus());
186
187 uart_buffer_.append(result.value());
188 ASSERT_EQ(uart_buffer_.status(), OkStatus());
189
190 size_t sync_data_packet_count = 0;
191 const StatusWithSize status_with_size =
192 DecodeHciUartData(uart_buffer_, [&](const Packet& decoded_packet) {
193 ASSERT_EQ(decoded_packet.type(), Packet::Type::kSyncDataPacket);
194 ++sync_data_packet_count;
195 });
196 EXPECT_EQ(status_with_size.status(), OkStatus());
197 EXPECT_EQ(status_with_size.size(), uart_buffer_.size());
198 EXPECT_EQ(sync_data_packet_count, 1u);
199 }
200
TEST_F(UartTransportTest,EventPacketIndicatorOnly)201 TEST_F(UartTransportTest, EventPacketIndicatorOnly) {
202 uart_buffer_.push_back(kUartEventPacketIndicator);
203 ASSERT_EQ(uart_buffer_.status(), OkStatus());
204
205 const StatusWithSize status_with_size =
206 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
207 EXPECT_EQ(status_with_size.status(), OkStatus());
208 EXPECT_EQ(status_with_size.size(), 0u);
209 }
210
TEST_F(UartTransportTest,EventPacketPartialPacket)211 TEST_F(UartTransportTest, EventPacketPartialPacket) {
212 uart_buffer_.push_back(kUartEventPacketIndicator);
213
214 std::array<std::byte, EventPacket::kHeaderSizeBytes> packet_buffer;
215 EventPacket packet(0u, ConstByteSpan());
216 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
217 ASSERT_EQ(result.status(), OkStatus());
218
219 uart_buffer_.append(result.value().first(result.value().size_bytes() - 1));
220 ASSERT_EQ(uart_buffer_.status(), OkStatus());
221
222 const StatusWithSize status_with_size =
223 DecodeHciUartData(uart_buffer_, [](const Packet&) { FAIL(); });
224 EXPECT_EQ(status_with_size.status(), OkStatus());
225 EXPECT_EQ(status_with_size.size(), 0u);
226 }
227
TEST_F(UartTransportTest,EventPacket)228 TEST_F(UartTransportTest, EventPacket) {
229 uart_buffer_.push_back(kUartEventPacketIndicator);
230
231 std::array<std::byte, EventPacket::kHeaderSizeBytes> packet_buffer;
232 EventPacket packet(0u, ConstByteSpan());
233 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
234 ASSERT_EQ(result.status(), OkStatus());
235
236 uart_buffer_.append(result.value());
237 ASSERT_EQ(uart_buffer_.status(), OkStatus());
238
239 size_t event_packet_count = 0;
240 const StatusWithSize status_with_size =
241 DecodeHciUartData(uart_buffer_, [&](const Packet& decoded_packet) {
242 ASSERT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
243 ++event_packet_count;
244 });
245 EXPECT_EQ(status_with_size.status(), OkStatus());
246 EXPECT_EQ(status_with_size.size(), uart_buffer_.size());
247 EXPECT_EQ(event_packet_count, 1u);
248 }
249
TEST_F(UartTransportTest,BadIndicatorThenPacketSequence)250 TEST_F(UartTransportTest, BadIndicatorThenPacketSequence) {
251 // Invalid packet indicator.
252 uart_buffer_.push_back(kInvalidPacketIndicator);
253
254 // Valid EventPacket w/ packet indicator.
255 uart_buffer_.push_back(kUartEventPacketIndicator);
256 std::array<std::byte, EventPacket::kHeaderSizeBytes> packet_buffer;
257 EventPacket packet(0u, ConstByteSpan());
258 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
259 ASSERT_EQ(result.status(), OkStatus());
260 uart_buffer_.append(result.value());
261 ASSERT_EQ(uart_buffer_.status(), OkStatus());
262
263 // First decode should fail after consuming the invalid packet indicator.
264 StatusWithSize status_with_size =
265 DecodeHciUartData(uart_buffer_, [&](const Packet&) { FAIL(); });
266 EXPECT_EQ(status_with_size.status(), Status::DataLoss());
267 EXPECT_EQ(status_with_size.size(), 1u);
268
269 const ConstByteSpan remaining_data =
270 ConstByteSpan(uart_buffer_).subspan(status_with_size.size());
271
272 // Second decode should work now that the invalid byte is gone.
273 size_t event_packet_count = 0;
274 status_with_size =
275 DecodeHciUartData(remaining_data, [&](const Packet& decoded_packet) {
276 ASSERT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
277 ++event_packet_count;
278 });
279 EXPECT_EQ(status_with_size.status(), OkStatus());
280 EXPECT_EQ(status_with_size.size(), remaining_data.size_bytes());
281 EXPECT_EQ(event_packet_count, 1u);
282 }
283
TEST_F(UartTransportTest,PacketThenBadIndicatorSequence)284 TEST_F(UartTransportTest, PacketThenBadIndicatorSequence) {
285 // Valid EventPacket w/ packet indicator.
286 uart_buffer_.push_back(kUartEventPacketIndicator);
287 std::array<std::byte, EventPacket::kHeaderSizeBytes> packet_buffer;
288 EventPacket packet(0u, ConstByteSpan());
289 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
290 ASSERT_EQ(result.status(), OkStatus());
291 uart_buffer_.append(result.value());
292 ASSERT_EQ(uart_buffer_.status(), OkStatus());
293
294 // Invalid packet indicator.
295 uart_buffer_.push_back(kInvalidPacketIndicator);
296
297 // First decode should fail, consuming all data.
298 size_t event_packet_count = 0;
299 const StatusWithSize status_with_size =
300 DecodeHciUartData(uart_buffer_, [&](const Packet& decoded_packet) {
301 ASSERT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
302 ++event_packet_count;
303 });
304 EXPECT_EQ(status_with_size.status(), Status::DataLoss());
305 EXPECT_EQ(status_with_size.size(), uart_buffer_.size());
306 EXPECT_EQ(event_packet_count, 1u);
307 }
308
TEST_F(UartTransportTest,AllPacketTypes)309 TEST_F(UartTransportTest, AllPacketTypes) {
310 // Valid CommandPacket w/ packet indicator.
311 {
312 uart_buffer_.push_back(kUartCommandPacketIndicator);
313 std::array<std::byte, CommandPacket::kHeaderSizeBytes> packet_buffer;
314 CommandPacket packet(0u, ConstByteSpan());
315 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
316 ASSERT_EQ(result.status(), OkStatus());
317 uart_buffer_.append(result.value());
318 ASSERT_EQ(uart_buffer_.status(), OkStatus());
319 }
320
321 // Valid AsyncDataPacket w/ packet indicator.
322 {
323 uart_buffer_.push_back(kUartAsyncDataPacketIndicator);
324 std::array<std::byte, AsyncDataPacket::kHeaderSizeBytes> packet_buffer;
325 AsyncDataPacket packet(0u, ConstByteSpan());
326 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
327 ASSERT_EQ(result.status(), OkStatus());
328 uart_buffer_.append(result.value());
329 ASSERT_EQ(uart_buffer_.status(), OkStatus());
330 }
331
332 // Valid SyncDataPacket w/ packet indicator.
333 {
334 uart_buffer_.push_back(kUartSyncDataPacketIndicator);
335 std::array<std::byte, SyncDataPacket::kHeaderSizeBytes> packet_buffer;
336 SyncDataPacket packet(0u, ConstByteSpan());
337 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
338 ASSERT_EQ(result.status(), OkStatus());
339 uart_buffer_.append(result.value());
340 ASSERT_EQ(uart_buffer_.status(), OkStatus());
341 }
342
343 // Valid EventPacket w/ packet indicator.
344 {
345 uart_buffer_.push_back(kUartEventPacketIndicator);
346 std::array<std::byte, EventPacket::kHeaderSizeBytes> packet_buffer;
347 EventPacket packet(0u, ConstByteSpan());
348 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
349 ASSERT_EQ(result.status(), OkStatus());
350 uart_buffer_.append(result.value());
351 ASSERT_EQ(uart_buffer_.status(), OkStatus());
352 }
353
354 // First decode should succeed, consuming all data.
355 size_t packet_count = 0u;
356 const StatusWithSize status_with_size =
357 DecodeHciUartData(uart_buffer_, [&](const Packet& decoded_packet) {
358 ++packet_count;
359 switch (packet_count) {
360 case 1u:
361 EXPECT_EQ(decoded_packet.type(), Packet::Type::kCommandPacket);
362 break;
363
364 case 2u:
365 EXPECT_EQ(decoded_packet.type(), Packet::Type::kAsyncDataPacket);
366 break;
367
368 case 3u:
369 EXPECT_EQ(decoded_packet.type(), Packet::Type::kSyncDataPacket);
370 break;
371
372 case 4u:
373 EXPECT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
374 break;
375 }
376 });
377 EXPECT_EQ(status_with_size.status(), OkStatus());
378 EXPECT_EQ(status_with_size.size(), uart_buffer_.size());
379 EXPECT_EQ(packet_count, 4u);
380 }
381
TEST_F(UartTransportTest,LotsOfEventPackets)382 TEST_F(UartTransportTest, LotsOfEventPackets) {
383 std::array<std::byte, EventPacket::kHeaderSizeBytes> packet_buffer;
384 EventPacket packet(0u, ConstByteSpan());
385 const Result<ConstByteSpan> result = packet.Encode(packet_buffer);
386 ASSERT_EQ(result.status(), OkStatus());
387
388 size_t expected_packet_count = 0;
389 while ((uart_buffer_.max_size() - uart_buffer_.size()) >
390 packet.size_bytes()) {
391 ++expected_packet_count;
392 uart_buffer_.push_back(kUartEventPacketIndicator);
393 uart_buffer_.append(result.value());
394 ASSERT_EQ(uart_buffer_.status(), OkStatus());
395 }
396
397 size_t event_packet_count = 0;
398 const StatusWithSize status_with_size =
399 DecodeHciUartData(uart_buffer_, [&](const Packet& decoded_packet) {
400 ASSERT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
401 ++event_packet_count;
402 });
403 EXPECT_EQ(status_with_size.status(), OkStatus());
404 EXPECT_EQ(status_with_size.size(), uart_buffer_.size());
405 EXPECT_EQ(event_packet_count, expected_packet_count);
406 }
407
408 } // namespace
409 } // namespace pw::bluetooth_hci
410