rusmpp_core/pdus/owned/
alert_notification.rs

1use rusmpp_macros::Rusmpp;
2
3use crate::{
4    pdus::owned::Pdu,
5    tlvs::owned::{Tlv, TlvValue},
6    types::owned::COctetString,
7    values::*,
8};
9
10/// The alert_notification PDU is sent by the MC to the ESME across a Receiver or Transceiver
11/// session. It is sent when the MC has detected that a particular mobile subscriber has become
12/// available and a delivery pending flag had been previously set for that subscriber by means of
13/// the set_dpf TLV.
14///
15/// A typical use of this operation is to trigger a data content ‘Push’ to the subscriber from a WAP
16/// Proxy Server.
17///
18/// Note: There is no associated alert_notification_resp PDU.
19#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
20#[rusmpp(decode = owned, test = skip)]
21#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
22#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
23#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
24pub struct AlertNotification {
25    /// Type of Number for alert SME.
26    pub source_addr_ton: Ton,
27    /// Numbering Plan Indicator for alert SME.
28    pub source_addr_npi: Npi,
29    /// Address of alert SME.
30    pub source_addr: COctetString<1, 65>,
31    /// Type of Number for ESME address
32    /// which requested the alert.
33    pub esme_addr_ton: Ton,
34    /// Numbering Plan Indicator for ESME
35    /// address which requested the alert.
36    pub esme_addr_npi: Npi,
37    /// Address for ESME which requested the alert.
38    pub esme_addr: COctetString<1, 65>,
39    /// The status of the mobile station [`MsAvailabilityStatus`].
40    #[rusmpp(length = "checked")]
41    ms_availability_status: Option<Tlv>,
42}
43
44impl AlertNotification {
45    pub fn new(
46        source_addr_ton: Ton,
47        source_addr_npi: Npi,
48        source_addr: COctetString<1, 65>,
49        esme_addr_ton: Ton,
50        esme_addr_npi: Npi,
51        esme_addr: COctetString<1, 65>,
52        ms_availability_status: Option<MsAvailabilityStatus>,
53    ) -> Self {
54        Self {
55            source_addr_ton,
56            source_addr_npi,
57            source_addr,
58            esme_addr_ton,
59            esme_addr_npi,
60            esme_addr,
61            ms_availability_status: ms_availability_status
62                .map(TlvValue::MsAvailabilityStatus)
63                .map(From::from),
64        }
65    }
66
67    pub const fn ms_availability_status_tlv(&self) -> Option<&Tlv> {
68        self.ms_availability_status.as_ref()
69    }
70
71    pub fn ms_availability_status(&self) -> Option<MsAvailabilityStatus> {
72        self.ms_availability_status_tlv()
73            .and_then(|tlv| match tlv.value() {
74                Some(TlvValue::MsAvailabilityStatus(value)) => Some(value),
75                _ => None,
76            })
77            .copied()
78    }
79
80    pub fn set_ms_availability_status(
81        &mut self,
82        ms_availability_status: Option<MsAvailabilityStatus>,
83    ) {
84        self.ms_availability_status = ms_availability_status
85            .map(TlvValue::MsAvailabilityStatus)
86            .map(From::from);
87    }
88
89    pub fn builder() -> AlertNotificationBuilder {
90        AlertNotificationBuilder::new()
91    }
92}
93
94impl From<AlertNotification> for Pdu {
95    fn from(value: AlertNotification) -> Self {
96        Self::AlertNotification(value)
97    }
98}
99
100#[derive(Debug, Default)]
101pub struct AlertNotificationBuilder {
102    inner: AlertNotification,
103}
104
105impl AlertNotificationBuilder {
106    pub fn new() -> Self {
107        Default::default()
108    }
109
110    pub fn source_addr_ton(mut self, source_addr_ton: Ton) -> Self {
111        self.inner.source_addr_ton = source_addr_ton;
112        self
113    }
114
115    pub fn source_addr_npi(mut self, source_addr_npi: Npi) -> Self {
116        self.inner.source_addr_npi = source_addr_npi;
117        self
118    }
119
120    pub fn source_addr(mut self, source_addr: COctetString<1, 65>) -> Self {
121        self.inner.source_addr = source_addr;
122        self
123    }
124
125    pub fn esme_addr_ton(mut self, esme_addr_ton: Ton) -> Self {
126        self.inner.esme_addr_ton = esme_addr_ton;
127        self
128    }
129
130    pub fn esme_addr_npi(mut self, esme_addr_npi: Npi) -> Self {
131        self.inner.esme_addr_npi = esme_addr_npi;
132        self
133    }
134
135    pub fn esme_addr(mut self, esme_addr: COctetString<1, 65>) -> Self {
136        self.inner.esme_addr = esme_addr;
137        self
138    }
139
140    pub fn ms_availability_status(
141        mut self,
142        ms_availability_status: Option<MsAvailabilityStatus>,
143    ) -> Self {
144        self.inner
145            .set_ms_availability_status(ms_availability_status);
146        self
147    }
148
149    pub fn build(self) -> AlertNotification {
150        self.inner
151    }
152}
153
154#[cfg(test)]
155mod tests {
156    use std::str::FromStr;
157
158    use crate::tests::TestInstance;
159
160    use super::*;
161
162    impl TestInstance for AlertNotification {
163        fn instances() -> alloc::vec::Vec<Self> {
164            alloc::vec![
165                Self::default(),
166                Self::builder()
167                    .ms_availability_status(Some(MsAvailabilityStatus::Available))
168                    .build(),
169                Self::builder()
170                    .source_addr_ton(Ton::International)
171                    .source_addr_npi(Npi::Isdn)
172                    .source_addr(COctetString::from_str("1234567890").unwrap())
173                    .esme_addr_ton(Ton::International)
174                    .esme_addr_npi(Npi::Isdn)
175                    .esme_addr(COctetString::from_str("0987654321").unwrap())
176                    .ms_availability_status(Some(MsAvailabilityStatus::Available))
177                    .build(),
178                Self::builder()
179                    .source_addr_ton(Ton::NetworkSpecific)
180                    .source_addr_npi(Npi::LandMobile)
181                    .source_addr(COctetString::from_str("1234567890").unwrap())
182                    .esme_addr_ton(Ton::Abbreviated)
183                    .esme_addr_npi(Npi::WapClientId)
184                    .esme_addr(COctetString::from_str("0987654321").unwrap())
185                    .ms_availability_status(Some(MsAvailabilityStatus::Other(255)))
186                    .build(),
187            ]
188        }
189    }
190
191    #[test]
192    fn encode_decode() {
193        crate::tests::owned::encode_decode_with_length_test_instances::<AlertNotification>();
194    }
195}