diff options
author | 2024-08-13 17:58:57 +0800 | |
---|---|---|
committer | 2024-08-14 15:54:38 +0800 | |
commit | 9d12639d7830038848815c6932ceed788d636b89 (patch) | |
tree | b48fc512478d2ab5a2b856522a7bfb1e146a913a | |
parent | 85806d6e18dbc94279f20d21fc2569eb31cc816f (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.rs | 91 |
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)), } } |