diff --git a/src/bin/wavehunter.rs b/src/bin/wavehunter.rs index 68708a6..5a014c2 100644 --- a/src/bin/wavehunter.rs +++ b/src/bin/wavehunter.rs @@ -75,12 +75,21 @@ fn main() -> Result<(), WavehunterError> { .map_err(WavehunterError::PcapFileWriteError)?; loop { - for msg in dev.read_response().map_err(WavehunterError::DiagReadError)? { - debug!("msg: {:?}", msg); - if let Some((timestamp, gsmtap_msg)) = gsmtap_parser.recv_message(msg).map_err(WavehunterError::GsmtapParsingError)? { - debug!("gsmtap_msg: {:?}", gsmtap_msg); - pcap_file.write_gsmtap_message(gsmtap_msg, timestamp) - .map_err(WavehunterError::PcapFileWriteError)?; + for maybe_msg in dev.read_response().map_err(WavehunterError::DiagReadError)? { + match maybe_msg { + Ok(msg) => { + debug!("msg: {:?}", msg); + let maybe_gsmtap_msg = gsmtap_parser.recv_message(msg) + .map_err(WavehunterError::GsmtapParsingError)?; + if let Some((timestamp, gsmtap_msg)) = maybe_gsmtap_msg { + debug!("gsmtap_msg: {:?}", gsmtap_msg); + pcap_file.write_gsmtap_message(gsmtap_msg, timestamp) + .map_err(WavehunterError::PcapFileWriteError)?; + } + }, + Err(e) => { + dbg!("error parsing message: {:?}", e); + }, } } } diff --git a/src/bin/wavehunter_reader.rs b/src/bin/wavehunter_reader.rs index 6293c3d..470d054 100644 --- a/src/bin/wavehunter_reader.rs +++ b/src/bin/wavehunter_reader.rs @@ -20,21 +20,21 @@ fn main() { pcap_file.write_iface_header().unwrap(); loop { - match qmdl_reader.read_response() { - Ok(msgs) => { - for msg in msgs { + for maybe_msg in qmdl_reader.read_response().expect("error reading qmdl file") { + match maybe_msg { + Ok(msg) => { debug!("msg: {:?}", msg); - if let Some((timestamp, gsmtap_msg)) = gsmtap_parser.recv_message(msg).unwrap() { + let maybe_gsmtap_msg = gsmtap_parser.recv_message(msg).expect("error parsing gsmtap message"); + if let Some((timestamp, gsmtap_msg)) = maybe_gsmtap_msg { debug!("gsmtap_msg: {:?}", gsmtap_msg); - pcap_file.write_gsmtap_message(gsmtap_msg, timestamp).unwrap(); + pcap_file.write_gsmtap_message(gsmtap_msg, timestamp) + .expect("error writing pcap packet"); } - } - }, - Err(err) if err.kind() == std::io::ErrorKind::UnexpectedEof => { - println!("Reached end of QMDL file, exiting..."); - std::process::exit(0); - }, - Err(err) => panic!("Error reading QMDL file {}", err), + }, + Err(e) => { + dbg!("error parsing message: {:?}", e); + }, + } } } } diff --git a/src/diag_device.rs b/src/diag_device.rs index c6db4e4..8cd2fea 100644 --- a/src/diag_device.rs +++ b/src/diag_device.rs @@ -137,8 +137,8 @@ impl DiagDevice { for msg in self.read_response()? { match msg { - Message::Log { .. } => info!("skipping log response..."), - Message::Response { payload, status, .. } => match payload { + Ok(Message::Log { .. }) => info!("skipping log response..."), + Ok(Message::Response { payload, status, .. }) => match payload { ResponsePayload::LogConfig(LogConfigResponse::RetrieveIdRanges { log_mask_sizes }) => { if status != 0 { return Err(DiagDeviceError::RequestFailed(status, req)); @@ -147,6 +147,7 @@ impl DiagDevice { }, _ => info!("skipping non-LogConfigResponse response..."), }, + Err(e) => error!("error parsing message: {:?}", e), } } @@ -159,8 +160,8 @@ impl DiagDevice { for msg in self.read_response()? { match msg { - Message::Log { .. } => info!("skipping log response..."), - Message::Response { payload, status, .. } => { + Ok(Message::Log { .. }) => info!("skipping log response..."), + Ok(Message::Response { payload, status, .. }) => { if let ResponsePayload::LogConfig(LogConfigResponse::SetMask) = payload { if status != 0 { return Err(DiagDeviceError::RequestFailed(status, req)); @@ -168,6 +169,7 @@ impl DiagDevice { return Ok(()); } }, + Err(e) => error!("error parsing message: {:?}", e), } } diff --git a/src/diag_reader.rs b/src/diag_reader.rs index 0b6ed3e..042bf37 100644 --- a/src/diag_reader.rs +++ b/src/diag_reader.rs @@ -1,9 +1,11 @@ use crate::diag; use crate::{diag::*, hdlc::hdlc_decapsulate}; +use crate::hdlc; use crc::{Crc, Algorithm}; use deku::prelude::*; -use log::{debug, info, warn, error}; +use log::{info, warn, error}; +use thiserror::Error; // this is sorta based on the params qcsuper uses, plus what seems to be used in // https://github.com/fgsect/scat/blob/f1538b397721df3ab8ba12acd26716abcf21f78b/util.py#L47 @@ -19,12 +21,22 @@ pub const CRC_CCITT_ALG: Algorithm = Algorithm { }; pub const CRC_CCITT: Crc = Crc::::new(&CRC_CCITT_ALG); +#[derive(Debug, Error)] +pub enum DiagParsingError { + #[error("Failed to parse Message: {0}, data: {1:?}")] + MessageParsingError(deku::DekuError, Vec), + #[error("HDLC decapsulation of message failed: {0}, data: {1:?}")] + HdlcDecapsulationError(hdlc::HdlcError, Vec), +} + +type MaybeMessage = Result; + pub trait DiagReader { type Err; fn get_next_messages_container(&mut self) -> Result; - fn read_response(&mut self) -> Result, Self::Err> { + fn read_response(&mut self) -> Result, Self::Err> { loop { let container = self.get_next_messages_container()?; if container.data_type == DataType::UserSpace { @@ -35,7 +47,7 @@ pub trait DiagReader { } } - fn parse_response_container(&self, container: MessagesContainer) -> Result, Self::Err> { + fn parse_response_container(&self, container: MessagesContainer) -> Result, Self::Err> { let mut result = Vec::new(); for msg in container.messages { for sub_msg in msg.data.split_inclusive(|&b| b == diag::MESSAGE_TERMINATOR) { @@ -45,16 +57,14 @@ pub trait DiagReader { if leftover_bytes.len() > 0 { warn!("warning: {} leftover bytes when parsing Message", leftover_bytes.len()); } - result.push(res); + result.push(Ok(res)); }, Err(e) => { - error!("error parsing response: {:?}", e); - debug!("{:?}", data); + result.push(Err(DiagParsingError::MessageParsingError(e, data))); }, }, Err(err) => { - error!("error decapsulating response: {:?}", err); - debug!("{:?}", &sub_msg); + result.push(Err(DiagParsingError::HdlcDecapsulationError(err, sub_msg.to_vec()))); } } }