1 /*
2 * Copyright 2022 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 #include "distance_measurement_manager.h"
18
19 #include "bta/include/bta_ras_api.h"
20 #include "btif/include/btif_common.h"
21 #include "hci/distance_measurement_manager.h"
22 #include "hci/hci_packets.h"
23 #include "main/shim/entry.h"
24 #include "main/shim/helpers.h"
25 #include "stack/include/acl_api.h"
26 #include "stack/include/main_thread.h"
27
28 using bluetooth::hci::DistanceMeasurementDetectedAttackLevel;
29 using bluetooth::hci::DistanceMeasurementErrorCode;
30 using bluetooth::hci::DistanceMeasurementMethod;
31 using namespace bluetooth;
32
33 extern tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr);
34
35 class DistanceMeasurementInterfaceImpl : public DistanceMeasurementInterface,
36 public bluetooth::hci::DistanceMeasurementCallbacks,
37 public bluetooth::ras::RasServerCallbacks,
38 public bluetooth::ras::RasClientCallbacks {
39 public:
~DistanceMeasurementInterfaceImpl()40 ~DistanceMeasurementInterfaceImpl() override {}
41
Init()42 void Init() {
43 // Register callback
44 bluetooth::shim::GetDistanceMeasurementManager()->RegisterDistanceMeasurementCallbacks(this);
45 do_in_main_thread(base::BindOnce(&bluetooth::ras::RasServer::RegisterCallbacks,
46 base::Unretained(bluetooth::ras::GetRasServer()), this));
47 do_in_main_thread(base::BindOnce(&bluetooth::ras::RasClient::RegisterCallbacks,
48 base::Unretained(bluetooth::ras::GetRasClient()), this));
49 }
50
51 /**
52 * Gets the BLE connection handle, must be called from main_thread.
53 * @param bd_addr could be random, rpa or identity address.
54 * @return BLE ACL handle
55 */
GetConnectionHandleAndRole(const RawAddress & bd_addr,hci::Role * hci_role=nullptr)56 static uint16_t GetConnectionHandleAndRole(const RawAddress& bd_addr,
57 hci::Role* hci_role = nullptr) {
58 tBTM_SEC_DEV_REC* p_sec_dev_rec = btm_find_dev(bd_addr);
59 if (p_sec_dev_rec != nullptr) {
60 if (hci_role != nullptr) {
61 *hci_role = p_sec_dev_rec->role_central ? hci::Role::CENTRAL : hci::Role::PERIPHERAL;
62 }
63 return p_sec_dev_rec->get_ble_hci_handle();
64 }
65 return kIllegalConnectionHandle;
66 }
67
RegisterDistanceMeasurementCallbacks(::DistanceMeasurementCallbacks * callbacks)68 void RegisterDistanceMeasurementCallbacks(::DistanceMeasurementCallbacks* callbacks) {
69 distance_measurement_callbacks_ = callbacks;
70 }
71
StartDistanceMeasurement(RawAddress identity_addr,uint16_t interval,uint8_t method)72 void StartDistanceMeasurement(RawAddress identity_addr, uint16_t interval, uint8_t method) {
73 do_in_main_thread(base::BindOnce(&DistanceMeasurementInterfaceImpl::DoStartDistanceMeasurement,
74 base::Unretained(this), identity_addr, interval, method));
75 }
76
DoStartDistanceMeasurement(RawAddress identity_addr,uint16_t interval,uint8_t method)77 void DoStartDistanceMeasurement(RawAddress identity_addr, uint16_t interval, uint8_t method) {
78 auto distance_measurement_method = static_cast<DistanceMeasurementMethod>(method);
79 hci::Role local_hci_role;
80 uint16_t connection_handle = GetConnectionHandleAndRole(identity_addr, &local_hci_role);
81 bluetooth::shim::GetDistanceMeasurementManager()->StartDistanceMeasurement(
82 bluetooth::ToGdAddress(identity_addr), connection_handle, local_hci_role, interval,
83 distance_measurement_method);
84 if (distance_measurement_method == DistanceMeasurementMethod::METHOD_CS) {
85 bluetooth::ras::GetRasClient()->Connect(identity_addr);
86 }
87 }
88
StopDistanceMeasurement(RawAddress identity_addr,uint8_t method)89 void StopDistanceMeasurement(RawAddress identity_addr, uint8_t method) {
90 do_in_main_thread(base::BindOnce(&DistanceMeasurementInterfaceImpl::DoStopDistanceMeasurement,
91 base::Unretained(this), identity_addr, method));
92 }
93
DoStopDistanceMeasurement(RawAddress identity_addr,uint8_t method)94 void DoStopDistanceMeasurement(RawAddress identity_addr, uint8_t method) {
95 bluetooth::shim::GetDistanceMeasurementManager()->StopDistanceMeasurement(
96 bluetooth::ToGdAddress(identity_addr), GetConnectionHandleAndRole(identity_addr),
97 static_cast<DistanceMeasurementMethod>(method));
98 }
99
100 // Callbacks of bluetooth::hci::DistanceMeasurementCallbacks
OnDistanceMeasurementStarted(bluetooth::hci::Address address,DistanceMeasurementMethod method)101 void OnDistanceMeasurementStarted(bluetooth::hci::Address address,
102 DistanceMeasurementMethod method) override {
103 do_in_jni_thread(base::BindOnce(&::DistanceMeasurementCallbacks::OnDistanceMeasurementStarted,
104 base::Unretained(distance_measurement_callbacks_),
105 bluetooth::ToRawAddress(address),
106 static_cast<uint8_t>(method)));
107 }
108
OnDistanceMeasurementStopped(bluetooth::hci::Address address,DistanceMeasurementErrorCode reason,DistanceMeasurementMethod method)109 void OnDistanceMeasurementStopped(bluetooth::hci::Address address,
110 DistanceMeasurementErrorCode reason,
111 DistanceMeasurementMethod method) override {
112 do_in_jni_thread(base::BindOnce(&::DistanceMeasurementCallbacks::OnDistanceMeasurementStopped,
113 base::Unretained(distance_measurement_callbacks_),
114 bluetooth::ToRawAddress(address), static_cast<uint8_t>(reason),
115 static_cast<uint8_t>(method)));
116 }
117
OnDistanceMeasurementResult(bluetooth::hci::Address address,uint32_t centimeter,uint32_t error_centimeter,int azimuth_angle,int error_azimuth_angle,int altitude_angle,int error_altitude_angle,uint64_t elapsed_realtime_nanos,int8_t confidence_level,double delay_spread_meters,DistanceMeasurementDetectedAttackLevel detected_attack_level,double velocity_meters_per_second,DistanceMeasurementMethod method)118 void OnDistanceMeasurementResult(bluetooth::hci::Address address, uint32_t centimeter,
119 uint32_t error_centimeter, int azimuth_angle,
120 int error_azimuth_angle, int altitude_angle,
121 int error_altitude_angle, uint64_t elapsed_realtime_nanos,
122 int8_t confidence_level, double delay_spread_meters,
123 DistanceMeasurementDetectedAttackLevel detected_attack_level,
124 double velocity_meters_per_second,
125 DistanceMeasurementMethod method) override {
126 do_in_jni_thread(base::BindOnce(
127 &::DistanceMeasurementCallbacks::OnDistanceMeasurementResult,
128 base::Unretained(distance_measurement_callbacks_), bluetooth::ToRawAddress(address),
129 centimeter, error_centimeter, azimuth_angle, error_azimuth_angle, altitude_angle,
130 error_altitude_angle, elapsed_realtime_nanos, confidence_level, delay_spread_meters,
131 static_cast<uint8_t>(detected_attack_level), velocity_meters_per_second,
132 static_cast<uint8_t>(method)));
133 }
134
OnRasFragmentReady(bluetooth::hci::Address address,uint16_t procedure_counter,bool is_last,std::vector<uint8_t> raw_data)135 void OnRasFragmentReady(bluetooth::hci::Address address, uint16_t procedure_counter, bool is_last,
136 std::vector<uint8_t> raw_data) override {
137 do_in_main_thread(base::BindOnce(&bluetooth::ras::RasServer::PushProcedureData,
138 base::Unretained(bluetooth::ras::GetRasServer()),
139 bluetooth::ToRawAddress(address), procedure_counter, is_last,
140 std::move(raw_data)));
141 }
142
OnVendorSpecificCharacteristics(std::vector<bluetooth::hal::VendorSpecificCharacteristic> vendor_specific_characteristics)143 void OnVendorSpecificCharacteristics(std::vector<bluetooth::hal::VendorSpecificCharacteristic>
144 vendor_specific_characteristics) override {
145 std::vector<bluetooth::ras::VendorSpecificCharacteristic> ras_vendor_specific_characteristics;
146 for (auto& characteristic : vendor_specific_characteristics) {
147 bluetooth::ras::VendorSpecificCharacteristic vendor_specific_characteristic;
148 vendor_specific_characteristic.characteristicUuid_ =
149 bluetooth::Uuid::From128BitBE(characteristic.characteristicUuid_);
150 vendor_specific_characteristic.value_ = characteristic.value_;
151 ras_vendor_specific_characteristics.emplace_back(vendor_specific_characteristic);
152 }
153 do_in_main_thread(base::BindOnce(&bluetooth::ras::RasServer::SetVendorSpecificCharacteristic,
154 base::Unretained(bluetooth::ras::GetRasServer()),
155 std::move(ras_vendor_specific_characteristics)));
156 }
157
OnVendorSpecificReply(bluetooth::hci::Address address,std::vector<bluetooth::hal::VendorSpecificCharacteristic> vendor_specific_characteristics)158 void OnVendorSpecificReply(bluetooth::hci::Address address,
159 std::vector<bluetooth::hal::VendorSpecificCharacteristic>
160 vendor_specific_characteristics) override {
161 std::vector<bluetooth::ras::VendorSpecificCharacteristic> ras_vendor_specific_characteristics;
162 for (auto& characteristic : vendor_specific_characteristics) {
163 bluetooth::ras::VendorSpecificCharacteristic vendor_specific_characteristic;
164 vendor_specific_characteristic.characteristicUuid_ =
165 bluetooth::Uuid::From128BitBE(characteristic.characteristicUuid_);
166 vendor_specific_characteristic.value_ = characteristic.value_;
167 ras_vendor_specific_characteristics.emplace_back(vendor_specific_characteristic);
168 }
169 do_in_main_thread(base::BindOnce(&bluetooth::ras::RasClient::SendVendorSpecificReply,
170 base::Unretained(bluetooth::ras::GetRasClient()),
171 bluetooth::ToRawAddress(address),
172 std::move(ras_vendor_specific_characteristics)));
173 }
174
OnHandleVendorSpecificReplyComplete(bluetooth::hci::Address address,bool success)175 void OnHandleVendorSpecificReplyComplete(bluetooth::hci::Address address, bool success) override {
176 do_in_main_thread(base::BindOnce(&bluetooth::ras::RasServer::HandleVendorSpecificReplyComplete,
177 base::Unretained(bluetooth::ras::GetRasServer()),
178 bluetooth::ToRawAddress(address), success));
179 }
180
181 // Must be called from main_thread
182 // Callbacks of bluetooth::ras::RasServerCallbacks
OnVendorSpecificReply(const RawAddress & address,const std::vector<bluetooth::ras::VendorSpecificCharacteristic> & vendor_specific_reply)183 void OnVendorSpecificReply(const RawAddress& address,
184 const std::vector<bluetooth::ras::VendorSpecificCharacteristic>&
185 vendor_specific_reply) override {
186 std::vector<bluetooth::hal::VendorSpecificCharacteristic> hal_vendor_specific_characteristics;
187 for (auto& characteristic : vendor_specific_reply) {
188 bluetooth::hal::VendorSpecificCharacteristic vendor_specific_characteristic;
189 vendor_specific_characteristic.characteristicUuid_ =
190 characteristic.characteristicUuid_.To128BitBE();
191 vendor_specific_characteristic.value_ = characteristic.reply_value_;
192 hal_vendor_specific_characteristics.emplace_back(vendor_specific_characteristic);
193 }
194 bluetooth::shim::GetDistanceMeasurementManager()->HandleVendorSpecificReply(
195 bluetooth::ToGdAddress(address), GetConnectionHandleAndRole(address),
196 hal_vendor_specific_characteristics);
197 }
198
199 // Must be called from main_thread
200 // Callbacks of bluetooth::ras::RasServerCallbacks
OnRasServerConnected(const RawAddress & identity_address)201 void OnRasServerConnected(const RawAddress& identity_address) override {
202 hci::Role local_hci_role;
203 uint16_t connection_handle = GetConnectionHandleAndRole(identity_address, &local_hci_role);
204 bluetooth::shim::GetDistanceMeasurementManager()->HandleRasServerConnected(
205 bluetooth::ToGdAddress(identity_address), connection_handle, local_hci_role);
206 }
207
208 // Must be called from main_thread
209 // Callbacks of bluetooth::ras::RasServerCallbacks
OnMtuChangedFromServer(const RawAddress & address,uint16_t mtu)210 void OnMtuChangedFromServer(const RawAddress& address, uint16_t mtu) override {
211 handle_mtu_changed(address, mtu);
212 }
213
OnMtuChangedFromClient(const RawAddress & address,uint16_t mtu)214 void OnMtuChangedFromClient(const RawAddress& address, uint16_t mtu) override {
215 handle_mtu_changed(address, mtu);
216 }
217
handle_mtu_changed(const RawAddress & address,uint16_t mtu)218 void handle_mtu_changed(const RawAddress& address, uint16_t mtu) {
219 uint16_t connection_handle = GetConnectionHandleAndRole(address);
220 bluetooth::shim::GetDistanceMeasurementManager()->HandleMtuChanged(connection_handle, mtu);
221 }
222
223 // Must be called from main_thread
224 // Callbacks of bluetooth::ras::RasSeverCallbacks
OnRasServerDisconnected(const RawAddress & identity_address)225 void OnRasServerDisconnected(const RawAddress& identity_address) override {
226 bluetooth::shim::GetDistanceMeasurementManager()->HandleRasServerDisconnected(
227 bluetooth::ToGdAddress(identity_address), GetConnectionHandleAndRole(identity_address));
228 }
229
230 // Must be called from main_thread
231 // Callbacks of bluetooth::ras::RasClientCallbacks
OnConnected(const RawAddress & address,uint16_t att_handle,const std::vector<bluetooth::ras::VendorSpecificCharacteristic> & vendor_specific_characteristics,uint16_t conn_interval)232 void OnConnected(const RawAddress& address, uint16_t att_handle,
233 const std::vector<bluetooth::ras::VendorSpecificCharacteristic>&
234 vendor_specific_characteristics,
235 uint16_t conn_interval) override {
236 std::vector<bluetooth::hal::VendorSpecificCharacteristic> hal_vendor_specific_characteristics;
237 for (auto& characteristic : vendor_specific_characteristics) {
238 bluetooth::hal::VendorSpecificCharacteristic vendor_specific_characteristic;
239 vendor_specific_characteristic.characteristicUuid_ =
240 characteristic.characteristicUuid_.To128BitBE();
241 vendor_specific_characteristic.value_ = characteristic.value_;
242 hal_vendor_specific_characteristics.emplace_back(vendor_specific_characteristic);
243 }
244
245 bluetooth::shim::GetDistanceMeasurementManager()->HandleRasClientConnectedEvent(
246 bluetooth::ToGdAddress(address), GetConnectionHandleAndRole(address), att_handle,
247 hal_vendor_specific_characteristics, conn_interval);
248 }
249
OnConnIntervalUpdated(const RawAddress & address,uint16_t conn_interval)250 void OnConnIntervalUpdated(const RawAddress& address, uint16_t conn_interval) {
251 bluetooth::shim::GetDistanceMeasurementManager()->HandleConnIntervalUpdated(
252 bluetooth::ToGdAddress(address), GetConnectionHandleAndRole(address), conn_interval);
253 }
254
OnDisconnected(const RawAddress & address,const ras::RasDisconnectReason & ras_disconnect_reason)255 void OnDisconnected(const RawAddress& address,
256 const ras::RasDisconnectReason& ras_disconnect_reason) {
257 bluetooth::shim::GetDistanceMeasurementManager()->HandleRasClientDisconnectedEvent(
258 bluetooth::ToGdAddress(address), ras_disconnect_reason);
259 }
260
261 // Must be called from main_thread
OnWriteVendorSpecificReplyComplete(const RawAddress & address,bool success)262 void OnWriteVendorSpecificReplyComplete(const RawAddress& address, bool success) {
263 bluetooth::shim::GetDistanceMeasurementManager()->HandleVendorSpecificReplyComplete(
264 bluetooth::ToGdAddress(address), GetConnectionHandleAndRole(address), success);
265 }
266
267 // Must be called from main_thread
OnRemoteData(const RawAddress & address,const std::vector<uint8_t> & data)268 void OnRemoteData(const RawAddress& address, const std::vector<uint8_t>& data) {
269 bluetooth::shim::GetDistanceMeasurementManager()->HandleRemoteData(
270 bluetooth::ToGdAddress(address), GetConnectionHandleAndRole(address), data);
271 }
272
273 // Must be called from main_thread
OnRemoteDataTimeout(const RawAddress & address)274 void OnRemoteDataTimeout(const RawAddress& address) {
275 bluetooth::shim::GetDistanceMeasurementManager()->HandleRemoteDataTimeout(
276 bluetooth::ToGdAddress(address), GetConnectionHandleAndRole(address));
277 }
278
279 private:
280 ::DistanceMeasurementCallbacks* distance_measurement_callbacks_;
281 static constexpr uint16_t kIllegalConnectionHandle = 0xffff;
282 };
283
284 DistanceMeasurementInterfaceImpl* distance_measurement_instance = nullptr;
285
init_distance_measurement_manager()286 void bluetooth::shim::init_distance_measurement_manager() {
287 static_cast<DistanceMeasurementInterfaceImpl*>(
288 bluetooth::shim::get_distance_measurement_instance())
289 ->Init();
290 }
291
get_distance_measurement_instance()292 DistanceMeasurementInterface* bluetooth::shim::get_distance_measurement_instance() {
293 if (distance_measurement_instance == nullptr) {
294 distance_measurement_instance = new DistanceMeasurementInterfaceImpl();
295 }
296 return distance_measurement_instance;
297 }
298