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