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 "test/headless/headless.h"
20 
21 #include <bluetooth/log.h>
22 #include <dlfcn.h>  //  dlopen
23 
24 #include <iostream>
25 #include <map>
26 #include <memory>
27 
28 #include "gd/os/log.h"
29 #include "include/hardware/bluetooth.h"
30 #include "test/headless/bt_stack_info.h"
31 #include "test/headless/interface.h"
32 #include "test/headless/log.h"
33 #include "test/headless/messenger.h"
34 #include "types/raw_address.h"
35 
36 //
37 // Aggregate disparate variables from callback API into unified single structure
38 //
39 extern bt_interface_t bluetoothInterface;
40 
41 using namespace bluetooth::test::headless;
42 using namespace bluetooth;
43 
44 namespace {
45 
46 constexpr char kHeadlessIcon[] = "��";
47 
48 std::map<const std::string, std::list<callback_function_t>>
49     interface_api_callback_map_;
50 
51 }  // namespace
52 
headless_add_callback(const std::string interface_name,callback_function_t function)53 void headless_add_callback(const std::string interface_name,
54                            callback_function_t function) {
55   if (interface_api_callback_map_.find(interface_name) ==
56       interface_api_callback_map_.end()) {
57     interface_api_callback_map_.emplace(interface_name,
58                                         std::list<callback_function_t>());
59   }
60   interface_api_callback_map_[interface_name].push_back(function);
61 }
62 
headless_remove_callback(const std::string interface_name)63 void headless_remove_callback(const std::string interface_name) {
64   if (interface_api_callback_map_.find(interface_name) ==
65       interface_api_callback_map_.end()) {
66     log::fatal("No callbacks registered for interface:{}", interface_name);
67   }
68   interface_api_callback_map_.erase(interface_name);
69 }
70 
71 std::mutex adapter_state_mutex_;
72 std::condition_variable adapter_state_cv_;
73 bt_state_t bt_state_{BT_STATE_OFF};
74 
adapter_state_changed(bt_state_t state)75 void adapter_state_changed(bt_state_t state) {
76   std::unique_lock<std::mutex> lck(adapter_state_mutex_);
77   bt_state_ = state;
78   adapter_state_cv_.notify_all();
79 }
adapter_properties(bt_status_t status,int num_properties,::bt_property_t * properties)80 void adapter_properties(bt_status_t status, int num_properties,
81                         ::bt_property_t* properties) {
82   const size_t num_callbacks = interface_api_callback_map_.size();
83   auto callback_list = interface_api_callback_map_.find(__func__);
84   if (callback_list != interface_api_callback_map_.end()) {
85     for (auto callback : callback_list->second) {
86       adapter_properties_params_t params(status, num_properties, properties);
87       (callback)(&params);
88     }
89   }
90   log::info("num_callbacks:{} status:{} num_properties:{} properties:{}",
91             num_callbacks, bt_status_text(status), num_properties,
92             fmt::ptr(properties));
93 }
94 
remote_device_properties(bt_status_t status,RawAddress * bd_addr,int num_properties,::bt_property_t * properties)95 void remote_device_properties(bt_status_t status, RawAddress* bd_addr,
96                               int num_properties, ::bt_property_t* properties) {
97   log::assert_that(bd_addr != nullptr, "assert failed: bd_addr != nullptr");
98   const size_t num_callbacks = interface_api_callback_map_.size();
99   auto callback_list = interface_api_callback_map_.find(__func__);
100   if (callback_list != interface_api_callback_map_.end()) {
101     RawAddress raw_address =
102         (bd_addr != nullptr) ? *bd_addr : RawAddress::kEmpty;
103     for (auto callback : callback_list->second) {
104       remote_device_properties_params_t params(status, raw_address,
105                                                num_properties, properties);
106       (callback)(&params);
107     }
108   }
109   log::info(
110       "num_callbacks:{} status:{} device:{} num_properties:{} properties:{}",
111       num_callbacks, bt_status_text(status), STR(*bd_addr), num_properties,
112       fmt::ptr(properties));
113 }
114 
115 // Aggregate disparate variables from callback API into unified single structure
device_found(int num_properties,::bt_property_t * properties)116 void device_found(int num_properties, ::bt_property_t* properties) {
117   [[maybe_unused]] const size_t num_callbacks =
118       interface_api_callback_map_.size();
119   auto callback_list = interface_api_callback_map_.find(__func__);
120   if (callback_list != interface_api_callback_map_.end()) {
121     for (auto callback : callback_list->second) {
122       device_found_params_t params(num_properties, properties);
123       (callback)(&params);
124     }
125   }
126   log::info("Device found callback: num_properties:{} properties:{}",
127             num_properties, fmt::ptr(properties));
128 }
129 
discovery_state_changed(bt_discovery_state_t state)130 void discovery_state_changed(bt_discovery_state_t state) {
131   auto callback_list = interface_api_callback_map_.find(__func__);
132   if (callback_list != interface_api_callback_map_.end()) {
133     for (auto callback : callback_list->second) {
134       discovery_state_changed_params_t params(state);
135       (callback)(&params);
136     }
137   }
138 }
139 
140 /** Bluetooth Legacy PinKey Request callback */
pin_request(RawAddress * remote_bd_addr,bt_bdname_t * bd_name,uint32_t cod,bool min_16_digit)141 void pin_request([[maybe_unused]] RawAddress* remote_bd_addr,
142                  [[maybe_unused]] bt_bdname_t* bd_name,
143                  [[maybe_unused]] uint32_t cod,
144                  [[maybe_unused]] bool min_16_digit) {
145   log::info("");
146 }
147 
ssp_request(RawAddress * remote_bd_addr,bt_ssp_variant_t pairing_variant,uint32_t pass_key)148 void ssp_request([[maybe_unused]] RawAddress* remote_bd_addr,
149                  [[maybe_unused]] bt_ssp_variant_t pairing_variant,
150                  [[maybe_unused]] uint32_t pass_key) {
151   log::info("");
152 }
153 
154 /** Bluetooth Bond state changed callback */
155 /* 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,int fail_reason)156 void bond_state_changed([[maybe_unused]] bt_status_t status,
157                         [[maybe_unused]] RawAddress* remote_bd_addr,
158                         [[maybe_unused]] bt_bond_state_t state,
159                         [[maybe_unused]] int fail_reason) {
160   log::info("");
161 }
162 
address_consolidate(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)163 void address_consolidate([[maybe_unused]] RawAddress* main_bd_addr,
164                          [[maybe_unused]] RawAddress* secondary_bd_addr) {
165   log::info("");
166 }
167 
le_address_associate(RawAddress * main_bd_addr,RawAddress * secondary_bd_addr)168 void le_address_associate([[maybe_unused]] RawAddress* main_bd_addr,
169                           [[maybe_unused]] RawAddress* secondary_bd_addr) {
170   log::info("");
171 }
172 
173 /** Bluetooth ACL connection state changed callback */
acl_state_changed(bt_status_t status,RawAddress * remote_bd_addr,bt_acl_state_t state,int transport_link_type,bt_hci_error_code_t hci_reason,bt_conn_direction_t direction,uint16_t acl_handle)174 void acl_state_changed(bt_status_t status, RawAddress* remote_bd_addr,
175                        bt_acl_state_t state, int transport_link_type,
176                        bt_hci_error_code_t hci_reason,
177                        bt_conn_direction_t direction, uint16_t acl_handle) {
178   log::assert_that(remote_bd_addr != nullptr,
179                    "assert failed: remote_bd_addr != nullptr");
180   const size_t num_callbacks = interface_api_callback_map_.size();
181   auto callback_list = interface_api_callback_map_.find(__func__);
182   if (callback_list != interface_api_callback_map_.end()) {
183     RawAddress raw_address(*remote_bd_addr);
184     for (auto callback : callback_list->second) {
185       acl_state_changed_params_t params(status, raw_address, state,
186                                         transport_link_type, hci_reason,
187                                         direction, acl_handle);
188       (callback)(&params);
189     }
190   }
191   log::info("num_callbacks:{} status:{} device:{} state:{}", num_callbacks,
192             bt_status_text(status), remote_bd_addr->ToString(),
193             (state) ? "disconnected" : "connected");
194 }
195 
196 /** 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)197 void link_quality_report([[maybe_unused]] uint64_t timestamp,
198                          [[maybe_unused]] int report_id,
199                          [[maybe_unused]] int rssi, [[maybe_unused]] int snr,
200                          [[maybe_unused]] int retransmission_count,
201                          [[maybe_unused]] int packets_not_receive_count,
202                          [[maybe_unused]] int negative_acknowledgement_count) {
203   log::info("");
204 }
205 
206 /** Switch buffer size callback */
switch_buffer_size(bool is_low_latency_buffer_size)207 void switch_buffer_size([[maybe_unused]] bool is_low_latency_buffer_size) {
208   log::info("");
209 }
210 
211 /** Switch codec callback */
switch_codec(bool is_low_latency_buffer_size)212 void switch_codec([[maybe_unused]] bool is_low_latency_buffer_size) {
213   log::info("");
214 }
215 
thread_event(bt_cb_thread_evt evt)216 void thread_event([[maybe_unused]] bt_cb_thread_evt evt) { log::info(""); }
217 
dut_mode_recv(uint16_t opcode,uint8_t * buf,uint8_t len)218 void dut_mode_recv([[maybe_unused]] uint16_t opcode,
219                    [[maybe_unused]] uint8_t* buf,
220                    [[maybe_unused]] uint8_t len) {
221   log::info("");
222 }
223 
le_test_mode(bt_status_t status,uint16_t num_packets)224 void le_test_mode([[maybe_unused]] bt_status_t status,
225                   [[maybe_unused]] uint16_t num_packets) {
226   log::info("");
227 }
228 
energy_info(bt_activity_energy_info * energy_info,bt_uid_traffic_t * uid_data)229 void energy_info([[maybe_unused]] bt_activity_energy_info* energy_info,
230                  [[maybe_unused]] bt_uid_traffic_t* uid_data) {
231   log::info("");
232 }
233 
234 bt_callbacks_t bt_callbacks{
235     /** set to sizeof(bt_callbacks_t) */
236     .size = sizeof(bt_callbacks_t),
237     .adapter_state_changed_cb = adapter_state_changed,
238     .adapter_properties_cb = adapter_properties,
239     .remote_device_properties_cb = remote_device_properties,
240     .device_found_cb = device_found,
241     .discovery_state_changed_cb = discovery_state_changed,
242     .pin_request_cb = pin_request,
243     .ssp_request_cb = ssp_request,
244     .bond_state_changed_cb = bond_state_changed,
245     .address_consolidate_cb = address_consolidate,
246     .le_address_associate_cb = le_address_associate,
247     .acl_state_changed_cb = acl_state_changed,
248     .thread_evt_cb = thread_event,
249     .dut_mode_recv_cb = dut_mode_recv,
250     .le_test_mode_cb = le_test_mode,
251     .energy_info_cb = energy_info,
252     .link_quality_report_cb = link_quality_report,
253     .switch_buffer_size_cb = switch_buffer_size,
254     .switch_codec_cb = switch_codec,
255 };
256 // HAL HARDWARE CALLBACKS
257 
258 // OS CALLOUTS
acquire_wake_lock_co(const char * lock_name)259 int acquire_wake_lock_co([[maybe_unused]] const char* lock_name) {
260   log::info("");
261   return 1;
262 }
263 
release_wake_lock_co(const char * lock_name)264 int release_wake_lock_co([[maybe_unused]] const char* lock_name) {
265   log::info("");
266   return 0;
267 }
268 
269 bt_os_callouts_t bt_os_callouts{
270     .size = sizeof(bt_os_callouts_t),
271     .acquire_wake_lock = acquire_wake_lock_co,
272     .release_wake_lock = release_wake_lock_co,
273 };
274 
SetUp()275 void HeadlessStack::SetUp() {
276   log::info("Entry");
277 
278   const bool start_restricted = false;
279   const bool is_common_criteria_mode = false;
280   const int config_compare_result = 0;
281   const bool is_atv = false;
282 
283   int status = bluetoothInterface.init(
284       &bt_callbacks, start_restricted, is_common_criteria_mode,
285       config_compare_result, StackInitFlags(), is_atv, nullptr);
286 
287   if (status == BT_STATUS_SUCCESS) {
288     log::info("Initialized bluetooth callbacks");
289   } else {
290     log::fatal("Failed to initialize Bluetooth stack");
291   }
292 
293   status = bluetoothInterface.set_os_callouts(&bt_os_callouts);
294   if (status == BT_STATUS_SUCCESS) {
295     log::info("Initialized os callouts");
296   } else {
297     log::error("Failed to set up Bluetooth OS callouts");
298   }
299 
300   bluetoothInterface.enable();
301   log::info("HeadlessStack stack has enabled");
302 
303   std::unique_lock<std::mutex> lck(adapter_state_mutex_);
304   while (bt_state_ != BT_STATE_ON) adapter_state_cv_.wait(lck);
305   log::info("HeadlessStack stack is operational");
306 
307   bt_stack_info_ = std::make_unique<BtStackInfo>();
308 
309   bluetooth::test::headless::start_messenger();
310 
311   LOG_CONSOLE("%s Headless stack has started up successfully", kHeadlessIcon);
312 }
313 
TearDown()314 void HeadlessStack::TearDown() {
315   bluetooth::test::headless::stop_messenger();
316 
317   log::info("Stack has disabled");
318   int status = bluetoothInterface.disable();
319 
320   log::info("Interface has been disabled status:{}", status);
321 
322   bluetoothInterface.cleanup();
323   log::info("Cleaned up hal bluetooth library");
324 
325   std::unique_lock<std::mutex> lck(adapter_state_mutex_);
326   while (bt_state_ != BT_STATE_OFF) adapter_state_cv_.wait(lck);
327   log::info("HeadlessStack stack has exited");
328   LOG_CONSOLE("%s Headless stack has shutdown successfully", kHeadlessIcon);
329 }
330