rusmpp/commands/pdu/
alert_notification.rs1use super::Pdu;
2use crate::{
3    commands::{
4        tlvs::{tlv::TLV, tlv_value::TLVValue},
5        types::{ms_availability_status::MsAvailabilityStatus, npi::Npi, ton::Ton},
6    },
7    ende::{
8        decode::{Decode, DecodeError, DecodeWithLength},
9        length::Length,
10    },
11    impl_length_encode, tri,
12    types::{c_octet_string::COctetString, u8::EndeU8},
13};
14
15impl_length_encode! {
16    #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
26    pub struct AlertNotification {
27        pub source_addr_ton: Ton,
29        pub source_addr_npi: Npi,
31        pub source_addr: COctetString<1, 65>,
33        pub esme_addr_ton: Ton,
36        pub esme_addr_npi: Npi,
39        pub esme_addr: COctetString<1, 65>,
41        ms_availability_status: Option<TLV>,
43    }
44}
45
46impl AlertNotification {
47    pub fn new(
48        source_addr_ton: Ton,
49        source_addr_npi: Npi,
50        source_addr: COctetString<1, 65>,
51        esme_addr_ton: Ton,
52        esme_addr_npi: Npi,
53        esme_addr: COctetString<1, 65>,
54        ms_availability_status: Option<MsAvailabilityStatus>,
55    ) -> Self {
56        Self {
57            source_addr_ton,
58            source_addr_npi,
59            source_addr,
60            esme_addr_ton,
61            esme_addr_npi,
62            esme_addr,
63            ms_availability_status: ms_availability_status
64                .map(|v| TLV::new(TLVValue::MsAvailabilityStatus(v))),
65        }
66    }
67
68    pub fn ms_availability_status(&self) -> Option<&TLV> {
69        self.ms_availability_status.as_ref()
70    }
71
72    pub fn set_ms_availability_status(
73        &mut self,
74        ms_availability_status: Option<MsAvailabilityStatus>,
75    ) {
76        self.ms_availability_status =
77            ms_availability_status.map(|v| TLV::new(TLVValue::MsAvailabilityStatus(v)));
78    }
79
80    pub fn builder() -> AlertNotificationBuilder {
81        AlertNotificationBuilder::new()
82    }
83
84    pub fn into_alert_notification(self) -> Pdu {
85        Pdu::AlertNotification(self)
86    }
87}
88
89impl DecodeWithLength for AlertNotification {
90    fn decode_from<R: std::io::Read>(reader: &mut R, length: usize) -> Result<Self, DecodeError>
91    where
92        Self: Sized,
93    {
94        let source_addr_ton = tri!(Ton::decode_from(reader));
95        let source_addr_npi = tri!(Npi::decode_from(reader));
96        let source_addr = tri!(COctetString::decode_from(reader));
97        let esme_addr_ton = tri!(Ton::decode_from(reader));
98        let esme_addr_npi = tri!(Npi::decode_from(reader));
99        let esme_addr = tri!(COctetString::decode_from(reader));
100
101        let ms_availability_status_length = length.saturating_sub(
102            source_addr_ton.length()
103                + source_addr_npi.length()
104                + source_addr.length()
105                + esme_addr_ton.length()
106                + esme_addr_npi.length()
107                + esme_addr.length(),
108        );
109
110        let ms_availability_status = tri!(TLV::length_checked_decode_from(
111            reader,
112            ms_availability_status_length
113        ));
114
115        Ok(Self {
116            source_addr_ton,
117            source_addr_npi,
118            source_addr,
119            esme_addr_ton,
120            esme_addr_npi,
121            esme_addr,
122            ms_availability_status,
123        })
124    }
125}
126
127#[derive(Default)]
128pub struct AlertNotificationBuilder {
129    inner: AlertNotification,
130}
131
132impl AlertNotificationBuilder {
133    pub fn new() -> Self {
134        Default::default()
135    }
136
137    pub fn source_addr_ton(mut self, source_addr_ton: Ton) -> Self {
138        self.inner.source_addr_ton = source_addr_ton;
139        self
140    }
141
142    pub fn source_addr_npi(mut self, source_addr_npi: Npi) -> Self {
143        self.inner.source_addr_npi = source_addr_npi;
144        self
145    }
146
147    pub fn source_addr(mut self, source_addr: COctetString<1, 65>) -> Self {
148        self.inner.source_addr = source_addr;
149        self
150    }
151
152    pub fn esme_addr_ton(mut self, esme_addr_ton: Ton) -> Self {
153        self.inner.esme_addr_ton = esme_addr_ton;
154        self
155    }
156
157    pub fn esme_addr_npi(mut self, esme_addr_npi: Npi) -> Self {
158        self.inner.esme_addr_npi = esme_addr_npi;
159        self
160    }
161
162    pub fn esme_addr(mut self, esme_addr: COctetString<1, 65>) -> Self {
163        self.inner.esme_addr = esme_addr;
164        self
165    }
166
167    pub fn ms_availability_status(
168        mut self,
169        ms_availability_status: Option<MsAvailabilityStatus>,
170    ) -> Self {
171        self.inner
172            .set_ms_availability_status(ms_availability_status);
173        self
174    }
175
176    pub fn build(self) -> AlertNotification {
177        self.inner
178    }
179}
180
181#[cfg(test)]
182mod tests {
183    use super::*;
184
185    #[test]
186    fn default_encode_decode() {
187        crate::ende::tests::default_encode_decode_with_length::<AlertNotification>();
188    }
189}