Parse the diagnostic notification when received in uci layer.
Test: atest libuwb_uci_rust_tests
Bug: 236969605
Change-Id: I41b32eff1b584df397c7d97499da657b1b0672ec
diff --git a/src/rust/uci/mod.rs b/src/rust/uci/mod.rs
index 6f56b66..d7a5df4 100644
--- a/src/rust/uci/mod.rs
+++ b/src/rust/uci/mod.rs
@@ -375,6 +375,7 @@
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)?;
}
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 @@
SessionUpdateControllerMulticastListNtf(SessionUpdateControllerMulticastListNtfPacket),
ShortMacTwoWayRangeDataNtf(ShortMacTwoWayRangeDataNtfPacket),
ExtendedMacTwoWayRangeDataNtf(ExtendedMacTwoWayRangeDataNtfPacket),
+ AndroidRangeDiagnosticsNtf(ParsedDiagnosticNtfPacket),
RawVendorNtf(UciNotificationPacket),
}
@@ -194,7 +195,12 @@
}
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_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 @@
}
}
}
+
+#[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 @@
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 @@
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 @@
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,