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