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