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 #pragma once
18
19 #include <complex>
20
21 #include "hci/hci_packets.h"
22 #include "module.h"
23
24 namespace bluetooth {
25 namespace hal {
26 /**
27 * See BLUETOOTH CORE SPECIFICATION Version 6.0 | Vol 4, Part E 7.7.65.44 ((LE CS Subevent Result)
28 * for details.
29 */
30 static constexpr uint8_t kInitiatorMeasuredOffsetBits = 15;
31 static constexpr uint16_t kUnavailableInitiatorMeasuredOffset = 0xC000;
32 static constexpr uint8_t kUnavailablePacketRssi = 0x7F;
33 static constexpr uint8_t kIQSampleBits = 12;
34
35 enum RangingHalVersion {
36 V_UNKNOWN = 0,
37 V_1 = 1,
38 V_2 = 2,
39 };
40
41 struct VendorSpecificCharacteristic {
42 std::array<uint8_t, 16> characteristicUuid_;
43 std::vector<uint8_t> value_;
44 };
45
46 struct ChannelSoundingRawData {
47 uint8_t num_antenna_paths_;
48 std::vector<uint8_t> step_channel_;
49 std::vector<std::vector<std::complex<double>>> tone_pct_initiator_;
50 std::vector<std::vector<std::complex<double>>> tone_pct_reflector_;
51 std::vector<std::vector<uint8_t>> tone_quality_indicator_initiator_;
52 std::vector<std::vector<uint8_t>> tone_quality_indicator_reflector_;
53 std::vector<int8_t> packet_quality_initiator;
54 std::vector<int8_t> packet_quality_reflector;
55 std::vector<int16_t> toa_tod_initiators_;
56 std::vector<int16_t> tod_toa_reflectors_;
57 };
58
59 // TODO: move to a utility file and add UT.
60 template <int BITS>
ConvertToSigned(uint16_t num)61 static inline int16_t ConvertToSigned(uint16_t num) {
62 unsigned msb_mask = 1 << (BITS - 1); // setup a mask for most significant bit
63 int16_t num_signed = num;
64 if ((num_signed & msb_mask) != 0) {
65 num_signed |= ~(msb_mask - 1); // extend the MSB
66 }
67 return num_signed;
68 }
69
70 struct Mode0Data {
Mode0DataMode0Data71 Mode0Data(const hci::LeCsMode0InitatorData& le_cs_mode0_data)
72 : packet_quality_(le_cs_mode0_data.packet_quality_),
73 packet_rssi_(le_cs_mode0_data.packet_rssi_),
74 packet_antenna_(le_cs_mode0_data.packet_antenna_),
75 initiator_measured_offset(le_cs_mode0_data.measured_freq_offset_) {}
76
Mode0DataMode0Data77 Mode0Data(const hci::LeCsMode0ReflectorData& le_cs_mode0_data)
78 : packet_quality_(le_cs_mode0_data.packet_quality_),
79 packet_rssi_(le_cs_mode0_data.packet_rssi_),
80 packet_antenna_(le_cs_mode0_data.packet_antenna_) {}
81
82 uint8_t packet_quality_ = 0;
83 uint8_t packet_rssi_ = kUnavailablePacketRssi;
84 uint8_t packet_antenna_ = 0;
85 uint16_t initiator_measured_offset = kUnavailableInitiatorMeasuredOffset;
86 };
87
88 struct Mode1Data {
Mode1DataMode1Data89 Mode1Data() {}
Mode1DataMode1Data90 Mode1Data(const hci::LeCsMode1InitatorData& le_cs_mode1_data)
91 : packet_quality_(le_cs_mode1_data.packet_quality_),
92 packet_nadm_(le_cs_mode1_data.packet_nadm_),
93 packet_rssi_(le_cs_mode1_data.packet_rssi_),
94 rtt_toa_tod_data_(le_cs_mode1_data.toa_tod_initiator_),
95 packet_antenna_(le_cs_mode1_data.packet_antenna_) {}
96
Mode1DataMode1Data97 Mode1Data(const hci::LeCsMode1InitatorDataWithPacketPct& le_cs_mode1_data)
98 : packet_quality_(le_cs_mode1_data.packet_quality_),
99 packet_nadm_(le_cs_mode1_data.packet_nadm_),
100 packet_rssi_(le_cs_mode1_data.packet_rssi_),
101 rtt_toa_tod_data_(le_cs_mode1_data.toa_tod_initiator_),
102 packet_antenna_(le_cs_mode1_data.packet_antenna_),
103 i_packet_pct1_(le_cs_mode1_data.packet_pct1_.i_sample_),
104 q_packet_pct1_(le_cs_mode1_data.packet_pct1_.q_sample_),
105 i_packet_pct2_(le_cs_mode1_data.packet_pct2_.i_sample_),
106 q_packet_pct2_(le_cs_mode1_data.packet_pct2_.q_sample_) {}
107
Mode1DataMode1Data108 Mode1Data(const hci::LeCsMode1ReflectorData& le_cs_mode1_data)
109 : packet_quality_(le_cs_mode1_data.packet_quality_),
110 packet_nadm_(le_cs_mode1_data.packet_nadm_),
111 packet_rssi_(le_cs_mode1_data.packet_rssi_),
112 rtt_toa_tod_data_(le_cs_mode1_data.tod_toa_reflector_),
113 packet_antenna_(le_cs_mode1_data.packet_antenna_) {}
114
Mode1DataMode1Data115 Mode1Data(const hci::LeCsMode1ReflectorDataWithPacketPct& le_cs_mode1_data)
116 : packet_quality_(le_cs_mode1_data.packet_quality_),
117 packet_nadm_(le_cs_mode1_data.packet_nadm_),
118 packet_rssi_(le_cs_mode1_data.packet_rssi_),
119 rtt_toa_tod_data_(le_cs_mode1_data.tod_toa_reflector_),
120 packet_antenna_(le_cs_mode1_data.packet_antenna_),
121 i_packet_pct1_(le_cs_mode1_data.packet_pct1_.i_sample_),
122 q_packet_pct1_(le_cs_mode1_data.packet_pct1_.q_sample_),
123 i_packet_pct2_(le_cs_mode1_data.packet_pct2_.i_sample_),
124 q_packet_pct2_(le_cs_mode1_data.packet_pct2_.q_sample_) {}
125
Mode1DataMode1Data126 Mode1Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data)
127 : packet_quality_(le_cs_mode3_data.packet_quality_),
128 packet_nadm_(le_cs_mode3_data.packet_nadm_),
129 packet_rssi_(le_cs_mode3_data.packet_rssi_),
130 rtt_toa_tod_data_(le_cs_mode3_data.toa_tod_initiator_),
131 packet_antenna_(le_cs_mode3_data.packet_antenna_) {}
132
Mode1DataMode1Data133 Mode1Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data)
134 : packet_quality_(le_cs_mode3_data.packet_quality_),
135 packet_nadm_(le_cs_mode3_data.packet_nadm_),
136 packet_rssi_(le_cs_mode3_data.packet_rssi_),
137 rtt_toa_tod_data_(le_cs_mode3_data.toa_tod_initiator_),
138 packet_antenna_(le_cs_mode3_data.packet_antenna_),
139 i_packet_pct1_(le_cs_mode3_data.packet_pct1_.i_sample_),
140 q_packet_pct1_(le_cs_mode3_data.packet_pct1_.q_sample_),
141 i_packet_pct2_(le_cs_mode3_data.packet_pct2_.i_sample_),
142 q_packet_pct2_(le_cs_mode3_data.packet_pct2_.q_sample_) {}
143
Mode1DataMode1Data144 Mode1Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data)
145 : packet_quality_(le_cs_mode3_data.packet_quality_),
146 packet_nadm_(le_cs_mode3_data.packet_nadm_),
147 packet_rssi_(le_cs_mode3_data.packet_rssi_),
148 rtt_toa_tod_data_(le_cs_mode3_data.tod_toa_reflector_),
149 packet_antenna_(le_cs_mode3_data.packet_antenna_) {}
150
Mode1DataMode1Data151 Mode1Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data)
152 : packet_quality_(le_cs_mode3_data.packet_quality_),
153 packet_nadm_(le_cs_mode3_data.packet_nadm_),
154 packet_rssi_(le_cs_mode3_data.packet_rssi_),
155 rtt_toa_tod_data_(le_cs_mode3_data.tod_toa_reflector_),
156 packet_antenna_(le_cs_mode3_data.packet_antenna_),
157 i_packet_pct1_(le_cs_mode3_data.packet_pct1_.i_sample_),
158 q_packet_pct1_(le_cs_mode3_data.packet_pct1_.q_sample_),
159 i_packet_pct2_(le_cs_mode3_data.packet_pct2_.i_sample_),
160 q_packet_pct2_(le_cs_mode3_data.packet_pct2_.q_sample_) {}
161
162 uint8_t packet_quality_ = 0;
163 hci::CsPacketNadm packet_nadm_ = hci::CsPacketNadm::UNKNOWN_NADM;
164 uint8_t packet_rssi_ = kUnavailablePacketRssi;
165 uint16_t rtt_toa_tod_data_ = 0;
166 uint8_t packet_antenna_ = 0;
167 std::optional<uint16_t> i_packet_pct1_ = std::nullopt;
168 std::optional<uint16_t> q_packet_pct1_ = std::nullopt;
169 std::optional<uint16_t> i_packet_pct2_ = std::nullopt;
170 std::optional<uint16_t> q_packet_pct2_ = std::nullopt;
171 };
172
173 struct Mode2Data {
Mode2DataMode2Data174 Mode2Data() {}
Mode2DataMode2Data175 Mode2Data(const hci::LeCsMode2Data& le_cs_mode2_data)
176 : antenna_permutation_index_(le_cs_mode2_data.antenna_permutation_index_) {
177 std::copy(le_cs_mode2_data.tone_data_.begin(), le_cs_mode2_data.tone_data_.end(),
178 std::back_inserter(tone_data_with_qualities_));
179 }
180
Mode2DataMode2Data181 Mode2Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data)
182 : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) {
183 std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(),
184 std::back_inserter(tone_data_with_qualities_));
185 }
186
Mode2DataMode2Data187 Mode2Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data)
188 : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) {
189 std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(),
190 std::back_inserter(tone_data_with_qualities_));
191 }
192
Mode2DataMode2Data193 Mode2Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data)
194 : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) {
195 std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(),
196 std::back_inserter(tone_data_with_qualities_));
197 }
198
Mode2DataMode2Data199 Mode2Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data)
200 : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) {
201 std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(),
202 std::back_inserter(tone_data_with_qualities_));
203 }
204
205 uint8_t antenna_permutation_index_ = 0;
206 std::vector<hci::LeCsToneDataWithQuality> tone_data_with_qualities_;
207 };
208
209 struct Mode3Data {
Mode3DataMode3Data210 Mode3Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data)
211 : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {}
212
Mode3DataMode3Data213 Mode3Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data)
214 : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {}
215
Mode3DataMode3Data216 Mode3Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data)
217 : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {}
218
Mode3DataMode3Data219 Mode3Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data)
220 : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {}
221
222 Mode1Data mode1_data_;
223 Mode2Data mode2_data_;
224 };
225
226 struct StepSpecificData {
227 uint8_t step_channel_;
228 uint8_t mode_type_;
229 // ModeSpecificData mode_specific_data_;
230 std::variant<Mode0Data, Mode1Data, Mode2Data, Mode3Data> mode_specific_data_;
231 };
232
233 struct SubeventResult {
234 /**
235 * Starting ACL connection event counter for the results reported in the event
236 */
237 int start_acl_conn_event_counter_;
238 /**
239 * Frequency compensation value in units of 0.01 ppm (15-bit signed integer)
240 * Unit: 0.01 ppm
241 * 0xC000 - Frequency compensation value is not available, or the role is not initiator
242 */
243 uint16_t frequency_compensation_ = 0xC000;
244 /**
245 * Reference power level
246 * Range: -127 to 20
247 * Unit: dBm
248 */
249 uint8_t reference_power_level_;
250 /**
251 * 0x00 Ignored because phase measurement does not occur during the CS step
252 * 0x01 to 0x04 Number of antenna paths used during the phase measurement stage of the CS step
253 */
254 uint8_t num_antenna_paths_;
255 /**
256 * Indicates the abort reason
257 */
258 hci::SubeventAbortReason subevent_abort_reason_;
259 /**
260 * The measured data for all steps
261 */
262 std::vector<StepSpecificData> step_data_;
263 /**
264 * Timestamp when all subevent data are received by the host; Not defined by the spec.
265 * Using epoch time in nanos (e.g., 1697673127175).
266 */
267 long timestamp_nanos_;
268 };
269
270 struct ProcedureDataV2 {
271 // for HAL v2
272 std::vector<std::shared_ptr<hal::SubeventResult>> local_subevent_data_;
273 std::vector<std::shared_ptr<hal::SubeventResult>> remote_subevent_data_;
274 hci::ProcedureAbortReason local_procedure_abort_reason_;
275 hci::ProcedureAbortReason remote_procedure_abort_reason_;
276 uint8_t local_selected_tx_power_;
277 uint8_t remote_selected_tx_power_;
278 // TODO(b/378942784): assign the sequence
279 int procedure_sequence_;
280 };
281
282 struct RangingResult {
283 double result_meters_;
284 // A normalized value from 0 (low confidence) to 100 (high confidence) representing the confidence
285 // of estimated distance. The value is -1 when unavailable.
286 int8_t confidence_level_;
287 };
288
289 class RangingHalCallback {
290 public:
291 virtual ~RangingHalCallback() = default;
292 virtual void OnOpened(uint16_t connection_handle,
293 const std::vector<VendorSpecificCharacteristic>& vendor_specific_reply) = 0;
294 virtual void OnOpenFailed(uint16_t connection_handle) = 0;
295 virtual void OnHandleVendorSpecificReplyComplete(uint16_t connection_handle, bool success) = 0;
296 virtual void OnResult(uint16_t connection_handle, const RangingResult& ranging_result) = 0;
297 };
298
299 class RangingHal : public ::bluetooth::Module {
300 public:
301 static const ModuleFactory Factory;
302
303 virtual ~RangingHal() = default;
304 virtual bool IsBound() = 0;
305 virtual RangingHalVersion GetRangingHalVersion() = 0;
306 virtual void RegisterCallback(RangingHalCallback* callback) = 0;
307 virtual std::vector<VendorSpecificCharacteristic> GetVendorSpecificCharacteristics() = 0;
308 virtual void OpenSession(
309 uint16_t connection_handle, uint16_t att_handle,
310 const std::vector<hal::VendorSpecificCharacteristic>& vendor_specific_data) = 0;
311 virtual void HandleVendorSpecificReply(
312 uint16_t connection_handle,
313 const std::vector<hal::VendorSpecificCharacteristic>& vendor_specific_reply) = 0;
314 virtual void WriteRawData(uint16_t connection_handle, const ChannelSoundingRawData& raw_data) = 0;
315 virtual void UpdateChannelSoundingConfig(
316 uint16_t connection_handle, const hci::LeCsConfigCompleteView& leCsConfigCompleteView,
317 uint8_t local_supported_sw_time, uint8_t remote_supported_sw_time,
318 uint16_t conn_interval) = 0;
319 virtual void UpdateConnInterval(uint16_t connection_handle, uint16_t conn_interval) = 0;
320 virtual void UpdateProcedureEnableConfig(
321 uint16_t connection_handle,
322 const hci::LeCsProcedureEnableCompleteView& leCsProcedureEnableCompleteView) = 0;
323 virtual void WriteProcedureData(uint16_t connection_handle, hci::CsRole local_cs_role,
324 const ProcedureDataV2& procedure_data,
325 uint16_t procedure_counter) = 0;
326 };
327
328 } // namespace hal
329 } // namespace bluetooth
330