summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Archie Pusaka <apusaka@chromium.org> 2024-08-13 17:58:57 +0800
committer Archie Pusaka <apusaka@google.com> 2024-08-14 15:54:38 +0800
commit9d12639d7830038848815c6932ceed788d636b89 (patch)
treeb48fc512478d2ab5a2b856522a7bfb1e146a913a
parent85806d6e18dbc94279f20d21fc2569eb31cc816f (diff)
Floss: Hcidoc: Support AOSP snoop log
AOSP log has datalink_type 1002 and a different logic to store the opcodes of the packet. Bug: 343594308 Test: m -j Test: Run hcidoc with snoop captured from AOSP Flag: EXEMPT, floss only changes Change-Id: I05da6242e93feef0f835592f999230d6b0b3f064
-rw-r--r--floss/hcidoc/src/parser.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/floss/hcidoc/src/parser.rs b/floss/hcidoc/src/parser.rs
index 23e2e9e5c9..26659bc424 100644
--- a/floss/hcidoc/src/parser.rs
+++ b/floss/hcidoc/src/parser.rs
@@ -29,6 +29,7 @@ const SNOOP_HEADER_SIZE: usize = 16;
#[derive(Debug, FromPrimitive, ToPrimitive)]
#[repr(u32)]
enum SnoopDatalinkType {
+ H4Uart = 1002,
LinuxMonitor = 2001,
}
@@ -200,6 +201,43 @@ impl GeneralSnoopPacket for LinuxSnoopPacket {
}
}
+pub struct H4SnoopPacket {
+ pub preamble: SnoopPacketPreamble,
+ pub data: Vec<u8>,
+ pub pkt_type: u8,
+}
+
+impl GeneralSnoopPacket for H4SnoopPacket {
+ fn adapter_index(&self) -> u16 {
+ 0
+ }
+ fn opcode(&self) -> SnoopOpcodes {
+ match self.pkt_type {
+ 0x01 => SnoopOpcodes::Command,
+ 0x02 => match self.preamble.flags & 0x01 {
+ 0x00 => SnoopOpcodes::AclTxPacket,
+ _ => SnoopOpcodes::AclRxPacket,
+ },
+ 0x03 => match self.preamble.flags & 0x01 {
+ 0x00 => SnoopOpcodes::ScoTxPacket,
+ _ => SnoopOpcodes::ScoRxPacket,
+ },
+ 0x04 => SnoopOpcodes::Event,
+ 0x05 => match self.preamble.flags & 0x01 {
+ 0x00 => SnoopOpcodes::IsoTx,
+ _ => SnoopOpcodes::IsoRx,
+ },
+ _ => SnoopOpcodes::Invalid,
+ }
+ }
+ fn preamble(&self) -> &SnoopPacketPreamble {
+ &self.preamble
+ }
+ fn data(&self) -> &Vec<u8> {
+ &self.data
+ }
+}
+
/// Maximum packet size for snoop is the max ACL size + 4 bytes.
const SNOOP_MAX_PACKET_SIZE: usize = 1486 + 4;
@@ -244,6 +282,58 @@ impl<'a> Iterator for LinuxSnoopReader<'a> {
}
}
+/// Reader for H4/UART/Android snoop files.
+pub struct H4SnoopReader<'a> {
+ fd: Box<dyn BufRead + 'a>,
+}
+
+impl<'a> H4SnoopReader<'a> {
+ fn new(fd: Box<dyn BufRead + 'a>) -> Self {
+ H4SnoopReader { fd }
+ }
+}
+
+impl<'a> Iterator for H4SnoopReader<'a> {
+ type Item = Box<dyn GeneralSnoopPacket>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let preamble = match SnoopPacketPreamble::from_fd(&mut self.fd) {
+ Some(preamble) => preamble,
+ None => {
+ return None;
+ }
+ };
+
+ if preamble.included_length > 0 {
+ let size: usize = (preamble.included_length - 1).try_into().unwrap();
+ let mut type_buf = [0u8; 1];
+ match self.fd.read_exact(&mut type_buf) {
+ Ok(()) => {}
+ Err(e) => {
+ eprintln!("Couldn't read any packet data: {}", e);
+ return None;
+ }
+ };
+
+ let mut rem_data = [0u8; SNOOP_MAX_PACKET_SIZE];
+ match self.fd.read_exact(&mut rem_data[0..size]) {
+ Ok(()) => Some(Box::new(H4SnoopPacket {
+ preamble,
+ data: rem_data[0..size].to_vec(),
+ pkt_type: type_buf[0],
+ })),
+ Err(e) => {
+ eprintln!("Couldn't read any packet data: {}", e);
+ None
+ }
+ }
+ } else {
+ eprintln!("Non-positive packet size: {}", preamble.included_length);
+ None
+ }
+ }
+}
+
pub struct LogParser {
fd: Box<dyn BufRead>,
log_type: SnoopDatalinkType,
@@ -270,6 +360,7 @@ impl<'a> LogParser {
pub fn get_snoop_iterator(self) -> Box<dyn Iterator<Item = Box<dyn GeneralSnoopPacket>>> {
let reader = Box::new(BufReader::new(self.fd));
match self.log_type {
+ SnoopDatalinkType::H4Uart => Box::new(H4SnoopReader::new(reader)),
SnoopDatalinkType::LinuxMonitor => Box::new(LinuxSnoopReader::new(reader)),
}
}