summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2022-05-02 17:52:32 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-05-02 17:52:32 +0000
commit3583a2f341900fd5ef8cbce5b8fc32b19dacfa6a (patch)
tree5d76fb939b405f6d0eaf86fdb6edf661fab88ace
parenteb785009802f4186f85e7bb09b6169d109f745fd (diff)
parent2b0921d7c3702a2a406df1b5d98c86d14bbfb704 (diff)
downloaduwb-3583a2f341900fd5ef8cbce5b8fc32b19dacfa6a.tar.gz
Merge "uwb_core: send SessionRangeData to SessionManager's caller" into tm-dev am: b38eb2dc32 am: 2b0921d7c3
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/uwb/+/17822713 Change-Id: I3102924f7ea923ca7532dfebcdbcc4e74111a671 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--src/rust/uwb_core/src/session/session_manager.rs128
-rw-r--r--src/rust/uwb_core/src/session/uwb_session.rs9
-rw-r--r--src/rust/uwb_core/src/uci/notification.rs78
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,
- })
+ }))
}
}