• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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