diff --git a/lib/src/diag/diaglog/mac.rs b/lib/src/diag/diaglog/mac.rs index ff066e2..6609773 100644 --- a/lib/src/diag/diaglog/mac.rs +++ b/lib/src/diag/diaglog/mac.rs @@ -26,8 +26,8 @@ pub enum SubpacketBody { #[deku(id_pat = "_")] Other { #[deku(count = "size")] - data: Vec - } + data: Vec, + }, } pub mod rach { @@ -78,7 +78,7 @@ pub mod rach { pub p_max: u8, pub scell_id: u8, pub unk1: u32, - pub unk2: u32 + pub unk2: u32, } #[derive(DekuRead, DekuWrite, Debug, Clone, PartialEq)] @@ -103,7 +103,7 @@ pub mod rach { preamble_power_offset: i16, unk1: u16, group: i8, - } + }, } #[derive(DekuRead, DekuWrite, Debug, Clone, PartialEq)] @@ -140,7 +140,7 @@ pub mod rach { rach_result: u8, contention: u8, msg_bitmask: u8, - } + }, } impl AttemptHeader { @@ -167,9 +167,9 @@ pub mod rach { #[cfg(test)] mod test { - use crate::diag::diaglog::mac::rach::{AdditionalInfo, AttemptHeader, Msg1, Msg2, Msg3}; - use super::*; use super::super::test_util::unhexlify; + use super::*; + use crate::diag::diaglog::mac::rach::{AdditionalInfo, AttemptHeader, Msg1, Msg2, Msg3}; use std::io::Seek; @@ -217,56 +217,198 @@ mod test { */ assert_rach_subpacket( "0101a06906022400010001071BFF98FF000001231A0400181C010007000600465C80BD0648000000", - rach::AttemptHeader::V2 { num_attempt: 1, rach_result: 0, contention: 1, msg_bitmask: 7 }, - Some(Msg1::V2 { preamble_index: 27, preamble_index_mask: 255, preamble_power_offset: -104 }), - Some(Msg2 { backoff: 0, result: 1, tc_rnti: 6691, ta: 4 }), - Some(Msg3 { grant_raw: 72728, grant: 7, harq_id: 6, mac_pdu: [0x00, 0x46, 0x5c, 0x80, 0xbd, 0x06, 0x48, 0x00, 0x00, 0x00] }), + rach::AttemptHeader::V2 { + num_attempt: 1, + rach_result: 0, + contention: 1, + msg_bitmask: 7, + }, + Some(Msg1::V2 { + preamble_index: 27, + preamble_index_mask: 255, + preamble_power_offset: -104, + }), + Some(Msg2 { + backoff: 0, + result: 1, + tc_rnti: 6691, + ta: 4, + }), + Some(Msg3 { + grant_raw: 72728, + grant: 7, + harq_id: 6, + mac_pdu: [0x00, 0x46, 0x5c, 0x80, 0xbd, 0x06, 0x48, 0x00, 0x00, 0x00], + }), None, ); assert_rach_subpacket( "0101a0690603280001000100010718ffa4ff000001c6610b00b4a2000012000120061f423f8d95075800", - rach::AttemptHeader::V3 { sub_id: 1, cell_id: 0, num_attempt: 1, rach_result: 0, contention: 1, msg_bitmask: 7 }, - Some(Msg1::V3Or31 { preamble_index: 24, preamble_index_mask: 255, preamble_power_offset: -92 }), - Some(Msg2 { backoff: 0, result: 1, tc_rnti: 25030, ta: 11 }), - Some(Msg3 { grant_raw: 41652, grant: 18, harq_id: 1, mac_pdu: [0x20, 0x06, 0x1f, 0x42, 0x3f, 0x8d, 0x95, 0x07, 0x58, 0x00] }), + rach::AttemptHeader::V3 { + sub_id: 1, + cell_id: 0, + num_attempt: 1, + rach_result: 0, + contention: 1, + msg_bitmask: 7, + }, + Some(Msg1::V3Or31 { + preamble_index: 24, + preamble_index_mask: 255, + preamble_power_offset: -92, + }), + Some(Msg2 { + backoff: 0, + result: 1, + tc_rnti: 25030, + ta: 11, + }), + Some(Msg3 { + grant_raw: 41652, + grant: 18, + harq_id: 1, + mac_pdu: [0x20, 0x06, 0x1f, 0x42, 0x3f, 0x8d, 0x95, 0x07, 0x58, 0x00], + }), None, ); assert_rach_subpacket( "0101739e063134000100010000033f0098ff0000013c6b070058ac010007000000468f47e2d446000000644b0000180001000000d5040000", - rach::AttemptHeader::V3 { sub_id: 1, cell_id: 0, num_attempt: 1, rach_result: 0, contention: 0, msg_bitmask: 3 }, - Some(Msg1::V3Or31 { preamble_index: 63, preamble_index_mask: 0, preamble_power_offset: -104 }), - Some(Msg2 { backoff: 0, result: 1, tc_rnti: 27452, ta: 7 }), + rach::AttemptHeader::V3 { + sub_id: 1, + cell_id: 0, + num_attempt: 1, + rach_result: 0, + contention: 0, + msg_bitmask: 3, + }, + Some(Msg1::V3Or31 { + preamble_index: 63, + preamble_index_mask: 0, + preamble_power_offset: -104, + }), + Some(Msg2 { + backoff: 0, + result: 1, + tc_rnti: 27452, + ta: 7, + }), None, - Some(AdditionalInfo { ul_earfcn: 19300, p_max: 24, scell_id: 0, unk1: 1, unk2: 1237 }), + Some(AdditionalInfo { + ul_earfcn: 19300, + p_max: 24, + scell_id: 0, + unk1: 1, + unk2: 1237, + }), ); - assert_rach_subpacket( + assert_rach_subpacket( "01010000063134000100010001070aff98ff0000011c48070018e2000007000000523b7dfd69b6000000f5540000ff0001000000d6040000", - AttemptHeader::V3 { sub_id: 1, cell_id: 0, num_attempt: 1, rach_result: 0, contention: 1, msg_bitmask: 7 }, - Some(Msg1::V3Or31 { preamble_index: 10, preamble_index_mask: 255, preamble_power_offset: -104 }), - Some(Msg2 { backoff: 0, result: 1, tc_rnti: 18460, ta: 7 }), - Some(Msg3 { grant_raw: 57880, grant: 7, harq_id: 0, mac_pdu: [0x00, 0x52, 0x3b, 0x7d, 0xfd, 0x69, 0xb6, 0x00, 0x00, 0x00] }), - Some(AdditionalInfo { ul_earfcn: 21749, p_max: 255, scell_id: 0, unk1: 1, unk2: 1238 }), + AttemptHeader::V3 { + sub_id: 1, + cell_id: 0, + num_attempt: 1, + rach_result: 0, + contention: 1, + msg_bitmask: 7, + }, + Some(Msg1::V3Or31 { + preamble_index: 10, + preamble_index_mask: 255, + preamble_power_offset: -104, + }), + Some(Msg2 { + backoff: 0, + result: 1, + tc_rnti: 18460, + ta: 7, + }), + Some(Msg3 { + grant_raw: 57880, + grant: 7, + harq_id: 0, + mac_pdu: [0x00, 0x52, 0x3b, 0x7d, 0xfd, 0x69, 0xb6, 0x00, 0x00, 0x00], + }), + Some(AdditionalInfo { + ul_earfcn: 21749, + p_max: 255, + scell_id: 0, + unk1: 1, + unk2: 1238, + }), ); assert_rach_subpacket( "01010000063238000100010000032900a4ffeb000000000195b603000000a0b412000420061f425dc9be41b800885e000017000100000065050000", - AttemptHeader::V3 { sub_id: 1, cell_id: 0, num_attempt: 1, rach_result: 0, contention: 0, msg_bitmask: 3 }, - Some(Msg1::V32 { preamble_index: 41, preamble_index_mask: 0, preamble_power_offset: -92, unk1: 235, group: 0 }), - Some(Msg2 { backoff: 0, result: 1, tc_rnti: 46741, ta: 3 }), + AttemptHeader::V3 { + sub_id: 1, + cell_id: 0, + num_attempt: 1, + rach_result: 0, + contention: 0, + msg_bitmask: 3, + }, + Some(Msg1::V32 { + preamble_index: 41, + preamble_index_mask: 0, + preamble_power_offset: -92, + unk1: 235, + group: 0, + }), + Some(Msg2 { + backoff: 0, + result: 1, + tc_rnti: 46741, + ta: 3, + }), None, - Some(AdditionalInfo { ul_earfcn: 24200, p_max: 23, scell_id: 0, unk1: 1, unk2: 1381 }), + Some(AdditionalInfo { + ul_earfcn: 24200, + p_max: 23, + scell_id: 0, + unk1: 1, + unk2: 1381, + }), ); assert_rach_subpacket( "010100000632380001000100010713ffa0ffeb0000000001ad5a0500000146b412000420061f425dc9be41b400665300001800010000001a050000", - AttemptHeader::V3 { sub_id: 1, cell_id: 0, num_attempt: 1, rach_result: 0, contention: 1, msg_bitmask: 7 }, - Some(Msg1::V32 { preamble_index: 19, preamble_index_mask: 255, preamble_power_offset: -96, unk1: 235, group: 0 }), - Some(Msg2 { backoff: 0, result: 1, tc_rnti: 23213, ta: 5 }), - Some(Msg3 { grant_raw: 3024486656, grant: 18, harq_id: 4, mac_pdu: [0x20, 0x06, 0x1f, 0x42, 0x5d, 0xc9, 0xbe, 0x41, 0xb4, 0x00] }), - Some(AdditionalInfo { ul_earfcn: 21350, p_max: 24, scell_id: 0, unk1: 1, unk2: 1306 }), + AttemptHeader::V3 { + sub_id: 1, + cell_id: 0, + num_attempt: 1, + rach_result: 0, + contention: 1, + msg_bitmask: 7, + }, + Some(Msg1::V32 { + preamble_index: 19, + preamble_index_mask: 255, + preamble_power_offset: -96, + unk1: 235, + group: 0, + }), + Some(Msg2 { + backoff: 0, + result: 1, + tc_rnti: 23213, + ta: 5, + }), + Some(Msg3 { + grant_raw: 3024486656, + grant: 18, + harq_id: 4, + mac_pdu: [0x20, 0x06, 0x1f, 0x42, 0x5d, 0xc9, 0xbe, 0x41, 0xb4, 0x00], + }), + Some(AdditionalInfo { + ul_earfcn: 21350, + p_max: 24, + scell_id: 0, + unk1: 1, + unk2: 1306, + }), ); } } diff --git a/lib/src/diag/diaglog/measurement.rs b/lib/src/diag/diaglog/measurement.rs index 8ca6c22..5fb96ec 100644 --- a/lib/src/diag/diaglog/measurement.rs +++ b/lib/src/diag/diaglog/measurement.rs @@ -2,8 +2,8 @@ //! much entirely based on Shinjo Park's work in scat, since we couldn't find //! any other documentation for the logs' structure. -use deku::prelude::*; use deku::ctx::Order; +use deku::prelude::*; fn decode_rsrp(rsrp: u16) -> f32 { rsrp as f32 / 16.0 - 180.0 @@ -141,7 +141,7 @@ pub mod neighbor_cells { pub struct Measurements { pub header: MeasurementsHeader, #[deku(count = "header.get_n_cells()")] - pub cells: Vec + pub cells: Vec, } impl Measurements { @@ -153,7 +153,6 @@ pub mod neighbor_cells { } } - #[derive(Clone, Debug, DekuRead, DekuWrite, PartialEq)] #[deku(bit_order = "lsb")] pub struct MeasurementsCell { @@ -195,10 +194,10 @@ pub mod neighbor_cells { #[cfg(test)] mod test { + use super::super::test_util::unhexlify; use super::*; use crate::diag::diaglog::LogBody; use crate::log_codes::{LOG_LTE_ML1_NEIGHBOR_MEAS, LOG_LTE_ML1_SERVING_CELL_MEAS_AND_EVAL_C}; - use super::super::test_util::unhexlify; use std::io::Seek; fn parse_ncell_measurements(hexlified_bytes: &str) -> (u8, neighbor_cells::Measurements) { @@ -208,14 +207,18 @@ mod test { if !reader.end() { let leftover_bits = reader.rest(); let leftover_bytes = total_size - reader.stream_position().unwrap() as usize; - panic!("failed to read entire buffer ({} bytes, {} bits left)", leftover_bytes, leftover_bits.len()); + panic!( + "failed to read entire buffer ({} bytes, {} bits left)", + leftover_bytes, + leftover_bits.len() + ); } let pkt_version = match data.header { neighbor_cells::MeasurementsHeader::V4 { .. } => 4, neighbor_cells::MeasurementsHeader::V5 { .. } => 5, }; (pkt_version, data) - }, + } Ok(x) => panic!("expected MeasurementAndEvaluation, but parsed {:?}", x), Err(x) => panic!("failed to parse MeasurementAndEvaluation {:?}", x), } @@ -223,19 +226,26 @@ mod test { fn parse_meas_eval(hexlified_bytes: &str) -> (u8, serving_cell::MeasurementAndEvaluation) { let (total_size, mut reader) = unhexlify(hexlified_bytes); - match LogBody::from_reader_with_ctx(&mut reader, (LOG_LTE_ML1_SERVING_CELL_MEAS_AND_EVAL_C as u16, 0)) { + match LogBody::from_reader_with_ctx( + &mut reader, + (LOG_LTE_ML1_SERVING_CELL_MEAS_AND_EVAL_C as u16, 0), + ) { Ok(LogBody::LteMl1ServingCellMeasurementAndEvaluation { data }) => { if !reader.end() { let leftover_bits = reader.rest(); let leftover_bytes = total_size - reader.stream_position().unwrap() as usize; - panic!("failed to read entire buffer ({} bytes, {} bits left)", leftover_bytes, leftover_bits.len()); + panic!( + "failed to read entire buffer ({} bytes, {} bits left)", + leftover_bytes, + leftover_bits.len() + ); } let pkt_version = match data.header { serving_cell::MeasurementAndEvaluationHeader::V4 { .. } => 4, serving_cell::MeasurementAndEvaluationHeader::V5 { .. } => 5, }; (pkt_version, data) - }, + } Ok(x) => panic!("expected MeasurementAndEvaluation, but parsed {:?}", x), Err(x) => panic!("failed to parse MeasurementAndEvaluation {:?}", x), } @@ -248,7 +258,7 @@ mod test { earfcn: u32, rsrp: f32, rsrq: f32, - rssi: f32 + rssi: f32, ) { let (parsed_pkt_version, data) = parse_meas_eval(hexlified_bytes); assert_eq!(parsed_pkt_version, pkt_version); @@ -270,7 +280,7 @@ mod test { 6300, -101.25, -14.0625, - -66.625 + -66.625, ); scell_meas_and_eval_case( "05010000160d0000d40e00004bb444005444450039e514133149070048adfe019f310100a23f0000", @@ -327,17 +337,13 @@ mod test { "040100009C1847008348E44DDEA44C00CAB4CC32B6D8420300000000FF773301FF77330122020100", 4, 6300, - vec![ - (131, -102.125, -75.75, -17.3125), - ] + vec![(131, -102.125, -75.75, -17.3125)], + ); + ncell_meas_case( + "05010000160d0000480000006cea413bb4433b00b4f3cc33cf3c130200000000ffefc00fffefc00f45081600", + 5, + 3350, + vec![(108, -120.75, -94.6875, -17.0625)], ); - ncell_meas_case( - "05010000160d0000480000006cea413bb4433b00b4f3cc33cf3c130200000000ffefc00fffefc00f45081600", - 5, - 3350, - vec![ - (108, -120.75, -94.6875, -17.0625), - ] - ); } } diff --git a/lib/src/diag/diaglog/test_util.rs b/lib/src/diag/diaglog/test_util.rs index d002b0d..061a085 100644 --- a/lib/src/diag/diaglog/test_util.rs +++ b/lib/src/diag/diaglog/test_util.rs @@ -1,11 +1,11 @@ -use std::io::Cursor; use deku::reader::Reader; +use std::io::Cursor; pub fn unhexlify(hexlified_bytes: &str) -> (usize, Reader>>) { let byte_len = hexlified_bytes.len() / 2; let bytes = (0..hexlified_bytes.len()) .step_by(2) - .map(|i| u8::from_str_radix(&hexlified_bytes[i..i+2], 16).unwrap()) + .map(|i| u8::from_str_radix(&hexlified_bytes[i..i + 2], 16).unwrap()) .collect(); (byte_len, Reader::new(Cursor::new(bytes))) } diff --git a/lib/src/diag_device.rs b/lib/src/diag_device.rs index d88626a..ab2952f 100644 --- a/lib/src/diag_device.rs +++ b/lib/src/diag_device.rs @@ -58,8 +58,8 @@ pub const LOG_CODES_FOR_RAW_PACKET_LOGGING: [u32; 15] = [ log_codes::LOG_DATA_PROTOCOL_LOGGING_C, // 0x11eb // LTE physical layer serving cell measurements: RSRP, RSRQ, RSSI log_codes::LOG_LTE_ML1_SERVING_CELL_MEAS_AND_EVAL_C, // 0xb17f - log_codes::LOG_LTE_ML1_SERVING_CELL_MEAS_RESPONSE, // 0xb193 - log_codes::LOG_LTE_ML1_NEIGHBOR_MEAS, // 0xb180 + log_codes::LOG_LTE_ML1_SERVING_CELL_MEAS_RESPONSE, // 0xb193 + log_codes::LOG_LTE_ML1_NEIGHBOR_MEAS, // 0xb180 // LTE MAC Random Access Channel response: contains Timing Advance log_codes::LOG_LTE_MAC_RACH_RESPONSE_C, // 0xb062 ]; diff --git a/lib/tests/test_lte_parsing.rs b/lib/tests/test_lte_parsing.rs index 9af8baf..fc913a3 100644 --- a/lib/tests/test_lte_parsing.rs +++ b/lib/tests/test_lte_parsing.rs @@ -1,7 +1,7 @@ use deku::prelude::*; use rayhunter::{ diag::Message, - diag::diaglog::{LogBody, Timestamp, rrc::LteRrcOtaPacket}, + diag::diaglog::{LogBody, rrc::LteRrcOtaPacket, Timestamp}, gsmtap::parser as gsmtap_parser, };