tramex_tools/interface/
onelog.rs1use std::str::FromStr;
4
5use crate::data::{AdditionalInfos, Trace};
6use crate::errors::TramexError;
7use crate::interface::association::TraceRelation;
8use crate::interface::functions::extract_hexe;
9use crate::interface::parser::hex_extractor::extract_binary_from_lines;
10
11use crate::interface::{layer::Layer, types::SourceLog};
12use crate::tramex_error;
13
14use super::parser::parser_basic::BasicParser;
15use super::parser::parser_nas::NASInfos;
16use super::parser::parser_rrc::RRCInfos;
17use super::types::Direction; #[derive(serde::Deserialize, Debug)]
20pub struct OneLog {
22 pub data: Vec<String>,
24
25 pub timestamp: i64,
27
28 pub layer: Layer,
30
31 pub src: SourceLog,
33
34 pub idx: u64,
36
37 pub dir: Option<String>,
39}
40
41impl OneLog {
42 pub fn extract_hexe(&self) -> Result<Vec<u8>, TramexError> {
46 extract_hexe(&self.data)
47 }
48
49 pub fn extract_canal_msg(&self) -> Option<String> {
51 if let Some(data_line) = self.data.first() {
53 log::debug!("{data_line:?}");
54 return Some(data_line.to_owned());
55 }
56 None
57 }
58
59 pub fn extract_data(&self) -> Result<Trace, TramexError> {
63 match self.layer {
64 Layer::RRC => {
65 let dir = match &self.dir {
67 Some(opt_dir) => match Direction::from_str(opt_dir) {
68 Ok(d) => d,
69 Err(_) => {
70 log::debug!("Direction: {:?}", self.dir);
71 return Err(tramex_error!(
72 format!("Can't format direction {}", opt_dir),
73 crate::errors::ErrorCode::WebSocketErrorDecodingMessage
74 ));
75 }
76 },
77 None => {
78 return Err(tramex_error!(
79 "Direction not found".to_owned(),
80 crate::errors::ErrorCode::WebSocketErrorDecodingMessage
81 ));
82 }
83 };
84 let firs_line = self.data[0].split(':').collect::<Vec<&str>>();
85 if firs_line.len() < 2 {
86 return Err(tramex_error!(
87 format!("Invalid first line {}", self.data[0]),
88 crate::errors::ErrorCode::WebSocketErrorDecodingMessage
89 ));
90 }
91 let rrc: RRCInfos = RRCInfos {
92 direction: dir,
93 canal: firs_line[0].to_owned(),
94 canal_msg: firs_line[1][1..].to_owned(),
95 };
96 let infos = AdditionalInfos::RRCInfos(rrc);
97 let text_lines: Vec<String> = self.data[1..].iter().map(|x| x.to_string()).collect();
98 let binary = extract_binary_from_lines(&self.data);
99 let trace = Trace {
100 timestamp: self.timestamp,
101 layer: Layer::RRC,
102 additional_infos: infos,
103 text: Some(text_lines),
104 binary,
105 relation: TraceRelation::default(),
106 };
107 Ok(trace)
108 }
109 Layer::NAS => {
110 let dir = match &self.dir {
111 Some(opt_dir) => match Direction::from_str(opt_dir) {
112 Ok(d) => d,
113 Err(_) => {
114 return Err(tramex_error!(
115 format!("Can't format direction {}", opt_dir),
116 crate::errors::ErrorCode::WebSocketErrorDecodingMessage
117 ));
118 }
119 },
120 None => {
121 return Err(tramex_error!(
122 "Direction not found".to_owned(),
123 crate::errors::ErrorCode::WebSocketErrorDecodingMessage
124 ));
125 }
126 };
127
128 let message_type = if self.data.is_empty() {
131 "Unknown".to_string()
132 } else {
133 let first_line = &self.data[0];
135 if let Some(colon_pos) = first_line.find(':') {
136 first_line[colon_pos + 1..].trim().to_string()
137 } else {
138 first_line.trim().to_string()
139 }
140 };
141
142 let nas = NASInfos {
143 direction: dir,
144 message_type,
145 };
146 let infos = AdditionalInfos::NASInfos(nas);
147 let text_lines: Vec<String> = self.data[1..].iter().map(|x| x.to_string()).collect();
148 let binary = extract_binary_from_lines(&self.data);
149 let trace = Trace {
150 timestamp: self.timestamp,
151 layer: Layer::NAS,
152 additional_infos: infos,
153 text: Some(text_lines),
154 binary,
155 relation: TraceRelation::default(),
156 };
157 Ok(trace)
158 }
159 _ => {
160 let mut trace = BasicParser::parse_with_layer(&self.data, self.layer.clone())
162 .map_err(|e| tramex_error!(e.message, crate::errors::ErrorCode::ParsingLayerNotImplemented))?;
163 trace.timestamp = self.timestamp;
165 Ok(trace)
166 }
167 }
168 }
169}