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