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 <gtest/gtest.h>
20
21 #include "AllocationTestHarness.h"
22
23 #include <stdint.h>
24
25 #include "device/include/controller.h"
26 #include "hci_internals.h"
27 #include "osi/include/allocator.h"
28 #include "osi/include/osi.h"
29 #include "packet_fragmenter.h"
30 #include "test_stubs.h"
31
32 DECLARE_TEST_MODES(init, set_data_sizes, no_fragmentation, fragmentation,
33 ble_no_fragmentation, ble_fragmentation,
34 non_acl_passthrough_fragmentation, no_reassembly, reassembly,
35 non_acl_passthrough_reassembly);
36
37 #define LOCAL_BLE_CONTROLLER_ID 1
38
39 static const char* sample_data =
40 "At this point they came in sight of thirty forty windmills that there are "
41 "on plain, and "
42 "as soon as Don Quixote saw them he said to his squire, \"Fortune is "
43 "arranging matters "
44 "for us better than we could have shaped our desires ourselves, for look "
45 "there, friend "
46 "Sancho Panza, where thirty or more monstrous giants present themselves, "
47 "all of whom I "
48 "mean to engage in battle and slay, and with whose spoils we shall begin "
49 "to make our "
50 "fortunes; for this is righteous warfare, and it is God's good service to "
51 "sweep so evil "
52 "a breed from off the face of the earth.\"";
53
54 static const char* small_sample_data = "\"What giants?\" said Sancho Panza.";
55 static const uint16_t test_handle_start = (0x1992 & 0xCFFF) | 0x2000;
56 static const uint16_t test_handle_continuation = (0x1992 & 0xCFFF) | 0x1000;
57 static int packet_index;
58 static unsigned int data_size_sum;
59
60 static const packet_fragmenter_t* fragmenter;
61
manufacture_packet_for_fragmentation(uint16_t event,const char * data)62 static BT_HDR* manufacture_packet_for_fragmentation(uint16_t event,
63 const char* data) {
64 uint16_t data_length = strlen(data);
65 uint16_t size = data_length;
66 if (event == MSG_STACK_TO_HC_HCI_ACL) {
67 size += 4; // 2 for the handle, 2 for the length;
68 }
69
70 BT_HDR* packet = (BT_HDR*)osi_malloc(size + sizeof(BT_HDR));
71 packet->len = size;
72 packet->offset = 0;
73 packet->event = event;
74 packet->layer_specific = 0;
75 uint8_t* packet_data = packet->data;
76
77 if (event == MSG_STACK_TO_HC_HCI_ACL) {
78 UINT16_TO_STREAM(packet_data, test_handle_start);
79 UINT16_TO_STREAM(packet_data, data_length);
80 }
81
82 memcpy(packet_data, data, data_length);
83 return packet;
84 }
85
expect_packet_fragmented(uint16_t event,int max_acl_data_size,BT_HDR * packet,const char * expected_data,bool send_complete)86 static void expect_packet_fragmented(uint16_t event, int max_acl_data_size,
87 BT_HDR* packet, const char* expected_data,
88 bool send_complete) {
89 uint8_t* data = packet->data + packet->offset;
90 int expected_data_offset;
91 int length_to_check;
92
93 if (event == MSG_STACK_TO_HC_HCI_ACL) {
94 uint16_t handle;
95 uint16_t length;
96 STREAM_TO_UINT16(handle, data);
97 STREAM_TO_UINT16(length, data);
98
99 if (packet_index == 0)
100 EXPECT_EQ(test_handle_start, handle);
101 else
102 EXPECT_EQ(test_handle_continuation, handle);
103
104 int length_remaining = strlen(expected_data) - data_size_sum;
105 int packet_data_length = packet->len - HCI_ACL_PREAMBLE_SIZE;
106 EXPECT_EQ(packet_data_length, length);
107
108 if (length_remaining > max_acl_data_size)
109 EXPECT_EQ(max_acl_data_size, packet_data_length);
110
111 length_to_check = packet_data_length;
112 expected_data_offset = packet_index * max_acl_data_size;
113 packet_index++;
114 } else {
115 length_to_check = strlen(expected_data);
116 expected_data_offset = 0;
117 }
118
119 for (int i = 0; i < length_to_check; i++) {
120 EXPECT_EQ(expected_data[expected_data_offset + i], data[i]);
121 data_size_sum++;
122 }
123
124 if (event == MSG_STACK_TO_HC_HCI_ACL)
125 EXPECT_TRUE(send_complete == (data_size_sum == strlen(expected_data)));
126
127 if (send_complete) osi_free(packet);
128 }
129
manufacture_packet_and_then_reassemble(uint16_t event,uint16_t acl_size,const char * data)130 static void manufacture_packet_and_then_reassemble(uint16_t event,
131 uint16_t acl_size,
132 const char* data) {
133 uint16_t data_length = strlen(data);
134
135 if (event == MSG_HC_TO_STACK_HCI_ACL) {
136 uint16_t total_length = data_length + 2; // 2 for l2cap length;
137 uint16_t length_sent = 0;
138 uint16_t l2cap_length = data_length - 2; // l2cap length field, 2 for the
139 // pretend channel id borrowed
140 // from the data
141
142 do {
143 int length_to_send = (length_sent + (acl_size - 4) < total_length)
144 ? (acl_size - 4)
145 : (total_length - length_sent);
146 BT_HDR* packet = (BT_HDR*)osi_malloc(length_to_send + 4 + sizeof(BT_HDR));
147 packet->len = length_to_send + 4;
148 packet->offset = 0;
149 packet->event = event;
150 packet->layer_specific = 0;
151
152 uint8_t* packet_data = packet->data;
153 if (length_sent == 0) { // first packet
154 UINT16_TO_STREAM(packet_data, test_handle_start);
155 UINT16_TO_STREAM(packet_data, length_to_send);
156 UINT16_TO_STREAM(packet_data, l2cap_length);
157 memcpy(packet_data, data, length_to_send - 2);
158 } else {
159 UINT16_TO_STREAM(packet_data, test_handle_continuation);
160 UINT16_TO_STREAM(packet_data, length_to_send);
161 memcpy(packet_data, data + length_sent - 2, length_to_send);
162 }
163
164 length_sent += length_to_send;
165 fragmenter->reassemble_and_dispatch(packet);
166 } while (length_sent < total_length);
167 } else {
168 BT_HDR* packet = (BT_HDR*)osi_malloc(data_length + sizeof(BT_HDR));
169 packet->len = data_length;
170 packet->offset = 0;
171 packet->event = event;
172 packet->layer_specific = 0;
173 memcpy(packet->data, data, data_length);
174
175 fragmenter->reassemble_and_dispatch(packet);
176 }
177 }
178
expect_packet_reassembled(uint16_t event,BT_HDR * packet,const char * expected_data)179 static void expect_packet_reassembled(uint16_t event, BT_HDR* packet,
180 const char* expected_data) {
181 uint16_t expected_data_length = strlen(expected_data);
182 uint8_t* data = packet->data + packet->offset;
183
184 if (event == MSG_HC_TO_STACK_HCI_ACL) {
185 uint16_t handle;
186 uint16_t length;
187 uint16_t l2cap_length;
188 STREAM_TO_UINT16(handle, data);
189 STREAM_TO_UINT16(length, data);
190 STREAM_TO_UINT16(l2cap_length, data);
191
192 EXPECT_EQ(test_handle_start, handle);
193 EXPECT_EQ(expected_data_length + 2, length);
194 EXPECT_EQ(expected_data_length - 2,
195 l2cap_length); // -2 for the pretend channel id
196 }
197
198 for (int i = 0; i < expected_data_length; i++) {
199 EXPECT_EQ(expected_data[i], data[i]);
200 data_size_sum++;
201 }
202
203 osi_free(packet);
204 }
205
206 STUB_FUNCTION(void, fragmented_callback, (BT_HDR * packet, bool send_complete))
DURING(no_fragmentation)207 DURING(no_fragmentation) AT_CALL(0) {
208 expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ACL, 42, packet,
209 small_sample_data, send_complete);
210 return;
211 }
212
DURING(fragmentation)213 DURING(fragmentation) {
214 expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ACL, 10, packet, sample_data,
215 send_complete);
216 return;
217 }
218
219 DURING(ble_no_fragmentation) AT_CALL(0) {
220 expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ACL, 42, packet,
221 small_sample_data, send_complete);
222 return;
223 }
224
DURING(ble_fragmentation)225 DURING(ble_fragmentation) {
226 expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ACL, 10, packet, sample_data,
227 send_complete);
228 return;
229 }
230
231 DURING(non_acl_passthrough_fragmentation) AT_CALL(0) {
232 expect_packet_fragmented(MSG_STACK_TO_HC_HCI_CMD, 10, packet, sample_data,
233 send_complete);
234 return;
235 }
236
237 UNEXPECTED_CALL;
238 }
239
240 STUB_FUNCTION(void, reassembled_callback, (BT_HDR * packet))
241 DURING(no_reassembly) AT_CALL(0) {
242 expect_packet_reassembled(MSG_HC_TO_STACK_HCI_ACL, packet, small_sample_data);
243 return;
244 }
245
246 DURING(reassembly) AT_CALL(0) {
247 expect_packet_reassembled(MSG_HC_TO_STACK_HCI_ACL, packet, sample_data);
248 return;
249 }
250
251 DURING(non_acl_passthrough_reassembly) AT_CALL(0) {
252 expect_packet_reassembled(MSG_HC_TO_STACK_HCI_EVT, packet, sample_data);
253 return;
254 }
255
256 UNEXPECTED_CALL;
257 }
258
259 STUB_FUNCTION(void, transmit_finished_callback,
260 (UNUSED_ATTR BT_HDR * packet,
261 UNUSED_ATTR bool sent_all_fragments))
262 UNEXPECTED_CALL;
263 }
264
265 STUB_FUNCTION(uint16_t, get_acl_data_size_classic, (void))
266 DURING(no_fragmentation, non_acl_passthrough_fragmentation, no_reassembly)
267 return 42;
268 DURING(fragmentation) return 10;
269 DURING(no_reassembly) return 1337;
270
271 UNEXPECTED_CALL;
272 return 0;
273 }
274
275 STUB_FUNCTION(uint16_t, get_acl_data_size_ble, (void))
276 DURING(ble_no_fragmentation) return 42;
277 DURING(ble_fragmentation) return 10;
278
279 UNEXPECTED_CALL;
280 return 0;
281 }
282
283 static void reset_for(TEST_MODES_T next) {
284 RESET_CALL_COUNT(fragmented_callback);
285 RESET_CALL_COUNT(reassembled_callback);
286 RESET_CALL_COUNT(transmit_finished_callback);
287 RESET_CALL_COUNT(get_acl_data_size_classic);
288 RESET_CALL_COUNT(get_acl_data_size_ble);
289 CURRENT_TEST_MODE = next;
290 }
291
292 class PacketFragmenterTest : public AllocationTestHarness {
293 protected:
294 virtual void SetUp() {
295 AllocationTestHarness::SetUp();
296 fragmenter =
297 packet_fragmenter_get_test_interface(&controller, &allocator_malloc);
298
299 packet_index = 0;
300 data_size_sum = 0;
301
302 callbacks.fragmented = fragmented_callback;
303 callbacks.reassembled = reassembled_callback;
304 callbacks.transmit_finished = transmit_finished_callback;
305 controller.get_acl_data_size_classic = get_acl_data_size_classic;
306 controller.get_acl_data_size_ble = get_acl_data_size_ble;
307
308 reset_for(init);
309 fragmenter->init(&callbacks);
310 }
311
312 virtual void TearDown() {
313 fragmenter->cleanup();
314 AllocationTestHarness::TearDown();
315 }
316
317 controller_t controller;
318 packet_fragmenter_callbacks_t callbacks;
319 };
320
321 TEST_F(PacketFragmenterTest, test_no_fragment_necessary) {
322 reset_for(no_fragmentation);
323 BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ACL,
324 small_sample_data);
325 fragmenter->fragment_and_dispatch(packet);
326
327 EXPECT_EQ(strlen(small_sample_data), data_size_sum);
328 EXPECT_CALL_COUNT(fragmented_callback, 1);
329 }
330
331 TEST_F(PacketFragmenterTest, test_fragment_necessary) {
332 reset_for(fragmentation);
333 BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ACL,
334 sample_data);
335 fragmenter->fragment_and_dispatch(packet);
336
337 EXPECT_EQ(strlen(sample_data), data_size_sum);
338 }
339
340 TEST_F(PacketFragmenterTest, test_ble_no_fragment_necessary) {
341 reset_for(ble_no_fragmentation);
342 BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ACL,
343 small_sample_data);
344 packet->event |= LOCAL_BLE_CONTROLLER_ID;
345 fragmenter->fragment_and_dispatch(packet);
346
347 EXPECT_EQ(strlen(small_sample_data), data_size_sum);
348 EXPECT_CALL_COUNT(fragmented_callback, 1);
349 }
350
351 TEST_F(PacketFragmenterTest, test_ble_fragment_necessary) {
352 reset_for(ble_fragmentation);
353 BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_ACL,
354 sample_data);
355 packet->event |= LOCAL_BLE_CONTROLLER_ID;
356 fragmenter->fragment_and_dispatch(packet);
357
358 EXPECT_EQ(strlen(sample_data), data_size_sum);
359 }
360
361 TEST_F(PacketFragmenterTest, test_non_acl_passthrough_fragmentation) {
362 reset_for(non_acl_passthrough_fragmentation);
363 BT_HDR* packet = manufacture_packet_for_fragmentation(MSG_STACK_TO_HC_HCI_CMD,
364 sample_data);
365 fragmenter->fragment_and_dispatch(packet);
366
367 EXPECT_EQ(strlen(sample_data), data_size_sum);
368 EXPECT_CALL_COUNT(fragmented_callback, 1);
369 }
370
371 TEST_F(PacketFragmenterTest, test_no_reassembly_necessary) {
372 reset_for(no_reassembly);
373 manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ACL, 1337,
374 small_sample_data);
375
376 EXPECT_EQ(strlen(small_sample_data), data_size_sum);
377 EXPECT_CALL_COUNT(reassembled_callback, 1);
378 }
379
380 TEST_F(PacketFragmenterTest, test_reassembly_necessary) {
381 reset_for(reassembly);
382 manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_ACL, 42,
383 sample_data);
384
385 EXPECT_EQ(strlen(sample_data), data_size_sum);
386 EXPECT_CALL_COUNT(reassembled_callback, 1);
387 }
388
389 TEST_F(PacketFragmenterTest, test_non_acl_passthrough_reasseembly) {
390 reset_for(non_acl_passthrough_reassembly);
391 manufacture_packet_and_then_reassemble(MSG_HC_TO_STACK_HCI_EVT, 42,
392 sample_data);
393
394 EXPECT_EQ(strlen(sample_data), data_size_sum);
395 EXPECT_CALL_COUNT(reassembled_callback, 1);
396 }
397