diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-13 17:24:27 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-13 17:24:27 +0000 |
commit | 298e3fdd2a49becf86e6c9cf61e194ac68c01648 (patch) | |
tree | 58bc51efb256cc67a751f3802ff3748355fe9fc4 | |
parent | f3f2368f948c2de2984d568427ecc6ba283150ac (diff) | |
parent | 44bd396458c0a0f4a5fa7ce808d04a49969b6e99 (diff) | |
download | uwb-android14-mainline-adbd-release.tar.gz |
Snap for 10491609 from 44bd396458c0a0f4a5fa7ce808d04a49969b6e99 to mainline-adbd-releaseaml_adb_340912530aml_adb_340912350aml_adb_340912200aml_adb_340912000android14-mainline-adbd-release
Change-Id: I618097e98106fc74e21852246bab62b16f0307a1
-rw-r--r-- | src/rust/uwb_core/protos/uwb_service.proto | 12 | ||||
-rw-r--r-- | src/rust/uwb_core/src/params/app_config_params.rs | 6 | ||||
-rw-r--r-- | src/rust/uwb_core/src/params/uci_packets.rs | 21 | ||||
-rw-r--r-- | src/rust/uwb_core/src/proto/mappings.rs | 6 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/command.rs | 23 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/error.rs | 5 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/mock_uci_manager.rs | 63 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/response.rs | 5 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_manager.rs | 76 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_manager_sync.rs | 23 | ||||
-rw-r--r-- | src/rust/uwb_uci_packets/uci_packets.pdl | 24 |
11 files changed, 244 insertions, 20 deletions
diff --git a/src/rust/uwb_core/protos/uwb_service.proto b/src/rust/uwb_core/protos/uwb_service.proto index e13765e..2577ab0 100644 --- a/src/rust/uwb_core/protos/uwb_service.proto +++ b/src/rust/uwb_core/protos/uwb_service.proto @@ -183,10 +183,14 @@ enum RangingMeasurementType { // Represent uwb_uci_packets::SessionType. enum SessionType { - FIRA_RANGING_SESSION = 0; - FIRA_DATA_TRANSFER = 1; - CCC = 2; - DEVICE_TEST_MODE = 3; + FIRA_RANGING_SESSION = 0x00; + FIRA_RANGING_AND_IN_BAND_DATA_SESSION = 0x01; + FIRA_DATA_TRANSFER = 0x02; + FIRA_RANGING_ONLY_PHASE = 0x03; + FIRA_IN_BAND_DATA_PHASE = 0x04; + FIRA_RANGING_WITH_DATA_PHASE = 0x05; + CCC = 0xA0; + DEVICE_TEST_MODE = 0xD0; } // Represent uwb_uci_packets::UpdateMulticastListAction. diff --git a/src/rust/uwb_core/src/params/app_config_params.rs b/src/rust/uwb_core/src/params/app_config_params.rs index bb06d52..a264002 100644 --- a/src/rust/uwb_core/src/params/app_config_params.rs +++ b/src/rust/uwb_core/src/params/app_config_params.rs @@ -94,8 +94,12 @@ impl AppConfigParams { pub fn is_type_matched(&self, session_type: SessionType) -> bool { match self { Self::Fira(_) => { - session_type == SessionType::FiraDataTransfer + session_type == SessionType::FiraDataTransferSession || session_type == SessionType::FiraRangingSession + || session_type == SessionType::FiraRangingAndInBandDataSession + || session_type == SessionType::FiraRangingOnlyPhase + || session_type == SessionType::FiraInBandDataPhase + || session_type == SessionType::FiraRangingWithDataPhase } Self::Ccc(_) | Self::CccStarted(_) => session_type == SessionType::Ccc, } diff --git a/src/rust/uwb_core/src/params/uci_packets.rs b/src/rust/uwb_core/src/params/uci_packets.rs index 5cd5822..23597ce 100644 --- a/src/rust/uwb_core/src/params/uci_packets.rs +++ b/src/rust/uwb_core/src/params/uci_packets.rs @@ -25,8 +25,8 @@ pub use uwb_uci_packets::{ DataTransferNtfStatusCode, DeviceConfigId, DeviceConfigStatus, DeviceConfigTlv, DeviceState, ExtendedAddressDlTdoaRangingMeasurement, ExtendedAddressOwrAoaRangingMeasurement, ExtendedAddressTwoWayRangingMeasurement, GroupId, MessageType, MulticastUpdateStatusCode, - PowerStats, RangingMeasurementType, ReasonCode, ResetConfig, SessionState, SessionType, - ShortAddressDlTdoaRangingMeasurement, ShortAddressOwrAoaRangingMeasurement, + PhaseList, PowerStats, RangingMeasurementType, ReasonCode, ResetConfig, SessionState, + SessionType, ShortAddressDlTdoaRangingMeasurement, ShortAddressOwrAoaRangingMeasurement, ShortAddressTwoWayRangingMeasurement, StatusCode, UpdateMulticastListAction, }; pub(crate) use uwb_uci_packets::{UciControlPacket, UciDataPacket, UciDataPacketHal}; @@ -184,6 +184,23 @@ impl TryFrom<String> for CountryCode { } } +/// absolute time in UWBS Time domain(ms) when this configuration applies +#[derive(Debug, Clone, PartialEq, Copy)] +pub struct UpdateTime([u8; 8]); + +impl UpdateTime { + /// Create a UpdateTime instance. + pub fn new(update_time: &[u8; 8]) -> Option<Self> { + Some(Self(*update_time)) + } +} + +impl From<UpdateTime> for [u8; 8] { + fn from(item: UpdateTime) -> [u8; 8] { + item.0 + } +} + /// The response of the UciManager::core_get_device_info() method. #[derive(Debug, Clone, PartialEq, Eq)] pub struct GetDeviceInfoResponse { diff --git a/src/rust/uwb_core/src/proto/mappings.rs b/src/rust/uwb_core/src/proto/mappings.rs index a08046d..1bd305b 100644 --- a/src/rust/uwb_core/src/proto/mappings.rs +++ b/src/rust/uwb_core/src/proto/mappings.rs @@ -526,7 +526,11 @@ enum_mapping! { enum_mapping! { ProtoSessionType => SessionType, FIRA_RANGING_SESSION => FiraRangingSession, - FIRA_DATA_TRANSFER => FiraDataTransfer, + FIRA_DATA_TRANSFER => FiraDataTransferSession, + FIRA_RANGING_AND_IN_BAND_DATA_SESSION => FiraRangingAndInBandDataSession, + FIRA_RANGING_ONLY_PHASE => FiraRangingOnlyPhase, + FIRA_IN_BAND_DATA_PHASE => FiraInBandDataPhase, + FIRA_RANGING_WITH_DATA_PHASE => FiraRangingWithDataPhase, CCC => Ccc, DEVICE_TEST_MODE => DeviceTestMode, } diff --git a/src/rust/uwb_core/src/uci/command.rs b/src/rust/uwb_core/src/uci/command.rs index 2afb5a8..8693073 100644 --- a/src/rust/uwb_core/src/uci/command.rs +++ b/src/rust/uwb_core/src/uci/command.rs @@ -20,9 +20,9 @@ use log::error; use crate::error::{Error, Result}; use crate::params::uci_packets::{ AppConfigTlv, AppConfigTlvType, Controlees, CountryCode, DeviceConfigId, DeviceConfigTlv, - ResetConfig, SessionId, SessionToken, SessionType, UpdateMulticastListAction, + ResetConfig, SessionId, SessionToken, SessionType, UpdateMulticastListAction, UpdateTime, }; -use uwb_uci_packets::{build_session_update_controller_multicast_list_cmd, GroupId, MessageType}; +use uwb_uci_packets::{ build_session_update_controller_multicast_list_cmd, GroupId, MessageType, PhaseList,}; /// The enum to represent the UCI commands. The definition of each field should follow UCI spec. #[allow(missing_docs)] @@ -80,6 +80,12 @@ pub enum UciCommand { SessionGetRangingCount { session_token: SessionToken, }, + SessionSetHybridConfig { + session_token: SessionToken, + number_of_phases: u8, + update_time: UpdateTime, + phase_list: Vec<PhaseList>, + }, AndroidSetCountryCode { country_code: CountryCode, }, @@ -189,6 +195,19 @@ impl TryFrom<UciCommand> for uwb_uci_packets::UciControlPacket { UciCommand::SessionQueryMaxDataSize { session_token } => { uwb_uci_packets::SessionQueryMaxDataSizeCmdBuilder { session_token }.build().into() } + UciCommand::SessionSetHybridConfig { + session_token, + number_of_phases, + update_time, + phase_list, + } => uwb_uci_packets::SessionSetHybridConfigCmdBuilder { + session_token, + number_of_phases, + update_time: update_time.into(), + phase_list, + } + .build() + .into(), }; Ok(packet) } diff --git a/src/rust/uwb_core/src/uci/error.rs b/src/rust/uwb_core/src/uci/error.rs index 3101eec..3f040eb 100644 --- a/src/rust/uwb_core/src/uci/error.rs +++ b/src/rust/uwb_core/src/uci/error.rs @@ -22,7 +22,10 @@ pub(crate) fn status_code_to_result(status: StatusCode) -> Result<()> { StatusCode::UciStatusInvalidParam | StatusCode::UciStatusInvalidRange | StatusCode::UciStatusInvalidMsgSize => Err(Error::BadParameters), - StatusCode::UciStatusSessionNotExist + StatusCode::UciStatusSessionDuplicate => Err(Error::DuplicatedSessionId), + StatusCode::UciStatusFailed + | StatusCode::UciStatusSessionNotExist + | StatusCode::UciStatusSessionNotConfigured | StatusCode::UciStatusErrorCccSeBusy | StatusCode::UciStatusErrorCccLifecycle => Err(Error::ProtocolSpecific), StatusCode::UciStatusCommandRetry => Err(Error::CommandRetry), diff --git a/src/rust/uwb_core/src/uci/mock_uci_manager.rs b/src/rust/uwb_core/src/uci/mock_uci_manager.rs index 21e1ddb..d7f944a 100644 --- a/src/rust/uwb_core/src/uci/mock_uci_manager.rs +++ b/src/rust/uwb_core/src/uci/mock_uci_manager.rs @@ -28,9 +28,9 @@ use tokio::time::timeout; use crate::error::{Error, Result}; use crate::params::uci_packets::{ app_config_tlvs_eq, device_config_tlvs_eq, AppConfigTlv, AppConfigTlvType, CapTlv, Controlees, - CoreSetConfigResponse, CountryCode, DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, + CoreSetConfigResponse, CountryCode, DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PhaseList, PowerStats, RawUciMessage, ResetConfig, SessionId, SessionState, SessionToken, SessionType, - SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, UpdateMulticastListAction, + SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, UpdateMulticastListAction, UpdateTime, }; use crate::uci::notification::{ CoreNotification, DataRcvNotification, SessionNotification, UciNotification, @@ -408,6 +408,26 @@ impl MockUciManager { }); } + /// Prepare Mock to expect session_set_hybrid_config. + /// + /// MockUciManager expects call with parameters, returns out as response + pub fn expect_session_set_hybrid_config( + &mut self, + expected_session_id: SessionId, + expected_number_of_phases: u8, + expected_update_time: UpdateTime, + expected_phase_list: Vec<PhaseList>, + out: Result<()>, + ) { + self.expected_calls.lock().unwrap().push_back(ExpectedCall::SessionSetHybridConfig { + expected_session_id, + expected_number_of_phases, + expected_update_time, + expected_phase_list, + out, + }); + } + /// Call Mock to send notifications. fn send_notifications(&self, notfs: Vec<UciNotification>) { for notf in notfs.into_iter() { @@ -941,6 +961,38 @@ impl UciManager for MockUciManager { ) -> Result<SessionToken> { Ok(1) // No uci call here, no mock required. } + + async fn session_set_hybrid_config( + &self, + session_id: SessionId, + number_of_phases: u8, + update_time: UpdateTime, + phase_list: Vec<PhaseList>, + ) -> Result<()> { + let mut expected_calls = self.expected_calls.lock().unwrap(); + match expected_calls.pop_front() { + Some(ExpectedCall::SessionSetHybridConfig { + expected_session_id, + expected_number_of_phases, + expected_update_time, + expected_phase_list, + out, + }) if expected_session_id == session_id + && expected_number_of_phases == number_of_phases + && expected_update_time == update_time + && expected_phase_list.len() == phase_list.len() + && expected_phase_list == phase_list => + { + self.expect_call_consumed.notify_one(); + out + } + Some(call) => { + expected_calls.push_front(call); + Err(Error::MockUndefined) + } + None => Err(Error::MockUndefined), + } + } } #[derive(Clone)] @@ -1054,4 +1106,11 @@ enum ExpectedCall { expected_app_payload_data: Vec<u8>, out: Result<()>, }, + SessionSetHybridConfig { + expected_session_id: SessionId, + expected_number_of_phases: u8, + expected_update_time: UpdateTime, + expected_phase_list: Vec<PhaseList>, + out: Result<()>, + }, } diff --git a/src/rust/uwb_core/src/uci/response.rs b/src/rust/uwb_core/src/uci/response.rs index dfeb6c8..23279c9 100644 --- a/src/rust/uwb_core/src/uci/response.rs +++ b/src/rust/uwb_core/src/uci/response.rs @@ -50,6 +50,7 @@ pub(super) enum UciResponse { AndroidGetPowerStats(Result<PowerStats>), RawUciCmd(Result<RawUciMessage>), SendUciData(Result<()>), + SessionSetHybridConfig(Result<()>), } impl UciResponse { @@ -76,6 +77,7 @@ impl UciResponse { Self::AndroidSetCountryCode(result) => Self::matches_result_retry(result), Self::AndroidGetPowerStats(result) => Self::matches_result_retry(result), Self::RawUciCmd(result) => Self::matches_result_retry(result), + Self::SessionSetHybridConfig(result) => Self::matches_result_retry(result), Self::CoreSetConfig(resp) => Self::matches_status_retry(&resp.status), Self::SessionSetAppConfig(resp) => Self::matches_status_retry(&resp.status), @@ -206,6 +208,9 @@ impl TryFrom<uwb_uci_packets::SessionConfigResponse> for UciResponse { SessionConfigResponseChild::SessionQueryMaxDataSizeRsp(evt) => { Ok(UciResponse::SessionQueryMaxDataSize(Ok(evt.get_max_data_size()))) } + SessionConfigResponseChild::SessionSetHybridConfigRsp(evt) => Ok( + UciResponse::SessionSetHybridConfig(status_code_to_result(evt.get_status())), + ), _ => Err(Error::Unknown), } } diff --git a/src/rust/uwb_core/src/uci/uci_manager.rs b/src/rust/uwb_core/src/uci/uci_manager.rs index 24c0737..2325751 100644 --- a/src/rust/uwb_core/src/uci/uci_manager.rs +++ b/src/rust/uwb_core/src/uci/uci_manager.rs @@ -28,7 +28,7 @@ use crate::params::uci_packets::{ CreditAvailability, DeviceConfigId, DeviceConfigTlv, DeviceState, GetDeviceInfoResponse, GroupId, MessageType, PowerStats, RawUciMessage, ResetConfig, SessionId, SessionState, SessionToken, SessionType, SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, - UciDataPacket, UciDataPacketHal, UpdateMulticastListAction, + UciDataPacket, UciDataPacketHal, UpdateMulticastListAction, UpdateTime, }; use crate::params::utils::bytes_to_u64; use crate::uci::message::UciMessage; @@ -41,7 +41,7 @@ use crate::uci::uci_hal::{UciHal, UciHalPacket}; use crate::uci::uci_logger::{UciLogger, UciLoggerMode, UciLoggerWrapper}; use crate::utils::{clean_mpsc_receiver, PinSleep}; use std::collections::{HashMap, VecDeque}; -use uwb_uci_packets::{Packet, RawUciControlPacket, UciDataSnd, UciDefragPacket}; +use uwb_uci_packets::{Packet, PhaseList, RawUciControlPacket, UciDataSnd, UciDefragPacket}; const UCI_TIMEOUT_MS: u64 = 800; const MAX_RETRY_COUNT: usize = 3; @@ -150,6 +150,14 @@ pub trait UciManager: 'static + Send + Sync + Clone { &self, session_id: SessionId, ) -> Result<SessionToken>; + /// Send UCI command for setting hybrid config + async fn session_set_hybrid_config( + &self, + session_id: SessionId, + number_of_phases: u8, + update_time: UpdateTime, + phase_list: Vec<PhaseList>, + ) -> Result<()>; } /// UciManagerImpl is the main implementation of UciManager. Using the actor model, UciManagerImpl @@ -552,6 +560,27 @@ impl UciManager for UciManagerImpl { ) -> Result<SessionToken> { Ok(self.get_session_token(&session_id).await?) } + + /// Send UCI command for setting hybrid config + async fn session_set_hybrid_config( + &self, + session_id: SessionId, + number_of_phases: u8, + update_time: UpdateTime, + phase_list: Vec<PhaseList>, + ) -> Result<()> { + let cmd = UciCommand::SessionSetHybridConfig { + session_token: self.get_session_token(&session_id).await?, + number_of_phases, + update_time, + phase_list, + }; + match self.send_cmd(UciManagerCmd::SendUciCommand { cmd }).await { + Ok(UciResponse::SessionSetHybridConfig(resp)) => resp, + Ok(_) => Err(Error::Unknown), + Err(e) => Err(e), + } + } } struct UciManagerActor<T: UciHal, U: UciLogger> { @@ -1383,7 +1412,7 @@ enum UciManagerCmd { }, } -#[cfg(any(test))] +#[cfg(test)] mod tests { use super::*; @@ -1897,6 +1926,47 @@ mod tests { } #[tokio::test] + async fn test_session_set_hybrid_config_ok() { + let session_id = 0x123; + let session_token = 0x123; + let number_of_phases = 0x02; + let update_time = UpdateTime::new(&[0x0; 8]).unwrap(); + let phase_list = vec![ + PhaseList { session_token: 0x12, start_slot_index: 0x13, end_slot_index: 0x01 }, + PhaseList { session_token: 0x14, start_slot_index: 0x13, end_slot_index: 0x01 }, + ]; + let phase_list_clone = phase_list.clone(); + + let (uci_manager, mut mock_hal) = setup_uci_manager_with_session_active( + |mut hal| async move { + let cmd = UciCommand::SessionSetHybridConfig { + session_token, + number_of_phases, + update_time, + phase_list: phase_list_clone, + }; + let resp = + into_uci_hal_packets(uwb_uci_packets::SessionSetHybridConfigRspBuilder { + status: uwb_uci_packets::StatusCode::UciStatusOk, + }); + + hal.expected_send_command(cmd, resp, Ok(())); + }, + UciLoggerMode::Disabled, + mpsc::unbounded_channel::<UciLogEvent>().0, + session_id, + session_token, + ) + .await; + + let result = uci_manager + .session_set_hybrid_config(session_token, number_of_phases, update_time, phase_list) + .await; + assert!(result.is_ok()); + assert!(mock_hal.wait_expected_calls_done().await); + } + + #[tokio::test] async fn test_session_get_app_config_ok() { let session_id = 0x123; let session_token = 0x123; diff --git a/src/rust/uwb_core/src/uci/uci_manager_sync.rs b/src/rust/uwb_core/src/uci/uci_manager_sync.rs index 4b1cf25..688f1e9 100644 --- a/src/rust/uwb_core/src/uci/uci_manager_sync.rs +++ b/src/rust/uwb_core/src/uci/uci_manager_sync.rs @@ -1,4 +1,4 @@ -// Copyright 2022, The Android Open Source Project + // Copyright 2022, The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,7 +29,7 @@ use crate::params::{ AppConfigTlv, AppConfigTlvType, CapTlv, CoreSetConfigResponse, CountryCode, DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PowerStats, RawUciMessage, ResetConfig, SessionId, SessionState, SessionType, SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, - UpdateMulticastListAction, + UpdateMulticastListAction, UpdateTime, }; #[cfg(any(test, feature = "mock-utils"))] use crate::uci::mock_uci_manager::MockUciManager; @@ -37,7 +37,7 @@ use crate::uci::notification::{CoreNotification, DataRcvNotification, SessionNot use crate::uci::uci_hal::UciHal; use crate::uci::uci_logger::{UciLogger, UciLoggerMode}; use crate::uci::uci_manager::{UciManager, UciManagerImpl}; -use uwb_uci_packets::Controlees; +use uwb_uci_packets::{Controlees, PhaseList}; /// The NotificationManager processes UciNotification relayed from UciManagerSync in a sync fashion. /// The UciManagerSync assumes the NotificationManager takes the responsibility to properly handle @@ -368,10 +368,27 @@ impl<U: UciManager> UciManagerSync<U> { app_payload_data, )) } + /// Get session token for session id. pub fn get_session_token(&self, session_id: SessionId) -> Result<u32> { self.runtime_handle.block_on(self.uci_manager.get_session_token_from_session_id(session_id)) } + + /// Send UCI command for setting hybrid configuration + pub fn session_set_hybrid_config( + &self, + session_id: SessionId, + number_of_phases: u8, + update_time: UpdateTime, + phase_list: Vec<PhaseList>, + ) -> Result<()> { + self.runtime_handle.block_on(self.uci_manager.session_set_hybrid_config( + session_id, + number_of_phases, + update_time, + phase_list, + )) + } } impl UciManagerSync<UciManagerImpl> { diff --git a/src/rust/uwb_uci_packets/uci_packets.pdl b/src/rust/uwb_uci_packets/uci_packets.pdl index 12bdb6c..067f67a 100644 --- a/src/rust/uwb_uci_packets/uci_packets.pdl +++ b/src/rust/uwb_uci_packets/uci_packets.pdl @@ -419,6 +419,7 @@ enum MulticastUpdateStatusCode : 8 { STATUS_ERROR_SUB_SESSION_KEY_NOT_FOUND = 0x05, STATUS_ERROR_SUB_SESSION_KEY_NOT_APPLICABLE = 0x06, STATUS_ERROR_SESSION_KEY_NOT_FOUND = 0x07, + STATUS_ERROR_ADDRESS_ALREADY_PRESENT = 0x08, } enum MacAddressIndicator : 8 { @@ -428,7 +429,11 @@ enum MacAddressIndicator : 8 { enum SessionType: 8 { FIRA_RANGING_SESSION = 0x00, - FIRA_DATA_TRANSFER = 0x01, + FIRA_RANGING_AND_IN_BAND_DATA_SESSION = 0x01, + FIRA_DATA_TRANSFER_SESSION = 0x02, + FIRA_RANGING_ONLY_PHASE = 0x03, + FIRA_IN_BAND_DATA_PHASE = 0x04, + FIRA_RANGING_WITH_DATA_PHASE = 0x05, CCC = 0xA0, DEVICE_TEST_MODE = 0xD0, } @@ -922,6 +927,23 @@ packet SessionUpdateControllerMulticastListCmd : SessionConfigCommand (opcode = _payload_, } +struct PhaseList { + session_token: 32, + start_slot_index: 16, + end_slot_index: 16, +} + +packet SessionSetHybridConfigCmd : SessionConfigCommand (opcode = 0x0c) { //SESSION_SET_HUS_CONFIG + session_token: 32, + number_of_phases: 8, + update_time: 8[8], + phase_list: PhaseList[], +} + +packet SessionSetHybridConfigRsp : SessionConfigResponse (opcode = 0x0c) { //SESSION_SET_HUS_CONFIG + status: StatusCode, +} + struct SessionUpdateControllerMulticastListCmdPayload { _count_(controlees): 8, controlees: Controlee[], |