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