Loading system/gd/hal/ranging_hal.h +235 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,15 @@ namespace bluetooth { namespace bluetooth { namespace hal { namespace hal { /** * See BLUETOOTH CORE SPECIFICATION Version 6.0 | Vol 4, Part E 7.7.65.44 ((LE CS Subevent Result) * for details. */ static constexpr uint8_t kInitiatorMeasuredOffsetBits = 15; static constexpr uint16_t kUnavailableInitiatorMeasuredOffset = 0xC000; static constexpr uint8_t kUnavailablePacketRssi = 0x7F; static constexpr uint8_t kIQSampleBits = 12; enum RangingHalVersion { enum RangingHalVersion { V_UNKNOWN = 0, V_UNKNOWN = 0, V_1 = 1, V_1 = 1, Loading @@ -47,6 +56,229 @@ struct ChannelSoundingRawData { std::vector<int16_t> tod_toa_reflectors_; std::vector<int16_t> tod_toa_reflectors_; }; }; // TODO: move to a utility file and add UT. template <int BITS> static inline int16_t ConvertToSigned(uint16_t num) { unsigned msb_mask = 1 << (BITS - 1); // setup a mask for most significant bit int16_t num_signed = num; if ((num_signed & msb_mask) != 0) { num_signed |= ~(msb_mask - 1); // extend the MSB } return num_signed; } struct Mode0Data { Mode0Data(const hci::LeCsMode0InitatorData& le_cs_mode0_data) : packet_quality_(le_cs_mode0_data.packet_quality_), packet_rssi_(le_cs_mode0_data.packet_rssi_), packet_antenna_(le_cs_mode0_data.packet_antenna_), initiator_measured_offset(le_cs_mode0_data.measured_freq_offset_) {} Mode0Data(const hci::LeCsMode0ReflectorData& le_cs_mode0_data) : packet_quality_(le_cs_mode0_data.packet_quality_), packet_rssi_(le_cs_mode0_data.packet_rssi_), packet_antenna_(le_cs_mode0_data.packet_antenna_) {} uint8_t packet_quality_ = 0; uint8_t packet_rssi_ = kUnavailablePacketRssi; uint8_t packet_antenna_ = 0; uint16_t initiator_measured_offset = kUnavailableInitiatorMeasuredOffset; }; struct Mode1Data { Mode1Data() {} Mode1Data(const hci::LeCsMode1InitatorData& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.toa_tod_initiator_), packet_antenna_(le_cs_mode1_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode1InitatorDataWithPacketPct& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.toa_tod_initiator_), packet_antenna_(le_cs_mode1_data.packet_antenna_), i_packet_pct1_(le_cs_mode1_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode1_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode1_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode1_data.packet_pct2_.q_sample_) {} Mode1Data(const hci::LeCsMode1ReflectorData& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.tod_toa_reflector_), packet_antenna_(le_cs_mode1_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode1ReflectorDataWithPacketPct& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.tod_toa_reflector_), packet_antenna_(le_cs_mode1_data.packet_antenna_), i_packet_pct1_(le_cs_mode1_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode1_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode1_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode1_data.packet_pct2_.q_sample_) {} Mode1Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.toa_tod_initiator_), packet_antenna_(le_cs_mode3_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.toa_tod_initiator_), packet_antenna_(le_cs_mode3_data.packet_antenna_), i_packet_pct1_(le_cs_mode3_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode3_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode3_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode3_data.packet_pct2_.q_sample_) {} Mode1Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.tod_toa_reflector_), packet_antenna_(le_cs_mode3_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.tod_toa_reflector_), packet_antenna_(le_cs_mode3_data.packet_antenna_), i_packet_pct1_(le_cs_mode3_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode3_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode3_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode3_data.packet_pct2_.q_sample_) {} uint8_t packet_quality_ = 0; hci::CsPacketNadm packet_nadm_ = hci::CsPacketNadm::UNKNOWN_NADM; uint8_t packet_rssi_ = kUnavailablePacketRssi; uint16_t rtt_toa_tod_data_ = 0; uint8_t packet_antenna_ = 0; std::optional<uint16_t> i_packet_pct1_ = std::nullopt; std::optional<uint16_t> q_packet_pct1_ = std::nullopt; std::optional<uint16_t> i_packet_pct2_ = std::nullopt; std::optional<uint16_t> q_packet_pct2_ = std::nullopt; }; struct Mode2Data { Mode2Data() {} Mode2Data(const hci::LeCsMode2Data& le_cs_mode2_data) : antenna_permutation_index_(le_cs_mode2_data.antenna_permutation_index_) { std::copy(le_cs_mode2_data.tone_data_.begin(), le_cs_mode2_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } uint8_t antenna_permutation_index_ = 0; std::vector<hci::LeCsToneDataWithQuality> tone_data_with_qualities_; }; struct Mode3Data { Mode3Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode3Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode3Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode3Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode1Data mode1_data_; Mode2Data mode2_data_; }; struct StepSpecificData { uint8_t step_channel_; uint8_t mode_type_; // ModeSpecificData mode_specific_data_; std::variant<Mode0Data, Mode1Data, Mode2Data, Mode3Data> mode_specific_data_; }; struct SubeventResult { /** * Starting ACL connection event counter for the results reported in the event */ int start_acl_conn_event_counter_; /** * Frequency compensation value in units of 0.01 ppm (15-bit signed integer) * Unit: 0.01 ppm * 0xC000 - Frequency compensation value is not available, or the role is not initiator */ uint16_t frequency_compensation_ = 0xC000; /** * Reference power level * Range: -127 to 20 * Unit: dBm */ uint8_t reference_power_level_; /** * 0x00 Ignored because phase measurement does not occur during the CS step * 0x01 to 0x04 Number of antenna paths used during the phase measurement stage of the CS step */ uint8_t num_antenna_paths_; /** * Indicates the abort reason */ hci::SubeventAbortReason subevent_abort_reason_; /** * The measured data for all steps */ std::vector<StepSpecificData> step_data_; /** * Timestamp when all subevent data are received by the host; Not defined by the spec. * Using epoch time in nanos (e.g., 1697673127175). */ long timestamp_nanos_; }; struct ProcedureDataV2 { // for HAL v2 std::vector<std::shared_ptr<hal::SubeventResult>> local_subevent_data_; std::vector<std::shared_ptr<hal::SubeventResult>> remote_subevent_data_; hci::ProcedureAbortReason local_procedure_abort_reason_; hci::ProcedureAbortReason remote_procedure_abort_reason_; uint8_t local_selected_tx_power_; uint8_t remote_selected_tx_power_; // TODO(b/378942784): assign the sequence int procedure_sequence_; }; struct RangingResult { struct RangingResult { double result_meters_; double result_meters_; // A normalized value from 0 (low confidence) to 100 (high confidence) representing the confidence // A normalized value from 0 (low confidence) to 100 (high confidence) representing the confidence Loading Loading @@ -86,6 +318,9 @@ public: virtual void UpdateProcedureEnableConfig( virtual void UpdateProcedureEnableConfig( uint16_t connection_handle, uint16_t connection_handle, const hci::LeCsProcedureEnableCompleteView& leCsProcedureEnableCompleteView) = 0; const hci::LeCsProcedureEnableCompleteView& leCsProcedureEnableCompleteView) = 0; virtual void WriteProcedureData(uint16_t connection_handle, hci::CsRole local_cs_role, const ProcedureDataV2& procedure_data, uint16_t procedure_counter) = 0; }; }; } // namespace hal } // namespace hal Loading system/gd/hal/ranging_hal_android.cc +173 −0 Original line number Original line Diff line number Diff line Loading @@ -51,6 +51,21 @@ using aidl::android::hardware::bluetooth::ranging::SubModeType; using aidl::android::hardware::bluetooth::ranging::VendorSpecificData; using aidl::android::hardware::bluetooth::ranging::VendorSpecificData; // using aidl::android::hardware::bluetooth::ranging:: // using aidl::android::hardware::bluetooth::ranging:: using aidl::android::hardware::bluetooth::ranging::ChannelSoundingProcedureData; using aidl::android::hardware::bluetooth::ranging::ModeData; using aidl::android::hardware::bluetooth::ranging::ModeOneData; using aidl::android::hardware::bluetooth::ranging::ModeThreeData; using aidl::android::hardware::bluetooth::ranging::ModeTwoData; using aidl::android::hardware::bluetooth::ranging::ModeType; using aidl::android::hardware::bluetooth::ranging::ModeZeroData; using aidl::android::hardware::bluetooth::ranging::Nadm; using aidl::android::hardware::bluetooth::ranging::PctIQSample; using aidl::android::hardware::bluetooth::ranging::ProcedureAbortReason; using aidl::android::hardware::bluetooth::ranging::RttToaTodData; using aidl::android::hardware::bluetooth::ranging::StepData; using aidl::android::hardware::bluetooth::ranging::SubeventAbortReason; using aidl::android::hardware::bluetooth::ranging::SubeventResultData; namespace bluetooth { namespace bluetooth { namespace hal { namespace hal { Loading Loading @@ -322,6 +337,164 @@ public: it->second->GetSession()->updateProcedureEnableConfig(pConfig); it->second->GetSession()->updateProcedureEnableConfig(pConfig); } } void WriteProcedureData(const uint16_t connection_handle, hci::CsRole local_cs_role, const ProcedureDataV2& procedure_data, uint16_t procedure_counter) override { auto session_it = session_trackers_.find(connection_handle); if (session_it == session_trackers_.end()) { log::error("Can't find session for connection_handle:0x{:04x}", connection_handle); return; } else if (session_it->second->GetSession() == nullptr) { log::error("Session not opened"); return; } ChannelSoundingProcedureData channel_sounding_procedure_data; channel_sounding_procedure_data.procedureCounter = procedure_counter; channel_sounding_procedure_data.procedureSequence = procedure_data.procedure_sequence_; if (local_cs_role == hci::CsRole::INITIATOR) { channel_sounding_procedure_data.initiatorSelectedTxPower = static_cast<int8_t>(procedure_data.local_selected_tx_power_); channel_sounding_procedure_data.reflectorSelectedTxPower = static_cast<int8_t>(procedure_data.remote_selected_tx_power_); channel_sounding_procedure_data.initiatorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.local_procedure_abort_reason_); channel_sounding_procedure_data.reflectorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.remote_procedure_abort_reason_); channel_sounding_procedure_data.initiatorSubeventResultData = get_subevent_result_data(procedure_data.local_subevent_data_, hci::CsRole::INITIATOR); channel_sounding_procedure_data.reflectorSubeventResultData = get_subevent_result_data( procedure_data.remote_subevent_data_, hci::CsRole::REFLECTOR); } else { channel_sounding_procedure_data.initiatorSelectedTxPower = static_cast<int8_t>(procedure_data.remote_selected_tx_power_); channel_sounding_procedure_data.reflectorSelectedTxPower = static_cast<int8_t>(procedure_data.local_selected_tx_power_); channel_sounding_procedure_data.initiatorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.remote_procedure_abort_reason_); channel_sounding_procedure_data.reflectorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.local_procedure_abort_reason_); channel_sounding_procedure_data.initiatorSubeventResultData = get_subevent_result_data( procedure_data.remote_subevent_data_, hci::CsRole::INITIATOR); channel_sounding_procedure_data.reflectorSubeventResultData = get_subevent_result_data(procedure_data.local_subevent_data_, hci::CsRole::REFLECTOR); session_it->second->GetSession()->writeProcedureData(channel_sounding_procedure_data); } } static std::vector<SubeventResultData> get_subevent_result_data( const std::vector<std::shared_ptr<SubeventResult>>& subevent_results, hci::CsRole cs_role) { std::vector<SubeventResultData> hal_subevents; for (auto subevent_result : subevent_results) { SubeventResultData aidl_subevent_result{ .startAclConnEventCounter = subevent_result->start_acl_conn_event_counter_, .frequencyCompensation = ConvertToSigned<kInitiatorMeasuredOffsetBits>( subevent_result->frequency_compensation_), .referencePowerLevelDbm = static_cast<int8_t>(subevent_result->reference_power_level_), .numAntennaPaths = static_cast<int8_t>(subevent_result->num_antenna_paths_), .subeventAbortReason = static_cast<SubeventAbortReason>(subevent_result->subevent_abort_reason_), .stepData = get_group_step_data(subevent_result->step_data_, cs_role), .timestampNanos = subevent_result->timestamp_nanos_, }; hal_subevents.push_back(aidl_subevent_result); } return hal_subevents; } static std::vector<StepData> get_group_step_data( const std::vector<StepSpecificData>& step_specific_data_list, hci::CsRole cs_role) { std::vector<StepData> group_step_data; for (auto step_specific_data : step_specific_data_list) { StepData step_data{ .stepChannel = static_cast<int8_t>(step_specific_data.step_channel_), .stepMode = static_cast<ModeType>(step_specific_data.mode_type_), }; get_step_mode_data(step_specific_data.mode_specific_data_, step_data.stepModeData, cs_role); group_step_data.push_back(step_data); } return group_step_data; } static void get_step_mode_data( std::variant<Mode0Data, Mode1Data, Mode2Data, Mode3Data> mode_specific_data, ModeData& mode_data, hci::CsRole cs_role) { if (std::holds_alternative<Mode0Data>(mode_specific_data)) { auto mode_0_data = std::get<Mode0Data>(mode_specific_data); ModeZeroData mode_zero_data{ .packetQuality = static_cast<int8_t>(mode_0_data.packet_quality_), .packetRssiDbm = static_cast<int8_t>(mode_0_data.packet_rssi_), .packetAntenna = static_cast<int8_t>(mode_0_data.packet_antenna_), }; mode_data = mode_zero_data; return; } if (std::holds_alternative<Mode1Data>(mode_specific_data)) { auto mode_1_data = std::get<Mode1Data>(mode_specific_data); mode_data = convert_mode_1_data(mode_1_data, cs_role); return; } if (std::holds_alternative<Mode2Data>(mode_specific_data)) { auto mode_2_data = std::get<Mode2Data>(mode_specific_data); mode_data = convert_mode_2_data(mode_2_data); return; } if (std::holds_alternative<Mode3Data>(mode_specific_data)) { auto mode_3_data = std::get<Mode3Data>(mode_specific_data); ModeThreeData mode_three_data{ .modeOneData = convert_mode_1_data(mode_3_data.mode1_data_, cs_role), .modeTwoData = convert_mode_2_data(mode_3_data.mode2_data_), }; mode_data = mode_three_data; return; } } static ModeOneData convert_mode_1_data(const Mode1Data& mode_1_data, hci::CsRole cs_role) { ModeOneData mode_one_data{ .packetQuality = static_cast<int8_t>(mode_1_data.packet_quality_), .packetNadm = static_cast<Nadm>(mode_1_data.packet_nadm_), .packetRssiDbm = static_cast<int8_t>(mode_1_data.packet_rssi_), .packetAntenna = static_cast<int8_t>(mode_1_data.packet_antenna_), }; if (cs_role == hci::CsRole::INITIATOR) { mode_one_data.rttToaTodData = RttToaTodData::make<RttToaTodData::Tag::toaTodInitiator>( static_cast<int16_t>(mode_1_data.rtt_toa_tod_data_)); } else { mode_one_data.rttToaTodData = RttToaTodData::make<RttToaTodData::Tag::todToaReflector>( static_cast<int16_t>(mode_1_data.rtt_toa_tod_data_)); } // TODO(b/378942784): once get 32 bits from controller, and check the unavailable data. if (mode_1_data.i_packet_pct1_.has_value()) { mode_one_data.packetPct1.emplace( ConvertToSigned<kIQSampleBits>(mode_1_data.i_packet_pct1_.value()), ConvertToSigned<kIQSampleBits>(mode_1_data.q_packet_pct1_.value())); } if (mode_1_data.i_packet_pct2_.has_value()) { mode_one_data.packetPct2.emplace( ConvertToSigned<kIQSampleBits>(mode_1_data.i_packet_pct2_.value()), ConvertToSigned<kIQSampleBits>(mode_1_data.q_packet_pct2_.value())); } return mode_one_data; } static ModeTwoData convert_mode_2_data(const Mode2Data& mode_2_data) { ModeTwoData mode_two_data{ .antennaPermutationIndex = static_cast<int8_t>(mode_2_data.antenna_permutation_index_), }; for (const auto& tone_data_with_quality : mode_2_data.tone_data_with_qualities_) { mode_two_data.toneQualityIndicators.emplace_back( tone_data_with_quality.tone_quality_indicator_); mode_two_data.tonePctIQSamples.emplace_back( ConvertToSigned<kIQSampleBits>(tone_data_with_quality.i_sample_), ConvertToSigned<kIQSampleBits>(tone_data_with_quality.q_sample_)); } return mode_two_data; } void CopyVendorSpecificData(const std::vector<hal::VendorSpecificCharacteristic>& source, void CopyVendorSpecificData(const std::vector<hal::VendorSpecificCharacteristic>& source, std::optional<std::vector<std::optional<VendorSpecificData>>>& dist) { std::optional<std::vector<std::optional<VendorSpecificData>>>& dist) { dist = std::make_optional<std::vector<std::optional<VendorSpecificData>>>(); dist = std::make_optional<std::vector<std::optional<VendorSpecificData>>>(); Loading system/gd/hal/ranging_hal_host.cc +4 −0 Original line number Original line Diff line number Diff line Loading @@ -54,6 +54,10 @@ public: const hci::LeCsProcedureEnableCompleteView& /* leCsProcedureEnableCompleteView */) const hci::LeCsProcedureEnableCompleteView& /* leCsProcedureEnableCompleteView */) override {} override {} void WriteProcedureData(uint16_t /* connection_handle */, hci::CsRole /* local_cs_role */, const ProcedureDataV2& /* procedure_data */, uint16_t /* procedure_counter */) {} protected: protected: void ListDependencies(ModuleList* /*list*/) const {} void ListDependencies(ModuleList* /*list*/) const {} Loading system/gd/hci/distance_measurement_manager.cc +214 −47 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
system/gd/hal/ranging_hal.h +235 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,15 @@ namespace bluetooth { namespace bluetooth { namespace hal { namespace hal { /** * See BLUETOOTH CORE SPECIFICATION Version 6.0 | Vol 4, Part E 7.7.65.44 ((LE CS Subevent Result) * for details. */ static constexpr uint8_t kInitiatorMeasuredOffsetBits = 15; static constexpr uint16_t kUnavailableInitiatorMeasuredOffset = 0xC000; static constexpr uint8_t kUnavailablePacketRssi = 0x7F; static constexpr uint8_t kIQSampleBits = 12; enum RangingHalVersion { enum RangingHalVersion { V_UNKNOWN = 0, V_UNKNOWN = 0, V_1 = 1, V_1 = 1, Loading @@ -47,6 +56,229 @@ struct ChannelSoundingRawData { std::vector<int16_t> tod_toa_reflectors_; std::vector<int16_t> tod_toa_reflectors_; }; }; // TODO: move to a utility file and add UT. template <int BITS> static inline int16_t ConvertToSigned(uint16_t num) { unsigned msb_mask = 1 << (BITS - 1); // setup a mask for most significant bit int16_t num_signed = num; if ((num_signed & msb_mask) != 0) { num_signed |= ~(msb_mask - 1); // extend the MSB } return num_signed; } struct Mode0Data { Mode0Data(const hci::LeCsMode0InitatorData& le_cs_mode0_data) : packet_quality_(le_cs_mode0_data.packet_quality_), packet_rssi_(le_cs_mode0_data.packet_rssi_), packet_antenna_(le_cs_mode0_data.packet_antenna_), initiator_measured_offset(le_cs_mode0_data.measured_freq_offset_) {} Mode0Data(const hci::LeCsMode0ReflectorData& le_cs_mode0_data) : packet_quality_(le_cs_mode0_data.packet_quality_), packet_rssi_(le_cs_mode0_data.packet_rssi_), packet_antenna_(le_cs_mode0_data.packet_antenna_) {} uint8_t packet_quality_ = 0; uint8_t packet_rssi_ = kUnavailablePacketRssi; uint8_t packet_antenna_ = 0; uint16_t initiator_measured_offset = kUnavailableInitiatorMeasuredOffset; }; struct Mode1Data { Mode1Data() {} Mode1Data(const hci::LeCsMode1InitatorData& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.toa_tod_initiator_), packet_antenna_(le_cs_mode1_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode1InitatorDataWithPacketPct& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.toa_tod_initiator_), packet_antenna_(le_cs_mode1_data.packet_antenna_), i_packet_pct1_(le_cs_mode1_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode1_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode1_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode1_data.packet_pct2_.q_sample_) {} Mode1Data(const hci::LeCsMode1ReflectorData& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.tod_toa_reflector_), packet_antenna_(le_cs_mode1_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode1ReflectorDataWithPacketPct& le_cs_mode1_data) : packet_quality_(le_cs_mode1_data.packet_quality_), packet_nadm_(le_cs_mode1_data.packet_nadm_), packet_rssi_(le_cs_mode1_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode1_data.tod_toa_reflector_), packet_antenna_(le_cs_mode1_data.packet_antenna_), i_packet_pct1_(le_cs_mode1_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode1_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode1_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode1_data.packet_pct2_.q_sample_) {} Mode1Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.toa_tod_initiator_), packet_antenna_(le_cs_mode3_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.toa_tod_initiator_), packet_antenna_(le_cs_mode3_data.packet_antenna_), i_packet_pct1_(le_cs_mode3_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode3_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode3_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode3_data.packet_pct2_.q_sample_) {} Mode1Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.tod_toa_reflector_), packet_antenna_(le_cs_mode3_data.packet_antenna_) {} Mode1Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data) : packet_quality_(le_cs_mode3_data.packet_quality_), packet_nadm_(le_cs_mode3_data.packet_nadm_), packet_rssi_(le_cs_mode3_data.packet_rssi_), rtt_toa_tod_data_(le_cs_mode3_data.tod_toa_reflector_), packet_antenna_(le_cs_mode3_data.packet_antenna_), i_packet_pct1_(le_cs_mode3_data.packet_pct1_.i_sample_), q_packet_pct1_(le_cs_mode3_data.packet_pct1_.q_sample_), i_packet_pct2_(le_cs_mode3_data.packet_pct2_.i_sample_), q_packet_pct2_(le_cs_mode3_data.packet_pct2_.q_sample_) {} uint8_t packet_quality_ = 0; hci::CsPacketNadm packet_nadm_ = hci::CsPacketNadm::UNKNOWN_NADM; uint8_t packet_rssi_ = kUnavailablePacketRssi; uint16_t rtt_toa_tod_data_ = 0; uint8_t packet_antenna_ = 0; std::optional<uint16_t> i_packet_pct1_ = std::nullopt; std::optional<uint16_t> q_packet_pct1_ = std::nullopt; std::optional<uint16_t> i_packet_pct2_ = std::nullopt; std::optional<uint16_t> q_packet_pct2_ = std::nullopt; }; struct Mode2Data { Mode2Data() {} Mode2Data(const hci::LeCsMode2Data& le_cs_mode2_data) : antenna_permutation_index_(le_cs_mode2_data.antenna_permutation_index_) { std::copy(le_cs_mode2_data.tone_data_.begin(), le_cs_mode2_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } Mode2Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data) : antenna_permutation_index_(le_cs_mode3_data.antenna_permutation_index_) { std::copy(le_cs_mode3_data.tone_data_.begin(), le_cs_mode3_data.tone_data_.end(), std::back_inserter(tone_data_with_qualities_)); } uint8_t antenna_permutation_index_ = 0; std::vector<hci::LeCsToneDataWithQuality> tone_data_with_qualities_; }; struct Mode3Data { Mode3Data(const hci::LeCsMode3InitatorData& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode3Data(const hci::LeCsMode3InitatorDataWithPacketPct& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode3Data(const hci::LeCsMode3ReflectorData& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode3Data(const hci::LeCsMode3ReflectorDataWithPacketPct& le_cs_mode3_data) : mode1_data_(le_cs_mode3_data), mode2_data_(le_cs_mode3_data) {} Mode1Data mode1_data_; Mode2Data mode2_data_; }; struct StepSpecificData { uint8_t step_channel_; uint8_t mode_type_; // ModeSpecificData mode_specific_data_; std::variant<Mode0Data, Mode1Data, Mode2Data, Mode3Data> mode_specific_data_; }; struct SubeventResult { /** * Starting ACL connection event counter for the results reported in the event */ int start_acl_conn_event_counter_; /** * Frequency compensation value in units of 0.01 ppm (15-bit signed integer) * Unit: 0.01 ppm * 0xC000 - Frequency compensation value is not available, or the role is not initiator */ uint16_t frequency_compensation_ = 0xC000; /** * Reference power level * Range: -127 to 20 * Unit: dBm */ uint8_t reference_power_level_; /** * 0x00 Ignored because phase measurement does not occur during the CS step * 0x01 to 0x04 Number of antenna paths used during the phase measurement stage of the CS step */ uint8_t num_antenna_paths_; /** * Indicates the abort reason */ hci::SubeventAbortReason subevent_abort_reason_; /** * The measured data for all steps */ std::vector<StepSpecificData> step_data_; /** * Timestamp when all subevent data are received by the host; Not defined by the spec. * Using epoch time in nanos (e.g., 1697673127175). */ long timestamp_nanos_; }; struct ProcedureDataV2 { // for HAL v2 std::vector<std::shared_ptr<hal::SubeventResult>> local_subevent_data_; std::vector<std::shared_ptr<hal::SubeventResult>> remote_subevent_data_; hci::ProcedureAbortReason local_procedure_abort_reason_; hci::ProcedureAbortReason remote_procedure_abort_reason_; uint8_t local_selected_tx_power_; uint8_t remote_selected_tx_power_; // TODO(b/378942784): assign the sequence int procedure_sequence_; }; struct RangingResult { struct RangingResult { double result_meters_; double result_meters_; // A normalized value from 0 (low confidence) to 100 (high confidence) representing the confidence // A normalized value from 0 (low confidence) to 100 (high confidence) representing the confidence Loading Loading @@ -86,6 +318,9 @@ public: virtual void UpdateProcedureEnableConfig( virtual void UpdateProcedureEnableConfig( uint16_t connection_handle, uint16_t connection_handle, const hci::LeCsProcedureEnableCompleteView& leCsProcedureEnableCompleteView) = 0; const hci::LeCsProcedureEnableCompleteView& leCsProcedureEnableCompleteView) = 0; virtual void WriteProcedureData(uint16_t connection_handle, hci::CsRole local_cs_role, const ProcedureDataV2& procedure_data, uint16_t procedure_counter) = 0; }; }; } // namespace hal } // namespace hal Loading
system/gd/hal/ranging_hal_android.cc +173 −0 Original line number Original line Diff line number Diff line Loading @@ -51,6 +51,21 @@ using aidl::android::hardware::bluetooth::ranging::SubModeType; using aidl::android::hardware::bluetooth::ranging::VendorSpecificData; using aidl::android::hardware::bluetooth::ranging::VendorSpecificData; // using aidl::android::hardware::bluetooth::ranging:: // using aidl::android::hardware::bluetooth::ranging:: using aidl::android::hardware::bluetooth::ranging::ChannelSoundingProcedureData; using aidl::android::hardware::bluetooth::ranging::ModeData; using aidl::android::hardware::bluetooth::ranging::ModeOneData; using aidl::android::hardware::bluetooth::ranging::ModeThreeData; using aidl::android::hardware::bluetooth::ranging::ModeTwoData; using aidl::android::hardware::bluetooth::ranging::ModeType; using aidl::android::hardware::bluetooth::ranging::ModeZeroData; using aidl::android::hardware::bluetooth::ranging::Nadm; using aidl::android::hardware::bluetooth::ranging::PctIQSample; using aidl::android::hardware::bluetooth::ranging::ProcedureAbortReason; using aidl::android::hardware::bluetooth::ranging::RttToaTodData; using aidl::android::hardware::bluetooth::ranging::StepData; using aidl::android::hardware::bluetooth::ranging::SubeventAbortReason; using aidl::android::hardware::bluetooth::ranging::SubeventResultData; namespace bluetooth { namespace bluetooth { namespace hal { namespace hal { Loading Loading @@ -322,6 +337,164 @@ public: it->second->GetSession()->updateProcedureEnableConfig(pConfig); it->second->GetSession()->updateProcedureEnableConfig(pConfig); } } void WriteProcedureData(const uint16_t connection_handle, hci::CsRole local_cs_role, const ProcedureDataV2& procedure_data, uint16_t procedure_counter) override { auto session_it = session_trackers_.find(connection_handle); if (session_it == session_trackers_.end()) { log::error("Can't find session for connection_handle:0x{:04x}", connection_handle); return; } else if (session_it->second->GetSession() == nullptr) { log::error("Session not opened"); return; } ChannelSoundingProcedureData channel_sounding_procedure_data; channel_sounding_procedure_data.procedureCounter = procedure_counter; channel_sounding_procedure_data.procedureSequence = procedure_data.procedure_sequence_; if (local_cs_role == hci::CsRole::INITIATOR) { channel_sounding_procedure_data.initiatorSelectedTxPower = static_cast<int8_t>(procedure_data.local_selected_tx_power_); channel_sounding_procedure_data.reflectorSelectedTxPower = static_cast<int8_t>(procedure_data.remote_selected_tx_power_); channel_sounding_procedure_data.initiatorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.local_procedure_abort_reason_); channel_sounding_procedure_data.reflectorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.remote_procedure_abort_reason_); channel_sounding_procedure_data.initiatorSubeventResultData = get_subevent_result_data(procedure_data.local_subevent_data_, hci::CsRole::INITIATOR); channel_sounding_procedure_data.reflectorSubeventResultData = get_subevent_result_data( procedure_data.remote_subevent_data_, hci::CsRole::REFLECTOR); } else { channel_sounding_procedure_data.initiatorSelectedTxPower = static_cast<int8_t>(procedure_data.remote_selected_tx_power_); channel_sounding_procedure_data.reflectorSelectedTxPower = static_cast<int8_t>(procedure_data.local_selected_tx_power_); channel_sounding_procedure_data.initiatorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.remote_procedure_abort_reason_); channel_sounding_procedure_data.reflectorProcedureAbortReason = static_cast<ProcedureAbortReason>(procedure_data.local_procedure_abort_reason_); channel_sounding_procedure_data.initiatorSubeventResultData = get_subevent_result_data( procedure_data.remote_subevent_data_, hci::CsRole::INITIATOR); channel_sounding_procedure_data.reflectorSubeventResultData = get_subevent_result_data(procedure_data.local_subevent_data_, hci::CsRole::REFLECTOR); session_it->second->GetSession()->writeProcedureData(channel_sounding_procedure_data); } } static std::vector<SubeventResultData> get_subevent_result_data( const std::vector<std::shared_ptr<SubeventResult>>& subevent_results, hci::CsRole cs_role) { std::vector<SubeventResultData> hal_subevents; for (auto subevent_result : subevent_results) { SubeventResultData aidl_subevent_result{ .startAclConnEventCounter = subevent_result->start_acl_conn_event_counter_, .frequencyCompensation = ConvertToSigned<kInitiatorMeasuredOffsetBits>( subevent_result->frequency_compensation_), .referencePowerLevelDbm = static_cast<int8_t>(subevent_result->reference_power_level_), .numAntennaPaths = static_cast<int8_t>(subevent_result->num_antenna_paths_), .subeventAbortReason = static_cast<SubeventAbortReason>(subevent_result->subevent_abort_reason_), .stepData = get_group_step_data(subevent_result->step_data_, cs_role), .timestampNanos = subevent_result->timestamp_nanos_, }; hal_subevents.push_back(aidl_subevent_result); } return hal_subevents; } static std::vector<StepData> get_group_step_data( const std::vector<StepSpecificData>& step_specific_data_list, hci::CsRole cs_role) { std::vector<StepData> group_step_data; for (auto step_specific_data : step_specific_data_list) { StepData step_data{ .stepChannel = static_cast<int8_t>(step_specific_data.step_channel_), .stepMode = static_cast<ModeType>(step_specific_data.mode_type_), }; get_step_mode_data(step_specific_data.mode_specific_data_, step_data.stepModeData, cs_role); group_step_data.push_back(step_data); } return group_step_data; } static void get_step_mode_data( std::variant<Mode0Data, Mode1Data, Mode2Data, Mode3Data> mode_specific_data, ModeData& mode_data, hci::CsRole cs_role) { if (std::holds_alternative<Mode0Data>(mode_specific_data)) { auto mode_0_data = std::get<Mode0Data>(mode_specific_data); ModeZeroData mode_zero_data{ .packetQuality = static_cast<int8_t>(mode_0_data.packet_quality_), .packetRssiDbm = static_cast<int8_t>(mode_0_data.packet_rssi_), .packetAntenna = static_cast<int8_t>(mode_0_data.packet_antenna_), }; mode_data = mode_zero_data; return; } if (std::holds_alternative<Mode1Data>(mode_specific_data)) { auto mode_1_data = std::get<Mode1Data>(mode_specific_data); mode_data = convert_mode_1_data(mode_1_data, cs_role); return; } if (std::holds_alternative<Mode2Data>(mode_specific_data)) { auto mode_2_data = std::get<Mode2Data>(mode_specific_data); mode_data = convert_mode_2_data(mode_2_data); return; } if (std::holds_alternative<Mode3Data>(mode_specific_data)) { auto mode_3_data = std::get<Mode3Data>(mode_specific_data); ModeThreeData mode_three_data{ .modeOneData = convert_mode_1_data(mode_3_data.mode1_data_, cs_role), .modeTwoData = convert_mode_2_data(mode_3_data.mode2_data_), }; mode_data = mode_three_data; return; } } static ModeOneData convert_mode_1_data(const Mode1Data& mode_1_data, hci::CsRole cs_role) { ModeOneData mode_one_data{ .packetQuality = static_cast<int8_t>(mode_1_data.packet_quality_), .packetNadm = static_cast<Nadm>(mode_1_data.packet_nadm_), .packetRssiDbm = static_cast<int8_t>(mode_1_data.packet_rssi_), .packetAntenna = static_cast<int8_t>(mode_1_data.packet_antenna_), }; if (cs_role == hci::CsRole::INITIATOR) { mode_one_data.rttToaTodData = RttToaTodData::make<RttToaTodData::Tag::toaTodInitiator>( static_cast<int16_t>(mode_1_data.rtt_toa_tod_data_)); } else { mode_one_data.rttToaTodData = RttToaTodData::make<RttToaTodData::Tag::todToaReflector>( static_cast<int16_t>(mode_1_data.rtt_toa_tod_data_)); } // TODO(b/378942784): once get 32 bits from controller, and check the unavailable data. if (mode_1_data.i_packet_pct1_.has_value()) { mode_one_data.packetPct1.emplace( ConvertToSigned<kIQSampleBits>(mode_1_data.i_packet_pct1_.value()), ConvertToSigned<kIQSampleBits>(mode_1_data.q_packet_pct1_.value())); } if (mode_1_data.i_packet_pct2_.has_value()) { mode_one_data.packetPct2.emplace( ConvertToSigned<kIQSampleBits>(mode_1_data.i_packet_pct2_.value()), ConvertToSigned<kIQSampleBits>(mode_1_data.q_packet_pct2_.value())); } return mode_one_data; } static ModeTwoData convert_mode_2_data(const Mode2Data& mode_2_data) { ModeTwoData mode_two_data{ .antennaPermutationIndex = static_cast<int8_t>(mode_2_data.antenna_permutation_index_), }; for (const auto& tone_data_with_quality : mode_2_data.tone_data_with_qualities_) { mode_two_data.toneQualityIndicators.emplace_back( tone_data_with_quality.tone_quality_indicator_); mode_two_data.tonePctIQSamples.emplace_back( ConvertToSigned<kIQSampleBits>(tone_data_with_quality.i_sample_), ConvertToSigned<kIQSampleBits>(tone_data_with_quality.q_sample_)); } return mode_two_data; } void CopyVendorSpecificData(const std::vector<hal::VendorSpecificCharacteristic>& source, void CopyVendorSpecificData(const std::vector<hal::VendorSpecificCharacteristic>& source, std::optional<std::vector<std::optional<VendorSpecificData>>>& dist) { std::optional<std::vector<std::optional<VendorSpecificData>>>& dist) { dist = std::make_optional<std::vector<std::optional<VendorSpecificData>>>(); dist = std::make_optional<std::vector<std::optional<VendorSpecificData>>>(); Loading
system/gd/hal/ranging_hal_host.cc +4 −0 Original line number Original line Diff line number Diff line Loading @@ -54,6 +54,10 @@ public: const hci::LeCsProcedureEnableCompleteView& /* leCsProcedureEnableCompleteView */) const hci::LeCsProcedureEnableCompleteView& /* leCsProcedureEnableCompleteView */) override {} override {} void WriteProcedureData(uint16_t /* connection_handle */, hci::CsRole /* local_cs_role */, const ProcedureDataV2& /* procedure_data */, uint16_t /* procedure_counter */) {} protected: protected: void ListDependencies(ModuleList* /*list*/) const {} void ListDependencies(ModuleList* /*list*/) const {} Loading
system/gd/hci/distance_measurement_manager.cc +214 −47 File changed.Preview size limit exceeded, changes collapsed. Show changes