1 /******************************************************************************
2  *
3  *  Copyright 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #include "hci/include/packet_fragmenter.h"
20 
21 #include <gtest/gtest.h>
22 #include <stdint.h>
23 
24 #include "hci/include/hci_layer.h"
25 #include "internal_include/bt_target.h"
26 #include "osi/include/allocator.h"
27 #include "osi/include/osi.h"
28 #include "stack/include/bt_hdr.h"
29 #include "test_stubs.h"
30 
31 #ifndef HCI_ISO_PREAMBLE_SIZE
32 #define HCI_ISO_PREAMBLE_SIZE 4
33 #endif
34 
35 DECLARE_TEST_MODES(init, iso_no_reassembly, iso_reassembly, iso_fragmentation,
36                    iso_no_fragmentation);
37 
38 #define LOCAL_BLE_CONTROLLER_ID 1
39 
40 static const char* sample_data =
41     "At this point they came in sight of thirty forty windmills that there are "
42     "on plain, and "
43     "as soon as Don Quixote saw them he said to his squire, \"Fortune is "
44     "arranging matters "
45     "for us better than we could have shaped our desires ourselves, for look "
46     "there, friend "
47     "Sancho Panza, where thirty or more monstrous giants present themselves, "
48     "all of whom I "
49     "mean to engage in battle and slay, and with whose spoils we shall begin "
50     "to make our "
51     "fortunes; for this is righteous warfare, and it is God's good service to "
52     "sweep so evil "
53     "a breed from off the face of the earth.\"";
54 
55 static const char* small_sample_data = "\"What giants?\" said Sancho Panza.";
56 static const uint16_t test_iso_handle_complete_with_ts =
57     (0x0666 | (0x0002 << 12) | (0x0001 << 14));
58 static const uint16_t test_iso_handle_complete_without_ts =
59     (0x0666 | (0x0002 << 12));
60 static const uint16_t test_iso_handle_start_with_ts = (0x0666 | (0x0001 << 14));
61 static const uint16_t test_iso_handle_start_without_ts =
62     (0x0666);  // Also base handle
63 static const uint16_t test_iso_handle_continuation = (0x0666 | (0x0001 << 12));
64 static const uint16_t test_iso_handle_end = (0x0666 | (0x0003 << 12));
65 
66 static int packet_index;
67 static unsigned int data_size_sum;
68 
69 static const packet_fragmenter_t* fragmenter;
70 
71 static uint32_t iso_timestamp = 0x32122321;
72 static uint16_t iso_packet_seq = 0x1291;
73 static bool iso_has_ts = true;
74 
manufacture_packet_for_fragmentation(uint16_t event,const char * data)75 static BT_HDR* manufacture_packet_for_fragmentation(uint16_t event,
76                                                     const char* data) {
77   uint16_t data_length = strlen(data);
78   uint16_t size = data_length;
79   if (event == MSG_STACK_TO_HC_HCI_ISO) {
80     size += 8;  // handle (2), length (2), packet_seq (2), sdu_len(2)
81     if (iso_has_ts) {
82       size += 4;
83     }
84   }
85 
86   BT_HDR* packet = (BT_HDR*)osi_malloc(size + sizeof(BT_HDR));
87   packet->len = size;
88   packet->offset = 0;
89   packet->event = event;
90   packet->layer_specific = 0;
91   uint8_t* packet_data = packet->data;
92 
93   if (event == MSG_STACK_TO_HC_HCI_ISO) {
94     if (iso_has_ts) {
95       packet->layer_specific |= BT_ISO_HDR_CONTAINS_TS;
96       UINT16_TO_STREAM(packet_data, test_iso_handle_start_with_ts);
97       UINT16_TO_STREAM(packet_data, data_length + 8);
98       UINT32_TO_STREAM(packet_data, iso_timestamp);
99     } else {
100       UINT16_TO_STREAM(packet_data, test_iso_handle_start_without_ts);
101       UINT16_TO_STREAM(packet_data, data_length + 4);
102     }
103     UINT16_TO_STREAM(packet_data, iso_packet_seq);
104     UINT16_TO_STREAM(packet_data, data_length);
105   }
106 
107   memcpy(packet_data, data, data_length);
108   return packet;
109 }
110 
expect_packet_fragmented(uint16_t event,int max_acl_data_size,BT_HDR * packet,const char * expected_data,bool send_complete)111 static void expect_packet_fragmented(uint16_t event, int max_acl_data_size,
112                                      BT_HDR* packet, const char* expected_data,
113                                      bool send_complete) {
114   uint8_t* data = packet->data + packet->offset;
115   int expected_data_offset;
116   int length_to_check;
117 
118   if (event == MSG_STACK_TO_HC_HCI_ISO) {
119     uint16_t handle;
120     uint16_t length;
121 
122     STREAM_TO_UINT16(handle, data);
123     STREAM_TO_UINT16(length, data);
124 
125     int length_remaining = strlen(expected_data) - data_size_sum;
126     int packet_data_length = packet->len - HCI_ISO_PREAMBLE_SIZE;
127 
128     if (packet_index == 0) {
129       uint8_t hdr_size = 8;  // ts, packet_seq, len
130 
131       if (iso_has_ts) {
132         uint32_t timestamp;
133         STREAM_TO_UINT32(timestamp, data);
134         ASSERT_EQ(timestamp, iso_timestamp);
135 
136         if (send_complete)
137           ASSERT_EQ(test_iso_handle_complete_with_ts, handle);
138         else
139           ASSERT_EQ(test_iso_handle_start_with_ts, handle);
140       } else {
141         if (send_complete)
142           ASSERT_EQ(test_iso_handle_complete_without_ts, handle);
143         else
144           ASSERT_EQ(test_iso_handle_start_without_ts, handle);
145         hdr_size -= 4;
146       }
147 
148       uint16_t packet_seq;
149       STREAM_TO_UINT16(packet_seq, data);
150       ASSERT_EQ(packet_seq, iso_packet_seq);
151 
152       uint16_t iso_sdu_length;
153       STREAM_TO_UINT16(iso_sdu_length, data);
154 
155       ASSERT_EQ(iso_sdu_length, strlen(expected_data));
156 
157       length_to_check = packet_data_length - hdr_size;
158     } else {
159       if (!send_complete)
160         ASSERT_EQ(test_iso_handle_continuation, handle);
161       else
162         ASSERT_EQ(test_iso_handle_end, handle);
163 
164       length_to_check = packet_data_length;
165     }
166 
167     if (length_remaining > max_acl_data_size)
168       ASSERT_EQ(max_acl_data_size, packet_data_length);
169 
170     expected_data_offset = packet_index * max_acl_data_size;
171     if (expected_data_offset > 0) {
172       if (iso_has_ts) {
173         expected_data_offset -= 8;
174       } else {
175         expected_data_offset -= 4;
176       }
177     }
178     packet_index++;
179   } else {
180     length_to_check = strlen(expected_data);
181     expected_data_offset = 0;
182   }
183 
184   for (int i = 0; i < length_to_check; i++) {
185     EXPECT_EQ(expected_data[expected_data_offset + i], data[i]);
186     data_size_sum++;
187   }
188 
189   if (event == MSG_STACK_TO_HC_HCI_ISO)
190     EXPECT_TRUE(send_complete == (data_size_sum == strlen(expected_data)));
191 
192   if (send_complete) osi_free(packet);
193 }
194 
manufacture_iso_packet_and_then_reassemble(uint16_t event,uint16_t iso_size,const char * data)195 static void manufacture_iso_packet_and_then_reassemble(uint16_t event,
196                                                        uint16_t iso_size,
197                                                        const char* data) {
198   uint16_t data_length = strlen(data);
199   uint16_t total_length;
200   uint16_t length_sent = 0;
201   uint16_t iso_length = data_length;
202   BT_HDR* packet;
203   uint8_t* packet_data;
204   uint8_t hdr_size = 4;  // packet seq, sdu len
205 
206   // ISO length (2), packet seq (2), optional timestamp (4)
207   total_length = data_length + 4;
208   if (iso_has_ts) total_length += 4;
209 
210   do {
211     int length_to_send = (length_sent + (iso_size - 4) < total_length)
212                              ? (iso_size - 4)
213                              : (total_length - length_sent);
214 
215     packet = (BT_HDR*)osi_malloc(length_to_send + 4 + sizeof(BT_HDR));
216     packet_data = packet->data;
217     packet->len = length_to_send + 4;
218     packet->offset = 0;
219     packet->event = event;
220     packet->layer_specific = 0;
221 
222     bool is_complete = length_to_send == total_length;
223 
224     if (length_sent == 0) {  // first packet
225       if (iso_has_ts) {
226         hdr_size += 4;
227         if (is_complete) {
228           UINT16_TO_STREAM(packet_data, test_iso_handle_complete_with_ts);
229         } else {
230           UINT16_TO_STREAM(packet_data, test_iso_handle_start_with_ts);
231         }
232       } else {
233         if (is_complete) {
234           UINT16_TO_STREAM(packet_data, test_iso_handle_complete_without_ts);
235         } else {
236           UINT16_TO_STREAM(packet_data, test_iso_handle_start_without_ts);
237         }
238       }
239 
240       UINT16_TO_STREAM(packet_data, length_to_send);
241 
242       if (iso_has_ts) {
243         UINT32_TO_STREAM(packet_data, iso_timestamp);
244       }
245 
246       UINT16_TO_STREAM(packet_data, iso_packet_seq);
247       UINT16_TO_STREAM(packet_data, iso_length);
248       memcpy(packet_data, data, length_to_send - hdr_size);
249     } else {
250       if (length_sent + length_to_send == total_length) {
251         UINT16_TO_STREAM(packet_data, test_iso_handle_end);
252       } else {
253         UINT16_TO_STREAM(packet_data, test_iso_handle_continuation);
254       }
255       UINT16_TO_STREAM(packet_data, length_to_send);
256       memcpy(packet_data, data + length_sent - hdr_size, length_to_send);
257     }
258 
259     length_sent += length_to_send;
260     fragmenter->reassemble_and_dispatch(packet);
261   } while (length_sent < total_length);
262 }
263 
manufacture_packet_and_then_reassemble(uint16_t event,uint16_t packet_size,const char * data)264 static void manufacture_packet_and_then_reassemble(uint16_t event,
265                                                    uint16_t packet_size,
266                                                    const char* data) {
267   uint16_t data_length = strlen(data);
268 
269   if (event == MSG_HC_TO_STACK_HCI_ISO) {
270     manufacture_iso_packet_and_then_reassemble(event, packet_size, data);
271   } else {
272     BT_HDR* packet = (BT_HDR*)osi_malloc(data_length + sizeof(BT_HDR));
273     packet->len = data_length;
274     packet->offset = 0;
275     packet->event = event;
276     packet->layer_specific = 0;
277     memcpy(packet->data, data, data_length);
278 
279     fragmenter->reassemble_and_dispatch(packet);
280   }
281 }
282 
expect_packet_reassembled_iso(uint16_t event,BT_HDR * packet,const char * expected_data,uint32_t expected_timestamp,uint16_t expected_packet_seq,bool is_complete=false)283 static void expect_packet_reassembled_iso(uint16_t event, BT_HDR* packet,
284                                           const char* expected_data,
285                                           uint32_t expected_timestamp,
286                                           uint16_t expected_packet_seq,
287                                           bool is_complete = false) {
288   uint16_t expected_data_length = strlen(expected_data);
289   uint8_t* data = packet->data;
290   uint8_t hdr_size = 8;
291   uint16_t handle;
292   uint16_t length;
293   uint16_t iso_length;
294   uint32_t timestamp;
295   uint16_t packet_seq;
296 
297   ASSERT_EQ(event, MSG_HC_TO_STACK_HCI_ISO);
298 
299   STREAM_TO_UINT16(handle, data);
300   STREAM_TO_UINT16(length, data);
301   if (iso_has_ts) {
302     STREAM_TO_UINT32(timestamp, data);
303     ASSERT_TRUE((packet->layer_specific & BT_ISO_HDR_CONTAINS_TS) != 0);
304     ASSERT_EQ(timestamp, expected_timestamp);
305     ASSERT_EQ(is_complete ? test_iso_handle_complete_with_ts
306                           : test_iso_handle_start_with_ts,
307               handle);
308   } else {
309     ASSERT_TRUE((packet->layer_specific & BT_ISO_HDR_CONTAINS_TS) == 0);
310     ASSERT_EQ(is_complete ? test_iso_handle_complete_without_ts
311                           : test_iso_handle_start_without_ts,
312               handle);
313     hdr_size -= 4;
314   }
315 
316   ASSERT_EQ(expected_data_length + hdr_size, length);
317 
318   STREAM_TO_UINT16(packet_seq, data);
319   ASSERT_EQ(packet_seq, expected_packet_seq);
320 
321   STREAM_TO_UINT16(iso_length, data);
322   ASSERT_EQ(expected_data_length, iso_length);
323 
324   for (int i = 0; i < expected_data_length; i++) {
325     ASSERT_EQ(expected_data[i], data[i]);
326     data_size_sum++;
327   }
328 
329   osi_free(packet);
330 }
331 
332 STUB_FUNCTION(void, fragmented_callback, (BT_HDR * packet, bool send_complete))
DURING(iso_fragmentation)333 DURING(iso_fragmentation) {
334   expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ISO, 10, packet, sample_data,
335                            send_complete);
336   return;
337 }
338 
DURING(iso_no_fragmentation)339 DURING(iso_no_fragmentation) {
340   expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ISO, 42, packet,
341                            small_sample_data, send_complete);
342   return;
343 }
344 
345 UNEXPECTED_CALL;
346 }
347 
348 STUB_FUNCTION(void, reassembled_callback, (BT_HDR * packet))
349 DURING(iso_reassembly) AT_CALL(0) {
350   expect_packet_reassembled_iso(MSG_HC_TO_STACK_HCI_ISO, packet, sample_data,
351                                 iso_timestamp, iso_packet_seq);
352   return;
353 }
354 
355 DURING(iso_no_reassembly) AT_CALL(0) {
356   expect_packet_reassembled_iso(MSG_HC_TO_STACK_HCI_ISO, packet,
357                                 small_sample_data, iso_timestamp,
358                                 iso_packet_seq, true);
359   return;
360 }
361 
362 UNEXPECTED_CALL;
363 }
364 
365 STUB_FUNCTION(uint16_t, get_iso_data_size, (void))
366 DURING(iso_no_fragmentation) return 42;
367 DURING(iso_fragmentation) return 10;
368 
369 UNEXPECTED_CALL;
370 return 0;
371 }
372 
373 static void reset_for(TEST_MODES_T next) {
374   RESET_CALL_COUNT(fragmented_callback);
375   RESET_CALL_COUNT(reassembled_callback);
376   CURRENT_TEST_MODE = next;
377 }
378 
379 class PacketFragmenterTest : public ::testing::Test {
380  protected:
381   void SetUp() override {
382     fragmenter = packet_fragmenter_get_interface();
383 
384     packet_index = 0;
385     data_size_sum = 0;
386 
387     callbacks.fragmented = fragmented_callback;
388     callbacks.reassembled = reassembled_callback;
389     reset_for(init);
390     fragmenter->init(&callbacks);
391   }
392 
393   void TearDown() override { fragmenter->cleanup(); }
394 
395   packet_fragmenter_callbacks_t callbacks;
396 };
397 
398 TEST_F(PacketFragmenterTest, test_iso_fragment_necessary) {
399   reset_for(iso_fragmentation);
400   iso_has_ts = true;
401 
402   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO,
403                                                         sample_data);
404   packet->event |= LOCAL_BLE_CONTROLLER_ID;
405   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
406 
407   ASSERT_EQ(strlen(sample_data), data_size_sum);
408 }
409 
410 TEST_F(PacketFragmenterTest, test_iso_no_fragment_necessary) {
411   reset_for(iso_no_fragmentation);
412   iso_has_ts = true;
413 
414   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO,
415                                                         small_sample_data);
416   packet->event |= LOCAL_BLE_CONTROLLER_ID;
417   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
418 
419   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
420 }
421 
422 TEST_F(PacketFragmenterTest, test_iso_fragment_necessary_no_ts) {
423   reset_for(iso_fragmentation);
424   iso_has_ts = false;
425   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO,
426                                                         sample_data);
427   packet->event |= LOCAL_BLE_CONTROLLER_ID;
428   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
429 
430   ASSERT_EQ(strlen(sample_data), data_size_sum);
431 }
432 
433 TEST_F(PacketFragmenterTest, test_iso_no_fragment_necessary_no_ts) {
434   reset_for(iso_no_fragmentation);
435   iso_has_ts = false;
436   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO,
437                                                         small_sample_data);
438   packet->event |= LOCAL_BLE_CONTROLLER_ID;
439   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
440 
441   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
442 }
443 
444 TEST_F(PacketFragmenterTest, test_iso_no_reassembly_necessary) {
445   reset_for(iso_no_reassembly);
446   iso_has_ts = true;
447   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, 50,
448                                          small_sample_data);
449 
450   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
451   EXPECT_CALL_COUNT(reassembled_callback, 1);
452 }
453 
454 TEST_F(PacketFragmenterTest, test_iso_reassembly_necessary) {
455   reset_for(iso_reassembly);
456   iso_has_ts = true;
457   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, 42,
458                                          sample_data);
459 
460   ASSERT_EQ(strlen(sample_data), data_size_sum);
461   EXPECT_CALL_COUNT(reassembled_callback, 1);
462 }
463 
464 TEST_F(PacketFragmenterTest, test_iso_no_reassembly_necessary_no_ts) {
465   reset_for(iso_no_reassembly);
466   iso_has_ts = false;
467   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, (42 + 4),
468                                          small_sample_data);
469 
470   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
471   EXPECT_CALL_COUNT(reassembled_callback, 1);
472 }
473 
474 TEST_F(PacketFragmenterTest, test_iso_reassembly_necessary_no_ts) {
475   reset_for(iso_reassembly);
476   iso_has_ts = false;
477   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, 42,
478                                          sample_data);
479 
480   ASSERT_EQ(strlen(sample_data), data_size_sum);
481   EXPECT_CALL_COUNT(reassembled_callback, 1);
482 }
483