1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <base/logging.h>
18 #include <gtest/gtest.h>
19 #include <stdint.h>
20 
21 #include "common/message_loop_thread.h"
22 #include "hci/src/hci_layer.cc"
23 #include "hci_internals.h"
24 #include "osi/include/allocator.h"
25 #include "osi/include/osi.h"
26 #include "osi/test/AllocationTestHarness.h"
27 #include "osi/test/test_stubs.h"
28 #include "stack/include/bt_types.h"
29 #include "stack/include/hcidefs.h"
30 
31 extern void allocation_tracker_uninit(void);
32 
33 allocator_t buffer_allocator_ = {
34     .alloc = osi_malloc,
35     .free = osi_free,
36 };
37 
monitor_socket(int ctrl_fd,int fd)38 void monitor_socket(int ctrl_fd, int fd) {
39   LOG(INFO) << __func__ << " UNIMPLEMENTED";
40 }
hci_initialize()41 void hci_initialize() { LOG(INFO) << __func__ << " UNIMPLEMENTED"; }
hci_close()42 void hci_close() { LOG(INFO) << __func__ << " UNIMPLEMENTED"; }
hci_transmit(BT_HDR * packet)43 void hci_transmit(BT_HDR* packet) { LOG(INFO) << __func__ << " UNIMPLEMENTED"; }
hci_open_firmware_log_file()44 int hci_open_firmware_log_file() { return INVALID_FD; }
hci_close_firmware_log_file(int fd)45 void hci_close_firmware_log_file(int fd) {}
hci_log_firmware_debug_packet(int fd,BT_HDR * packet)46 void hci_log_firmware_debug_packet(int fd, BT_HDR* packet) {}
buffer_allocator_get_interface()47 const allocator_t* buffer_allocator_get_interface() {
48   return &buffer_allocator_;
49 }
50 
51 /**
52  * Test class to test selected functionality in hci/src/hci_layer.cc
53  */
54 class HciLayerTest : public AllocationTestHarness {
55  protected:
SetUp()56   void SetUp() override {
57     AllocationTestHarness::SetUp();
58     // Disable our allocation tracker to allow ASAN full range
59     allocation_tracker_uninit();
60     commands_pending_response = list_new(NULL);
61     buffer_allocator = &buffer_allocator_;
62   }
63 
TearDown()64   void TearDown() override {
65     list_free(commands_pending_response);
66     AllocationTestHarness::TearDown();
67   }
68 
AllocateHciEventPacket(size_t packet_length) const69   BT_HDR* AllocateHciEventPacket(size_t packet_length) const {
70     return AllocatePacket(packet_length, MSG_HC_TO_STACK_HCI_EVT);
71   }
72 
GetPayloadPointer(BT_HDR * packet) const73   uint8_t* GetPayloadPointer(BT_HDR* packet) const {
74     return static_cast<uint8_t*>(packet->data);
75   }
76 
77  private:
AllocatePacket(size_t packet_length,uint16_t event) const78   BT_HDR* AllocatePacket(size_t packet_length, uint16_t event) const {
79     BT_HDR* packet =
80         static_cast<BT_HDR*>(osi_calloc(sizeof(BT_HDR) + packet_length));
81     packet->offset = 0;
82     packet->len = packet_length;
83     packet->layer_specific = 0;
84     packet->event = MSG_HC_TO_STACK_HCI_EVT;
85     return packet;
86   }
87 };
88 
TEST_F(HciLayerTest,FilterIncomingEvent)89 TEST_F(HciLayerTest, FilterIncomingEvent) {
90   {
91     BT_HDR* packet = AllocateHciEventPacket(3);
92 
93     auto p = GetPayloadPointer(packet);
94     *p++ = HCI_COMMAND_STATUS_EVT;
95     *p++ = 0x0;  // length
96 
97     CHECK(filter_incoming_event(packet));
98   }
99 
100   {
101     BT_HDR* packet = AllocateHciEventPacket(3);
102 
103     auto p = GetPayloadPointer(packet);
104     *p++ = HCI_COMMAND_STATUS_EVT;
105     *p++ = 0x1;  // length
106     *p++ = 0xff;
107 
108     CHECK(filter_incoming_event(packet));
109   }
110 
111   {
112     BT_HDR* packet = AllocateHciEventPacket(6);
113 
114     auto p = GetPayloadPointer(packet);
115     *p++ = HCI_COMMAND_STATUS_EVT;
116     *p++ = 0x04;  // length
117     *p++ = 0x00;  // status
118     *p++ = 0x01;  // credits
119     *p++ = 0x34;  // opcode0
120     *p++ = 0x12;  // opcode1
121 
122     CHECK(filter_incoming_event(packet));
123   }
124 }
125