rusmpp_core/pdus/borrowed/
cancel_sm.rs

1use rusmpp_macros::Rusmpp;
2
3use crate::{
4    pdus::borrowed::Pdu,
5    types::borrowed::COctetString,
6    values::{borrowed::*, *},
7};
8
9/// This command is issued by the ESME to cancel one or more previously submitted short
10/// messages that are pending delivery. The command may specify a particular message to
11/// cancel, or all messages matching a particular source, destination and service_type.
12///
13/// If the message_id is set to the ID of a previously submitted message, then provided the
14/// source address supplied by the ESME matches that of the stored message, that message
15/// will be cancelled.
16///
17/// If the message_id is NULL, all outstanding undelivered messages with matching source and
18/// destination addresses (and service_type if specified) are cancelled.
19/// Where the original submit_sm, data_sm or submit_multi ‘source address’ is defaulted to
20/// NULL, then the source address in the cancel_sm command should also be NULL.
21#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
22#[rusmpp(decode = borrowed, test = skip)]
23#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
24#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
25pub struct CancelSm<'a> {
26    /// Set to indicate SMS Application service,
27    /// if cancellation of a group of application
28    /// service messages is desired.
29    /// Otherwise set to NULL.
30    pub service_type: ServiceType<'a>,
31    /// Message ID of the message to be
32    /// cancelled. This must be the MC
33    /// assigned Message ID of the original
34    /// message.
35    ///
36    /// Set to NULL if cancelling a group of
37    /// messages.
38    pub message_id: COctetString<'a, 1, 65>,
39    /// Type of Number of message originator.
40    /// This is used for verification purposes,
41    /// and must match that supplied in the
42    /// original message submission request PDU.
43    ///
44    /// If not known, set to NULL.
45    pub source_addr_ton: Ton,
46    /// Numbering Plan Identity of message
47    /// originator.
48    ///
49    /// This is used for verification purposes,
50    /// and must match that supplied in the
51    /// original message submission request PDU.
52    ///
53    /// If not known, set to NULL.
54    pub source_addr_npi: Npi,
55    /// Source address of message(s) to be
56    /// cancelled. This is used for verification
57    /// purposes, and must match that supplied
58    /// in the original message submission
59    /// request PDU(s).
60    ///
61    /// If not known, set to NULL.
62    pub source_addr: COctetString<'a, 1, 21>,
63    /// Type of number of destination SME
64    /// address of the message(s) to be cancelled.
65    ///
66    /// This is used for verification purposes,
67    /// and must match that supplied in the
68    /// original message submission request
69    /// PDU (e.g. submit_sm).
70    ///
71    /// May be set to NULL when the
72    /// message_id is provided.
73    pub dest_addr_ton: Ton,
74    /// Numbering Plan Indicator of destination
75    /// SME address of the message(s) to be
76    /// cancelled.
77    ///
78    /// This is used for verification purposes,
79    /// and must match that supplied in the
80    /// original message submission request
81    /// PDU.
82    ///
83    /// May be set to NULL when the
84    /// message_id is provided.
85    pub dest_addr_npi: Npi,
86    /// Destination address of message(s) to be
87    /// cancelled.
88    ///
89    /// This is used for verification purposes,
90    /// and must match that supplied in the
91    /// original message submission request
92    /// PDU.
93    ///
94    /// May be set to NULL when the
95    /// message_id is provided.
96    pub destination_addr: COctetString<'a, 1, 21>,
97}
98
99impl<'a> CancelSm<'a> {
100    #[allow(clippy::too_many_arguments)]
101    pub fn new(
102        service_type: ServiceType<'a>,
103        message_id: COctetString<'a, 1, 65>,
104        source_addr_ton: Ton,
105        source_addr_npi: Npi,
106        source_addr: COctetString<'a, 1, 21>,
107        dest_addr_ton: Ton,
108        dest_addr_npi: Npi,
109        destination_addr: COctetString<'a, 1, 21>,
110    ) -> Self {
111        Self {
112            service_type,
113            message_id,
114            source_addr_ton,
115            source_addr_npi,
116            source_addr,
117            dest_addr_ton,
118            dest_addr_npi,
119            destination_addr,
120        }
121    }
122
123    pub fn builder() -> CancelSmBuilder<'a> {
124        CancelSmBuilder::new()
125    }
126}
127
128impl<'a, const N: usize> From<CancelSm<'a>> for Pdu<'a, N> {
129    fn from(value: CancelSm<'a>) -> Self {
130        Self::CancelSm(value)
131    }
132}
133
134#[derive(Debug, Default)]
135pub struct CancelSmBuilder<'a> {
136    inner: CancelSm<'a>,
137}
138
139impl<'a> CancelSmBuilder<'a> {
140    pub fn new() -> Self {
141        Self::default()
142    }
143
144    pub fn service_type(mut self, service_type: ServiceType<'a>) -> Self {
145        self.inner.service_type = service_type;
146        self
147    }
148
149    pub fn message_id(mut self, message_id: COctetString<'a, 1, 65>) -> Self {
150        self.inner.message_id = message_id;
151        self
152    }
153
154    pub fn source_addr_ton(mut self, source_addr_ton: Ton) -> Self {
155        self.inner.source_addr_ton = source_addr_ton;
156        self
157    }
158
159    pub fn source_addr_npi(mut self, source_addr_npi: Npi) -> Self {
160        self.inner.source_addr_npi = source_addr_npi;
161        self
162    }
163
164    pub fn source_addr(mut self, source_addr: COctetString<'a, 1, 21>) -> Self {
165        self.inner.source_addr = source_addr;
166        self
167    }
168
169    pub fn dest_addr_ton(mut self, dest_addr_ton: Ton) -> Self {
170        self.inner.dest_addr_ton = dest_addr_ton;
171        self
172    }
173
174    pub fn dest_addr_npi(mut self, dest_addr_npi: Npi) -> Self {
175        self.inner.dest_addr_npi = dest_addr_npi;
176        self
177    }
178
179    pub fn destination_addr(mut self, destination_addr: COctetString<'a, 1, 21>) -> Self {
180        self.inner.destination_addr = destination_addr;
181        self
182    }
183
184    pub fn build(self) -> CancelSm<'a> {
185        self.inner
186    }
187}
188
189#[cfg(test)]
190mod tests {
191    use crate::tests::TestInstance;
192
193    use super::*;
194
195    impl TestInstance for CancelSm<'_> {
196        fn instances() -> alloc::vec::Vec<Self> {
197            alloc::vec![
198                Self::default(),
199                Self::builder()
200                    .service_type(ServiceType::default())
201                    .message_id(COctetString::new(b"message_id\0").unwrap())
202                    .source_addr_ton(Ton::International)
203                    .source_addr_npi(Npi::Unknown)
204                    .source_addr(COctetString::new(b"source_addr\0").unwrap())
205                    .dest_addr_ton(Ton::International)
206                    .dest_addr_npi(Npi::Unknown)
207                    .destination_addr(COctetString::new(b"destination_addr\0").unwrap())
208                    .build(),
209            ]
210        }
211    }
212
213    #[test]
214    fn encode_decode() {
215        crate::tests::borrowed::encode_decode_test_instances::<CancelSm>();
216    }
217}