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