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)(¶ms);
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)(¶ms);
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)(¶ms);
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)(¶ms);
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)(¶ms);
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