diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-08-10 10:39:52 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-08-10 10:39:52 +0000 |
commit | 8986e8c256b17fb3430141d18ae1d6656d1c2d3a (patch) | |
tree | ce8ff5155fa4a4e9adb439ff81370f87fa0e22e3 | |
parent | 788287c7df96041f190d5ddb636bb25670a2dcaa (diff) | |
parent | 26d4e8bd586048be563929251cec44c737ac0726 (diff) | |
download | uwb-8986e8c256b17fb3430141d18ae1d6656d1c2d3a.tar.gz |
Snap for 8928942 from 26d4e8bd586048be563929251cec44c737ac0726 to mainline-mediaprovider-releaseaml_mpr_331011070
Change-Id: I959f224abc38f807a5d9040dbe37bbdbd9a19d0a
-rwxr-xr-x | src/Android.bp | 3 | ||||
-rw-r--r-- | src/rust/event_manager/mock_event_manager.rs | 18 | ||||
-rw-r--r-- | src/rust/event_manager/mod.rs | 54 | ||||
-rw-r--r-- | src/rust/uci/mod.rs | 9 | ||||
-rw-r--r-- | src/rust/uci/uci_hrcv.rs | 8 | ||||
-rw-r--r-- | src/rust/uwb_core/src/uci/uci_manager_sync.rs | 49 | ||||
-rw-r--r-- | src/rust/uwb_uci_packets/src/lib.rs | 111 | ||||
-rw-r--r-- | src/rust/uwb_uci_packets/uci_packets.pdl | 24 |
8 files changed, 241 insertions, 35 deletions
diff --git a/src/Android.bp b/src/Android.bp index c335c31..8bd2271 100755 --- a/src/Android.bp +++ b/src/Android.bp @@ -190,6 +190,9 @@ rust_library { name: "libuwb_core", defaults: ["libuwb_core_defaults"], crate_name: "uwb_core", + apex_available: [ + "com.android.uwb", + ], } rust_test { diff --git a/src/rust/event_manager/mock_event_manager.rs b/src/rust/event_manager/mock_event_manager.rs index bc84afb..03d940a 100644 --- a/src/rust/event_manager/mock_event_manager.rs +++ b/src/rust/event_manager/mock_event_manager.rs @@ -105,7 +105,11 @@ impl Drop for MockEventManager { } #[cfg(any(test, fuzzing))] impl EventManager for MockEventManager { - fn device_status_notification_received(&self, _data: DeviceStatusNtfPacket) -> Result<()> { + fn device_status_notification_received( + &self, + _data: DeviceStatusNtfPacket, + _chip_id: &str, + ) -> Result<()> { let out = { let mut expected_calls = self.expected_calls.lock().unwrap(); match expected_calls.pop_front() { @@ -121,7 +125,11 @@ impl EventManager for MockEventManager { self.unwrap_out(out, "device_status_notification_received") } - fn core_generic_error_notification_received(&self, _data: GenericErrorPacket) -> Result<()> { + fn core_generic_error_notification_received( + &self, + _data: GenericErrorPacket, + _chip_id: &str, + ) -> Result<()> { let out = { let mut expected_calls = self.expected_calls.lock().unwrap(); match expected_calls.pop_front() { @@ -209,7 +217,11 @@ impl EventManager for MockEventManager { self.unwrap_out(out, "session_update_controller_multicast_list_notification_received") } - fn vendor_uci_notification_received(&self, _data: UciNotificationPacket) -> Result<()> { + fn vendor_uci_notification_received( + &self, + _data: UciNotificationPacket, + _chip_id: &str, + ) -> Result<()> { let out = { let mut expected_calls = self.expected_calls.lock().unwrap(); match expected_calls.pop_front() { diff --git a/src/rust/event_manager/mod.rs b/src/rust/event_manager/mod.rs index 81ecde4..5d0f625 100644 --- a/src/rust/event_manager/mod.rs +++ b/src/rust/event_manager/mod.rs @@ -50,8 +50,16 @@ const EXTENDED_MAC_ADDRESS_LEN: usize = 8; // of less safety. pub trait EventManager { - fn device_status_notification_received(&self, data: DeviceStatusNtfPacket) -> Result<()>; - fn core_generic_error_notification_received(&self, data: GenericErrorPacket) -> Result<()>; + fn device_status_notification_received( + &self, + data: DeviceStatusNtfPacket, + chip_id: &str, + ) -> Result<()>; + fn core_generic_error_notification_received( + &self, + data: GenericErrorPacket, + chip_id: &str, + ) -> Result<()>; fn session_status_notification_received(&self, data: SessionStatusNtfPacket) -> Result<()>; fn short_range_data_notification_received( &self, @@ -65,7 +73,11 @@ pub trait EventManager { &self, data: SessionUpdateControllerMulticastListNtfPacket, ) -> Result<()>; - fn vendor_uci_notification_received(&self, data: UciNotificationPacket) -> Result<()>; + fn vendor_uci_notification_received( + &self, + data: UciNotificationPacket, + chip_id: &str, + ) -> Result<()>; } // Manages calling Java callbacks through the JNI. @@ -77,16 +89,24 @@ pub struct EventManagerImpl { } impl EventManager for EventManagerImpl { - fn device_status_notification_received(&self, data: DeviceStatusNtfPacket) -> Result<()> { + fn device_status_notification_received( + &self, + data: DeviceStatusNtfPacket, + chip_id: &str, + ) -> Result<()> { let env = self.jvm.attach_current_thread()?; - let result = self.handle_device_status_notification_received(&env, data); + let result = self.handle_device_status_notification_received(&env, data, chip_id); self.clear_exception(env); result } - fn core_generic_error_notification_received(&self, data: GenericErrorPacket) -> Result<()> { + fn core_generic_error_notification_received( + &self, + data: GenericErrorPacket, + chip_id: &str, + ) -> Result<()> { let env = self.jvm.attach_current_thread()?; - let result = self.handle_core_generic_error_notification_received(&env, data); + let result = self.handle_core_generic_error_notification_received(&env, data, chip_id); self.clear_exception(env); result } @@ -128,9 +148,13 @@ impl EventManager for EventManagerImpl { self.clear_exception(env); result } - fn vendor_uci_notification_received(&self, data: UciNotificationPacket) -> Result<()> { + fn vendor_uci_notification_received( + &self, + data: UciNotificationPacket, + chip_id: &str, + ) -> Result<()> { let env = self.jvm.attach_current_thread()?; - let result = self.handle_vendor_uci_notification_received(&env, data); + let result = self.handle_vendor_uci_notification_received(&env, data, chip_id); self.clear_exception(env); result } @@ -178,6 +202,7 @@ impl EventManagerImpl { &self, env: &JNIEnv, data: DeviceStatusNtfPacket, + chip_id: &str, ) -> Result<()> { let state = data.get_device_state().to_i32().ok_or_else(|| { error!("Failed converting device_state to i32"); @@ -186,8 +211,8 @@ impl EventManagerImpl { env.call_method( self.obj.as_obj(), "onDeviceStatusNotificationReceived", - "(I)V", - &[JValue::Int(state)], + "(ILjava/lang/String;)V", + &[JValue::Int(state), JValue::Object(JObject::from(env.new_string(chip_id)?))], ) .map(|_| ()) // drop void method return } @@ -222,6 +247,7 @@ impl EventManagerImpl { &self, env: &JNIEnv, data: GenericErrorPacket, + chip_id: &str, ) -> Result<()> { let status = data.get_status().to_i32().ok_or_else(|| { error!("Failed converting status to i32"); @@ -230,8 +256,8 @@ impl EventManagerImpl { env.call_method( self.obj.as_obj(), "onCoreGenericErrorNotificationReceived", - "(I)V", - &[JValue::Int(status)], + "(ILjava/lang/String;)V", + &[JValue::Int(status), JValue::Object(JObject::from(env.new_string(chip_id)?))], ) .map(|_| ()) // drop void method return } @@ -681,6 +707,7 @@ impl EventManagerImpl { &self, env: &JNIEnv, data: UciNotificationPacket, + _chip_id: &str, ) -> Result<()> { let gid: i32 = data.get_group_id().to_i32().ok_or_else(|| { error!("Failed to convert gid"); @@ -693,6 +720,7 @@ impl EventManagerImpl { let payload: Vec<u8> = EventManagerImpl::get_vendor_uci_payload(data)?; let payload_jbytearray = env.byte_array_from_slice(payload.as_ref())?; + // TODO(b/237533396): Add chip_id parameter to onVendorUciNotificationReceived env.call_method( self.obj.as_obj(), "onVendorUciNotificationReceived", diff --git a/src/rust/uci/mod.rs b/src/rust/uci/mod.rs index 6f56b66..43a24b5 100644 --- a/src/rust/uci/mod.rs +++ b/src/rust/uci/mod.rs @@ -351,7 +351,7 @@ impl<T: EventManager> Driver<T> { log::debug!("Received hal notification {:?}", response); match response { uci_hrcv::UciNotification::DeviceStatusNtf(response) => { - self.event_manager.device_status_notification_received(response)?; + self.event_manager.device_status_notification_received(response, &chip_id)?; } uci_hrcv::UciNotification::GenericError(response) => { if let (StatusCode::UciStatusCommandRetry, Some((_, retryer))) = @@ -359,7 +359,7 @@ impl<T: EventManager> Driver<T> { { retryer.retry(); } - self.event_manager.core_generic_error_notification_received(response)?; + self.event_manager.core_generic_error_notification_received(response, &chip_id)?; } uci_hrcv::UciNotification::SessionStatusNtf(response) => { self.invoke_hal_session_init_if_necessary(&response, chip_id).await; @@ -375,8 +375,9 @@ impl<T: EventManager> Driver<T> { self.event_manager .session_update_controller_multicast_list_notification_received(response)?; } + uci_hrcv::UciNotification::AndroidRangeDiagnosticsNtf(_response) => {} uci_hrcv::UciNotification::RawVendorNtf(response) => { - self.event_manager.vendor_uci_notification_received(response)?; + self.event_manager.vendor_uci_notification_received(response, &chip_id)?; } } Ok(()) @@ -418,7 +419,7 @@ impl<T: EventManager> Driver<T> { UwbEvent::ERROR => { // Send device status notification with error state. let device_status_ntf = DeviceStatusNtfBuilder { device_state: DeviceState::DeviceStateError}.build(); - self.event_manager.device_status_notification_received(device_status_ntf)?; + self.event_manager.device_status_notification_received(device_status_ntf, &chip_id)?; self.set_state(UwbState::None); } _ => () diff --git a/src/rust/uci/uci_hrcv.rs b/src/rust/uci/uci_hrcv.rs index bf6562b..ab5da94 100644 --- a/src/rust/uci/uci_hrcv.rs +++ b/src/rust/uci/uci_hrcv.rs @@ -54,6 +54,7 @@ pub enum UciNotification { SessionUpdateControllerMulticastListNtf(SessionUpdateControllerMulticastListNtfPacket), ShortMacTwoWayRangeDataNtf(ShortMacTwoWayRangeDataNtfPacket), ExtendedMacTwoWayRangeDataNtf(ExtendedMacTwoWayRangeDataNtfPacket), + AndroidRangeDiagnosticsNtf(ParsedDiagnosticNtfPacket), RawVendorNtf(UciNotificationPacket), } @@ -194,7 +195,12 @@ fn range_data_notification(evt: RangeDataNtfPacket) -> Result<UciNotification, U } fn android_notification(evt: AndroidNotificationPacket) -> Result<UciNotification, UwbErr> { - Err(UwbErr::Specialize(evt.to_vec())) + match evt.specialize() { + AndroidNotificationChild::AndroidRangeDiagnosticsNtf(evt) => { + Ok(UciNotification::AndroidRangeDiagnosticsNtf(parse_diagnostics_ntf(evt)?)) + } + _ => Err(UwbErr::Specialize(evt.to_vec())), + } } fn vendor_notification(evt: UciNotificationPacket) -> Result<UciNotification, UwbErr> { 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 3cc1531..815a5c4 100644 --- a/src/rust/uwb_core/src/uci/uci_manager_sync.rs +++ b/src/rust/uwb_core/src/uci/uci_manager_sync.rs @@ -23,7 +23,7 @@ use tokio::runtime::{Builder as RuntimeBuilder, Runtime}; use tokio::sync::mpsc; use tokio::task; -use crate::error::Result; +use crate::error::{Error, Result}; use crate::params::{ AppConfigTlv, AppConfigTlvType, CapTlv, Controlee, CoreSetConfigResponse, CountryCode, DeviceConfigId, DeviceConfigTlv, GetDeviceInfoResponse, PowerStats, RawVendorMessage, @@ -54,7 +54,7 @@ pub trait NotificationManager: 'static { /// Builder for NotificationManager. Builder is sent between threads. pub trait NotificationManagerBuilder<T: NotificationManager>: 'static + Send + Sync { /// Builds NotificationManager. The build operation Consumes Builder. - fn build(self) -> T; + fn build(self) -> Option<T>; } struct NotificationDriver<U: NotificationManager> { @@ -118,7 +118,7 @@ impl UciManagerSync { uci_manager_runtime: Runtime, hal: T, notification_manager_builder: V, - ) -> Self { + ) -> Result<Self> { // UciManagerImpl::new uses tokio::spawn, so it is called inside the runtime as async fn. let mut uci_manager_impl = uci_manager_runtime.block_on(async { UciManagerImpl::new(hal) }); let (core_notification_sender, core_notification_receiver) = @@ -133,24 +133,46 @@ impl UciManagerSync { uci_manager_impl.set_vendor_notification_sender(vendor_notification_sender).await; }); // The potentially !Send NotificationManager is created in a separate thread. + let (driver_status_sender, mut driver_status_receiver) = mpsc::unbounded_channel::<bool>(); std::thread::spawn(move || { - let notification_runtime = RuntimeBuilder::new_current_thread() - .enable_all() - .build() - .expect("uwb_core: Failed to build Tokio Runtime!"); + let notification_runtime = + match RuntimeBuilder::new_current_thread().enable_all().build() { + Ok(nr) => nr, + Err(_) => { + // unwrap safe since receiver is in scope + driver_status_sender.send(false).unwrap(); + return; + } + }; + let local = task::LocalSet::new(); + let notification_manager = match notification_manager_builder.build() { + Some(nm) => { + // unwrap safe since receiver is in scope + driver_status_sender.send(true).unwrap(); + nm + } + None => { + // unwrap safe since receiver is in scope + driver_status_sender.send(false).unwrap(); + return; + } + }; let mut notification_driver = NotificationDriver::new( core_notification_receiver, session_notification_receiver, vendor_notification_receiver, - notification_manager_builder.build(), + notification_manager, ); local.spawn_local(async move { task::spawn_local(async move { notification_driver.run().await }).await.unwrap(); }); notification_runtime.block_on(local); }); - Self { runtime: uci_manager_runtime, uci_manager_impl } + match driver_status_receiver.blocking_recv() { + Some(true) => Ok(Self { runtime: uci_manager_runtime, uci_manager_impl }), + _ => Err(Error::Unknown), + } } /// Start UCI HAL and blocking until UCI commands can be sent. @@ -328,11 +350,11 @@ mod tests { initial_count: usize, } impl NotificationManagerBuilder<MockNotificationManager> for MockNotificationManagerBuilder { - fn build(self) -> MockNotificationManager { - MockNotificationManager { + fn build(self) -> Option<MockNotificationManager> { + Some(MockNotificationManager { device_state_sender: self.device_state_sender, nonsend_counter: Rc::new(RefCell::new(self.initial_count)), - } + }) } } fn into_raw_messages<T: Into<uwb_uci_packets::UciPacketPacket>>( @@ -355,7 +377,8 @@ mod tests { Builder::new_multi_thread().enable_all().build().unwrap(), hal, MockNotificationManagerBuilder { device_state_sender, initial_count: 0 }, - ); + ) + .unwrap(); assert!(uci_manager_sync.open_hal().is_ok()); let device_state = test_rt.block_on(async { device_state_receiver.recv().await }); assert_eq!(device_state, Some(DeviceState::DeviceStateReady)); diff --git a/src/rust/uwb_uci_packets/src/lib.rs b/src/rust/uwb_uci_packets/src/lib.rs index ef44ecf..d940fa3 100644 --- a/src/rust/uwb_uci_packets/src/lib.rs +++ b/src/rust/uwb_uci_packets/src/lib.rs @@ -169,3 +169,114 @@ impl PacketDefrager { } } } + +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub struct ParsedDiagnosticNtfPacket { + session_id: u32, + sequence_number: u32, + frame_reports: Vec<ParsedFrameReport>, +} + +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub struct ParsedFrameReport { + uwb_msg_id: u8, + action: u8, + antenna_set: u8, + rssi: Vec<u8>, + aoa: Vec<AoaMeasurement>, + cir: Vec<CirValue>, +} + +pub fn parse_diagnostics_ntf( + evt: AndroidRangeDiagnosticsNtfPacket, +) -> Result<ParsedDiagnosticNtfPacket> { + let session_id = evt.get_session_id(); + let sequence_number = evt.get_sequence_number(); + let mut parsed_frame_reports = Vec::new(); + for report in evt.get_frame_reports() { + let mut rssi_vec = Vec::new(); + let mut aoa_vec = Vec::new(); + let mut cir_vec = Vec::new(); + for tlv in &report.frame_report_tlvs { + match FrameReportTlvPacketPacket::parse( + &[vec![tlv.t as u8, tlv.v.len() as u8], tlv.v.clone()].concat(), + ) { + Ok(pkt) => match pkt.specialize() { + FrameReportTlvPacketChild::Rssi(rssi) => { + rssi_vec.append(&mut rssi.get_rssi().clone()) + } + FrameReportTlvPacketChild::Aoa(aoa) => { + aoa_vec.append(&mut aoa.get_aoa().clone()) + } + FrameReportTlvPacketChild::Cir(cir) => { + cir_vec.append(&mut cir.get_cir_value().clone()) + } + _ => return Err(Error::InvalidPacketError), + }, + Err(e) => { + error!("Failed to parse the packet {:?}", e); + return Err(Error::InvalidPacketError); + } + } + } + parsed_frame_reports.push(ParsedFrameReport { + uwb_msg_id: report.uwb_msg_id, + action: report.action, + antenna_set: report.antenna_set, + rssi: rssi_vec, + aoa: aoa_vec, + cir: cir_vec, + }); + } + Ok(ParsedDiagnosticNtfPacket { + session_id, + sequence_number, + frame_reports: parsed_frame_reports, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_diagnostics_ntf() { + let rssi_vec = vec![0x01, 0x02, 0x03]; + let rssi = RssiBuilder { rssi: rssi_vec.clone() }.build(); + let aoa_1 = AoaMeasurement { tdoa: 1, pdoa: 2, aoa: 3, fom: 4, t: 1 }; + let aoa_2 = AoaMeasurement { tdoa: 5, pdoa: 6, aoa: 7, fom: 8, t: 2 }; + let aoa = AoaBuilder { aoa: vec![aoa_1.clone(), aoa_2.clone()] }.build(); + let cir_vec = vec![CirValue { + first_path_index: 1, + first_path_snr: 2, + first_path_ns: 3, + peak_path_index: 4, + peak_path_snr: 5, + peak_path_ns: 6, + first_path_sample_offset: 7, + samples_number: 2, + sample_window: vec![0, 1, 2, 3], + }]; + let cir = CirBuilder { cir_value: cir_vec.clone() }.build(); + let mut frame_reports = Vec::new(); + let tlvs = vec![ + FrameReportTlv { t: rssi.get_t(), v: rssi.get_rssi().to_vec() }, + FrameReportTlv { t: aoa.get_t(), v: aoa.to_vec()[2..].to_vec() }, + FrameReportTlv { t: cir.get_t(), v: cir.to_vec()[2..].to_vec() }, + ]; + let frame_report = + FrameReport { uwb_msg_id: 1, action: 1, antenna_set: 1, frame_report_tlvs: tlvs }; + frame_reports.push(frame_report); + let packet = + AndroidRangeDiagnosticsNtfBuilder { session_id: 1, sequence_number: 1, frame_reports } + .build(); + let mut parsed_packet = parse_diagnostics_ntf(packet).unwrap(); + let parsed_frame_report = parsed_packet.frame_reports.pop().unwrap(); + assert_eq!(rssi_vec, parsed_frame_report.rssi); + assert_eq!(aoa_1, parsed_frame_report.aoa[0]); + assert_eq!(aoa_2, parsed_frame_report.aoa[1]); + assert_eq!(cir_vec, parsed_frame_report.cir); + } +} diff --git a/src/rust/uwb_uci_packets/uci_packets.pdl b/src/rust/uwb_uci_packets/uci_packets.pdl index c523f4e..884c7c6 100644 --- a/src/rust/uwb_uci_packets/uci_packets.pdl +++ b/src/rust/uwb_uci_packets/uci_packets.pdl @@ -845,6 +845,16 @@ struct FrameReportTlv { v: 8[], } +packet FrameReportTlvPacket { + t: FrameReportTlvType, + _size_(_body_): 8, + _body_, +} + +packet Rssi : FrameReportTlvPacket (t = RSSI) { + rssi: 8[], +} + struct AoaMeasurement { tdoa: 16, pdoa: 16, @@ -853,6 +863,14 @@ struct AoaMeasurement { t: 8, } +packet Aoa : FrameReportTlvPacket (t = AOA) { + aoa: AoaMeasurement[], +} + +test Aoa { + "\x01\x08\x00\x01\x00\x01\x00\x01\x01\x01", +} + struct CirValue { first_path_index : 16, first_path_snr: 16, @@ -866,11 +884,15 @@ struct CirValue { sample_window: 8[], } -struct Cir { +packet Cir : FrameReportTlvPacket (t = CIR) { _count_(cir_value): 8, cir_value: CirValue[], } +test Cir { + "\x02\x15\x01\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x02\x04\x00\x01\x02\x03\x04", +} + struct FrameReport { uwb_msg_id: 8, action: 8, |