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