1/******************************************************************************
2 *
3 *  Copyright (C) 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
32DECLARE_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
39static 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
54static const char* small_sample_data = "\"What giants?\" said Sancho Panza.";
55static const uint16_t test_handle_start = (0x1992 & 0xCFFF) | 0x2000;
56static const uint16_t test_handle_continuation = (0x1992 & 0xCFFF) | 0x1000;
57static int packet_index;
58static unsigned int data_size_sum;
59
60static const packet_fragmenter_t* fragmenter;
61
62static 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
86static 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
130static 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
179static 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
206STUB_FUNCTION(void, fragmented_callback, (BT_HDR * packet, bool send_complete))
207DURING(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
213DURING(fragmentation) {
214  expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ACL, 10, packet, sample_data,
215                           send_complete);
216  return;
217}
218
219DURING(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
225DURING(ble_fragmentation) {
226  expect_packet_fragmented(MSG_STACK_TO_HC_HCI_ACL, 10, packet, sample_data,
227                           send_complete);
228  return;
229}
230
231DURING(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
237UNEXPECTED_CALL;
238}
239
240STUB_FUNCTION(void, reassembled_callback, (BT_HDR * packet))
241DURING(no_reassembly) AT_CALL(0) {
242  expect_packet_reassembled(MSG_HC_TO_STACK_HCI_ACL, packet, small_sample_data);
243  return;
244}
245
246DURING(reassembly) AT_CALL(0) {
247  expect_packet_reassembled(MSG_HC_TO_STACK_HCI_ACL, packet, sample_data);
248  return;
249}
250
251DURING(non_acl_passthrough_reassembly) AT_CALL(0) {
252  expect_packet_reassembled(MSG_HC_TO_STACK_HCI_EVT, packet, sample_data);
253  return;
254}
255
256UNEXPECTED_CALL;
257}
258
259STUB_FUNCTION(void, transmit_finished_callback,
260              (UNUSED_ATTR BT_HDR * packet,
261               UNUSED_ATTR bool sent_all_fragments))
262UNEXPECTED_CALL;
263}
264
265STUB_FUNCTION(uint16_t, get_acl_data_size_classic, (void))
266DURING(no_fragmentation, non_acl_passthrough_fragmentation, no_reassembly)
267return 42;
268DURING(fragmentation) return 10;
269DURING(no_reassembly) return 1337;
270
271UNEXPECTED_CALL;
272return 0;
273}
274
275STUB_FUNCTION(uint16_t, get_acl_data_size_ble, (void))
276DURING(ble_no_fragmentation) return 42;
277DURING(ble_fragmentation) return 10;
278
279UNEXPECTED_CALL;
280return 0;
281}
282
283static 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
292class 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
321TEST_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
331TEST_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
340TEST_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
351TEST_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
361TEST_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
371TEST_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
380TEST_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
389TEST_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