1use rusmpp_macros::Rusmpp;
2
3use crate::{
4 encode::Length,
5 pdus::owned::Pdu,
6 tlvs::owned::{MessageDeliveryRequestTlvValue, Tlv},
7 types::owned::{COctetString, EmptyOrFullCOctetString, OctetString},
8 values::{owned::*, *},
9};
10
11#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Rusmpp)]
14#[rusmpp(decode = owned, test = skip)]
15#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
16#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
17#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
18pub struct DeliverSm {
19 pub service_type: ServiceType,
29 pub source_addr_ton: Ton,
31 pub source_addr_npi: Npi,
33 pub source_addr: COctetString<1, 21>,
35 pub dest_addr_ton: Ton,
37 pub dest_addr_npi: Npi,
39 pub destination_addr: COctetString<1, 21>,
45 pub esm_class: EsmClass,
48 pub protocol_id: u8,
51 pub priority_flag: PriorityFlag,
53 pub schedule_delivery_time: EmptyOrFullCOctetString<17>,
58 pub validity_period: EmptyOrFullCOctetString<17>,
65 pub registered_delivery: RegisteredDelivery,
68 pub replace_if_present_flag: ReplaceIfPresentFlag,
70 pub data_coding: DataCoding,
72 pub sm_default_msg_id: u8,
75 sm_length: u8,
77 #[rusmpp(length = sm_length)]
85 short_message: OctetString<0, 255>,
86 #[rusmpp(length = "unchecked")]
88 tlvs: alloc::vec::Vec<Tlv>,
89}
90
91impl DeliverSm {
92 #[allow(clippy::too_many_arguments)]
93 pub fn new(
94 service_type: ServiceType,
95 source_addr_ton: Ton,
96 source_addr_npi: Npi,
97 source_addr: COctetString<1, 21>,
98 dest_addr_ton: Ton,
99 dest_addr_npi: Npi,
100 destination_addr: COctetString<1, 21>,
101 esm_class: EsmClass,
102 protocol_id: u8,
103 priority_flag: PriorityFlag,
104 schedule_delivery_time: EmptyOrFullCOctetString<17>,
105 validity_period: EmptyOrFullCOctetString<17>,
106 registered_delivery: RegisteredDelivery,
107 replace_if_present_flag: ReplaceIfPresentFlag,
108 data_coding: DataCoding,
109 sm_default_msg_id: u8,
110 short_message: OctetString<0, 255>,
111 tlvs: alloc::vec::Vec<MessageDeliveryRequestTlvValue>,
112 ) -> Self {
113 let tlvs = tlvs.into_iter().map(From::from).collect();
114
115 let sm_length = short_message.length() as u8;
116
117 Self {
118 service_type,
119 source_addr_ton,
120 source_addr_npi,
121 source_addr,
122 dest_addr_ton,
123 dest_addr_npi,
124 destination_addr,
125 esm_class,
126 protocol_id,
127 priority_flag,
128 schedule_delivery_time,
129 validity_period,
130 registered_delivery,
131 replace_if_present_flag,
132 data_coding,
133 sm_default_msg_id,
134 sm_length,
135 short_message,
136 tlvs,
137 }
138 }
139
140 pub const fn sm_length(&self) -> u8 {
141 self.sm_length
142 }
143
144 pub fn short_message(&self) -> &OctetString<0, 255> {
145 &self.short_message
146 }
147
148 pub fn set_short_message(&mut self, short_message: OctetString<0, 255>) {
155 self.short_message = short_message;
156 self.sm_length = self.short_message.length() as u8;
157 }
158
159 pub fn tlvs(&self) -> &[Tlv] {
160 &self.tlvs
161 }
162
163 pub fn set_tlvs(&mut self, tlvs: alloc::vec::Vec<MessageDeliveryRequestTlvValue>) {
164 self.tlvs = tlvs.into_iter().map(From::from).collect();
165 }
166
167 pub fn clear_tlvs(&mut self) {
168 self.tlvs.clear();
169 }
170
171 pub fn push_tlv(&mut self, tlv: impl Into<MessageDeliveryRequestTlvValue>) {
172 self.tlvs.push(Tlv::from(tlv.into()));
173 }
174
175 pub fn builder() -> DeliverSmBuilder {
176 DeliverSmBuilder::new()
177 }
178}
179
180impl From<DeliverSm> for Pdu {
181 fn from(value: DeliverSm) -> Self {
182 Self::DeliverSm(value)
183 }
184}
185
186#[derive(Debug, Default)]
187pub struct DeliverSmBuilder {
188 inner: DeliverSm,
189}
190
191impl DeliverSmBuilder {
192 pub fn new() -> Self {
193 Self::default()
194 }
195
196 pub fn service_type(mut self, service_type: ServiceType) -> Self {
197 self.inner.service_type = service_type;
198 self
199 }
200
201 pub fn source_addr_ton(mut self, source_addr_ton: Ton) -> Self {
202 self.inner.source_addr_ton = source_addr_ton;
203 self
204 }
205
206 pub fn source_addr_npi(mut self, source_addr_npi: Npi) -> Self {
207 self.inner.source_addr_npi = source_addr_npi;
208 self
209 }
210
211 pub fn source_addr(mut self, source_addr: COctetString<1, 21>) -> Self {
212 self.inner.source_addr = source_addr;
213 self
214 }
215
216 pub fn dest_addr_ton(mut self, dest_addr_ton: Ton) -> Self {
217 self.inner.dest_addr_ton = dest_addr_ton;
218 self
219 }
220
221 pub fn dest_addr_npi(mut self, dest_addr_npi: Npi) -> Self {
222 self.inner.dest_addr_npi = dest_addr_npi;
223 self
224 }
225
226 pub fn destination_addr(mut self, destination_addr: COctetString<1, 21>) -> Self {
227 self.inner.destination_addr = destination_addr;
228 self
229 }
230
231 pub fn esm_class(mut self, esm_class: EsmClass) -> Self {
232 self.inner.esm_class = esm_class;
233 self
234 }
235
236 pub fn protocol_id(mut self, protocol_id: u8) -> Self {
237 self.inner.protocol_id = protocol_id;
238 self
239 }
240
241 pub fn priority_flag(mut self, priority_flag: PriorityFlag) -> Self {
242 self.inner.priority_flag = priority_flag;
243 self
244 }
245
246 pub fn schedule_delivery_time(
247 mut self,
248 schedule_delivery_time: EmptyOrFullCOctetString<17>,
249 ) -> Self {
250 self.inner.schedule_delivery_time = schedule_delivery_time;
251 self
252 }
253
254 pub fn validity_period(mut self, validity_period: EmptyOrFullCOctetString<17>) -> Self {
255 self.inner.validity_period = validity_period;
256 self
257 }
258
259 pub fn registered_delivery(mut self, registered_delivery: RegisteredDelivery) -> Self {
260 self.inner.registered_delivery = registered_delivery;
261 self
262 }
263
264 pub fn replace_if_present_flag(
265 mut self,
266 replace_if_present_flag: ReplaceIfPresentFlag,
267 ) -> Self {
268 self.inner.replace_if_present_flag = replace_if_present_flag;
269 self
270 }
271
272 pub fn data_coding(mut self, data_coding: DataCoding) -> Self {
273 self.inner.data_coding = data_coding;
274 self
275 }
276
277 pub fn sm_default_msg_id(mut self, sm_default_msg_id: u8) -> Self {
278 self.inner.sm_default_msg_id = sm_default_msg_id;
279 self
280 }
281
282 pub fn short_message(mut self, short_message: OctetString<0, 255>) -> Self {
283 self.inner.set_short_message(short_message);
284 self
285 }
286
287 pub fn tlvs(mut self, tlvs: alloc::vec::Vec<MessageDeliveryRequestTlvValue>) -> Self {
288 self.inner.set_tlvs(tlvs);
289 self
290 }
291
292 pub fn clear_tlvs(mut self) -> Self {
293 self.inner.clear_tlvs();
294 self
295 }
296
297 pub fn push_tlv(mut self, tlv: impl Into<MessageDeliveryRequestTlvValue>) -> Self {
298 self.inner.push_tlv(tlv);
299 self
300 }
301
302 pub fn build(self) -> DeliverSm {
303 self.inner
304 }
305}
306
307#[cfg(test)]
308mod tests {
309 use std::str::FromStr;
310
311 use crate::{tests::TestInstance, types::owned::AnyOctetString};
312
313 use super::*;
314
315 impl TestInstance for DeliverSm {
316 fn instances() -> alloc::vec::Vec<Self> {
317 alloc::vec![
318 Self::default(),
319 Self::builder()
320 .source_addr_ton(Ton::International)
321 .source_addr_npi(Npi::Isdn)
322 .source_addr(COctetString::from_str("Source Address").unwrap())
323 .dest_addr_ton(Ton::International)
324 .dest_addr_npi(Npi::Isdn)
325 .destination_addr(COctetString::from_str("Destination Address").unwrap())
326 .schedule_delivery_time(EmptyOrFullCOctetString::empty())
327 .validity_period(EmptyOrFullCOctetString::empty())
328 .registered_delivery(RegisteredDelivery::default())
329 .replace_if_present_flag(ReplaceIfPresentFlag::Replace)
330 .short_message(OctetString::from_static_slice(b"Short Message").unwrap())
331 .build(),
332 Self::builder()
333 .source_addr_ton(Ton::International)
334 .source_addr_npi(Npi::Isdn)
335 .source_addr(COctetString::from_str("Source Address").unwrap())
336 .dest_addr_ton(Ton::International)
337 .dest_addr_npi(Npi::Isdn)
338 .destination_addr(COctetString::from_str("Destination Address").unwrap())
339 .protocol_id(0)
340 .schedule_delivery_time(EmptyOrFullCOctetString::empty())
341 .validity_period(EmptyOrFullCOctetString::empty())
342 .registered_delivery(RegisteredDelivery::default())
343 .replace_if_present_flag(ReplaceIfPresentFlag::Replace)
344 .data_coding(DataCoding::default())
345 .sm_default_msg_id(0)
346 .short_message(OctetString::from_static_slice(b"Short Message").unwrap())
347 .tlvs(alloc::vec![
348 MessageDeliveryRequestTlvValue::MessagePayload(MessagePayload::new(
349 AnyOctetString::from_static_slice(b"Message Payload"),
350 )),
351 MessageDeliveryRequestTlvValue::MessagePayload(MessagePayload::new(
352 AnyOctetString::from_static_slice(b"Message Payload 2"),
353 )),
354 MessageDeliveryRequestTlvValue::CallbackNumPresInd(
355 CallbackNumPresInd::new(
356 Presentation::NumberNotAvailable,
357 Screening::VerifiedAndPassed,
358 ),
359 ),
360 ])
361 .build(),
362 ]
363 }
364 }
365
366 #[test]
367 fn encode_decode() {
368 crate::tests::owned::encode_decode_with_length_test_instances::<DeliverSm>();
369 }
370
371 #[test]
372 fn short_message_length() {
373 let short_message = OctetString::from_static_slice(b"Short Message").unwrap();
374
375 let submit_sm = DeliverSm::builder()
376 .short_message(short_message.clone())
377 .build();
378
379 assert_eq!(submit_sm.short_message(), &short_message);
380 assert_eq!(submit_sm.sm_length(), short_message.length() as u8);
381 }
382}