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 = (0x0666 | (0x0002 << 12) | (0x0001 << 14));
57 static const uint16_t test_iso_handle_complete_without_ts = (0x0666 | (0x0002 << 12));
58 static const uint16_t test_iso_handle_start_with_ts = (0x0666 | (0x0001 << 14));
59 static const uint16_t test_iso_handle_start_without_ts = (0x0666);  // Also base handle
60 static const uint16_t test_iso_handle_continuation = (0x0666 | (0x0001 << 12));
61 static const uint16_t test_iso_handle_end = (0x0666 | (0x0003 << 12));
62 
63 static int packet_index;
64 static unsigned int data_size_sum;
65 
66 static const packet_fragmenter_t* fragmenter;
67 
68 static uint32_t iso_timestamp = 0x32122321;
69 static uint16_t iso_packet_seq = 0x1291;
70 static bool iso_has_ts = true;
71 
manufacture_packet_for_fragmentation(uint16_t event,const char * data)72 static BT_HDR* manufacture_packet_for_fragmentation(uint16_t event, const char* data) {
73   uint16_t data_length = strlen(data);
74   uint16_t size = data_length;
75   if (event == MSG_STACK_TO_HC_HCI_ISO) {
76     size += 8;  // handle (2), length (2), packet_seq (2), sdu_len(2)
77     if (iso_has_ts) {
78       size += 4;
79     }
80   }
81 
82   BT_HDR* packet = (BT_HDR*)osi_malloc(size + sizeof(BT_HDR));
83   packet->len = size;
84   packet->offset = 0;
85   packet->event = event;
86   packet->layer_specific = 0;
87   uint8_t* packet_data = packet->data;
88 
89   if (event == MSG_STACK_TO_HC_HCI_ISO) {
90     if (iso_has_ts) {
91       packet->layer_specific |= BT_ISO_HDR_CONTAINS_TS;
92       UINT16_TO_STREAM(packet_data, test_iso_handle_start_with_ts);
93       UINT16_TO_STREAM(packet_data, data_length + 8);
94       UINT32_TO_STREAM(packet_data, iso_timestamp);
95     } else {
96       UINT16_TO_STREAM(packet_data, test_iso_handle_start_without_ts);
97       UINT16_TO_STREAM(packet_data, data_length + 4);
98     }
99     UINT16_TO_STREAM(packet_data, iso_packet_seq);
100     UINT16_TO_STREAM(packet_data, data_length);
101   }
102 
103   memcpy(packet_data, data, data_length);
104   return packet;
105 }
106 
expect_packet_fragmented(uint16_t event,int max_acl_data_size,BT_HDR * packet,const char * expected_data,bool send_complete)107 static void expect_packet_fragmented(uint16_t event, int max_acl_data_size, BT_HDR* packet,
108                                      const char* expected_data, bool send_complete) {
109   uint8_t* data = packet->data + packet->offset;
110   int expected_data_offset;
111   int length_to_check;
112 
113   if (event == MSG_STACK_TO_HC_HCI_ISO) {
114     uint16_t handle;
115     uint16_t length;
116 
117     STREAM_TO_UINT16(handle, data);
118     STREAM_TO_UINT16(length, data);
119 
120     int length_remaining = strlen(expected_data) - data_size_sum;
121     int packet_data_length = packet->len - HCI_ISO_PREAMBLE_SIZE;
122 
123     if (packet_index == 0) {
124       uint8_t hdr_size = 8;  // ts, packet_seq, len
125 
126       if (iso_has_ts) {
127         uint32_t timestamp;
128         STREAM_TO_UINT32(timestamp, data);
129         ASSERT_EQ(timestamp, iso_timestamp);
130 
131         if (send_complete) {
132           ASSERT_EQ(test_iso_handle_complete_with_ts, handle);
133         } else {
134           ASSERT_EQ(test_iso_handle_start_with_ts, handle);
135         }
136       } else {
137         if (send_complete) {
138           ASSERT_EQ(test_iso_handle_complete_without_ts, handle);
139         } else {
140           ASSERT_EQ(test_iso_handle_start_without_ts, handle);
141         }
142         hdr_size -= 4;
143       }
144 
145       uint16_t packet_seq;
146       STREAM_TO_UINT16(packet_seq, data);
147       ASSERT_EQ(packet_seq, iso_packet_seq);
148 
149       uint16_t iso_sdu_length;
150       STREAM_TO_UINT16(iso_sdu_length, data);
151 
152       ASSERT_EQ(iso_sdu_length, strlen(expected_data));
153 
154       length_to_check = packet_data_length - hdr_size;
155     } else {
156       if (!send_complete) {
157         ASSERT_EQ(test_iso_handle_continuation, handle);
158       } else {
159         ASSERT_EQ(test_iso_handle_end, handle);
160       }
161 
162       length_to_check = packet_data_length;
163     }
164 
165     if (length_remaining > max_acl_data_size) {
166       ASSERT_EQ(max_acl_data_size, packet_data_length);
167     }
168 
169     expected_data_offset = packet_index * max_acl_data_size;
170     if (expected_data_offset > 0) {
171       if (iso_has_ts) {
172         expected_data_offset -= 8;
173       } else {
174         expected_data_offset -= 4;
175       }
176     }
177     packet_index++;
178   } else {
179     length_to_check = strlen(expected_data);
180     expected_data_offset = 0;
181   }
182 
183   for (int i = 0; i < length_to_check; i++) {
184     EXPECT_EQ(expected_data[expected_data_offset + i], data[i]);
185     data_size_sum++;
186   }
187 
188   if (event == MSG_STACK_TO_HC_HCI_ISO) {
189     EXPECT_TRUE(send_complete == (data_size_sum == strlen(expected_data)));
190   }
191 
192   if (send_complete) {
193     osi_free(packet);
194   }
195 }
196 
manufacture_iso_packet_and_then_reassemble(uint16_t event,uint16_t iso_size,const char * data)197 static void manufacture_iso_packet_and_then_reassemble(uint16_t event, uint16_t iso_size,
198                                                        const char* data) {
199   uint16_t data_length = strlen(data);
200   uint16_t total_length;
201   uint16_t length_sent = 0;
202   uint16_t iso_length = data_length;
203   BT_HDR* packet;
204   uint8_t* packet_data;
205   uint8_t hdr_size = 4;  // packet seq, sdu len
206 
207   // ISO length (2), packet seq (2), optional timestamp (4)
208   total_length = data_length + 4;
209   if (iso_has_ts) {
210     total_length += 4;
211   }
212 
213   do {
214     int length_to_send = (length_sent + (iso_size - 4) < total_length)
215                                  ? (iso_size - 4)
216                                  : (total_length - length_sent);
217 
218     packet = (BT_HDR*)osi_malloc(length_to_send + 4 + sizeof(BT_HDR));
219     packet_data = packet->data;
220     packet->len = length_to_send + 4;
221     packet->offset = 0;
222     packet->event = event;
223     packet->layer_specific = 0;
224 
225     bool is_complete = length_to_send == total_length;
226 
227     if (length_sent == 0) {  // first packet
228       if (iso_has_ts) {
229         hdr_size += 4;
230         if (is_complete) {
231           UINT16_TO_STREAM(packet_data, test_iso_handle_complete_with_ts);
232         } else {
233           UINT16_TO_STREAM(packet_data, test_iso_handle_start_with_ts);
234         }
235       } else {
236         if (is_complete) {
237           UINT16_TO_STREAM(packet_data, test_iso_handle_complete_without_ts);
238         } else {
239           UINT16_TO_STREAM(packet_data, test_iso_handle_start_without_ts);
240         }
241       }
242 
243       UINT16_TO_STREAM(packet_data, length_to_send);
244 
245       if (iso_has_ts) {
246         UINT32_TO_STREAM(packet_data, iso_timestamp);
247       }
248 
249       UINT16_TO_STREAM(packet_data, iso_packet_seq);
250       UINT16_TO_STREAM(packet_data, iso_length);
251       memcpy(packet_data, data, length_to_send - hdr_size);
252     } else {
253       if (length_sent + length_to_send == total_length) {
254         UINT16_TO_STREAM(packet_data, test_iso_handle_end);
255       } else {
256         UINT16_TO_STREAM(packet_data, test_iso_handle_continuation);
257       }
258       UINT16_TO_STREAM(packet_data, length_to_send);
259       memcpy(packet_data, data + length_sent - hdr_size, length_to_send);
260     }
261 
262     length_sent += length_to_send;
263     fragmenter->reassemble_and_dispatch(packet);
264   } while (length_sent < total_length);
265 }
266 
manufacture_packet_and_then_reassemble(uint16_t event,uint16_t packet_size,const char * data)267 static void manufacture_packet_and_then_reassemble(uint16_t event, uint16_t packet_size,
268                                                    const char* data) {
269   uint16_t data_length = strlen(data);
270 
271   if (event == MSG_HC_TO_STACK_HCI_ISO) {
272     manufacture_iso_packet_and_then_reassemble(event, packet_size, data);
273   } else {
274     BT_HDR* packet = (BT_HDR*)osi_malloc(data_length + sizeof(BT_HDR));
275     packet->len = data_length;
276     packet->offset = 0;
277     packet->event = event;
278     packet->layer_specific = 0;
279     memcpy(packet->data, data, data_length);
280 
281     fragmenter->reassemble_and_dispatch(packet);
282   }
283 }
284 
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)285 static void expect_packet_reassembled_iso(uint16_t event, BT_HDR* packet, const char* expected_data,
286                                           uint32_t expected_timestamp, 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_NE(0, (packet->layer_specific & BT_ISO_HDR_CONTAINS_TS));
304     ASSERT_EQ(timestamp, expected_timestamp);
305     ASSERT_EQ(is_complete ? test_iso_handle_complete_with_ts : test_iso_handle_start_with_ts,
306               handle);
307   } else {
308     ASSERT_EQ(0, (packet->layer_specific & BT_ISO_HDR_CONTAINS_TS));
309     ASSERT_EQ(is_complete ? test_iso_handle_complete_without_ts : test_iso_handle_start_without_ts,
310               handle);
311     hdr_size -= 4;
312   }
313 
314   ASSERT_EQ(expected_data_length + hdr_size, length);
315 
316   STREAM_TO_UINT16(packet_seq, data);
317   ASSERT_EQ(packet_seq, expected_packet_seq);
318 
319   STREAM_TO_UINT16(iso_length, data);
320   ASSERT_EQ(expected_data_length, iso_length);
321 
322   for (int i = 0; i < expected_data_length; i++) {
323     ASSERT_EQ(expected_data[i], data[i]);
324     data_size_sum++;
325   }
326 
327   osi_free(packet);
328 }
329 
330 STUB_FUNCTION(void, fragmented_callback, (BT_HDR * packet, bool send_complete))
DURING(iso_fragmentation)331 DURING(iso_fragmentation) {
332   expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ISO, 10, packet, sample_data, send_complete);
333   return;
334 }
335 
DURING(iso_no_fragmentation)336 DURING(iso_no_fragmentation) {
337   expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ISO, 42, packet, small_sample_data, send_complete);
338   return;
339 }
340 
341 UNEXPECTED_CALL;
342 }
343 
344 STUB_FUNCTION(void, reassembled_callback, (BT_HDR * packet))
345 DURING(iso_reassembly) AT_CALL(0) {
346   expect_packet_reassembled_iso(MSG_HC_TO_STACK_HCI_ISO, packet, sample_data, iso_timestamp,
347                                 iso_packet_seq);
348   return;
349 }
350 
351 DURING(iso_no_reassembly) AT_CALL(0) {
352   expect_packet_reassembled_iso(MSG_HC_TO_STACK_HCI_ISO, packet, small_sample_data, iso_timestamp,
353                                 iso_packet_seq, true);
354   return;
355 }
356 
357 UNEXPECTED_CALL;
358 }
359 
360 STUB_FUNCTION(uint16_t, get_iso_data_size, (void))
361 DURING(iso_no_fragmentation) return 42;
362 DURING(iso_fragmentation) return 10;
363 
364 UNEXPECTED_CALL;
365 return 0;
366 }
367 
368 static void reset_for(TEST_MODES_T next) {
369   RESET_CALL_COUNT(fragmented_callback);
370   RESET_CALL_COUNT(reassembled_callback);
371   CURRENT_TEST_MODE = next;
372 }
373 
374 class PacketFragmenterTest : public ::testing::Test {
375 protected:
376   void SetUp() override {
377     fragmenter = packet_fragmenter_get_interface();
378 
379     packet_index = 0;
380     data_size_sum = 0;
381 
382     callbacks.fragmented = fragmented_callback;
383     callbacks.reassembled = reassembled_callback;
384     reset_for(init);
385     fragmenter->init(&callbacks);
386   }
387 
388   void TearDown() override { fragmenter->cleanup(); }
389 
390   packet_fragmenter_callbacks_t callbacks;
391 };
392 
393 TEST_F(PacketFragmenterTest, test_iso_fragment_necessary) {
394   reset_for(iso_fragmentation);
395   iso_has_ts = true;
396 
397   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, sample_data);
398   packet->event |= LOCAL_BLE_CONTROLLER_ID;
399   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
400 
401   ASSERT_EQ(strlen(sample_data), data_size_sum);
402 }
403 
404 TEST_F(PacketFragmenterTest, test_iso_no_fragment_necessary) {
405   reset_for(iso_no_fragmentation);
406   iso_has_ts = true;
407 
408   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, small_sample_data);
409   packet->event |= LOCAL_BLE_CONTROLLER_ID;
410   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
411 
412   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
413 }
414 
415 TEST_F(PacketFragmenterTest, test_iso_fragment_necessary_no_ts) {
416   reset_for(iso_fragmentation);
417   iso_has_ts = false;
418   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, sample_data);
419   packet->event |= LOCAL_BLE_CONTROLLER_ID;
420   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
421 
422   ASSERT_EQ(strlen(sample_data), data_size_sum);
423 }
424 
425 TEST_F(PacketFragmenterTest, test_iso_no_fragment_necessary_no_ts) {
426   reset_for(iso_no_fragmentation);
427   iso_has_ts = false;
428   BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ISO, small_sample_data);
429   packet->event |= LOCAL_BLE_CONTROLLER_ID;
430   fragmenter->fragment_and_dispatch(packet, get_iso_data_size());
431 
432   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
433 }
434 
435 TEST_F(PacketFragmenterTest, test_iso_no_reassembly_necessary) {
436   reset_for(iso_no_reassembly);
437   iso_has_ts = true;
438   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, 50, small_sample_data);
439 
440   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
441   EXPECT_CALL_COUNT(reassembled_callback, 1);
442 }
443 
444 TEST_F(PacketFragmenterTest, test_iso_reassembly_necessary) {
445   reset_for(iso_reassembly);
446   iso_has_ts = true;
447   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, 42, sample_data);
448 
449   ASSERT_EQ(strlen(sample_data), data_size_sum);
450   EXPECT_CALL_COUNT(reassembled_callback, 1);
451 }
452 
453 TEST_F(PacketFragmenterTest, test_iso_no_reassembly_necessary_no_ts) {
454   reset_for(iso_no_reassembly);
455   iso_has_ts = false;
456   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, (42 + 4), small_sample_data);
457 
458   ASSERT_EQ(strlen(small_sample_data), data_size_sum);
459   EXPECT_CALL_COUNT(reassembled_callback, 1);
460 }
461 
462 TEST_F(PacketFragmenterTest, test_iso_reassembly_necessary_no_ts) {
463   reset_for(iso_reassembly);
464   iso_has_ts = false;
465   manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ISO, 42, sample_data);
466 
467   ASSERT_EQ(strlen(sample_data), data_size_sum);
468   EXPECT_CALL_COUNT(reassembled_callback, 1);
469 }
470