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