1 /*
2  * Copyright 2024 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 <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSounding.h>
18 #include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSoundingSession.h>
19 #include <aidl/android/hardware/bluetooth/ranging/BnBluetoothChannelSoundingSessionCallback.h>
20 #include <aidl/android/hardware/bluetooth/ranging/IBluetoothChannelSounding.h>
21 #include <android/binder_manager.h>
22 #include <bluetooth/log.h>
23 
24 #include <unordered_map>
25 
26 // AIDL uses syslog.h, so these defines conflict with log/log.h
27 #undef LOG_DEBUG
28 #undef LOG_INFO
29 #undef LOG_WARNING
30 
31 #include "ranging_hal.h"
32 
33 using aidl::android::hardware::bluetooth::ranging::BluetoothChannelSoundingParameters;
34 using aidl::android::hardware::bluetooth::ranging::BnBluetoothChannelSoundingSessionCallback;
35 using aidl::android::hardware::bluetooth::ranging::Ch3cShapeType;
36 using aidl::android::hardware::bluetooth::ranging::ChannelSelectionType;
37 using aidl::android::hardware::bluetooth::ranging::ChannelSoudingRawData;
38 using aidl::android::hardware::bluetooth::ranging::ChannelSoundingProcedureData;
39 using aidl::android::hardware::bluetooth::ranging::ComplexNumber;
40 using aidl::android::hardware::bluetooth::ranging::Config;
41 using aidl::android::hardware::bluetooth::ranging::CsSyncPhyType;
42 using aidl::android::hardware::bluetooth::ranging::IBluetoothChannelSounding;
43 using aidl::android::hardware::bluetooth::ranging::IBluetoothChannelSoundingSession;
44 using aidl::android::hardware::bluetooth::ranging::IBluetoothChannelSoundingSessionCallback;
45 using aidl::android::hardware::bluetooth::ranging::ModeType;
46 using aidl::android::hardware::bluetooth::ranging::ProcedureEnableConfig;
47 using aidl::android::hardware::bluetooth::ranging::Role;
48 using aidl::android::hardware::bluetooth::ranging::RttType;
49 using aidl::android::hardware::bluetooth::ranging::StepTonePct;
50 using aidl::android::hardware::bluetooth::ranging::SubModeType;
51 using aidl::android::hardware::bluetooth::ranging::VendorSpecificData;
52 // using aidl::android::hardware::bluetooth::ranging::
53 
54 using aidl::android::hardware::bluetooth::ranging::ChannelSoundingProcedureData;
55 using aidl::android::hardware::bluetooth::ranging::ModeData;
56 using aidl::android::hardware::bluetooth::ranging::ModeOneData;
57 using aidl::android::hardware::bluetooth::ranging::ModeThreeData;
58 using aidl::android::hardware::bluetooth::ranging::ModeTwoData;
59 using aidl::android::hardware::bluetooth::ranging::ModeType;
60 using aidl::android::hardware::bluetooth::ranging::ModeZeroData;
61 using aidl::android::hardware::bluetooth::ranging::Nadm;
62 using aidl::android::hardware::bluetooth::ranging::PctIQSample;
63 using aidl::android::hardware::bluetooth::ranging::ProcedureAbortReason;
64 using aidl::android::hardware::bluetooth::ranging::RttToaTodData;
65 using aidl::android::hardware::bluetooth::ranging::StepData;
66 using aidl::android::hardware::bluetooth::ranging::SubeventAbortReason;
67 using aidl::android::hardware::bluetooth::ranging::SubeventResultData;
68 
69 namespace bluetooth {
70 namespace hal {
71 
72 class BluetoothChannelSoundingSessionTracker : public BnBluetoothChannelSoundingSessionCallback {
73 public:
BluetoothChannelSoundingSessionTracker(uint16_t connection_handle,RangingHalCallback * ranging_hal_callback,bool for_vendor_specific_reply)74   BluetoothChannelSoundingSessionTracker(uint16_t connection_handle,
75                                          RangingHalCallback* ranging_hal_callback,
76                                          bool for_vendor_specific_reply)
77       : connection_handle_(connection_handle),
78         ranging_hal_callback_(ranging_hal_callback),
79         for_vendor_specific_reply_(for_vendor_specific_reply) {}
80 
onOpened(::aidl::android::hardware::bluetooth::ranging::Reason in_reason)81   ::ndk::ScopedAStatus onOpened(::aidl::android::hardware::bluetooth::ranging::Reason in_reason) {
82     log::info("connection_handle 0x{:04x}, reason {}", connection_handle_, (uint16_t)in_reason);
83     if (for_vendor_specific_reply_) {
84       ranging_hal_callback_->OnHandleVendorSpecificReplyComplete(connection_handle_, true);
85     }
86     return ::ndk::ScopedAStatus::ok();
87   }
88 
onOpenFailed(::aidl::android::hardware::bluetooth::ranging::Reason in_reason)89   ::ndk::ScopedAStatus onOpenFailed(
90           ::aidl::android::hardware::bluetooth::ranging::Reason in_reason) {
91     log::info("connection_handle 0x{:04x}, reason {}", connection_handle_, (uint16_t)in_reason);
92     bluetooth_channel_sounding_session_ = nullptr;
93     if (for_vendor_specific_reply_) {
94       ranging_hal_callback_->OnHandleVendorSpecificReplyComplete(connection_handle_, false);
95     } else {
96       ranging_hal_callback_->OnOpenFailed(connection_handle_);
97     }
98     return ::ndk::ScopedAStatus::ok();
99   }
100 
onResult(const::aidl::android::hardware::bluetooth::ranging::RangingResult & in_result)101   ::ndk::ScopedAStatus onResult(
102           const ::aidl::android::hardware::bluetooth::ranging::RangingResult& in_result) {
103     log::verbose("resultMeters {}", in_result.resultMeters);
104     hal::RangingResult ranging_result = {
105             .result_meters_ = in_result.resultMeters,
106             .confidence_level_ = in_result.confidenceLevel,
107     };
108     ranging_hal_callback_->OnResult(connection_handle_, ranging_result);
109     return ::ndk::ScopedAStatus::ok();
110   }
111 
onClose(::aidl::android::hardware::bluetooth::ranging::Reason in_reason)112   ::ndk::ScopedAStatus onClose(::aidl::android::hardware::bluetooth::ranging::Reason in_reason) {
113     log::info("reason {}", (uint16_t)in_reason);
114     bluetooth_channel_sounding_session_ = nullptr;
115     return ::ndk::ScopedAStatus::ok();
116   }
onCloseFailed(::aidl::android::hardware::bluetooth::ranging::Reason in_reason)117   ::ndk::ScopedAStatus onCloseFailed(
118           ::aidl::android::hardware::bluetooth::ranging::Reason in_reason) {
119     log::info("reason {}", (uint16_t)in_reason);
120     return ::ndk::ScopedAStatus::ok();
121   }
122 
GetSession()123   std::shared_ptr<IBluetoothChannelSoundingSession>& GetSession() {
124     return bluetooth_channel_sounding_session_;
125   }
126 
127 private:
128   std::shared_ptr<IBluetoothChannelSoundingSession> bluetooth_channel_sounding_session_ = nullptr;
129   uint16_t connection_handle_;
130   RangingHalCallback* ranging_hal_callback_;
131   bool for_vendor_specific_reply_;
132 };
133 
134 class RangingHalAndroid : public RangingHal {
135 public:
IsBound()136   bool IsBound() override { return bluetooth_channel_sounding_ != nullptr; }
137 
GetRangingHalVersion()138   RangingHalVersion GetRangingHalVersion() { return hal_ver_; }
139 
RegisterCallback(RangingHalCallback * callback)140   void RegisterCallback(RangingHalCallback* callback) { ranging_hal_callback_ = callback; }
141 
GetVendorSpecificCharacteristics()142   std::vector<VendorSpecificCharacteristic> GetVendorSpecificCharacteristics() override {
143     std::vector<VendorSpecificCharacteristic> vendor_specific_characteristics = {};
144     if (bluetooth_channel_sounding_ != nullptr) {
145       std::optional<std::vector<std::optional<VendorSpecificData>>> vendorSpecificDataOptional;
146       bluetooth_channel_sounding_->getVendorSpecificData(&vendorSpecificDataOptional);
147       if (vendorSpecificDataOptional.has_value()) {
148         for (auto vendor_specific_data : vendorSpecificDataOptional.value()) {
149           VendorSpecificCharacteristic vendor_specific_characteristic;
150           vendor_specific_characteristic.characteristicUuid_ =
151                   vendor_specific_data->characteristicUuid;
152           vendor_specific_characteristic.value_ = vendor_specific_data->opaqueValue;
153           vendor_specific_characteristics.emplace_back(vendor_specific_characteristic);
154         }
155       }
156       log::info("size {}", vendor_specific_characteristics.size());
157     } else {
158       log::warn("bluetooth_channel_sounding_ is nullptr");
159     }
160 
161     return vendor_specific_characteristics;
162   }
163 
OpenSession(uint16_t connection_handle,uint16_t att_handle,const std::vector<hal::VendorSpecificCharacteristic> & vendor_specific_data)164   void OpenSession(uint16_t connection_handle, uint16_t att_handle,
165                    const std::vector<hal::VendorSpecificCharacteristic>& vendor_specific_data) {
166     log::info("connection_handle 0x{:04x}, att_handle 0x{:04x} size of vendor_specific_data {}",
167               connection_handle, att_handle, vendor_specific_data.size());
168     session_trackers_[connection_handle] =
169             ndk::SharedRefBase::make<BluetoothChannelSoundingSessionTracker>(
170                     connection_handle, ranging_hal_callback_, false);
171     BluetoothChannelSoundingParameters parameters;
172     parameters.aclHandle = connection_handle;
173     parameters.role = aidl::android::hardware::bluetooth::ranging::Role::INITIATOR;
174     parameters.realTimeProcedureDataAttHandle = att_handle;
175     CopyVendorSpecificData(vendor_specific_data, parameters.vendorSpecificData);
176 
177     auto& tracker = session_trackers_[connection_handle];
178     bluetooth_channel_sounding_->openSession(parameters, tracker, &tracker->GetSession());
179 
180     if (tracker->GetSession() != nullptr) {
181       std::vector<VendorSpecificCharacteristic> vendor_specific_reply = {};
182       std::optional<std::vector<std::optional<VendorSpecificData>>> vendorSpecificDataOptional;
183       tracker->GetSession()->getVendorSpecificReplies(&vendorSpecificDataOptional);
184 
185       if (vendorSpecificDataOptional.has_value()) {
186         for (auto& data : vendorSpecificDataOptional.value()) {
187           VendorSpecificCharacteristic vendor_specific_characteristic;
188           vendor_specific_characteristic.characteristicUuid_ = data->characteristicUuid;
189           vendor_specific_characteristic.value_ = data->opaqueValue;
190           vendor_specific_reply.emplace_back(vendor_specific_characteristic);
191         }
192       }
193       ranging_hal_callback_->OnOpened(connection_handle, vendor_specific_reply);
194     }
195   }
196 
HandleVendorSpecificReply(uint16_t connection_handle,const std::vector<hal::VendorSpecificCharacteristic> & vendor_specific_reply)197   void HandleVendorSpecificReply(
198           uint16_t connection_handle,
199           const std::vector<hal::VendorSpecificCharacteristic>& vendor_specific_reply) {
200     log::info("connection_handle 0x{:04x}", connection_handle);
201     session_trackers_[connection_handle] =
202             ndk::SharedRefBase::make<BluetoothChannelSoundingSessionTracker>(
203                     connection_handle, ranging_hal_callback_, true);
204     BluetoothChannelSoundingParameters parameters;
205     parameters.aclHandle = connection_handle;
206     parameters.role = aidl::android::hardware::bluetooth::ranging::Role::REFLECTOR;
207     CopyVendorSpecificData(vendor_specific_reply, parameters.vendorSpecificData);
208     auto& tracker = session_trackers_[connection_handle];
209     bluetooth_channel_sounding_->openSession(parameters, tracker, &tracker->GetSession());
210   }
211 
WriteRawData(uint16_t connection_handle,const ChannelSoundingRawData & raw_data)212   void WriteRawData(uint16_t connection_handle, const ChannelSoundingRawData& raw_data) {
213     if (session_trackers_.find(connection_handle) == session_trackers_.end()) {
214       log::error("Can't find session for connection_handle:0x{:04x}", connection_handle);
215       return;
216     } else if (session_trackers_[connection_handle]->GetSession() == nullptr) {
217       log::error("Session not opened");
218       return;
219     }
220 
221     ChannelSoudingRawData hal_raw_data;
222     hal_raw_data.numAntennaPaths = raw_data.num_antenna_paths_;
223     hal_raw_data.stepChannels = raw_data.step_channel_;
224     hal_raw_data.initiatorData.stepTonePcts.emplace(std::vector<std::optional<StepTonePct>>{});
225     hal_raw_data.reflectorData.stepTonePcts.emplace(std::vector<std::optional<StepTonePct>>{});
226     // Add tone data for mode 2, mode 3
227     for (uint8_t i = 0; i < raw_data.tone_pct_initiator_.size(); i++) {
228       StepTonePct step_tone_pct;
229       for (uint8_t j = 0; j < raw_data.tone_pct_initiator_[i].size(); j++) {
230         ComplexNumber complex_number;
231         complex_number.imaginary = raw_data.tone_pct_initiator_[i][j].imag();
232         complex_number.real = raw_data.tone_pct_initiator_[i][j].real();
233         step_tone_pct.tonePcts.emplace_back(complex_number);
234       }
235       step_tone_pct.toneQualityIndicator = raw_data.tone_quality_indicator_initiator_[i];
236       hal_raw_data.initiatorData.stepTonePcts.value().emplace_back(step_tone_pct);
237     }
238     for (uint8_t i = 0; i < raw_data.tone_pct_reflector_.size(); i++) {
239       StepTonePct step_tone_pct;
240       for (uint8_t j = 0; j < raw_data.tone_pct_reflector_[i].size(); j++) {
241         ComplexNumber complex_number;
242         complex_number.imaginary = raw_data.tone_pct_reflector_[i][j].imag();
243         complex_number.real = raw_data.tone_pct_reflector_[i][j].real();
244         step_tone_pct.tonePcts.emplace_back(complex_number);
245       }
246       step_tone_pct.toneQualityIndicator = raw_data.tone_quality_indicator_reflector_[i];
247       hal_raw_data.reflectorData.stepTonePcts.value().emplace_back(step_tone_pct);
248     }
249     // Add RTT data for mode 1, mode 3
250     if (!raw_data.toa_tod_initiators_.empty()) {
251       hal_raw_data.toaTodInitiator = std::vector<int32_t>(raw_data.toa_tod_initiators_.begin(),
252                                                           raw_data.toa_tod_initiators_.end());
253       hal_raw_data.initiatorData.packetQuality = std::vector<uint8_t>(
254               raw_data.packet_quality_initiator.begin(), raw_data.packet_quality_initiator.end());
255     }
256     if (!raw_data.tod_toa_reflectors_.empty()) {
257       hal_raw_data.todToaReflector = std::vector<int32_t>(raw_data.tod_toa_reflectors_.begin(),
258                                                           raw_data.tod_toa_reflectors_.end());
259       hal_raw_data.reflectorData.packetQuality = std::vector<uint8_t>(
260               raw_data.packet_quality_reflector.begin(), raw_data.packet_quality_reflector.end());
261     }
262     session_trackers_[connection_handle]->GetSession()->writeRawData(hal_raw_data);
263   }
264 
UpdateChannelSoundingConfig(uint16_t connection_handle,const hci::LeCsConfigCompleteView & leCsConfigCompleteView,uint8_t local_supported_sw_time,uint8_t remote_supported_sw_time,uint16_t conn_interval)265   void UpdateChannelSoundingConfig(uint16_t connection_handle,
266                                    const hci::LeCsConfigCompleteView& leCsConfigCompleteView,
267                                    uint8_t local_supported_sw_time,
268                                    uint8_t remote_supported_sw_time,
269                                    uint16_t conn_interval) override {
270     auto it = session_trackers_.find(connection_handle);
271     if (it == session_trackers_.end()) {
272       log::error("Can't find session for connection_handle:0x{:04x}", connection_handle);
273       return;
274     } else if (it->second->GetSession() == nullptr) {
275       log::error("Session not opened");
276       return;
277     }
278 
279     Config csConfig{
280             .modeType = static_cast<ModeType>(
281                     static_cast<int>(leCsConfigCompleteView.GetMainModeType())),
282             .subModeType = static_cast<SubModeType>(
283                     static_cast<int>(leCsConfigCompleteView.GetSubModeType())),
284             .rttType = static_cast<RttType>(static_cast<int>(leCsConfigCompleteView.GetRttType())),
285             .channelMap = leCsConfigCompleteView.GetChannelMap(),
286             .minMainModeSteps = leCsConfigCompleteView.GetMinMainModeSteps(),
287             .maxMainModeSteps = leCsConfigCompleteView.GetMaxMainModeSteps(),
288             .mainModeRepetition =
289                     static_cast<int8_t>(leCsConfigCompleteView.GetMainModeRepetition()),
290             .mode0Steps = static_cast<int8_t>(leCsConfigCompleteView.GetMode0Steps()),
291             .role = static_cast<Role>(static_cast<int>(leCsConfigCompleteView.GetRole())),
292             .csSyncPhyType = static_cast<CsSyncPhyType>(
293                     static_cast<int>(leCsConfigCompleteView.GetCsSyncPhy())),
294             .channelSelectionType = static_cast<ChannelSelectionType>(
295                     static_cast<int>(leCsConfigCompleteView.GetChannelSelectionType())),
296             .ch3cShapeType = static_cast<Ch3cShapeType>(
297                     static_cast<int>(leCsConfigCompleteView.GetCh3cShape())),
298             .ch3cJump = static_cast<int8_t>(leCsConfigCompleteView.GetCh3cJump()),
299             .channelMapRepetition = leCsConfigCompleteView.GetChannelMapRepetition(),
300             .tIp1TimeUs = leCsConfigCompleteView.GetTIp1Time(),
301             .tIp2TimeUs = leCsConfigCompleteView.GetTIp2Time(),
302             .tFcsTimeUs = leCsConfigCompleteView.GetTFcsTime(),
303             .tPmTimeUs = static_cast<int8_t>(leCsConfigCompleteView.GetTPmTime()),
304             .tSwTimeUsSupportedByLocal = static_cast<int8_t>(local_supported_sw_time),
305             .tSwTimeUsSupportedByRemote = static_cast<int8_t>(remote_supported_sw_time),
306             .bleConnInterval = conn_interval,
307     };
308 
309     it->second->GetSession()->updateChannelSoundingConfig(csConfig);
310   }
311 
UpdateConnInterval(uint16_t connection_handle,uint16_t conn_interval)312   void UpdateConnInterval(uint16_t connection_handle, uint16_t conn_interval) override {
313     auto it = session_trackers_.find(connection_handle);
314     if (it == session_trackers_.end()) {
315       log::error("Can't find session for connection_handle:0x{:04x}", connection_handle);
316       return;
317     } else if (it->second->GetSession() == nullptr) {
318       log::error("Session not opened");
319       return;
320     }
321 
322     it->second->GetSession()->updateBleConnInterval(conn_interval);
323   }
324 
UpdateProcedureEnableConfig(uint16_t connection_handle,const hci::LeCsProcedureEnableCompleteView & leCsProcedureEnableCompleteView)325   void UpdateProcedureEnableConfig(
326           uint16_t connection_handle,
327           const hci::LeCsProcedureEnableCompleteView& leCsProcedureEnableCompleteView) override {
328     auto it = session_trackers_.find(connection_handle);
329     if (it == session_trackers_.end()) {
330       log::error("Can't find session for connection_handle:0x{:04x}", connection_handle);
331       return;
332     } else if (it->second->GetSession() == nullptr) {
333       log::error("Session not opened");
334       return;
335     }
336 
337     ProcedureEnableConfig pConfig{
338             .toneAntennaConfigSelection = static_cast<int8_t>(
339                     leCsProcedureEnableCompleteView.GetToneAntennaConfigSelection()),
340             .subeventLenUs = static_cast<int>(leCsProcedureEnableCompleteView.GetSubeventLen()),
341             .subeventsPerEvent =
342                     static_cast<int8_t>(leCsProcedureEnableCompleteView.GetSubeventsPerEvent()),
343             .subeventInterval = leCsProcedureEnableCompleteView.GetSubeventInterval(),
344             .eventInterval = leCsProcedureEnableCompleteView.GetEventInterval(),
345             .procedureInterval = leCsProcedureEnableCompleteView.GetProcedureInterval(),
346             .procedureCount = leCsProcedureEnableCompleteView.GetProcedureCount(),
347             // TODO(b/378942784): update the max procedure len, the current complete view does not
348             // have it.
349             .maxProcedureLen = 0,
350     };
351 
352     it->second->GetSession()->updateProcedureEnableConfig(pConfig);
353   }
354 
WriteProcedureData(const uint16_t connection_handle,hci::CsRole local_cs_role,const ProcedureDataV2 & procedure_data,uint16_t procedure_counter)355   void WriteProcedureData(const uint16_t connection_handle, hci::CsRole local_cs_role,
356                           const ProcedureDataV2& procedure_data,
357                           uint16_t procedure_counter) override {
358     auto session_it = session_trackers_.find(connection_handle);
359     if (session_it == session_trackers_.end()) {
360       log::error("Can't find session for connection_handle:0x{:04x}", connection_handle);
361       return;
362     } else if (session_it->second->GetSession() == nullptr) {
363       log::error("Session not opened");
364       return;
365     }
366     ChannelSoundingProcedureData channel_sounding_procedure_data;
367     channel_sounding_procedure_data.procedureCounter = procedure_counter;
368     channel_sounding_procedure_data.procedureSequence = procedure_data.procedure_sequence_;
369 
370     if (local_cs_role == hci::CsRole::INITIATOR) {
371       channel_sounding_procedure_data.initiatorSelectedTxPower =
372               static_cast<int8_t>(procedure_data.local_selected_tx_power_);
373       channel_sounding_procedure_data.reflectorSelectedTxPower =
374               static_cast<int8_t>(procedure_data.remote_selected_tx_power_);
375       channel_sounding_procedure_data.initiatorProcedureAbortReason =
376               static_cast<ProcedureAbortReason>(procedure_data.local_procedure_abort_reason_);
377       channel_sounding_procedure_data.reflectorProcedureAbortReason =
378               static_cast<ProcedureAbortReason>(procedure_data.remote_procedure_abort_reason_);
379       channel_sounding_procedure_data.initiatorSubeventResultData =
380               get_subevent_result_data(procedure_data.local_subevent_data_, hci::CsRole::INITIATOR);
381       channel_sounding_procedure_data.reflectorSubeventResultData = get_subevent_result_data(
382               procedure_data.remote_subevent_data_, hci::CsRole::REFLECTOR);
383     } else {
384       channel_sounding_procedure_data.initiatorSelectedTxPower =
385               static_cast<int8_t>(procedure_data.remote_selected_tx_power_);
386       channel_sounding_procedure_data.reflectorSelectedTxPower =
387               static_cast<int8_t>(procedure_data.local_selected_tx_power_);
388       channel_sounding_procedure_data.initiatorProcedureAbortReason =
389               static_cast<ProcedureAbortReason>(procedure_data.remote_procedure_abort_reason_);
390       channel_sounding_procedure_data.reflectorProcedureAbortReason =
391               static_cast<ProcedureAbortReason>(procedure_data.local_procedure_abort_reason_);
392       channel_sounding_procedure_data.initiatorSubeventResultData = get_subevent_result_data(
393               procedure_data.remote_subevent_data_, hci::CsRole::INITIATOR);
394       channel_sounding_procedure_data.reflectorSubeventResultData =
395               get_subevent_result_data(procedure_data.local_subevent_data_, hci::CsRole::REFLECTOR);
396 
397       session_it->second->GetSession()->writeProcedureData(channel_sounding_procedure_data);
398     }
399   }
400 
get_subevent_result_data(const std::vector<std::shared_ptr<SubeventResult>> & subevent_results,hci::CsRole cs_role)401   static std::vector<SubeventResultData> get_subevent_result_data(
402           const std::vector<std::shared_ptr<SubeventResult>>& subevent_results,
403           hci::CsRole cs_role) {
404     std::vector<SubeventResultData> hal_subevents;
405     for (auto subevent_result : subevent_results) {
406       SubeventResultData aidl_subevent_result{
407               .startAclConnEventCounter = subevent_result->start_acl_conn_event_counter_,
408               .frequencyCompensation = ConvertToSigned<kInitiatorMeasuredOffsetBits>(
409                       subevent_result->frequency_compensation_),
410               .referencePowerLevelDbm =
411                       static_cast<int8_t>(subevent_result->reference_power_level_),
412               .numAntennaPaths = static_cast<int8_t>(subevent_result->num_antenna_paths_),
413               .subeventAbortReason =
414                       static_cast<SubeventAbortReason>(subevent_result->subevent_abort_reason_),
415               .stepData = get_group_step_data(subevent_result->step_data_, cs_role),
416               .timestampNanos = subevent_result->timestamp_nanos_,
417       };
418       hal_subevents.push_back(aidl_subevent_result);
419     }
420     return hal_subevents;
421   }
422 
get_group_step_data(const std::vector<StepSpecificData> & step_specific_data_list,hci::CsRole cs_role)423   static std::vector<StepData> get_group_step_data(
424           const std::vector<StepSpecificData>& step_specific_data_list, hci::CsRole cs_role) {
425     std::vector<StepData> group_step_data;
426     for (auto step_specific_data : step_specific_data_list) {
427       StepData step_data{
428               .stepChannel = static_cast<int8_t>(step_specific_data.step_channel_),
429               .stepMode = static_cast<ModeType>(step_specific_data.mode_type_),
430       };
431       get_step_mode_data(step_specific_data.mode_specific_data_, step_data.stepModeData, cs_role);
432       group_step_data.push_back(step_data);
433     }
434     return group_step_data;
435   }
436 
get_step_mode_data(std::variant<Mode0Data,Mode1Data,Mode2Data,Mode3Data> mode_specific_data,ModeData & mode_data,hci::CsRole cs_role)437   static void get_step_mode_data(
438           std::variant<Mode0Data, Mode1Data, Mode2Data, Mode3Data> mode_specific_data,
439           ModeData& mode_data, hci::CsRole cs_role) {
440     if (std::holds_alternative<Mode0Data>(mode_specific_data)) {
441       auto mode_0_data = std::get<Mode0Data>(mode_specific_data);
442       ModeZeroData mode_zero_data{
443               .packetQuality = static_cast<int8_t>(mode_0_data.packet_quality_),
444               .packetRssiDbm = static_cast<int8_t>(mode_0_data.packet_rssi_),
445               .packetAntenna = static_cast<int8_t>(mode_0_data.packet_antenna_),
446       };
447       mode_data = mode_zero_data;
448       return;
449     }
450     if (std::holds_alternative<Mode1Data>(mode_specific_data)) {
451       auto mode_1_data = std::get<Mode1Data>(mode_specific_data);
452       mode_data = convert_mode_1_data(mode_1_data, cs_role);
453       return;
454     }
455     if (std::holds_alternative<Mode2Data>(mode_specific_data)) {
456       auto mode_2_data = std::get<Mode2Data>(mode_specific_data);
457       mode_data = convert_mode_2_data(mode_2_data);
458       return;
459     }
460     if (std::holds_alternative<Mode3Data>(mode_specific_data)) {
461       auto mode_3_data = std::get<Mode3Data>(mode_specific_data);
462       ModeThreeData mode_three_data{
463               .modeOneData = convert_mode_1_data(mode_3_data.mode1_data_, cs_role),
464               .modeTwoData = convert_mode_2_data(mode_3_data.mode2_data_),
465       };
466       mode_data = mode_three_data;
467       return;
468     }
469   }
470 
convert_mode_1_data(const Mode1Data & mode_1_data,hci::CsRole cs_role)471   static ModeOneData convert_mode_1_data(const Mode1Data& mode_1_data, hci::CsRole cs_role) {
472     ModeOneData mode_one_data{
473             .packetQuality = static_cast<int8_t>(mode_1_data.packet_quality_),
474             .packetNadm = static_cast<Nadm>(mode_1_data.packet_nadm_),
475             .packetRssiDbm = static_cast<int8_t>(mode_1_data.packet_rssi_),
476             .packetAntenna = static_cast<int8_t>(mode_1_data.packet_antenna_),
477     };
478     if (cs_role == hci::CsRole::INITIATOR) {
479       mode_one_data.rttToaTodData = RttToaTodData::make<RttToaTodData::Tag::toaTodInitiator>(
480               static_cast<int16_t>(mode_1_data.rtt_toa_tod_data_));
481     } else {
482       mode_one_data.rttToaTodData = RttToaTodData::make<RttToaTodData::Tag::todToaReflector>(
483               static_cast<int16_t>(mode_1_data.rtt_toa_tod_data_));
484     }
485     // TODO(b/378942784): once get 32 bits from controller, and check the unavailable data.
486     if (mode_1_data.i_packet_pct1_.has_value()) {
487       mode_one_data.packetPct1.emplace(
488               ConvertToSigned<kIQSampleBits>(mode_1_data.i_packet_pct1_.value()),
489               ConvertToSigned<kIQSampleBits>(mode_1_data.q_packet_pct1_.value()));
490     }
491     if (mode_1_data.i_packet_pct2_.has_value()) {
492       mode_one_data.packetPct2.emplace(
493               ConvertToSigned<kIQSampleBits>(mode_1_data.i_packet_pct2_.value()),
494               ConvertToSigned<kIQSampleBits>(mode_1_data.q_packet_pct2_.value()));
495     }
496     return mode_one_data;
497   }
498 
convert_mode_2_data(const Mode2Data & mode_2_data)499   static ModeTwoData convert_mode_2_data(const Mode2Data& mode_2_data) {
500     ModeTwoData mode_two_data{
501             .antennaPermutationIndex = static_cast<int8_t>(mode_2_data.antenna_permutation_index_),
502     };
503     for (const auto& tone_data_with_quality : mode_2_data.tone_data_with_qualities_) {
504       mode_two_data.toneQualityIndicators.emplace_back(
505               tone_data_with_quality.tone_quality_indicator_);
506       mode_two_data.tonePctIQSamples.emplace_back(
507               ConvertToSigned<kIQSampleBits>(tone_data_with_quality.i_sample_),
508               ConvertToSigned<kIQSampleBits>(tone_data_with_quality.q_sample_));
509     }
510     return mode_two_data;
511   }
512 
CopyVendorSpecificData(const std::vector<hal::VendorSpecificCharacteristic> & source,std::optional<std::vector<std::optional<VendorSpecificData>>> & dist)513   void CopyVendorSpecificData(const std::vector<hal::VendorSpecificCharacteristic>& source,
514                               std::optional<std::vector<std::optional<VendorSpecificData>>>& dist) {
515     dist = std::make_optional<std::vector<std::optional<VendorSpecificData>>>();
516     for (auto& data : source) {
517       VendorSpecificData vendor_specific_data;
518       vendor_specific_data.characteristicUuid = data.characteristicUuid_;
519       vendor_specific_data.opaqueValue = data.value_;
520       dist->push_back(vendor_specific_data);
521     }
522   }
523 
524 protected:
ListDependencies(ModuleList *) const525   void ListDependencies(ModuleList* /*list*/) const {}
526 
get_ranging_hal_version()527   RangingHalVersion get_ranging_hal_version() {
528     int ver = 0;
529     auto aidl_ret = bluetooth_channel_sounding_->getInterfaceVersion(&ver);
530     if (aidl_ret.isOk()) {
531       log::info("ranging HAL version - {}", ver);
532       return static_cast<RangingHalVersion>(ver);
533     }
534     log::warn("ranging HAL version is not available.");
535     return RangingHalVersion::V_UNKNOWN;
536   }
537 
Start()538   void Start() override {
539     std::string instance = std::string() + IBluetoothChannelSounding::descriptor + "/default";
540     log::info("AServiceManager_isDeclared {}", AServiceManager_isDeclared(instance.c_str()));
541     if (AServiceManager_isDeclared(instance.c_str())) {
542       ::ndk::SpAIBinder binder(AServiceManager_waitForService(instance.c_str()));
543       bluetooth_channel_sounding_ = IBluetoothChannelSounding::fromBinder(binder);
544       log::info("Bind IBluetoothChannelSounding {}", IsBound() ? "Success" : "Fail");
545       if (bluetooth_channel_sounding_ != nullptr) {
546         hal_ver_ = get_ranging_hal_version();
547       }
548     }
549   }
550 
Stop()551   void Stop() override { bluetooth_channel_sounding_ = nullptr; }
552 
ToString() const553   std::string ToString() const override { return std::string("RangingHalAndroid"); }
554 
555 private:
556   std::shared_ptr<IBluetoothChannelSounding> bluetooth_channel_sounding_;
557   RangingHalCallback* ranging_hal_callback_;
558   std::unordered_map<uint16_t, std::shared_ptr<BluetoothChannelSoundingSessionTracker>>
559           session_trackers_;
560   RangingHalVersion hal_ver_;
561 };
562 
__anon8d9c35d00102() 563 const ModuleFactory RangingHal::Factory = ModuleFactory([]() { return new RangingHalAndroid(); });
564 
565 }  // namespace hal
566 }  // namespace bluetooth
567