diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2022-04-28 17:39:23 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-04-28 17:39:23 +0000 |
commit | b38eb2dc32721b75cd63a064e9a31ea0c1805f53 (patch) | |
tree | 5d76fb939b405f6d0eaf86fdb6edf661fab88ace | |
parent | 0e94af61b7bd9c2d3c1ea6fdd1f37f372ccc3c19 (diff) | |
parent | cb41a81e65d870b55a5089bdcf38d39825652fb5 (diff) | |
download | uwb-b38eb2dc32721b75cd63a064e9a31ea0c1805f53.tar.gz |
Merge "uwb_core: send SessionRangeData to SessionManager's caller" into tm-dev
-rw-r--r-- | src/rust/uwb_core/src/session/session_manager.rs | 128 | ||||
-rw-r--r-- | src/rust/uwb_core/src/session/uwb_session.rs | 9 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/notification.rs | 78 |
3 files changed, 192 insertions, 23 deletions
diff --git a/src/rust/uwb_core/src/session/session_manager.rs b/src/rust/uwb_core/src/session/session_manager.rs index 592affe..9828ca9 100644 --- a/src/rust/uwb_core/src/session/session_manager.rs +++ b/src/rust/uwb_core/src/session/session_manager.rs @@ -20,7 +20,7 @@ use tokio::sync::{mpsc, oneshot}; use crate::session::error::{Error, Result}; use crate::session::params::AppConfigParams; use crate::session::uwb_session::UwbSession; -use crate::uci::notification::UciNotification; +use crate::uci::notification::{SessionRangeData, UciNotification}; use crate::uci::params::{ Controlee, SessionId, SessionState, SessionType, UpdateMulticastListAction, }; @@ -53,9 +53,16 @@ impl SessionManager { session_id: SessionId, session_type: SessionType, params: AppConfigParams, + range_data_sender: mpsc::UnboundedSender<SessionRangeData>, ) -> Result<()> { - let result = - self.send_cmd(SessionCommand::InitSession { session_id, session_type, params }).await; + let result = self + .send_cmd(SessionCommand::InitSession { + session_id, + session_type, + params, + range_data_sender, + }) + .await; if result.is_err() && result != Err(Error::DuplicatedSessionId(session_id)) { let _ = self.deinit_session(session_id).await; } @@ -148,7 +155,7 @@ impl<T: UciManager> SessionManagerActor<T> { fn handle_cmd(&mut self, cmd: SessionCommand, result_sender: oneshot::Sender<Result<()>>) { match cmd { - SessionCommand::InitSession { session_id, session_type, params } => { + SessionCommand::InitSession { session_id, session_type, params, range_data_sender } => { if self.active_sessions.contains_key(&session_id) { let _ = result_sender.send(Err(Error::DuplicatedSessionId(session_id))); return; @@ -164,8 +171,12 @@ impl<T: UciManager> SessionManagerActor<T> { return; } - let mut session = - UwbSession::new(self.uci_manager.clone(), session_id, session_type); + let mut session = UwbSession::new( + self.uci_manager.clone(), + session_id, + session_type, + range_data_sender, + ); session.initialize(params, result_sender); // We store the session first. If the initialize() fails, then SessionManager will @@ -257,6 +268,12 @@ impl<T: UciManager> SessionManagerActor<T> { ); } }, + UciNotification::RangeData(data) => { + match self.active_sessions.get_mut(&data.session_id) { + Some(session) => session.on_range_data_received(data), + None => warn!("Received range data of the unknown Session: {:?}", data), + } + } _ => {} } } @@ -268,6 +285,7 @@ enum SessionCommand { session_id: SessionId, session_type: SessionType, params: AppConfigParams, + range_data_sender: mpsc::UnboundedSender<SessionRangeData>, }, DeinitSession { session_id: SessionId, @@ -296,8 +314,10 @@ mod tests { use crate::session::params::fira_app_config_params::*; use crate::uci::error::StatusCode; use crate::uci::mock_uci_manager::MockUciManager; + use crate::uci::notification::RangingMeasurements; use crate::uci::params::{ - ControleeStatus, MulticastUpdateStatusCode, ReasonCode, SetAppConfigResponse, + ControleeStatus, MulticastUpdateStatusCode, RangingMeasurementType, ReasonCode, + SetAppConfigResponse, ShortAddressTwoWayRangingMeasurement, }; use crate::utils::init_test_logging; @@ -367,11 +387,15 @@ mod tests { assert_eq!(result, Err(Error::UnknownSessionId(session_id))); // Initialize a normal session should be successful. - let result = session_manager.init_session(session_id, session_type, params.clone()).await; + let result = session_manager + .init_session(session_id, session_type, params.clone(), mpsc::unbounded_channel().0) + .await; assert_eq!(result, Ok(())); // Initialize a session multiple times without deinitialize should fail. - let result = session_manager.init_session(session_id, session_type, params).await; + let result = session_manager + .init_session(session_id, session_type, params, mpsc::unbounded_channel().0) + .await; assert_eq!(result, Err(Error::DuplicatedSessionId(session_id))); // Deinitialize the session should be successful. @@ -398,7 +422,9 @@ mod tests { }) .await; - let result = session_manager.init_session(session_id, session_type, params).await; + let result = session_manager + .init_session(session_id, session_type, params, mpsc::unbounded_channel().0) + .await; assert_eq!(result, Err(Error::Timeout)); assert!(mock_uci_manager.wait_expected_calls_done().await); @@ -443,7 +469,9 @@ mod tests { }) .await; - let result = session_manager.init_session(session_id, session_type, params).await; + let result = session_manager + .init_session(session_id, session_type, params, mpsc::unbounded_channel().0) + .await; assert_eq!(result, Ok(())); let result = session_manager.start_ranging(session_id).await; assert_eq!(result, Ok(())); @@ -505,7 +533,9 @@ mod tests { }) .await; - let result = session_manager.init_session(session_id, session_type, params).await; + let result = session_manager + .init_session(session_id, session_type, params, mpsc::unbounded_channel().0) + .await; assert_eq!(result, Ok(())); let result = session_manager.update_controller_multicast_list(session_id, action, controlees).await; @@ -556,7 +586,9 @@ mod tests { }) .await; - let result = session_manager.init_session(session_id, session_type, params).await; + let result = session_manager + .init_session(session_id, session_type, params, mpsc::unbounded_channel().0) + .await; assert_eq!(result, Ok(())); // This method should timeout waiting for the notification. let result = @@ -565,4 +597,74 @@ mod tests { assert!(mock_uci_manager.wait_expected_calls_done().await); } + + #[tokio::test] + async fn test_receive_session_range_data() { + let session_id = 0x123; + let session_type = SessionType::FiraRangingSession; + let params = generate_params(); + let tlvs = params.generate_tlvs(); + let range_data = SessionRangeData { + sequence_number: 1, + session_id, + current_ranging_interval_ms: 3, + ranging_measurement_type: RangingMeasurementType::TwoWay, + ranging_measurements: RangingMeasurements::Short(vec![ + ShortAddressTwoWayRangingMeasurement { + mac_address: 0x123, + status: StatusCode::UciStatusOk, + nlos: 0, + distance: 4, + aoa_azimuth: 5, + aoa_azimuth_fom: 6, + aoa_elevation: 7, + aoa_elevation_fom: 8, + aoa_destination_azimuth: 9, + aoa_destination_azimuth_fom: 10, + aoa_destination_elevation: 11, + aoa_destination_elevation_fom: 12, + slot_index: 0, + }, + ]), + }; + + let range_data_clone = range_data.clone(); + let (mut session_manager, mut mock_uci_manager) = + setup_session_manager(move |uci_manager| { + let init_notfs = vec![UciNotification::SessionStatus { + session_id, + session_state: SessionState::SessionStateInit, + reason_code: ReasonCode::StateChangeWithSessionManagementCommands, + }]; + let set_app_config_notfs = vec![ + UciNotification::SessionStatus { + session_id, + session_state: SessionState::SessionStateIdle, + reason_code: ReasonCode::StateChangeWithSessionManagementCommands, + }, + UciNotification::RangeData(range_data_clone), + ]; + uci_manager.expect_session_init(session_id, session_type, init_notfs, Ok(())); + uci_manager.expect_session_set_app_config( + session_id, + tlvs, + set_app_config_notfs, + Ok(SetAppConfigResponse { + status: StatusCode::UciStatusOk, + config_status: vec![], + }), + ); + }) + .await; + + let (range_data_sender, mut range_data_receiver) = mpsc::unbounded_channel(); + let result = + session_manager.init_session(session_id, session_type, params, range_data_sender).await; + assert_eq!(result, Ok(())); + + let received_range_data = range_data_receiver.recv().await.unwrap(); + assert_eq!(received_range_data, range_data); + + assert!(mock_uci_manager.wait_expected_calls_done().await); + } } diff --git a/src/rust/uwb_core/src/session/uwb_session.rs b/src/rust/uwb_core/src/session/uwb_session.rs index 3717348..dc430a3 100644 --- a/src/rust/uwb_core/src/session/uwb_session.rs +++ b/src/rust/uwb_core/src/session/uwb_session.rs @@ -21,6 +21,7 @@ use tokio::time::timeout; use crate::session::error::{Error, Result}; use crate::session::params::AppConfigParams; use crate::uci::error::StatusCode; +use crate::uci::notification::SessionRangeData; use crate::uci::params::{ Controlee, ControleeStatus, MulticastUpdateStatusCode, SessionId, SessionState, SessionType, UpdateMulticastListAction, @@ -32,6 +33,7 @@ const NOTIFICATION_TIMEOUT_MS: u64 = 1000; pub(crate) struct UwbSession { cmd_sender: mpsc::UnboundedSender<(Command, oneshot::Sender<Result<()>>)>, state_sender: watch::Sender<SessionState>, + range_data_sender: mpsc::UnboundedSender<SessionRangeData>, controlee_status_notf_sender: Option<oneshot::Sender<Vec<ControleeStatus>>>, } @@ -40,6 +42,7 @@ impl UwbSession { uci_manager: T, session_id: SessionId, session_type: SessionType, + range_data_sender: mpsc::UnboundedSender<SessionRangeData>, ) -> Self { let (cmd_sender, cmd_receiver) = mpsc::unbounded_channel(); let (state_sender, mut state_receiver) = watch::channel(SessionState::SessionStateDeinit); @@ -55,7 +58,7 @@ impl UwbSession { ); tokio::spawn(async move { actor.run().await }); - Self { cmd_sender, state_sender, controlee_status_notf_sender: None } + Self { cmd_sender, state_sender, range_data_sender, controlee_status_notf_sender: None } } pub fn initialize( @@ -109,6 +112,10 @@ impl UwbSession { let _ = sender.send(status_list); } } + + pub fn on_range_data_received(&mut self, data: SessionRangeData) { + let _ = self.range_data_sender.send(data); + } } struct UwbSessionActor<T: UciManager> { diff --git a/src/rust/uwb_core/src/uci/notification.rs b/src/rust/uwb_core/src/uci/notification.rs index 89b4bb1..6e4e6dd 100644 --- a/src/rust/uwb_core/src/uci/notification.rs +++ b/src/rust/uwb_core/src/uci/notification.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::convert::{TryFrom, TryInto}; +use std::iter::zip; use num_traits::ToPrimitive; use uwb_uci_packets::Packet; @@ -37,22 +38,81 @@ pub(crate) enum UciNotification { remaining_multicast_list_size: usize, status_list: Vec<ControleeStatus>, }, - RangeData { - sequence_number: u32, - session_id: SessionId, - current_ranging_interval_ms: u32, - ranging_measurement_type: RangingMeasurementType, - ranging_measurements: RangingMeasurements, - }, + RangeData(SessionRangeData), RawVendor(RawVendorMessage), } +#[derive(Debug, Clone, PartialEq)] +pub(crate) struct SessionRangeData { + pub sequence_number: u32, + pub session_id: SessionId, + pub current_ranging_interval_ms: u32, + pub ranging_measurement_type: RangingMeasurementType, + pub ranging_measurements: RangingMeasurements, +} + #[derive(Debug, Clone)] pub(crate) enum RangingMeasurements { Short(Vec<ShortAddressTwoWayRangingMeasurement>), Extended(Vec<ExtendedAddressTwoWayRangingMeasurement>), } +impl PartialEq for RangingMeasurements { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Short(a_vec), Self::Short(b_vec)) => { + a_vec.len() == b_vec.len() + && zip(a_vec, b_vec) + .all(|(a, b)| short_address_two_way_ranging_measurement_eq(a, b)) + } + (Self::Extended(a_vec), Self::Extended(b_vec)) => { + a_vec.len() == b_vec.len() + && zip(a_vec, b_vec) + .all(|(a, b)| extended_address_two_way_ranging_measurement_eq(a, b)) + } + _ => false, + } + } +} + +fn short_address_two_way_ranging_measurement_eq( + a: &ShortAddressTwoWayRangingMeasurement, + b: &ShortAddressTwoWayRangingMeasurement, +) -> bool { + a.mac_address == b.mac_address + && a.status == b.status + && a.nlos == b.nlos + && a.distance == b.distance + && a.aoa_azimuth == b.aoa_azimuth + && a.aoa_azimuth_fom == b.aoa_azimuth_fom + && a.aoa_elevation == b.aoa_elevation + && a.aoa_elevation_fom == b.aoa_elevation_fom + && a.aoa_destination_azimuth == b.aoa_destination_azimuth + && a.aoa_destination_azimuth_fom == b.aoa_destination_azimuth_fom + && a.aoa_destination_elevation == b.aoa_destination_elevation + && a.aoa_destination_elevation_fom == b.aoa_destination_elevation_fom + && a.slot_index == b.slot_index +} + +fn extended_address_two_way_ranging_measurement_eq( + a: &ExtendedAddressTwoWayRangingMeasurement, + b: &ExtendedAddressTwoWayRangingMeasurement, +) -> bool { + a.mac_address == b.mac_address + && a.status == b.status + && a.nlos == b.nlos + && a.distance == b.distance + && a.aoa_azimuth == b.aoa_azimuth + && a.aoa_azimuth_fom == b.aoa_azimuth_fom + && a.aoa_elevation == b.aoa_elevation + && a.aoa_elevation_fom == b.aoa_elevation_fom + && a.aoa_destination_azimuth == b.aoa_destination_azimuth + && a.aoa_destination_azimuth_fom == b.aoa_destination_azimuth_fom + && a.aoa_destination_elevation == b.aoa_destination_elevation + && a.aoa_destination_elevation_fom == b.aoa_destination_elevation_fom + && a.slot_index == b.slot_index +} + impl UciNotification { pub fn need_retry(&self) -> bool { matches!(self, Self::CoreGenericError(StatusCode::UciStatusCommandRetry)) @@ -140,13 +200,13 @@ impl TryFrom<uwb_uci_packets::RangeDataNtfPacket> for UciNotification { } _ => return Err(Error::Specialize(evt.to_vec())), }; - Ok(UciNotification::RangeData { + Ok(UciNotification::RangeData(SessionRangeData { sequence_number: evt.get_sequence_number(), session_id: evt.get_session_id(), current_ranging_interval_ms: evt.get_current_ranging_interval(), ranging_measurement_type: evt.get_ranging_measurement_type(), ranging_measurements, - }) + })) } } |