uwb_core: add start/stop ranging method at SessionManager
This CL adds start_ranging() and stop_ranging methods at
SessionManager. The methods call UciManager's methods and wait for the
session status notification.
Bug: 228136039
Test: cargo test
Test: cargo clippy
Change-Id: I6ff52eb00544e8595962db051c0aac431426eb4c
diff --git a/src/rust/uwb_core/src/session/session_manager.rs b/src/rust/uwb_core/src/session/session_manager.rs
index b29bd33..a44a983 100644
--- a/src/rust/uwb_core/src/session/session_manager.rs
+++ b/src/rust/uwb_core/src/session/session_manager.rs
@@ -64,6 +64,14 @@
self.send_cmd(SessionCommand::DeinitSession { session_id }).await
}
+ async fn start_ranging(&mut self, session_id: SessionId) -> Result<()> {
+ self.send_cmd(SessionCommand::StartRanging { session_id }).await
+ }
+
+ async fn stop_ranging(&mut self, session_id: SessionId) -> Result<()> {
+ self.send_cmd(SessionCommand::StopRanging { session_id }).await
+ }
+
// Send the |cmd| to the SessionManagerActor.
async fn send_cmd(&self, cmd: SessionCommand) -> Result<()> {
let (result_sender, result_receiver) = oneshot::channel();
@@ -154,6 +162,27 @@
}
}
}
+
+ SessionCommand::StartRanging { session_id } => {
+ match self.active_sessions.get_mut(&session_id) {
+ None => {
+ let _ = result_sender.send(Err(Error::UnknownSessionId(session_id)));
+ }
+ Some(session) => {
+ session.start_ranging(result_sender);
+ }
+ }
+ }
+ SessionCommand::StopRanging { session_id } => {
+ match self.active_sessions.get_mut(&session_id) {
+ None => {
+ let _ = result_sender.send(Err(Error::UnknownSessionId(session_id)));
+ }
+ Some(session) => {
+ session.stop_ranging(result_sender);
+ }
+ }
+ }
}
}
@@ -187,6 +216,8 @@
enum SessionCommand {
InitSession { session_id: SessionId, session_type: SessionType, params: AppConfigParams },
DeinitSession { session_id: SessionId },
+ StartRanging { session_id: SessionId },
+ StopRanging { session_id: SessionId },
}
#[cfg(test)]
@@ -314,4 +345,53 @@
assert!(mock_uci_manager.wait_expected_calls_done().await);
}
+
+ #[tokio::test]
+ async fn test_start_stop_ranging() {
+ let session_id = 0x123;
+ let session_type = SessionType::FiraRangingSession;
+ let params = generate_params();
+ let tlvs = params.generate_tlvs();
+
+ let (mut session_manager, mut mock_uci_manager) =
+ setup_session_manager(move |uci_manager| {
+ let state_init_notf = vec![UciNotification::SessionStatus {
+ session_id,
+ session_state: SessionState::SessionStateInit,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands,
+ }];
+ let state_idle_notf = vec![UciNotification::SessionStatus {
+ session_id,
+ session_state: SessionState::SessionStateIdle,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands,
+ }];
+ let state_active_notf = vec![UciNotification::SessionStatus {
+ session_id,
+ session_state: SessionState::SessionStateActive,
+ reason_code: ReasonCode::StateChangeWithSessionManagementCommands,
+ }];
+ uci_manager.expect_session_init(session_id, session_type, state_init_notf, Ok(()));
+ uci_manager.expect_session_set_app_config(
+ session_id,
+ tlvs,
+ state_idle_notf.clone(),
+ Ok(SetAppConfigResponse {
+ status: StatusCode::UciStatusOk,
+ config_status: vec![],
+ }),
+ );
+ uci_manager.expect_range_start(session_id, state_active_notf, Ok(()));
+ uci_manager.expect_range_stop(session_id, state_idle_notf, Ok(()));
+ })
+ .await;
+
+ let result = session_manager.init_session(session_id, session_type, params).await;
+ assert_eq!(result, Ok(()));
+ let result = session_manager.start_ranging(session_id).await;
+ assert_eq!(result, Ok(()));
+ let result = session_manager.stop_ranging(session_id).await;
+ assert_eq!(result, Ok(()));
+
+ 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 37f3824..66b5fd6 100644
--- a/src/rust/uwb_core/src/session/uwb_session.rs
+++ b/src/rust/uwb_core/src/session/uwb_session.rs
@@ -64,6 +64,14 @@
let _ = self.cmd_sender.send((Command::Deinitialize, result_sender));
}
+ pub fn start_ranging(&mut self, result_sender: oneshot::Sender<Result<()>>) {
+ let _ = self.cmd_sender.send((Command::StartRanging, result_sender));
+ }
+
+ pub fn stop_ranging(&mut self, result_sender: oneshot::Sender<Result<()>>) {
+ let _ = self.cmd_sender.send((Command::StopRanging, result_sender));
+ }
+
pub fn set_state(&mut self, state: SessionState) {
let _ = self.state_sender.send(state);
}
@@ -101,6 +109,8 @@
let result = match cmd {
Command::Initialize { params } => self.initialize(params).await,
Command::Deinitialize => self.deinitialize().await,
+ Command::StartRanging => self.start_ranging().await,
+ Command::StopRanging => self.stop_ranging().await,
};
let _ = result_sender.send(result);
}
@@ -149,6 +159,52 @@
Ok(())
}
+ async fn start_ranging(&mut self) -> Result<()> {
+ let state = *self.state_receiver.borrow();
+ match state {
+ SessionState::SessionStateActive => {
+ warn!("Session {} is already running", self.session_id);
+ Ok(())
+ }
+ SessionState::SessionStateIdle => {
+ if let Err(e) = self.uci_manager.range_start(self.session_id).await {
+ error!("Failed to start ranging: {:?}", e);
+ return Err(Error::Uci);
+ }
+ self.wait_state(SessionState::SessionStateActive).await?;
+
+ Ok(())
+ }
+ _ => {
+ error!("Session {} cannot start running at {:?}", self.session_id, state);
+ Err(Error::WrongState(state))
+ }
+ }
+ }
+
+ async fn stop_ranging(&mut self) -> Result<()> {
+ let state = *self.state_receiver.borrow();
+ match state {
+ SessionState::SessionStateIdle => {
+ warn!("Session {} is already stopped", self.session_id);
+ Ok(())
+ }
+ SessionState::SessionStateActive => {
+ if let Err(e) = self.uci_manager.range_stop(self.session_id).await {
+ error!("Failed to start ranging: {:?}", e);
+ return Err(Error::Uci);
+ }
+ self.wait_state(SessionState::SessionStateIdle).await?;
+
+ Ok(())
+ }
+ _ => {
+ error!("Session {} cannot stop running at {:?}", self.session_id, state);
+ Err(Error::WrongState(state))
+ }
+ }
+ }
+
async fn wait_state(&mut self, expected_state: SessionState) -> Result<()> {
const WAIT_STATE_TIMEOUT_MS: u64 = 1000;
match timeout(Duration::from_millis(WAIT_STATE_TIMEOUT_MS), self.state_receiver.changed())
@@ -182,4 +238,6 @@
enum Command {
Initialize { params: AppConfigParams },
Deinitialize,
+ StartRanging,
+ StopRanging,
}
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 c69dc51..f3aa425 100644
--- a/src/rust/uwb_core/src/uci/mock_uci_manager.rs
+++ b/src/rust/uwb_core/src/uci/mock_uci_manager.rs
@@ -180,18 +180,30 @@
);
}
- pub fn expect_range_start(&mut self, expected_session_id: SessionId, out: Result<()>) {
- self.expected_calls
- .lock()
- .unwrap()
- .push_back(ExpectedCall::RangeStart { expected_session_id, out });
+ pub fn expect_range_start(
+ &mut self,
+ expected_session_id: SessionId,
+ notfs: Vec<UciNotification>,
+ out: Result<()>,
+ ) {
+ self.expected_calls.lock().unwrap().push_back(ExpectedCall::RangeStart {
+ expected_session_id,
+ notfs,
+ out,
+ });
}
- pub fn expect_range_stop(&mut self, expected_session_id: SessionId, out: Result<()>) {
- self.expected_calls
- .lock()
- .unwrap()
- .push_back(ExpectedCall::RangeStop { expected_session_id, out });
+ pub fn expect_range_stop(
+ &mut self,
+ expected_session_id: SessionId,
+ notfs: Vec<UciNotification>,
+ out: Result<()>,
+ ) {
+ self.expected_calls.lock().unwrap().push_back(ExpectedCall::RangeStop {
+ expected_session_id,
+ notfs,
+ out,
+ });
}
pub fn expect_range_get_ranging_count(
@@ -523,10 +535,13 @@
async fn range_start(&mut self, session_id: SessionId) -> Result<()> {
let mut expected_calls = self.expected_calls.lock().unwrap();
match expected_calls.pop_front() {
- Some(ExpectedCall::RangeStart { expected_session_id, out })
+ Some(ExpectedCall::RangeStart { expected_session_id, notfs, out })
if expected_session_id == session_id =>
{
self.expect_call_consumed.notify_one();
+ for notf in notfs.into_iter() {
+ let _ = self.notf_sender.as_mut().unwrap().send(notf);
+ }
out
}
Some(call) => {
@@ -540,10 +555,13 @@
async fn range_stop(&mut self, session_id: SessionId) -> Result<()> {
let mut expected_calls = self.expected_calls.lock().unwrap();
match expected_calls.pop_front() {
- Some(ExpectedCall::RangeStop { expected_session_id, out })
+ Some(ExpectedCall::RangeStop { expected_session_id, notfs, out })
if expected_session_id == session_id =>
{
self.expect_call_consumed.notify_one();
+ for notf in notfs.into_iter() {
+ let _ = self.notf_sender.as_mut().unwrap().send(notf);
+ }
out
}
Some(call) => {
@@ -692,10 +710,12 @@
},
RangeStart {
expected_session_id: SessionId,
+ notfs: Vec<UciNotification>,
out: Result<()>,
},
RangeStop {
expected_session_id: SessionId,
+ notfs: Vec<UciNotification>,
out: Result<()>,
},
RangeGetRangingCount {