tramex_tools/interface/parser/
parser_ngap.rs1use super::ParsingError;
3use super::hex_extractor::extract_binary_from_lines;
4use crate::data::{AdditionalInfos, Trace};
5use crate::interface::association::TraceRelation;
6use std::str::FromStr;
7
8use crate::interface::{layer::Layer, types::Direction};
9
10use super::FileParser;
11
12#[derive(Debug, Clone)]
13pub struct NGAPInfos {
15 pub direction: Direction,
18
19 pub message_type: String,
21
22 pub connection_info: Option<String>,
24}
25
26pub struct NGAPParser;
28
29impl FileParser for NGAPParser {
30 fn parse_additional_infos(lines: &[String]) -> Result<AdditionalInfos, ParsingError> {
31 let line = &lines[0];
32 let parts: Vec<&str> = line.split_whitespace().collect();
33
34 if parts.len() < 6 {
37 return Err(ParsingError::new(
38 "Could not find enough (6) parameters for NGAP".to_string(),
39 1,
40 ));
41 }
42
43 let direction_result = Direction::from_str(parts[2]);
44 let direction = match direction_result {
45 Ok(d) => d,
46 Err(_) => {
47 return Err(ParsingError::new(
48 format!("The direction could not be parsed in the part {:?} of {}", parts[2], line),
49 1,
50 ));
51 }
52 };
53
54 let connection_info = if parts.len() > 5 && parts[5].contains(':') {
56 Some(parts[5].to_string())
57 } else {
58 None
59 };
60
61 let message_start_idx = if connection_info.is_some() { 6 } else { 5 };
63 let message_type = if parts.len() > message_start_idx {
64 parts[message_start_idx..].join(" ")
65 } else {
66 "Unknown".to_string()
67 };
68
69 Ok(AdditionalInfos::NGAPInfos(NGAPInfos {
70 direction,
71 message_type,
72 connection_info,
73 }))
74 }
75
76 fn parse(lines: &[String]) -> Result<Trace, ParsingError> {
77 let additional_infos = match Self::parse_additional_infos(lines) {
78 Ok(m) => m,
79 Err(e) => {
80 return Err(e);
81 }
82 };
83
84 let text = lines.to_vec();
85 let binary = extract_binary_from_lines(lines);
86
87 let timestamp = if let Some(first_line) = lines.first() {
89 super::parse_timestamp(first_line)?
90 } else {
91 0
92 };
93
94 let trace = Trace {
95 timestamp,
96 layer: Layer::NGAP,
97 additional_infos,
98 text: Some(text),
99 binary,
100 relation: TraceRelation::default(),
101 };
102 Ok(trace)
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn test_parse_ngap_line() {
112 let line = "13:20:58.310 [NGAP] TO 0080 003d 127.0.1.100:38412 UE context release complete";
113 let lines = vec![line.to_string()];
114
115 let result = NGAPParser::parse_additional_infos(&lines);
116 assert!(result.is_ok());
117
118 match result.unwrap() {
119 AdditionalInfos::NGAPInfos(infos) => {
120 assert_eq!(infos.direction, Direction::TO);
121 assert_eq!(infos.message_type, "UE context release complete");
122 assert_eq!(infos.connection_info, Some("127.0.1.100:38412".to_string()));
123 }
124 _ => panic!("Expected NGAPInfos"),
125 }
126 }
127
128 #[test]
129 fn test_parse_ngap_from() {
130 let line = "13:20:58.310 [NGAP] FROM 0080 003d 127.0.1.100:38412 Downlink NAS transport";
131 let lines = vec![line.to_string()];
132
133 let result = NGAPParser::parse_additional_infos(&lines);
134 assert!(result.is_ok());
135
136 match result.unwrap() {
137 AdditionalInfos::NGAPInfos(infos) => {
138 assert_eq!(infos.direction, Direction::FROM);
139 assert_eq!(infos.message_type, "Downlink NAS transport");
140 }
141 _ => panic!("Expected NGAPInfos"),
142 }
143 }
144
145 #[test]
146 fn test_parse_ngap_no_connection_info() {
147 let line = "13:20:58.310 [NGAP] TO 0080 003d UE context release complete";
148 let lines = vec![line.to_string()];
149
150 let result = NGAPParser::parse_additional_infos(&lines);
151 assert!(result.is_ok());
152
153 match result.unwrap() {
154 AdditionalInfos::NGAPInfos(infos) => {
155 assert_eq!(infos.connection_info, None);
156 assert_eq!(infos.message_type, "UE context release complete");
157 }
158 _ => panic!("Expected NGAPInfos"),
159 }
160 }
161
162 #[test]
163 fn test_parse_ngap_invalid_direction() {
164 let line = "13:20:58.310 [NGAP] INVALID 0080 003d 127.0.1.100:38412 UE context release complete";
165 let lines = vec![line.to_string()];
166
167 let result = NGAPParser::parse_additional_infos(&lines);
168 assert!(result.is_err());
169 }
170}