use crate::error::PfcpError;
use crate::ie::{Ie, IeType};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Interface {
Access,
Core,
Smf,
Amf,
Dn,
Lcs,
ScScf,
InterSystem,
Iu,
S1,
S11,
S12,
S1U,
S2a,
S2b,
S4,
S5S8,
S6a,
SGi,
Sm,
Sn,
Szn,
X2,
}
impl From<u8> for Interface {
fn from(v: u8) -> Self {
match v {
0 => Interface::Access,
1 => Interface::Core,
2 => Interface::Smf,
3 => Interface::Amf,
4 => Interface::Dn,
5 => Interface::Lcs,
6 => Interface::ScScf,
7 => Interface::InterSystem,
10 => Interface::Iu,
11 => Interface::S1,
12 => Interface::S11,
13 => Interface::S12,
14 => Interface::S1U,
15 => Interface::S2a,
16 => Interface::S2b,
17 => Interface::S4,
18 => Interface::S5S8,
19 => Interface::S6a,
20 => Interface::SGi,
21 => Interface::Sm,
22 => Interface::Sn,
23 => Interface::Szn,
24 => Interface::X2,
_ => Interface::Access, }
}
}
impl From<Interface> for u8 {
fn from(i: Interface) -> Self {
match i {
Interface::Access => 0,
Interface::Core => 1,
Interface::Smf => 2,
Interface::Amf => 3,
Interface::Dn => 4,
Interface::Lcs => 5,
Interface::ScScf => 6,
Interface::InterSystem => 7,
Interface::Iu => 10,
Interface::S1 => 11,
Interface::S11 => 12,
Interface::S12 => 13,
Interface::S1U => 14,
Interface::S2a => 15,
Interface::S2b => 16,
Interface::S4 => 17,
Interface::S5S8 => 18,
Interface::S6a => 19,
Interface::SGi => 20,
Interface::Sm => 21,
Interface::Sn => 22,
Interface::Szn => 23,
Interface::X2 => 24,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DestinationInterface {
pub interface: Interface,
}
impl DestinationInterface {
pub fn new(interface: Interface) -> Self {
DestinationInterface { interface }
}
pub fn marshal(&self) -> Vec<u8> {
vec![self.interface.into()]
}
pub fn unmarshal(payload: &[u8]) -> Result<Self, PfcpError> {
if payload.is_empty() {
return Err(PfcpError::invalid_length(
"Destination Interface",
IeType::DestinationInterface,
1,
0,
));
}
Ok(DestinationInterface {
interface: payload[0].into(),
})
}
pub fn to_ie(&self) -> Ie {
Ie::new(IeType::DestinationInterface, self.marshal())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_destination_interface_marshal_unmarshal() {
let di = DestinationInterface::new(Interface::Access);
let marshaled = di.marshal();
let unmarshaled = DestinationInterface::unmarshal(&marshaled).unwrap();
assert_eq!(unmarshaled.interface, Interface::Access);
}
#[test]
fn test_destination_interface_unmarshal_empty() {
let result = DestinationInterface::unmarshal(&[]);
assert!(result.is_err());
let err = result.unwrap_err();
assert!(matches!(err, PfcpError::InvalidLength { .. }));
assert!(err.to_string().contains("Destination Interface"));
assert!(err.to_string().contains("1"));
assert!(err.to_string().contains("0"));
}
}