From 2504a1da2e82237ebbd65cad5e8be4047c53006f Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 13 Dec 2023 13:05:47 -0800 Subject: [PATCH 1/5] add failsafe writer and reader --- Cargo.toml | 4 ++ src/diag_device.rs | 129 ++++++++++++++++++++++++++++++++--------- src/failsafe_reader.rs | 22 +++++++ src/main.rs | 2 +- 4 files changed, 129 insertions(+), 28 deletions(-) create mode 100644 src/failsafe_reader.rs diff --git a/Cargo.toml b/Cargo.toml index 38eabfd..2818110 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "failsafe_reader" +path = "src/failsafe_reader.rs" + [dependencies] bytes = "1.5.0" chrono = "0.4.31" diff --git a/src/diag_device.rs b/src/diag_device.rs index 9989fd3..0a5540f 100644 --- a/src/diag_device.rs +++ b/src/diag_device.rs @@ -3,7 +3,7 @@ use crate::diag::{Message, ResponsePayload, Request, LogConfigRequest, LogConfig use crate::log_codes; use std::fs::File; -use std::io::Read; +use std::io::{Read, Write, Seek}; use std::os::fd::AsRawFd; use thiserror::Error; use crc::{Crc, Algorithm}; @@ -41,6 +41,7 @@ pub const CRC_CCITT_ALG: Algorithm = Algorithm { check: 0x2189, residue: 0x0000, }; +pub const CRC_CCITT: Crc = Crc::::new(&CRC_CCITT_ALG); pub const LOG_CODES_FOR_RAW_PACKET_LOGGING: [u32; 11] = [ // Layer 2: @@ -68,33 +69,55 @@ const MEMORY_DEVICE_MODE: i32 = 2; const DIAG_IOCTL_REMOTE_DEV: u32 = 32; const DIAG_IOCTL_SWITCH_LOGGING: u32 = 7; +const FAILSAFE_PATH: &str = "/data/wavehunter-failsafe"; + pub struct DiagDevice<'a> { file: &'a File, + failsafe_file: File, read_buf: Vec, use_mdm: i32, - crc: Crc, } -impl<'a> DiagDevice<'a> { - pub fn new(file: &'a File) -> DiagResult { - let fd = file.as_raw_fd(); +#[derive(Debug, DekuRead, DekuWrite)] +#[deku(endian = "little")] +struct FailsafeReadBlock<'a> { + size: u32, + #[deku(count = "size")] + data: &'a [u8], +} - enable_frame_readwrite(fd, MEMORY_DEVICE_MODE)?; - let use_mdm = determine_use_mdm(fd)?; +pub struct FailsafeFileReader { + file: File, +} - Ok(DiagDevice { - read_buf: vec![0; BUFFER_LEN], - file, - crc: Crc::::new(&CRC_CCITT_ALG), - use_mdm, - }) +impl FailsafeFileReader { + pub fn new

(path: P) -> DiagResult where P: AsRef { + let file = std::fs::File::options() + .read(true) + .open(path)?; + Ok(FailsafeFileReader { file }) + } +} + +pub trait DiagInterface { + fn get_next_messages_container(&mut self) -> DiagResult; + + fn read_response(&mut self) -> DiagResult> { + loop { + let container = self.get_next_messages_container()?; + if container.data_type == DataType::UserSpace { + return self.parse_response_container(container); + } else { + println!("skipping non-userspace message...") + } + } } fn parse_response_container(&self, container: MessagesContainer) -> DiagResult> { let mut result = Vec::new(); for msg in container.messages { for sub_msg in msg.data.split_inclusive(|&b| b == 0x7e) { - match hdlc_decapsulate(&sub_msg, &self.crc) { + match hdlc_decapsulate(&sub_msg, &CRC_CCITT) { Ok(data) => match Message::from_bytes((&data, 0)) { Ok(((leftover_bytes, _), res)) => { if leftover_bytes.len() > 0 { @@ -116,28 +139,80 @@ impl<'a> DiagDevice<'a> { } Ok(result) } +} - pub fn read_response(&mut self) -> DiagResult> { - loop { - let bytes_read = self.file.read(&mut self.read_buf).unwrap(); - let ((leftover_bytes, _), res_container) = MessagesContainer::from_bytes((&self.read_buf[0..bytes_read], 0))?; - if leftover_bytes.len() > 0 { - println!("warning: {} leftover bytes when parsing MessagesContainer", leftover_bytes.len()); - } - if res_container.data_type == DataType::UserSpace { - return self.parse_response_container(res_container); - } else { - println!("skipping non-userspace message...") - } + +impl DiagInterface for FailsafeFileReader { + fn get_next_messages_container(&mut self) -> DiagResult { + let mut bytes_read_buf = [0; 4]; + match self.file.read_exact(&mut bytes_read_buf) { + Ok(_) => {}, + Err(e) => { + dbg!(e.kind()); + if e.kind() == std::io::ErrorKind::UnexpectedEof { + println!("reached end of failsafe file, exiting..."); + std::process::exit(0); + } + return Err(e.into()); + }, } + let bytes_read = u32::from_le_bytes(bytes_read_buf) as usize; + let mut data = vec![0; bytes_read as usize]; + self.file.read_exact(&mut data)?; + let ((leftover_bytes, _), container) = MessagesContainer::from_bytes((&data, 0))?; + if leftover_bytes.len() > 0 { + println!("warning: {} leftover bytes when parsing MessagesContainer", leftover_bytes.len()); + } + Ok(container) } +} + +impl<'a> DiagInterface for DiagDevice<'a> { + fn get_next_messages_container(&mut self) -> DiagResult { + let bytes_read = self.file.read(&mut self.read_buf).unwrap(); + { + let failsafe_block = FailsafeReadBlock { + size: bytes_read as u32, + data: &self.read_buf[0..bytes_read], + }; + let failsafe_block_bytes = failsafe_block.to_bytes().unwrap(); + self.failsafe_file.write_all(&failsafe_block_bytes).unwrap(); + } + let ((leftover_bytes, _), container) = MessagesContainer::from_bytes((&self.read_buf[0..bytes_read], 0))?; + if leftover_bytes.len() > 0 { + println!("warning: {} leftover bytes when parsing MessagesContainer", leftover_bytes.len()); + } + Ok(container) + } +} + +impl<'a> DiagDevice<'a> { + pub fn new(file: &'a File) -> DiagResult { + let fd = file.as_raw_fd(); + + enable_frame_readwrite(fd, MEMORY_DEVICE_MODE)?; + let use_mdm = determine_use_mdm(fd)?; + + let failsafe_file = std::fs::File::options() + .create(true) + .write(true) + .open(FAILSAFE_PATH)?; + + Ok(DiagDevice { + read_buf: vec![0; BUFFER_LEN], + file, + failsafe_file, + use_mdm, + }) + } + pub fn write_request(&mut self, req: &Request) -> DiagResult<()> { let buf = RequestContainer { data_type: DataType::UserSpace, use_mdm: self.use_mdm > 0, mdm_field: -1, - hdlc_encapsulated_request: hdlc_encapsulate(&req.to_bytes().unwrap(), &self.crc), + hdlc_encapsulated_request: hdlc_encapsulate(&req.to_bytes().unwrap(), &CRC_CCITT), }.to_bytes().unwrap(); unsafe { let fd = self.file.as_raw_fd(); diff --git a/src/failsafe_reader.rs b/src/failsafe_reader.rs new file mode 100644 index 0000000..7d57c39 --- /dev/null +++ b/src/failsafe_reader.rs @@ -0,0 +1,22 @@ +mod hdlc; +mod diag; +mod diag_device; +mod log_codes; + +use crate::diag_device::{FailsafeFileReader, DiagInterface}; + +fn main() -> diag_device::DiagResult<()> { + // this should eventually be removed for prod + env_logger::init(); + let args: Vec = std::env::args().collect(); + if args.len() != 2 { + println!("Usage: {} /path/to/failsafe/file", args[0]); + } + let mut failsafe_reader = FailsafeFileReader::new(&args[1])?; + + loop { + for msg in failsafe_reader.read_response()? { + println!("msg: {:?}", msg); + } + } +} diff --git a/src/main.rs b/src/main.rs index 1d56fa4..28b17ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ mod diag; mod diag_device; mod log_codes; -use crate::diag_device::DiagDevice; +use crate::diag_device::{DiagDevice, DiagInterface}; fn main() -> diag_device::DiagResult<()> { // this should eventually be removed for prod From 6cc22c3863388d64f75bcc0c7a4b5e8498efeba5 Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 13 Dec 2023 13:09:52 -0800 Subject: [PATCH 2/5] exit failsafe_reader if incorrect args are supplied --- src/failsafe_reader.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/failsafe_reader.rs b/src/failsafe_reader.rs index 7d57c39..b52996b 100644 --- a/src/failsafe_reader.rs +++ b/src/failsafe_reader.rs @@ -11,6 +11,7 @@ fn main() -> diag_device::DiagResult<()> { let args: Vec = std::env::args().collect(); if args.len() != 2 { println!("Usage: {} /path/to/failsafe/file", args[0]); + std::process::exit(1); } let mut failsafe_reader = FailsafeFileReader::new(&args[1])?; From 0187fa51e877e13d9be480b38af3c04e83464cd3 Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 13 Dec 2023 13:37:57 -0800 Subject: [PATCH 3/5] rename failsafe mode to debug mode --- Cargo.toml | 4 +- src/{failsafe_reader.rs => debug_reader.rs} | 8 ++-- src/diag_device.rs | 46 +++++++++++---------- src/main.rs | 3 +- 4 files changed, 33 insertions(+), 28 deletions(-) rename src/{failsafe_reader.rs => debug_reader.rs} (59%) diff --git a/Cargo.toml b/Cargo.toml index 2818110..fccbdd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [[bin]] -name = "failsafe_reader" -path = "src/failsafe_reader.rs" +name = "debug_reader" +path = "src/debug_reader.rs" [dependencies] bytes = "1.5.0" diff --git a/src/failsafe_reader.rs b/src/debug_reader.rs similarity index 59% rename from src/failsafe_reader.rs rename to src/debug_reader.rs index b52996b..0d25e55 100644 --- a/src/failsafe_reader.rs +++ b/src/debug_reader.rs @@ -3,20 +3,20 @@ mod diag; mod diag_device; mod log_codes; -use crate::diag_device::{FailsafeFileReader, DiagInterface}; +use crate::diag_device::{DebugFileReader, DiagReader}; fn main() -> diag_device::DiagResult<()> { // this should eventually be removed for prod env_logger::init(); let args: Vec = std::env::args().collect(); if args.len() != 2 { - println!("Usage: {} /path/to/failsafe/file", args[0]); + println!("Usage: {} /path/to/debug/file", args[0]); std::process::exit(1); } - let mut failsafe_reader = FailsafeFileReader::new(&args[1])?; + let mut debug_reader = DebugFileReader::new(&args[1])?; loop { - for msg in failsafe_reader.read_response()? { + for msg in debug_reader.read_response()? { println!("msg: {:?}", msg); } } diff --git a/src/diag_device.rs b/src/diag_device.rs index 0a5540f..ad8b956 100644 --- a/src/diag_device.rs +++ b/src/diag_device.rs @@ -69,37 +69,35 @@ const MEMORY_DEVICE_MODE: i32 = 2; const DIAG_IOCTL_REMOTE_DEV: u32 = 32; const DIAG_IOCTL_SWITCH_LOGGING: u32 = 7; -const FAILSAFE_PATH: &str = "/data/wavehunter-failsafe"; - pub struct DiagDevice<'a> { file: &'a File, - failsafe_file: File, + debug_file: Option, read_buf: Vec, use_mdm: i32, } #[derive(Debug, DekuRead, DekuWrite)] #[deku(endian = "little")] -struct FailsafeReadBlock<'a> { +struct DebugReadBlock<'a> { size: u32, #[deku(count = "size")] data: &'a [u8], } -pub struct FailsafeFileReader { +pub struct DebugFileReader { file: File, } -impl FailsafeFileReader { +impl DebugFileReader { pub fn new

(path: P) -> DiagResult where P: AsRef { let file = std::fs::File::options() .read(true) .open(path)?; - Ok(FailsafeFileReader { file }) + Ok(DebugFileReader { file }) } } -pub trait DiagInterface { +pub trait DiagReader { fn get_next_messages_container(&mut self) -> DiagResult; fn read_response(&mut self) -> DiagResult> { @@ -142,7 +140,7 @@ pub trait DiagInterface { } -impl DiagInterface for FailsafeFileReader { +impl DiagReader for DebugFileReader { fn get_next_messages_container(&mut self) -> DiagResult { let mut bytes_read_buf = [0; 4]; match self.file.read_exact(&mut bytes_read_buf) { @@ -150,7 +148,7 @@ impl DiagInterface for FailsafeFileReader { Err(e) => { dbg!(e.kind()); if e.kind() == std::io::ErrorKind::UnexpectedEof { - println!("reached end of failsafe file, exiting..."); + println!("reached end of debug file, exiting..."); std::process::exit(0); } return Err(e.into()); @@ -167,16 +165,16 @@ impl DiagInterface for FailsafeFileReader { } } -impl<'a> DiagInterface for DiagDevice<'a> { +impl<'a> DiagReader for DiagDevice<'a> { fn get_next_messages_container(&mut self) -> DiagResult { let bytes_read = self.file.read(&mut self.read_buf).unwrap(); - { - let failsafe_block = FailsafeReadBlock { + if let Some(debug_file) = self.debug_file.as_mut() { + let debug_block = DebugReadBlock { size: bytes_read as u32, data: &self.read_buf[0..bytes_read], }; - let failsafe_block_bytes = failsafe_block.to_bytes().unwrap(); - self.failsafe_file.write_all(&failsafe_block_bytes).unwrap(); + let debug_block_bytes = debug_block.to_bytes().unwrap(); + debug_file.write_all(&debug_block_bytes).unwrap(); } let ((leftover_bytes, _), container) = MessagesContainer::from_bytes((&self.read_buf[0..bytes_read], 0))?; if leftover_bytes.len() > 0 { @@ -193,19 +191,25 @@ impl<'a> DiagDevice<'a> { enable_frame_readwrite(fd, MEMORY_DEVICE_MODE)?; let use_mdm = determine_use_mdm(fd)?; - let failsafe_file = std::fs::File::options() - .create(true) - .write(true) - .open(FAILSAFE_PATH)?; - Ok(DiagDevice { read_buf: vec![0; BUFFER_LEN], file, - failsafe_file, + debug_file: None, use_mdm, }) } + // Creates a file at the given path where all binary output from /dev/diag + // will be recorded. + pub fn enable_debug_mode

(&mut self, path: P) -> DiagResult<()> where P: AsRef { + let debug_file = std::fs::File::options() + .create(true) + .write(true) + .open(path)?; + println!("enabling debug mode, writing debug output to {:?}", debug_file); + self.debug_file = Some(debug_file); + Ok(()) + } pub fn write_request(&mut self, req: &Request) -> DiagResult<()> { let buf = RequestContainer { diff --git a/src/main.rs b/src/main.rs index 28b17ee..e83c760 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ mod diag; mod diag_device; mod log_codes; -use crate::diag_device::{DiagDevice, DiagInterface}; +use crate::diag_device::{DiagDevice, DiagReader}; fn main() -> diag_device::DiagResult<()> { // this should eventually be removed for prod @@ -14,6 +14,7 @@ fn main() -> diag_device::DiagResult<()> { .write(true) .open("/dev/diag")?; let mut dev = DiagDevice::new(&file)?; + dev.enable_debug_mode("/data/wavehunter-debug")?; dev.config_logs()?; loop { From 69d40a766a73cb2a441532cee39717b1912dc258 Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 13 Dec 2023 14:21:18 -0800 Subject: [PATCH 4/5] some renaming, reorganization --- src/debug_file.rs | 50 ++++++++++++++++++++ src/debug_reader.rs | 5 +- src/diag_device.rs | 110 ++------------------------------------------ src/diag_reader.rs | 61 ++++++++++++++++++++++++ src/hdlc.rs | 2 +- src/main.rs | 5 +- 6 files changed, 125 insertions(+), 108 deletions(-) create mode 100644 src/debug_file.rs create mode 100644 src/diag_reader.rs diff --git a/src/debug_file.rs b/src/debug_file.rs new file mode 100644 index 0000000..3dd2c2a --- /dev/null +++ b/src/debug_file.rs @@ -0,0 +1,50 @@ +use crate::diag_reader::DiagReader; +use crate::diag_device::DiagResult; +use crate::diag::*; + +use deku::prelude::*; +use std::fs::File; +use std::io::Read; + +#[derive(Debug, DekuRead, DekuWrite)] +#[deku(endian = "little")] +pub struct DebugFileBlock<'a> { + pub size: u32, + #[deku(count = "size")] + pub data: &'a [u8], +} + +pub struct DebugFileReader { + file: File, +} + +impl DebugFileReader { + pub fn new

(path: P) -> DiagResult where P: AsRef { + let file = std::fs::File::options() + .read(true) + .open(path)?; + Ok(DebugFileReader { file }) + } +} + + +impl DiagReader for DebugFileReader { + fn get_next_messages_container(&mut self) -> DiagResult { + let mut bytes_read_buf = [0; 4]; + if let Err(e) = self.file.read_exact(&mut bytes_read_buf) { + if e.kind() == std::io::ErrorKind::UnexpectedEof { + println!("reached end of debug file, exiting..."); + std::process::exit(0); + } + return Err(e.into()); + } + let bytes_read = u32::from_le_bytes(bytes_read_buf) as usize; + let mut data = vec![0; bytes_read as usize]; + self.file.read_exact(&mut data)?; + let ((leftover_bytes, _), container) = MessagesContainer::from_bytes((&data, 0))?; + if leftover_bytes.len() > 0 { + println!("warning: {} leftover bytes when parsing MessagesContainer", leftover_bytes.len()); + } + Ok(container) + } +} diff --git a/src/debug_reader.rs b/src/debug_reader.rs index 0d25e55..ad64432 100644 --- a/src/debug_reader.rs +++ b/src/debug_reader.rs @@ -1,9 +1,12 @@ mod hdlc; mod diag; mod diag_device; +mod diag_reader; +mod debug_file; mod log_codes; -use crate::diag_device::{DebugFileReader, DiagReader}; +use crate::debug_file::DebugFileReader; +use crate::diag_reader::DiagReader; fn main() -> diag_device::DiagResult<()> { // this should eventually be removed for prod diff --git a/src/diag_device.rs b/src/diag_device.rs index ad8b956..b697e96 100644 --- a/src/diag_device.rs +++ b/src/diag_device.rs @@ -1,12 +1,13 @@ -use crate::hdlc::{hdlc_encapsulate, hdlc_decapsulate, HdlcError}; +use crate::hdlc::{hdlc_encapsulate, HdlcError}; use crate::diag::{Message, ResponsePayload, Request, LogConfigRequest, LogConfigResponse, build_log_mask_request, RequestContainer, DataType, MessagesContainer}; +use crate::diag_reader::{DiagReader, CRC_CCITT}; +use crate::debug_file::DebugFileBlock; use crate::log_codes; use std::fs::File; -use std::io::{Read, Write, Seek}; +use std::io::{Read, Write}; use std::os::fd::AsRawFd; use thiserror::Error; -use crc::{Crc, Algorithm}; use deku::prelude::*; pub type DiagResult = Result; @@ -29,20 +30,6 @@ pub enum DiagDeviceError { DekuError(#[from] DekuError), } -// 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 -pub const CRC_CCITT_ALG: Algorithm = Algorithm { - poly: 0x1021, - init: 0xffff, - refin: true, - refout: true, - width: 16, - xorout: 0xffff, - check: 0x2189, - residue: 0x0000, -}; -pub const CRC_CCITT: Crc = Crc::::new(&CRC_CCITT_ALG); - pub const LOG_CODES_FOR_RAW_PACKET_LOGGING: [u32; 11] = [ // Layer 2: log_codes::LOG_GPRS_MAC_SIGNALLING_MESSAGE_C, // 0x5226 @@ -76,100 +63,13 @@ pub struct DiagDevice<'a> { use_mdm: i32, } -#[derive(Debug, DekuRead, DekuWrite)] -#[deku(endian = "little")] -struct DebugReadBlock<'a> { - size: u32, - #[deku(count = "size")] - data: &'a [u8], -} -pub struct DebugFileReader { - file: File, -} - -impl DebugFileReader { - pub fn new

(path: P) -> DiagResult where P: AsRef { - let file = std::fs::File::options() - .read(true) - .open(path)?; - Ok(DebugFileReader { file }) - } -} - -pub trait DiagReader { - fn get_next_messages_container(&mut self) -> DiagResult; - - fn read_response(&mut self) -> DiagResult> { - loop { - let container = self.get_next_messages_container()?; - if container.data_type == DataType::UserSpace { - return self.parse_response_container(container); - } else { - println!("skipping non-userspace message...") - } - } - } - - fn parse_response_container(&self, container: MessagesContainer) -> DiagResult> { - let mut result = Vec::new(); - for msg in container.messages { - for sub_msg in msg.data.split_inclusive(|&b| b == 0x7e) { - match hdlc_decapsulate(&sub_msg, &CRC_CCITT) { - Ok(data) => match Message::from_bytes((&data, 0)) { - Ok(((leftover_bytes, _), res)) => { - if leftover_bytes.len() > 0 { - println!("warning: {} leftover bytes when parsing Message", leftover_bytes.len()); - } - result.push(res); - }, - Err(e) => { - println!("error parsing response: {:?}", e); - println!("{:?}", data); - }, - }, - Err(err) => { - println!("error decapsulating response: {:?}", err); - println!("{:?}", &sub_msg); - } - } - } - } - Ok(result) - } -} - - -impl DiagReader for DebugFileReader { - fn get_next_messages_container(&mut self) -> DiagResult { - let mut bytes_read_buf = [0; 4]; - match self.file.read_exact(&mut bytes_read_buf) { - Ok(_) => {}, - Err(e) => { - dbg!(e.kind()); - if e.kind() == std::io::ErrorKind::UnexpectedEof { - println!("reached end of debug file, exiting..."); - std::process::exit(0); - } - return Err(e.into()); - }, - } - let bytes_read = u32::from_le_bytes(bytes_read_buf) as usize; - let mut data = vec![0; bytes_read as usize]; - self.file.read_exact(&mut data)?; - let ((leftover_bytes, _), container) = MessagesContainer::from_bytes((&data, 0))?; - if leftover_bytes.len() > 0 { - println!("warning: {} leftover bytes when parsing MessagesContainer", leftover_bytes.len()); - } - Ok(container) - } -} impl<'a> DiagReader for DiagDevice<'a> { fn get_next_messages_container(&mut self) -> DiagResult { let bytes_read = self.file.read(&mut self.read_buf).unwrap(); if let Some(debug_file) = self.debug_file.as_mut() { - let debug_block = DebugReadBlock { + let debug_block = DebugFileBlock { size: bytes_read as u32, data: &self.read_buf[0..bytes_read], }; diff --git a/src/diag_reader.rs b/src/diag_reader.rs new file mode 100644 index 0000000..00ded53 --- /dev/null +++ b/src/diag_reader.rs @@ -0,0 +1,61 @@ +use crate::{diag::*, hdlc::hdlc_decapsulate}; +use crate::diag_device::DiagResult; + +use crc::{Crc, Algorithm}; +use deku::prelude::*; + +// 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 +pub const CRC_CCITT_ALG: Algorithm = Algorithm { + poly: 0x1021, + init: 0xffff, + refin: true, + refout: true, + width: 16, + xorout: 0xffff, + check: 0x2189, + residue: 0x0000, +}; +pub const CRC_CCITT: Crc = Crc::::new(&CRC_CCITT_ALG); + +pub trait DiagReader { + fn get_next_messages_container(&mut self) -> DiagResult; + + fn read_response(&mut self) -> DiagResult> { + loop { + let container = self.get_next_messages_container()?; + if container.data_type == DataType::UserSpace { + return self.parse_response_container(container); + } else { + println!("skipping non-userspace message...") + } + } + } + + fn parse_response_container(&self, container: MessagesContainer) -> DiagResult> { + let mut result = Vec::new(); + for msg in container.messages { + for sub_msg in msg.data.split_inclusive(|&b| b == 0x7e) { + match hdlc_decapsulate(&sub_msg, &CRC_CCITT) { + Ok(data) => match Message::from_bytes((&data, 0)) { + Ok(((leftover_bytes, _), res)) => { + if leftover_bytes.len() > 0 { + println!("warning: {} leftover bytes when parsing Message", leftover_bytes.len()); + } + result.push(res); + }, + Err(e) => { + println!("error parsing response: {:?}", e); + println!("{:?}", data); + }, + }, + Err(err) => { + println!("error decapsulating response: {:?}", err); + println!("{:?}", &sub_msg); + } + } + } + } + Ok(result) + } +} diff --git a/src/hdlc.rs b/src/hdlc.rs index 78dc663..7813e5b 100644 --- a/src/hdlc.rs +++ b/src/hdlc.rs @@ -87,7 +87,7 @@ mod tests { #[test] fn test_hdlc_encapsulate() { - let crc = Crc::::new(&crate::diag_device::CRC_CCITT_ALG); + let crc = Crc::::new(&crate::diag_reader::CRC_CCITT_ALG); let data = vec![0x01, 0x02, 0x03, 0x04]; let expected = vec![1, 2, 3, 4, 145, 57, 126]; let encapsulated = hdlc_encapsulate(&data, &crc); diff --git a/src/main.rs b/src/main.rs index e83c760..9ed718f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ mod hdlc; mod diag; mod diag_device; +mod diag_reader; +mod debug_file; mod log_codes; -use crate::diag_device::{DiagDevice, DiagReader}; +use crate::diag_device::DiagDevice; +use crate::diag_reader::DiagReader; fn main() -> diag_device::DiagResult<()> { // this should eventually be removed for prod From 557de415d7f23e8a76147605f852214c99b4b216 Mon Sep 17 00:00:00 2001 From: Will Greenberg Date: Wed, 13 Dec 2023 16:51:21 -0800 Subject: [PATCH 5/5] More reorganization, renamed to Wave Hunter --- Cargo.lock | 30 +++++++++---------- Cargo.toml | 14 +++++++-- README.md | 26 ++++++++++++++++ src/{main.rs => bin/wavehunter.rs} | 13 ++------ .../wavehunter_reader.rs} | 14 +++------ src/diag.rs | 7 ----- src/lib.rs | 6 ++++ 7 files changed, 65 insertions(+), 45 deletions(-) rename src/{main.rs => bin/wavehunter.rs} (67%) rename src/{debug_reader.rs => bin/wavehunter_reader.rs} (67%) create mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 0077895..b720e2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,21 +197,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "diag" -version = "0.1.0" -dependencies = [ - "bytes", - "chrono", - "crc", - "deku", - "env_logger", - "libc", - "log", - "pcap-file", - "thiserror", -] - [[package]] name = "env_logger" version = "0.10.1" @@ -596,6 +581,21 @@ version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +[[package]] +name = "wavehunter" +version = "0.1.0" +dependencies = [ + "bytes", + "chrono", + "crc", + "deku", + "env_logger", + "libc", + "log", + "pcap-file", + "thiserror", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index fccbdd4..10c1465 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,21 @@ [package] -name = "diag" +name = "wavehunter" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "wavehunter" +path = "src/lib.rs" + [[bin]] -name = "debug_reader" -path = "src/debug_reader.rs" +name = "wavehunter-reader" +path = "src/bin/wavehunter_reader.rs" + +[[bin]] +name = "wavehunter" +path = "src/bin/wavehunter.rs" [dependencies] bytes = "1.5.0" diff --git a/README.md b/README.md index 26a8172..d10ff20 100644 --- a/README.md +++ b/README.md @@ -1 +1,27 @@ +# Wave Hunter + +``` +@@@ @@@ @@@ @@@@@@ @@@ @@@ @@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@@@@@ @@@@@@@@ @@@@@@@ +@@! @@! @@! @@! @@@ @@! @@@ @@! @@! @@@ @@! @@@ @@!@!@@@ @!! @@! @@! @@@ +@!! !!@ @!@ @!@!@!@! @!@ !@! @!!!:! @!@!@!@! @!@ !@! @!@@!!@! @!! @!!!:! @!@!!@! + !: !!: !! !!: !!! !: .:! !!: !!: !!! !!: !!! !!: !!! !!: !!: !!: :!! + ::.: ::: : : : :: : :: :: : : : :.:: : :: : : : :: :: : : : + +_ _ _ _ _ _ _ _ +)`'-.,_)`'-.,_)`'-.,_)`'-.,_)`'-.,_)`'-.,_)`'-.,_)`'-.,_ + + O . + O ' ' + o ' . + o .' + __________.-' '...___ + .-' ### '''...__ + / a### ## ''--.._ ______ + '. # ######## ' .-' + '-._ ..**********#### ___...---'''\ ' + '-._ __________...---''' \ l + \ | apc '._| + \__; +``` + diag helper binary for the Orbic mobile hotspot. Based on code from [QCSuper](https://github.com/P1sec/QCSuper) diff --git a/src/main.rs b/src/bin/wavehunter.rs similarity index 67% rename from src/main.rs rename to src/bin/wavehunter.rs index 9ed718f..c0e8b66 100644 --- a/src/main.rs +++ b/src/bin/wavehunter.rs @@ -1,14 +1,7 @@ -mod hdlc; -mod diag; -mod diag_device; -mod diag_reader; -mod debug_file; -mod log_codes; +use wavehunter::diag_device::{DiagDevice, DiagResult}; +use wavehunter::diag_reader::DiagReader; -use crate::diag_device::DiagDevice; -use crate::diag_reader::DiagReader; - -fn main() -> diag_device::DiagResult<()> { +fn main() -> DiagResult<()> { // this should eventually be removed for prod env_logger::init(); diff --git a/src/debug_reader.rs b/src/bin/wavehunter_reader.rs similarity index 67% rename from src/debug_reader.rs rename to src/bin/wavehunter_reader.rs index ad64432..cbb99c1 100644 --- a/src/debug_reader.rs +++ b/src/bin/wavehunter_reader.rs @@ -1,14 +1,8 @@ -mod hdlc; -mod diag; -mod diag_device; -mod diag_reader; -mod debug_file; -mod log_codes; +use wavehunter::debug_file::DebugFileReader; +use wavehunter::diag_reader::DiagReader; +use wavehunter::diag_device::DiagResult; -use crate::debug_file::DebugFileReader; -use crate::diag_reader::DiagReader; - -fn main() -> diag_device::DiagResult<()> { +fn main() -> DiagResult<()> { // this should eventually be removed for prod env_logger::init(); let args: Vec = std::env::args().collect(); diff --git a/src/diag.rs b/src/diag.rs index 4eb19c3..fd8136b 100644 --- a/src/diag.rs +++ b/src/diag.rs @@ -391,11 +391,4 @@ mod test { }, }); } - - #[test] - fn test_fuck() { - env_logger::init(); - let data = vec![32, 0, 0, 0, 1, 0, 0, 0, 122, 1, 0, 0, 16, 0, 38, 0, 38, 0, 192, 176, 153, 128, 249, 211, 218, 62, 2, 1, 20, 14, 48, 0, 160, 0, 14, 6, 1, 0, 217, 39, 5, 0, 0, 0, 0, 7, 0, 64, 2, 14, 213, 72, 153, 192, 168, 216, 126]; - dbg!(MessagesContainer::from_bytes((&data, 0)).unwrap()); - } } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..e288db4 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,6 @@ +pub mod hdlc; +pub mod diag; +pub mod diag_device; +pub mod diag_reader; +pub mod debug_file; +pub mod log_codes;