tramex_tools/interface/
layer.rs

1//! Layer enum and Layers struct
2use std::fmt;
3use std::fmt::Display;
4use std::fmt::Formatter;
5use std::str::FromStr;
6
7#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone, Default)]
8/// Layer enum
9pub enum Layer {
10    #[default]
11    /// Physical layer
12    PHY,
13
14    /// Medium Access Control layer
15    MAC,
16
17    /// Radio Link Control layer
18    RLC,
19
20    /// Packet Data Convergence Protocol layer
21    PDCP,
22
23    /// Radio Resource Control layer
24    RRC,
25
26    /// Non Access Stratum layer
27    NAS,
28
29    /// S1 Application Protocol layer
30    S1AP,
31
32    /// Next Generation Application Protocol layer
33    NGAP,
34
35    /// X2 Application Protocol layer
36    X2AP,
37
38    /// Xn Application Protocol layer
39    XNAP,
40
41    /// M2 Application Protocol layer
42    M2AP,
43
44    /// LTE Positioning Protocol A layer
45    LPPA,
46
47    /// NR Positioning Protocol A layer
48    NRPPA,
49
50    /// GTPU layer
51    GTPU,
52
53    /// SDAP layer
54    SDAP,
55
56    /// Special layer of amarisoft
57    PROD,
58}
59
60impl FromStr for Layer {
61    type Err = ();
62
63    fn from_str(input: &str) -> Result<Layer, Self::Err> {
64        match input {
65            "PHY" => Ok(Layer::PHY),
66            "MAC" => Ok(Layer::MAC),
67            "RLC" => Ok(Layer::RLC),
68            "PDCP" => Ok(Layer::PDCP),
69            "RRC" => Ok(Layer::RRC),
70            "NAS" => Ok(Layer::NAS),
71            "S1AP" => Ok(Layer::S1AP),
72            "NGAP" => Ok(Layer::NGAP),
73            "X2AP" => Ok(Layer::X2AP),
74            "XNAP" => Ok(Layer::XNAP),
75            "M2AP" => Ok(Layer::M2AP),
76            "LPPA" => Ok(Layer::LPPA),
77            "NRPPA" => Ok(Layer::NRPPA),
78            "GTPU" => Ok(Layer::GTPU),
79            "SDAP" => Ok(Layer::SDAP),
80            _ => Err(()),
81        }
82    }
83}
84
85#[derive(Debug, serde::Deserialize, Clone, Default)]
86/// LayerLogLevel enum
87pub enum LayerLogLevel {
88    /// Debug log level
89    Debug,
90
91    #[default]
92    /// Warn log level
93    Warn,
94}
95
96impl LayerLogLevel {
97    /// Check if this is the Warn level (used for skip_serializing_if)
98    pub fn is_warn(&self) -> bool {
99        matches!(self, LayerLogLevel::Warn)
100    }
101}
102
103impl serde::Serialize for LayerLogLevel {
104    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
105    where
106        S: serde::Serializer,
107    {
108        match *self {
109            LayerLogLevel::Debug => serializer.serialize_str("debug"),
110            LayerLogLevel::Warn => serializer.serialize_str("warn"),
111        }
112    }
113}
114
115impl Display for LayerLogLevel {
116    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
117        match self {
118            LayerLogLevel::Debug => write!(f, "debug"),
119            LayerLogLevel::Warn => write!(f, "warn"),
120        }
121    }
122}
123
124#[derive(serde::Serialize, serde::Deserialize, Default, Debug, Clone)]
125/// Layers struct
126pub struct Layers {
127    #[serde(rename(serialize = "PHY"))]
128    /// Physical layer
129    pub phy: LayerLogLevel,
130
131    #[serde(rename(serialize = "MAC"))]
132    /// Medium Access Control layer
133    pub mac: LayerLogLevel,
134
135    #[serde(rename(serialize = "RLC"))]
136    /// Radio Link Control layer
137    pub rlc: LayerLogLevel,
138
139    #[serde(rename(serialize = "PDCP"))]
140    /// Packet Data Convergence Protocol layer
141    pub pdcp: LayerLogLevel,
142
143    #[serde(rename(serialize = "RRC"))]
144    /// Radio Resource Control layer
145    pub rrc: LayerLogLevel,
146
147    #[serde(rename(serialize = "NAS"))]
148    /// Non Access Stratum layer
149    pub nas: LayerLogLevel,
150
151    #[serde(rename(serialize = "S72"))]
152    /// S1 Application Protocol layer
153    pub s72: LayerLogLevel,
154
155    #[serde(rename(serialize = "S1AP"))]
156    /// S1 Application Protocol layer
157    pub s1ap: LayerLogLevel,
158
159    #[serde(rename(serialize = "NGAP"))]
160    /// Next Generation Application Protocol layer
161    pub ngap: LayerLogLevel,
162
163    #[serde(rename(serialize = "GTPU"))]
164    /// GTPU layer
165    pub gtpu: LayerLogLevel,
166
167    #[serde(rename(serialize = "X2AP"))]
168    /// X2 Application Protocol layer
169    pub x2ap: LayerLogLevel,
170
171    #[serde(rename(serialize = "XnAP"))]
172    /// Xn Application Protocol layer
173    pub xnap: LayerLogLevel,
174
175    #[serde(rename(serialize = "M2AP"))]
176    /// M2 Application Protocol layer
177    pub m2ap: LayerLogLevel,
178
179    #[serde(rename(serialize = "LPPa"))]
180    /// LTE Positioning Protocol A layer
181    pub lppa: LayerLogLevel,
182
183    #[serde(rename(serialize = "NRPPa"))]
184    /// NR Positioning Protocol A layer
185    pub nrppa: LayerLogLevel,
186
187    #[serde(rename(serialize = "TRX"))]
188    /// TRX layer
189    pub trx: LayerLogLevel,
190
191    #[serde(rename(serialize = "SDAP"), skip_serializing_if = "LayerLogLevel::is_warn")]
192    /// SDAP layer (not supported by all servers, skipped if warn)
193    pub sdap: LayerLogLevel,
194}
195
196impl Layers {
197    /// Create new Layers struct
198    pub fn new() -> Self {
199        Self::default()
200    }
201
202    /// Create new Layers but in an optiniated way
203    pub fn new_optiniated() -> Self {
204        let mut layers = Layers::new();
205        // Add default visible layers here :
206        layers.rrc = LayerLogLevel::Debug;
207        layers.phy = LayerLogLevel::Debug;
208        layers
209    }
210
211    /// Check if a specific layer is enabled (Debug level)
212    pub fn is_layer_enabled(&self, layer: &Layer) -> bool {
213        match layer {
214            Layer::PHY => matches!(self.phy, LayerLogLevel::Debug),
215            Layer::MAC => matches!(self.mac, LayerLogLevel::Debug),
216            Layer::RLC => matches!(self.rlc, LayerLogLevel::Debug),
217            Layer::PDCP => matches!(self.pdcp, LayerLogLevel::Debug),
218            Layer::RRC => matches!(self.rrc, LayerLogLevel::Debug),
219            Layer::NAS => matches!(self.nas, LayerLogLevel::Debug),
220            Layer::S1AP => matches!(self.s1ap, LayerLogLevel::Debug),
221            Layer::NGAP => matches!(self.ngap, LayerLogLevel::Debug),
222            Layer::X2AP => matches!(self.x2ap, LayerLogLevel::Debug),
223            Layer::XNAP => matches!(self.xnap, LayerLogLevel::Debug),
224            Layer::M2AP => matches!(self.m2ap, LayerLogLevel::Debug),
225            Layer::LPPA => matches!(self.lppa, LayerLogLevel::Debug),
226            Layer::NRPPA => matches!(self.nrppa, LayerLogLevel::Debug),
227            Layer::GTPU => matches!(self.gtpu, LayerLogLevel::Debug),
228            Layer::SDAP => matches!(self.sdap, LayerLogLevel::Debug),
229            Layer::PROD => true, // Always show PROD layer
230        }
231    }
232
233    /// Create new Layers struct with all debug (except SDAP which causes issues with some servers)
234    pub fn all_debug() -> Self {
235        Self {
236            phy: LayerLogLevel::Debug,
237            mac: LayerLogLevel::Debug,
238            rlc: LayerLogLevel::Debug,
239            pdcp: LayerLogLevel::Debug,
240            rrc: LayerLogLevel::Debug,
241            nas: LayerLogLevel::Debug,
242            s72: LayerLogLevel::Debug,
243            s1ap: LayerLogLevel::Debug,
244            ngap: LayerLogLevel::Debug,
245            gtpu: LayerLogLevel::Debug,
246            x2ap: LayerLogLevel::Debug,
247            xnap: LayerLogLevel::Debug,
248            m2ap: LayerLogLevel::Debug,
249            lppa: LayerLogLevel::Debug,
250            nrppa: LayerLogLevel::Debug,
251            trx: LayerLogLevel::Debug,
252            sdap: LayerLogLevel::Warn, // Keep Warn - SDAP causes issues with some servers
253        }
254    }
255}