• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)(&params);
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)(&params);
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)(&params);
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