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