1use rusmpp_macros::Rusmpp;
2
3use crate::{
4 pdus::owned::Pdu,
5 tlvs::owned::{BroadcastRequestTlvValue, Tlv},
6 types::owned::{COctetString, EmptyOrFullCOctetString},
7 values::{owned::*, *},
8};
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default, Rusmpp)]
13#[rusmpp(decode = owned, test = skip)]
14#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
15#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
16#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
17pub struct BroadcastSm {
18 pub service_type: ServiceType,
28 pub source_addr_ton: Ton,
32 pub source_addr_npi: Npi,
36 pub source_addr: COctetString<1, 21>,
40 pub message_id: COctetString<1, 65>,
55 pub priority_flag: PriorityFlag,
57 pub schedule_delivery_time: EmptyOrFullCOctetString<17>,
62 pub validity_period: EmptyOrFullCOctetString<17>,
69 pub replace_if_present_flag: ReplaceIfPresentFlag,
76 pub data_coding: DataCoding,
79 pub sm_default_msg_id: u8,
84 #[rusmpp(length = "unchecked")]
86 tlvs: alloc::vec::Vec<Tlv>,
87}
88
89impl BroadcastSm {
90 #[allow(clippy::too_many_arguments)]
91 pub fn new(
92 service_type: ServiceType,
93 source_addr_ton: Ton,
94 source_addr_npi: Npi,
95 source_addr: COctetString<1, 21>,
96 message_id: COctetString<1, 65>,
97 priority_flag: PriorityFlag,
98 schedule_delivery_time: EmptyOrFullCOctetString<17>,
99 validity_period: EmptyOrFullCOctetString<17>,
100 replace_if_present_flag: ReplaceIfPresentFlag,
101 data_coding: DataCoding,
102 sm_default_msg_id: u8,
103 tlvs: alloc::vec::Vec<BroadcastRequestTlvValue>,
104 ) -> Self {
105 let tlvs = tlvs.into_iter().map(From::from).collect();
106
107 Self {
108 service_type,
109 source_addr_ton,
110 source_addr_npi,
111 source_addr,
112 message_id,
113 priority_flag,
114 schedule_delivery_time,
115 validity_period,
116 replace_if_present_flag,
117 data_coding,
118 sm_default_msg_id,
119 tlvs,
120 }
121 }
122
123 pub fn tlvs(&self) -> &[Tlv] {
124 &self.tlvs
125 }
126
127 pub fn set_tlvs(&mut self, tlvs: alloc::vec::Vec<BroadcastRequestTlvValue>) {
128 self.tlvs = tlvs.into_iter().map(From::from).collect();
129 }
130
131 pub fn clear_tlvs(&mut self) {
132 self.tlvs.clear();
133 }
134
135 pub fn push_tlv(&mut self, tlv: impl Into<BroadcastRequestTlvValue>) {
136 self.tlvs.push(Tlv::from(tlv.into()));
137 }
138
139 pub fn builder() -> BroadcastSmBuilder {
140 BroadcastSmBuilder::new()
141 }
142}
143
144impl From<BroadcastSm> for Pdu {
145 fn from(value: BroadcastSm) -> Self {
146 Self::BroadcastSm(value)
147 }
148}
149
150#[derive(Debug, Default)]
151pub struct BroadcastSmBuilder {
152 inner: BroadcastSm,
153}
154
155impl BroadcastSmBuilder {
156 pub fn new() -> Self {
157 Self::default()
158 }
159
160 pub fn service_type(mut self, service_type: ServiceType) -> Self {
161 self.inner.service_type = service_type;
162 self
163 }
164
165 pub fn source_addr_ton(mut self, source_addr_ton: Ton) -> Self {
166 self.inner.source_addr_ton = source_addr_ton;
167 self
168 }
169
170 pub fn source_addr_npi(mut self, source_addr_npi: Npi) -> Self {
171 self.inner.source_addr_npi = source_addr_npi;
172 self
173 }
174
175 pub fn source_addr(mut self, source_addr: COctetString<1, 21>) -> Self {
176 self.inner.source_addr = source_addr;
177 self
178 }
179
180 pub fn message_id(mut self, message_id: COctetString<1, 65>) -> Self {
181 self.inner.message_id = message_id;
182 self
183 }
184
185 pub fn priority_flag(mut self, priority_flag: PriorityFlag) -> Self {
186 self.inner.priority_flag = priority_flag;
187 self
188 }
189
190 pub fn schedule_delivery_time(
191 mut self,
192 schedule_delivery_time: EmptyOrFullCOctetString<17>,
193 ) -> Self {
194 self.inner.schedule_delivery_time = schedule_delivery_time;
195 self
196 }
197
198 pub fn validity_period(mut self, validity_period: EmptyOrFullCOctetString<17>) -> Self {
199 self.inner.validity_period = validity_period;
200 self
201 }
202
203 pub fn replace_if_present_flag(
204 mut self,
205 replace_if_present_flag: ReplaceIfPresentFlag,
206 ) -> Self {
207 self.inner.replace_if_present_flag = replace_if_present_flag;
208 self
209 }
210
211 pub fn data_coding(mut self, data_coding: DataCoding) -> Self {
212 self.inner.data_coding = data_coding;
213 self
214 }
215
216 pub fn sm_default_msg_id(mut self, sm_default_msg_id: u8) -> Self {
217 self.inner.sm_default_msg_id = sm_default_msg_id;
218 self
219 }
220
221 pub fn tlvs(mut self, tlvs: alloc::vec::Vec<BroadcastRequestTlvValue>) -> Self {
222 self.inner.set_tlvs(tlvs);
223 self
224 }
225
226 pub fn clear_tlvs(mut self) -> Self {
227 self.inner.clear_tlvs();
228 self
229 }
230
231 pub fn push_tlv(mut self, tlv: impl Into<BroadcastRequestTlvValue>) -> Self {
232 self.inner.push_tlv(tlv);
233 self
234 }
235
236 pub fn build(self) -> BroadcastSm {
237 self.inner
238 }
239}
240
241#[cfg(test)]
242mod tests {
243 use std::str::FromStr;
244
245 use crate::{tests::TestInstance, types::owned::OctetString};
246
247 use super::*;
248
249 impl TestInstance for BroadcastSm {
250 fn instances() -> alloc::vec::Vec<Self> {
251 alloc::vec![
252 Self::default(),
253 Self::builder()
254 .service_type(ServiceType::new(
255 GenericServiceType::CellularMessaging.into(),
256 ))
257 .source_addr_ton(Ton::International)
258 .source_addr_npi(Npi::Isdn)
259 .source_addr(COctetString::from_str("SourceAddr").unwrap())
260 .message_id(COctetString::from_str("MessageId").unwrap())
261 .priority_flag(PriorityFlag::from(PriorityFlagType::from(GsmSms::from(1))))
262 .schedule_delivery_time(EmptyOrFullCOctetString::empty())
263 .validity_period(EmptyOrFullCOctetString::empty())
264 .replace_if_present_flag(ReplaceIfPresentFlag::Replace)
265 .data_coding(DataCoding::LatinHebrew)
266 .sm_default_msg_id(0)
267 .build(),
268 Self::builder()
269 .service_type(ServiceType::new(
270 GenericServiceType::UnstructuredSupplementaryServicesData.into(),
271 ))
272 .source_addr_ton(Ton::International)
273 .source_addr_npi(Npi::Isdn)
274 .source_addr(COctetString::from_str("SourceAddr").unwrap())
275 .message_id(COctetString::from_str("MessageId").unwrap())
276 .priority_flag(PriorityFlag::from(PriorityFlagType::from(Ansi136::Bulk)))
277 .schedule_delivery_time(
278 EmptyOrFullCOctetString::from_static_slice(b"2023-10-01T00:00\0").unwrap(),
279 )
280 .validity_period(EmptyOrFullCOctetString::empty())
281 .replace_if_present_flag(ReplaceIfPresentFlag::DoNotReplace)
282 .data_coding(DataCoding::GsmMessageClassControl)
283 .sm_default_msg_id(255)
284 .tlvs(alloc::vec![
285 BroadcastRequestTlvValue::CallbackNum(
286 OctetString::from_str("1234567890").unwrap(),
287 ),
288 BroadcastRequestTlvValue::LanguageIndicator(LanguageIndicator::German),
289 BroadcastRequestTlvValue::SmsSignal(1024),
290 ])
291 .build(),
292 ]
293 }
294 }
295
296 #[test]
297 fn encode_decode() {
298 crate::tests::owned::encode_decode_with_length_test_instances::<BroadcastSm>();
299 }
300}