summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-08-10 10:39:52 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-08-10 10:39:52 +0000
commit8986e8c256b17fb3430141d18ae1d6656d1c2d3a (patch)
treece8ff5155fa4a4e9adb439ff81370f87fa0e22e3
parent788287c7df96041f190d5ddb636bb25670a2dcaa (diff)
parent26d4e8bd586048be563929251cec44c737ac0726 (diff)
downloaduwb-8986e8c256b17fb3430141d18ae1d6656d1c2d3a.tar.gz
Snap for 8928942 from 26d4e8bd586048be563929251cec44c737ac0726 to mainline-mediaprovider-releaseaml_mpr_331011070
Change-Id: I959f224abc38f807a5d9040dbe37bbdbd9a19d0a
-rwxr-xr-xsrc/Android.bp3
-rw-r--r--src/rust/event_manager/mock_event_manager.rs18
-rw-r--r--src/rust/event_manager/mod.rs54
-rw-r--r--src/rust/uci/mod.rs9
-rw-r--r--src/rust/uci/uci_hrcv.rs8
-rw-r--r--src/rust/uwb_core/src/uci/uci_manager_sync.rs49
-rw-r--r--src/rust/uwb_uci_packets/src/lib.rs111
-rw-r--r--src/rust/uwb_uci_packets/uci_packets.pdl24
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,