tramex_tools/interface/
onelog.rs

1//! This module contains the definition of the OneLog struct.
2
3use std::str::FromStr;
4
5use crate::data::Trace;
6use crate::errors::TramexError;
7use crate::interface::functions::extract_hexe;
8use crate::interface::parser::ParsedHeader;
9
10use crate::interface::{layer::Layer, types::SourceLog};
11use crate::tramex_error;
12
13use super::types::Direction;
14
15#[derive(serde::Deserialize, Debug)]
16/// Data structure to store the log.
17pub struct OneLog {
18    /// Each item is a string representing a line of log.
19    pub data: Vec<String>,
20
21    /// Milliseconds since January 1st 1970.
22    pub timestamp: i64,
23
24    /// log layer
25    pub layer: Layer,
26
27    /// Source of the log.
28    pub src: SourceLog,
29
30    /// index
31    pub idx: u64,
32
33    /// Direction (UL/DL/TO/FROM)
34    pub dir: Option<String>,
35
36    /// UE identifier
37    pub ue_id: Option<u64>,
38
39    /// Cell identifier
40    pub cell: Option<u64>,
41
42    /// RNTI
43    pub rnti: Option<u64>,
44
45    /// Frame number (PHY)
46    pub frame: Option<u16>,
47
48    /// Slot number (PHY)
49    pub slot: Option<u8>,
50
51    /// Channel name (PHY: PDCCH, PDSCH, etc.)
52    pub channel: Option<String>,
53
54    /// Log level
55    pub level: Option<u8>,
56}
57
58impl OneLog {
59    /// Extract the hexadecimal representation of the log.
60    /// # Errors
61    /// Returns a TramexError if the hexe representation could not be extracted.
62    pub fn extract_hexe(&self) -> Result<Vec<u8>, TramexError> {
63        extract_hexe(&self.data)
64    }
65
66    /// Extract the canal message of the log.
67    pub fn extract_canal_msg(&self) -> Option<String> {
68        // TODO implement this function correctly
69        if let Some(data_line) = self.data.first() {
70            log::debug!("{data_line:?}");
71            return Some(data_line.to_owned());
72        }
73        None
74    }
75
76    /// Build a ParsedHeader from the WebSocket JSON fields.
77    ///
78    /// # Errors
79    /// Returns a TramexError if the header cannot be built.
80    fn build_header(&self) -> Result<ParsedHeader, TramexError> {
81        let direction = match &self.dir {
82            Some(opt_dir) => Direction::from_str(opt_dir).unwrap_or(Direction::NA),
83            None => Direction::NA,
84        };
85
86        Ok(ParsedHeader {
87            timestamp: self.timestamp,
88            layer: self.layer.clone(),
89            direction,
90            ue_id: self.ue_id,
91            cell: self.cell,
92            rnti: self.rnti,
93            frame: self.frame,
94            slot: self.slot,
95            channel: self.channel.clone(),
96            connection_info: None,
97        })
98    }
99
100    /// Extract the data of the log using the unified LayerParser pipeline.
101    /// # Errors
102    /// Returns a TramexError if the data could not be extracted.
103    pub fn extract_data(&self) -> Result<Trace, TramexError> {
104        use crate::interface::parser::LayerParser;
105        use crate::interface::parser::build_trace;
106        use crate::interface::parser::parser_basic::BasicParser;
107        use crate::interface::parser::parser_gtpu::GTPUParser;
108        use crate::interface::parser::parser_nas::NASParser;
109        use crate::interface::parser::parser_ngap::NGAPParser;
110        use crate::interface::parser::parser_phy::PHYParser;
111        use crate::interface::parser::parser_rrc::RRCParser;
112
113        let header = self.build_header()?;
114
115        let additional_infos = match self.layer {
116            Layer::RRC => RRCParser::parse_layer(&header, &self.data),
117            Layer::NAS => NASParser::parse_layer(&header, &self.data),
118            Layer::NGAP => NGAPParser::parse_layer(&header, &self.data),
119            Layer::GTPU => GTPUParser::parse_layer(&header, &self.data),
120            Layer::PHY => PHYParser::parse_layer(&header, &self.data),
121            _ => BasicParser::parse_layer(&header, &self.data),
122        }
123        .map_err(|e| tramex_error!(e.message, crate::errors::ErrorCode::ParsingLayerNotImplemented))?;
124
125        Ok(build_trace(&header, additional_infos, &self.data))
126    }
127}