Loading system/gd/hci/distance_measurement_manager.cc +106 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ #include "os/log.h" #include "os/repeating_alarm.h" #include "packet/packet_view.h" #include "ras/ras_packets.h" using namespace bluetooth::ras; namespace bluetooth { namespace hci { Loading Loading @@ -64,7 +67,11 @@ static constexpr uint8_t kReportWithNoAbort = 0x00; struct DistanceMeasurementManager::impl { struct CsProcedureData { CsProcedureData(uint16_t procedure_counter, uint8_t num_antenna_paths) CsProcedureData( uint16_t procedure_counter, uint8_t num_antenna_paths, uint8_t configuration_id, uint8_t selected_tx_power) : counter(procedure_counter), num_antenna_paths(num_antenna_paths) { local_status = CsProcedureDoneStatus::PARTIAL_RESULTS; remote_status = CsProcedureDoneStatus::PARTIAL_RESULTS; Loading @@ -78,6 +85,14 @@ struct DistanceMeasurementManager::impl { tone_quality_indicator_initiator.push_back(empty_vector); tone_quality_indicator_reflector.push_back(empty_vector); } segmentation_header_.first_segment_ = 1; segmentation_header_.last_segment_ = 0; segmentation_header_.rolling_segment_counter_ = 0; ranging_header_.ranging_counter_ = counter; ranging_header_.configuration_id_ = configuration_id; ranging_header_.selected_tx_power_ = selected_tx_power; ranging_header_.antenna_paths_mask_ = 0x01; ranging_header_.pct_format_ = PctFormat::IQ; } // Procedure counter uint16_t counter; Loading @@ -102,6 +117,13 @@ struct DistanceMeasurementManager::impl { CsProcedureDoneStatus remote_status; // If the procedure is aborted by either the local or remote side. bool aborted = false; // RAS data SegmentationHeader segmentation_header_; RangingHeader ranging_header_; std::vector<uint8_t> ras_subevents; // raw data for multi_subevents; RasSubeventHeader ras_subevent_header_; std::vector<uint8_t> ras_subevent_data_; uint8_t ras_subevent_counter_ = 0; }; ~impl() {} Loading Loading @@ -565,8 +587,13 @@ struct DistanceMeasurementManager::impl { if (event_view.GetState() == Enable::ENABLED) { log::debug("Procedure enabled, {}", event_view.ToString()); if (cs_trackers_.find(connection_handle) != cs_trackers_.end() && cs_trackers_[connection_handle].waiting_for_start_callback) { if (cs_trackers_.find(connection_handle) == cs_trackers_.end()) { return; } cs_trackers_[connection_handle].config_id = event_view.GetConfigId(); cs_trackers_[connection_handle].selected_tx_power = event_view.GetSelectedTxPower(); if (cs_trackers_[connection_handle].waiting_for_start_callback) { cs_trackers_[connection_handle].waiting_for_start_callback = false; distance_measurement_callbacks_->OnDistanceMeasurementStarted( cs_trackers_[connection_handle].address, METHOD_CS); Loading Loading @@ -608,6 +635,22 @@ struct DistanceMeasurementManager::impl { procedure_data->frequency_compensation.push_back( cs_event_result.GetFrequencyCompensation()); } uint16_t antenna_paths_mask = 0; for (uint8_t i = 0; i < procedure_data->num_antenna_paths; i++) { antenna_paths_mask |= (1 << i); } // RAS procedure_data->ranging_header_.antenna_paths_mask_ = antenna_paths_mask; log::debug("RAS Update subevent_header counter:{}", procedure_data->ras_subevent_counter_++); auto& ras_subevent_header = procedure_data->ras_subevent_header_; ras_subevent_header.start_acl_conn_event_ = cs_event_result.GetStartAclConnEvent(); ras_subevent_header.frequency_compensation_ = cs_event_result.GetFrequencyCompensation(); ras_subevent_header.ranging_done_status_ = static_cast<RangingDoneStatus>(cs_event_result.GetProcedureDoneStatus()); ras_subevent_header.subevent_done_status_ = static_cast<SubeventDoneStatus>(cs_event_result.GetSubeventDoneStatus()); ras_subevent_header.reference_power_level_ = cs_event_result.GetReferencePowerLevel(); ras_subevent_header.num_steps_reported_ = 0; } else { auto cs_event_result = LeCsSubeventResultContinueView::Create(event); if (!cs_event_result.IsValid()) { Loading Loading @@ -642,18 +685,48 @@ struct DistanceMeasurementManager::impl { if (procedure_data == nullptr) { return; } procedure_data->ras_subevent_header_.num_steps_reported_ += result_data_structures.size(); if (abort_reason != kReportWithNoAbort) { // Even the procedure is aborted, we should keep following process and // handle it when all corresponding remote data received. procedure_data->aborted = true; } else { } parse_cs_result_data( result_data_structures, *procedure_data, cs_trackers_[connection_handle].role); } // Update procedure status procedure_data->local_status = procedure_done_status; check_cs_procedure_complete(procedure_data, connection_handle); // Send data to RAS server if (subevent_done_status != CsSubeventDoneStatus::PARTIAL_RESULTS) { auto builder = RasSubeventBuilder::Create( procedure_data->ras_subevent_header_, procedure_data->ras_subevent_data_); auto subevent_raw = builder_to_bytes(std::move(builder)); append_vector(procedure_data->ras_subevents, subevent_raw); // erase buffer procedure_data->ras_subevent_data_.clear(); send_on_demand_data(procedure_data); } } void send_on_demand_data(CsProcedureData* procedure_data) { if (procedure_data->local_status != CsProcedureDoneStatus::PARTIAL_RESULTS) { procedure_data->segmentation_header_.last_segment_ = 1; } auto builder = OnDemandRangingDataBuilder::Create( procedure_data->segmentation_header_, procedure_data->counter, procedure_data->ranging_header_, procedure_data->ras_subevents); auto raw_data = builder_to_bytes(std::move(builder)); log::debug("counter: {}, size:{}", procedure_data->counter, (uint16_t)raw_data.size()); // TODO, push data to RAS server procedure_data->ras_subevents.clear(); procedure_data->segmentation_header_.first_segment_ = 0; procedure_data->segmentation_header_.rolling_segment_counter_++; procedure_data->segmentation_header_.rolling_segment_counter_ %= 64; } void init_cs_procedure_data( Loading @@ -680,7 +753,11 @@ struct DistanceMeasurementManager::impl { } } log::info("Create data for procedure_counter: {}", procedure_counter); data_list.emplace_back(procedure_counter, num_antenna_paths); data_list.emplace_back( procedure_counter, num_antenna_paths, cs_trackers_[connection_handle].config_id, cs_trackers_[connection_handle].selected_tx_power); if (data_list.size() > kProcedureDataBufferSize) { log::warn("buffer full, drop procedure data with counter: {}", data_list.front().counter); Loading Loading @@ -732,14 +809,22 @@ struct DistanceMeasurementManager::impl { CsProcedureData& procedure_data, CsRole role) { uint8_t num_antenna_paths = procedure_data.num_antenna_paths; auto& ras_data = procedure_data.ras_subevent_data_; for (auto result_data_structure : result_data_structures) { uint16_t mode = result_data_structure.step_mode_; uint16_t step_channel = result_data_structure.step_channel_; uint16_t data_length = result_data_structure.step_data_.size(); log::verbose( "mode: {}, channel: {}, data_length: {}", mode, step_channel, (uint16_t)result_data_structure.step_data_.size()); ras_data.emplace_back(mode); if (data_length == 0) { ras_data.back() |= (1 << 7); // set step aborted continue; } append_vector(ras_data, result_data_structure.step_data_); // Parse data into structs from an iterator auto bytes = std::make_shared<std::vector<uint8_t>>(); Loading Loading @@ -980,6 +1065,18 @@ struct DistanceMeasurementManager::impl { DistanceMeasurementMethod::METHOD_RSSI); } std::vector<uint8_t> builder_to_bytes(std::unique_ptr<PacketBuilder<true>> builder) { std::shared_ptr<std::vector<uint8_t>> bytes = std::make_shared<std::vector<uint8_t>>(); BitInserter bi(*bytes); builder->Serialize(bi); return *bytes; } void append_vector(std::vector<uint8_t>& v1, std::vector<uint8_t>& v2) { v1.reserve(v2.size()); v1.insert(v1.end(), v2.begin(), v2.end()); } struct RSSITracker { uint16_t handle; uint16_t interval_ms; Loading @@ -999,6 +1096,8 @@ struct DistanceMeasurementManager::impl { CsSubModeType sub_mode_type; CsRttType rtt_type; bool remote_support_phase_based_ranging = false; uint8_t config_id = 0; uint8_t selected_tx_power = 0; std::vector<CsProcedureData> procedure_data_list; uint16_t interval_ms; bool waiting_for_start_callback = false; Loading Loading
system/gd/hci/distance_measurement_manager.cc +106 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ #include "os/log.h" #include "os/repeating_alarm.h" #include "packet/packet_view.h" #include "ras/ras_packets.h" using namespace bluetooth::ras; namespace bluetooth { namespace hci { Loading Loading @@ -64,7 +67,11 @@ static constexpr uint8_t kReportWithNoAbort = 0x00; struct DistanceMeasurementManager::impl { struct CsProcedureData { CsProcedureData(uint16_t procedure_counter, uint8_t num_antenna_paths) CsProcedureData( uint16_t procedure_counter, uint8_t num_antenna_paths, uint8_t configuration_id, uint8_t selected_tx_power) : counter(procedure_counter), num_antenna_paths(num_antenna_paths) { local_status = CsProcedureDoneStatus::PARTIAL_RESULTS; remote_status = CsProcedureDoneStatus::PARTIAL_RESULTS; Loading @@ -78,6 +85,14 @@ struct DistanceMeasurementManager::impl { tone_quality_indicator_initiator.push_back(empty_vector); tone_quality_indicator_reflector.push_back(empty_vector); } segmentation_header_.first_segment_ = 1; segmentation_header_.last_segment_ = 0; segmentation_header_.rolling_segment_counter_ = 0; ranging_header_.ranging_counter_ = counter; ranging_header_.configuration_id_ = configuration_id; ranging_header_.selected_tx_power_ = selected_tx_power; ranging_header_.antenna_paths_mask_ = 0x01; ranging_header_.pct_format_ = PctFormat::IQ; } // Procedure counter uint16_t counter; Loading @@ -102,6 +117,13 @@ struct DistanceMeasurementManager::impl { CsProcedureDoneStatus remote_status; // If the procedure is aborted by either the local or remote side. bool aborted = false; // RAS data SegmentationHeader segmentation_header_; RangingHeader ranging_header_; std::vector<uint8_t> ras_subevents; // raw data for multi_subevents; RasSubeventHeader ras_subevent_header_; std::vector<uint8_t> ras_subevent_data_; uint8_t ras_subevent_counter_ = 0; }; ~impl() {} Loading Loading @@ -565,8 +587,13 @@ struct DistanceMeasurementManager::impl { if (event_view.GetState() == Enable::ENABLED) { log::debug("Procedure enabled, {}", event_view.ToString()); if (cs_trackers_.find(connection_handle) != cs_trackers_.end() && cs_trackers_[connection_handle].waiting_for_start_callback) { if (cs_trackers_.find(connection_handle) == cs_trackers_.end()) { return; } cs_trackers_[connection_handle].config_id = event_view.GetConfigId(); cs_trackers_[connection_handle].selected_tx_power = event_view.GetSelectedTxPower(); if (cs_trackers_[connection_handle].waiting_for_start_callback) { cs_trackers_[connection_handle].waiting_for_start_callback = false; distance_measurement_callbacks_->OnDistanceMeasurementStarted( cs_trackers_[connection_handle].address, METHOD_CS); Loading Loading @@ -608,6 +635,22 @@ struct DistanceMeasurementManager::impl { procedure_data->frequency_compensation.push_back( cs_event_result.GetFrequencyCompensation()); } uint16_t antenna_paths_mask = 0; for (uint8_t i = 0; i < procedure_data->num_antenna_paths; i++) { antenna_paths_mask |= (1 << i); } // RAS procedure_data->ranging_header_.antenna_paths_mask_ = antenna_paths_mask; log::debug("RAS Update subevent_header counter:{}", procedure_data->ras_subevent_counter_++); auto& ras_subevent_header = procedure_data->ras_subevent_header_; ras_subevent_header.start_acl_conn_event_ = cs_event_result.GetStartAclConnEvent(); ras_subevent_header.frequency_compensation_ = cs_event_result.GetFrequencyCompensation(); ras_subevent_header.ranging_done_status_ = static_cast<RangingDoneStatus>(cs_event_result.GetProcedureDoneStatus()); ras_subevent_header.subevent_done_status_ = static_cast<SubeventDoneStatus>(cs_event_result.GetSubeventDoneStatus()); ras_subevent_header.reference_power_level_ = cs_event_result.GetReferencePowerLevel(); ras_subevent_header.num_steps_reported_ = 0; } else { auto cs_event_result = LeCsSubeventResultContinueView::Create(event); if (!cs_event_result.IsValid()) { Loading Loading @@ -642,18 +685,48 @@ struct DistanceMeasurementManager::impl { if (procedure_data == nullptr) { return; } procedure_data->ras_subevent_header_.num_steps_reported_ += result_data_structures.size(); if (abort_reason != kReportWithNoAbort) { // Even the procedure is aborted, we should keep following process and // handle it when all corresponding remote data received. procedure_data->aborted = true; } else { } parse_cs_result_data( result_data_structures, *procedure_data, cs_trackers_[connection_handle].role); } // Update procedure status procedure_data->local_status = procedure_done_status; check_cs_procedure_complete(procedure_data, connection_handle); // Send data to RAS server if (subevent_done_status != CsSubeventDoneStatus::PARTIAL_RESULTS) { auto builder = RasSubeventBuilder::Create( procedure_data->ras_subevent_header_, procedure_data->ras_subevent_data_); auto subevent_raw = builder_to_bytes(std::move(builder)); append_vector(procedure_data->ras_subevents, subevent_raw); // erase buffer procedure_data->ras_subevent_data_.clear(); send_on_demand_data(procedure_data); } } void send_on_demand_data(CsProcedureData* procedure_data) { if (procedure_data->local_status != CsProcedureDoneStatus::PARTIAL_RESULTS) { procedure_data->segmentation_header_.last_segment_ = 1; } auto builder = OnDemandRangingDataBuilder::Create( procedure_data->segmentation_header_, procedure_data->counter, procedure_data->ranging_header_, procedure_data->ras_subevents); auto raw_data = builder_to_bytes(std::move(builder)); log::debug("counter: {}, size:{}", procedure_data->counter, (uint16_t)raw_data.size()); // TODO, push data to RAS server procedure_data->ras_subevents.clear(); procedure_data->segmentation_header_.first_segment_ = 0; procedure_data->segmentation_header_.rolling_segment_counter_++; procedure_data->segmentation_header_.rolling_segment_counter_ %= 64; } void init_cs_procedure_data( Loading @@ -680,7 +753,11 @@ struct DistanceMeasurementManager::impl { } } log::info("Create data for procedure_counter: {}", procedure_counter); data_list.emplace_back(procedure_counter, num_antenna_paths); data_list.emplace_back( procedure_counter, num_antenna_paths, cs_trackers_[connection_handle].config_id, cs_trackers_[connection_handle].selected_tx_power); if (data_list.size() > kProcedureDataBufferSize) { log::warn("buffer full, drop procedure data with counter: {}", data_list.front().counter); Loading Loading @@ -732,14 +809,22 @@ struct DistanceMeasurementManager::impl { CsProcedureData& procedure_data, CsRole role) { uint8_t num_antenna_paths = procedure_data.num_antenna_paths; auto& ras_data = procedure_data.ras_subevent_data_; for (auto result_data_structure : result_data_structures) { uint16_t mode = result_data_structure.step_mode_; uint16_t step_channel = result_data_structure.step_channel_; uint16_t data_length = result_data_structure.step_data_.size(); log::verbose( "mode: {}, channel: {}, data_length: {}", mode, step_channel, (uint16_t)result_data_structure.step_data_.size()); ras_data.emplace_back(mode); if (data_length == 0) { ras_data.back() |= (1 << 7); // set step aborted continue; } append_vector(ras_data, result_data_structure.step_data_); // Parse data into structs from an iterator auto bytes = std::make_shared<std::vector<uint8_t>>(); Loading Loading @@ -980,6 +1065,18 @@ struct DistanceMeasurementManager::impl { DistanceMeasurementMethod::METHOD_RSSI); } std::vector<uint8_t> builder_to_bytes(std::unique_ptr<PacketBuilder<true>> builder) { std::shared_ptr<std::vector<uint8_t>> bytes = std::make_shared<std::vector<uint8_t>>(); BitInserter bi(*bytes); builder->Serialize(bi); return *bytes; } void append_vector(std::vector<uint8_t>& v1, std::vector<uint8_t>& v2) { v1.reserve(v2.size()); v1.insert(v1.end(), v2.begin(), v2.end()); } struct RSSITracker { uint16_t handle; uint16_t interval_ms; Loading @@ -999,6 +1096,8 @@ struct DistanceMeasurementManager::impl { CsSubModeType sub_mode_type; CsRttType rtt_type; bool remote_support_phase_based_ranging = false; uint8_t config_id = 0; uint8_t selected_tx_power = 0; std::vector<CsProcedureData> procedure_data_list; uint16_t interval_ms; bool waiting_for_start_callback = false; Loading