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}