tramex_tools/interface/parser/
hex_extractor.rs1pub fn extract_binary_from_lines(lines: &[String]) -> Option<Vec<u8>> {
18 let mut binary = Vec::new();
19 let mut found_hex_lines = false;
20 let mut last_offset: Option<usize> = None;
21
22 for line in lines {
23 let trimmed = line.trim();
24
25 if trimmed == "..." || trimmed.starts_with("...") {
28 return None;
29 }
30
31 if let Some(colon_pos) = trimmed.find(':') {
34 let before_colon = &trimmed[..colon_pos];
36 let offset_str = before_colon.trim();
37
38 if offset_str.len() == 4
40 && offset_str.chars().all(|c| c.is_ascii_hexdigit())
41 && let Ok(offset) = usize::from_str_radix(offset_str, 16)
42 {
43 if let Some(last) = last_offset {
46 if offset <= last {
49 return None;
51 }
52 }
53 last_offset = Some(offset);
54
55 found_hex_lines = true;
56
57 let hex_part = &trimmed[colon_pos + 1..];
59
60 for part in hex_part.split_whitespace() {
63 if part.len() == 2 && part.chars().all(|c| c.is_ascii_hexdigit()) {
65 if let Ok(byte) = u8::from_str_radix(part, 16) {
66 binary.push(byte);
67 }
68 } else {
69 break;
71 }
72 }
73 }
74 }
75 }
76
77 if found_hex_lines && !binary.is_empty() {
78 Some(binary)
79 } else {
80 None
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_extract_complete_hex() {
90 let lines = vec![
91 "13:21:07.077 [RRC] DL - 01 BCCH-NR: SIB2".to_string(),
92 " 0000: 74 81 01 70 10 40 04 06 00 00 ca 00 24 68 a0 38 t..p.@......$h.8".to_string(),
93 " 0010: 05 21 09 a0 30 00 00 46 4c 6b 6c 61 f3 70 40 20 .!..0..FLkla.p@ ".to_string(),
94 ];
95
96 let binary = extract_binary_from_lines(&lines);
97 assert!(binary.is_some(), "Binary extraction failed");
98 let bytes = binary.unwrap();
99 assert_eq!(bytes.len(), 32, "Expected 32 bytes, got {}", bytes.len());
100 assert_eq!(bytes[0], 0x74);
101 assert_eq!(bytes[1], 0x81);
102 assert_eq!(bytes[16], 0x05);
103 }
104
105 #[test]
106 fn test_extract_incomplete_hex() {
107 let lines = vec![
108 "13:20:45.574 [GTPU] TO 127.0.1.100:2152 G-PDU".to_string(),
109 " 0000: 34 ff 05 b4 53 15 ca a3 00 00 00 85 01 10 01 00 4...S...........".to_string(),
110 " ...".to_string(),
111 ];
112
113 let binary = extract_binary_from_lines(&lines);
114 assert!(binary.is_none());
115 }
116
117 #[test]
118 fn test_no_hex_dump() {
119 let lines = vec![
120 "13:20:45.575 [PHY] UL 003d 01 4644 729.9 PUSCH".to_string(),
121 " Link: re@0".to_string(),
122 ];
123
124 let binary = extract_binary_from_lines(&lines);
125 assert!(binary.is_none());
126 }
127}