Files
rayhunter/src/qmdl.rs
Will Greenberg 59c0a9d944 Use QMDL instead of our custom debug file format
This might be a bit premature, but since we don't seem to be
experiencing any more parsing errors when reading MessagesContainers,
let's switch to outputting a standard QMDL (Qualcomm Mobile
Diagnostic Log) file. This file format is more widely used by tools
like scat, and the only data we lose out on is the container metadata
and non-UserData messages (which we weren't using anyway).
2024-01-03 11:29:58 -08:00

75 lines
2.3 KiB
Rust

//! QMDL files are Qualcomm Mobile Diagnostic Logs. Their format is very simple,
//! just a series of of concatenated HDLC encapsulated diag::Message structs.
use crate::diag_reader::DiagReader;
use crate::diag_device::DiagResult;
use crate::diag::{MessagesContainer, MESSAGE_TERMINATOR, HdlcEncapsulatedMessage, DataType};
use std::fs::File;
use std::io::{Write, BufReader, BufRead};
pub struct QmdlFileWriter {
file: File,
pub total_written: usize,
}
impl QmdlFileWriter {
pub fn new<P>(path: P) -> DiagResult<Self> where P: AsRef<std::path::Path> {
let file = std::fs::File::options()
.create(true)
.append(true)
.open(path)?;
Ok(QmdlFileWriter {
file,
total_written: 0,
})
}
pub fn write_container(&mut self, container: &MessagesContainer) -> DiagResult<()> {
for msg in &container.messages {
self.file.write_all(&msg.data)?;
self.total_written += msg.data.len();
}
Ok(())
}
}
pub struct QmdlFileReader {
file: BufReader<File>,
buf: Vec<u8>
}
impl QmdlFileReader {
pub fn new<P>(path: P) -> DiagResult<Self> where P: AsRef<std::path::Path> {
let file = std::fs::File::options()
.read(true)
.open(path)?;
Ok(QmdlFileReader {
file: BufReader::new(file),
buf: Vec::new(),
})
}
}
impl DiagReader for QmdlFileReader {
fn get_next_messages_container(&mut self) -> DiagResult<MessagesContainer> {
let bytes_read = self.file.read_until(MESSAGE_TERMINATOR, &mut self.buf)?;
// Since QMDL is just a flat list of messages, we can't actually
// reproduce the container structure they came from in the original
// read. So we'll just pretend that all containers had exactly one
// message. As far as I know, the number of messages per container
// doesn't actually affect anything, so this should be fine.
Ok(MessagesContainer {
data_type: DataType::UserSpace,
num_messages: 1,
messages: vec![
HdlcEncapsulatedMessage {
len: 1,
data: self.buf[0..bytes_read].to_vec(),
},
]
})
}
}