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