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