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 #define LOG_TAG "bt_headless"
18 
19 #include <dlfcn.h>  //  dlopen
20 #include <algorithm>
21 #include <iostream>
22 #include <map>
23 
24 #include "base/logging.h"  // LOG() stdout and android log
25 #include "include/hardware/bluetooth.h"
26 #include "osi/include/log.h"  // android log only
27 #include "test/headless/get_options.h"
28 #include "test/headless/headless.h"
29 #include "test/headless/interface.h"
30 
31 extern bt_interface_t bluetoothInterface;
32 
33 using namespace bluetooth::test::headless;
34 
35 std::map<const std::string, std::list<callback_function_t>>
36     interface_api_callback_map_;
37 
headless_add_callback(const std::string interface_name,callback_function_t function)38 void headless_add_callback(const std::string interface_name,
39                            callback_function_t function) {
40   if (interface_api_callback_map_.find(interface_name) ==
41       interface_api_callback_map_.end()) {
42     interface_api_callback_map_.emplace(interface_name,
43                                         std::list<callback_function_t>());
44   }
45   interface_api_callback_map_[interface_name].push_back(function);
46 }
47 
headless_remove_callback(const std::string interface_name,callback_function_t function)48 void headless_remove_callback(const std::string interface_name,
49                               callback_function_t function) {
50   if (interface_api_callback_map_.find(interface_name) ==
51       interface_api_callback_map_.end()) {
52     ASSERT_LOG(false, "No callbacks registered for interface:%s",
53                interface_name.c_str());
54   }
55   interface_api_callback_map_[interface_name].remove(function);
56 }
57 
58 namespace {
59 std::mutex adapter_state_mutex_;
60 std::condition_variable adapter_state_cv_;
61 bt_state_t bt_state_{BT_STATE_OFF};
62 
adapter_state_changed(bt_state_t state)63 void adapter_state_changed(bt_state_t state) {
64   std::unique_lock<std::mutex> lck(adapter_state_mutex_);
65   bt_state_ = state;
66   adapter_state_cv_.notify_all();
67 }
adapter_properties(bt_status_t status,int num_properties,bt_property_t * properties)68 void adapter_properties(bt_status_t status, int num_properties,
69                         bt_property_t* properties) {
70   LOG_INFO("%s", __func__);
71 }
72 
remote_device_properties(bt_status_t status,RawAddress * bd_addr,int num_properties,bt_property_t * properties)73 void remote_device_properties(bt_status_t status, RawAddress* bd_addr,
74                               int num_properties, bt_property_t* properties) {
75   LOG_INFO("%s", __func__);
76 }
77 
device_found(int num_properties,bt_property_t * properties)78 void device_found(int num_properties, bt_property_t* properties) {
79   LOG_INFO("%s", __func__);
80 }
81 
discovery_state_changed(bt_discovery_state_t state)82 void discovery_state_changed(bt_discovery_state_t state) {
83   LOG_INFO("%s", __func__);
84 }
85 
86 /** Bluetooth Legacy PinKey Request callback */
pin_request(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bool min_16_digit)87 void pin_request(RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
88                  bool min_16_digit) {
89   LOG_INFO("%s", __func__);
90 }
91 
ssp_request(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bt_ssp_variant_t pairing_variant,uint32_t pass_key)92 void ssp_request(RawAddress* remote_bd_addr, bt_bdname_t* bd_name, uint32_t cod,
93                  bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
94   LOG_INFO("%s", __func__);
95 }
96 
97 /** Bluetooth Bond state changed callback */
98 /* Invoked in response to create_bond, cancel_bond or remove_bond */
bond_state_changed(bt_status_t status,RawAddress * remote_bd_addr,bt_bond_state_t state)99 void bond_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
100                         bt_bond_state_t state) {
101   LOG_INFO("%s", __func__);
102 }
103 
104 /** Bluetooth ACL connection state changed callback */
acl_state_changed(bt_status_t status,RawAddress * remote_bd_addr,bt_acl_state_t state,bt_hci_error_code_t hci_reason)105 void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
106                        bt_acl_state_t state, bt_hci_error_code_t hci_reason) {
107   auto callback_list = interface_api_callback_map_.at(__func__);
108   for (auto callback : callback_list) {
109     interface_data_t params{
110         .name = __func__,
111         .params.acl_state_changed.status = status,
112         .params.acl_state_changed.remote_bd_addr = remote_bd_addr,
113         .params.acl_state_changed.state = state,
114         .params.acl_state_changed.hci_reason = hci_reason,
115     };
116     (callback)(params);
117   }
118   LOG_INFO("%s status:%s device:%s state:%s", __func__,
119            bt_status_text(status).c_str(), remote_bd_addr->ToString().c_str(),
120            (state) ? "disconnected" : "connected");
121 }
122 
123 /** Bluetooth Link Quality Report callback */
link_quality_report(uint64_t timestamp,int report_id,int rssi,int snr,int retransmission_count,int packets_not_receive_count,int negative_acknowledgement_count)124 void link_quality_report(uint64_t timestamp, int report_id, int rssi, int snr,
125     int retransmission_count, int packets_not_receive_count,
126     int negative_acknowledgement_count) {
127   LOG_INFO("%s", __func__);
128 }
129 
thread_event(bt_cb_thread_evt evt)130 void thread_event(bt_cb_thread_evt evt) { LOG_INFO("%s", __func__); }
131 
dut_mode_recv(uint16_t opcode,uint8_t * buf,uint8_t len)132 void dut_mode_recv(uint16_t opcode, uint8_t* buf, uint8_t len) {
133   LOG_INFO("%s", __func__);
134 }
135 
le_test_mode(bt_status_t status,uint16_t num_packets)136 void le_test_mode(bt_status_t status, uint16_t num_packets) {
137   LOG_INFO("%s", __func__);
138 }
139 
energy_info(bt_activity_energy_info * energy_info,bt_uid_traffic_t * uid_data)140 void energy_info(bt_activity_energy_info* energy_info,
141                  bt_uid_traffic_t* uid_data) {
142   LOG_INFO("%s", __func__);
143 }
144 
145 bt_callbacks_t bt_callbacks{
146     /** set to sizeof(bt_callbacks_t) */
147     .size = sizeof(bt_callbacks_t),
148     .adapter_state_changed_cb = adapter_state_changed,
149     .adapter_properties_cb = adapter_properties,
150     .remote_device_properties_cb = remote_device_properties,
151     .device_found_cb = device_found,
152     .discovery_state_changed_cb = discovery_state_changed,
153     .pin_request_cb = pin_request,
154     .ssp_request_cb = ssp_request,
155     .bond_state_changed_cb = bond_state_changed,
156     .acl_state_changed_cb = acl_state_changed,
157     .thread_evt_cb = thread_event,
158     .dut_mode_recv_cb = dut_mode_recv,
159     .le_test_mode_cb = le_test_mode,
160     .energy_info_cb = energy_info,
161     .link_quality_report_cb = link_quality_report,
162 };
163 // HAL HARDWARE CALLBACKS
164 
165 // OS CALLOUTS
set_wake_alarm_co(uint64_t delay_millis,bool should_wake,alarm_cb cb,void * data)166 bool set_wake_alarm_co(uint64_t delay_millis, bool should_wake, alarm_cb cb,
167                        void* data) {
168   LOG_INFO("%s", __func__);
169   return true;
170 }
acquire_wake_lock_co(const char * lock_name)171 int acquire_wake_lock_co(const char* lock_name) {
172   LOG_INFO("%s", __func__);
173   return 1;
174 }
175 
release_wake_lock_co(const char * lock_name)176 int release_wake_lock_co(const char* lock_name) {
177   LOG_INFO("%s", __func__);
178   return 0;
179 }
180 
181 bt_os_callouts_t bt_os_callouts{
182     .size = sizeof(bt_os_callouts_t),
183     .set_wake_alarm = set_wake_alarm_co,
184     .acquire_wake_lock = acquire_wake_lock_co,
185     .release_wake_lock = release_wake_lock_co,
186 };
187 }  // namespace
188 
SetUp()189 void HeadlessStack::SetUp() {
190   LOG(INFO) << __func__ << " Entry";
191 
192   const bool start_restricted = false;
193   const bool is_common_criteria_mode = false;
194   const int config_compare_result = 0;
195   const bool is_atv = false;
196   int status = bluetoothInterface.init(
197       &bt_callbacks, start_restricted, is_common_criteria_mode,
198       config_compare_result, StackInitFlags(), is_atv);
199 
200   (status == BT_STATUS_SUCCESS)
201       ? LOG(INFO) << __func__ << " Initialized bluetooth callbacks"
202       : LOG(FATAL) << "Failed to initialize Bluetooth stack";
203 
204   status = bluetoothInterface.set_os_callouts(&bt_os_callouts);
205   (status == BT_STATUS_SUCCESS)
206       ? LOG(INFO) << __func__ << " Initialized os callouts"
207       : LOG(ERROR) << "Failed to set up Bluetooth OS callouts";
208 
209   bluetoothInterface.enable();
210   LOG_INFO("%s HeadlessStack stack has enabled", __func__);
211 
212   std::unique_lock<std::mutex> lck(adapter_state_mutex_);
213   while (bt_state_ != BT_STATE_ON) adapter_state_cv_.wait(lck);
214   LOG_INFO("%s HeadlessStack stack is operational", __func__);
215 }
216 
TearDown()217 void HeadlessStack::TearDown() {
218   LOG_INFO("Stack has disabled");
219   int status = bluetoothInterface.disable();
220 
221   LOG(INFO) << __func__ << " Interface has been disabled status:" << status;
222 
223   bluetoothInterface.cleanup();
224   LOG(INFO) << __func__ << " Cleaned up hal bluetooth library";
225 
226   std::unique_lock<std::mutex> lck(adapter_state_mutex_);
227   while (bt_state_ != BT_STATE_OFF) adapter_state_cv_.wait(lck);
228   LOG_INFO("%s HeadlessStack stack has exited", __func__);
229 }
230