1use bytes::BytesMut;
2
3use crate::{
4 CommandId,
5 decode::{
6 DecodeError, DecodeResultExt,
7 owned::{Decode, DecodeWithKeyOptional, DecodeWithLength},
8 },
9 encode::Length,
10 types::owned::AnyOctetString,
11};
12
13use super::*;
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
17#[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
18#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
19#[cfg_attr(feature = "serde-deserialize-unchecked", derive(::serde::Deserialize))]
20pub enum Pdu {
21 BindTransmitter(BindTransmitter),
25 BindTransmitterResp(BindTransmitterResp),
29 BindReceiver(BindReceiver),
35 BindReceiverResp(BindReceiverResp),
39 BindTransceiver(BindTransceiver),
45 BindTransceiverResp(BindTransceiverResp),
49 Outbind(Outbind),
56 AlertNotification(AlertNotification),
66 SubmitSm(SubmitSm),
69 SubmitSmResp(SubmitSmResp),
70 QuerySm(QuerySm),
76 QuerySmResp(QuerySmResp),
77 DeliverSm(DeliverSm),
80 DeliverSmResp(DeliverSmResp),
81 DataSm(DataSm),
86 DataSmResp(DataSmResp),
87 CancelSm(CancelSm),
100 ReplaceSm(ReplaceSm),
107 SubmitMulti(SubmitMulti),
111 SubmitMultiResp(SubmitMultiResp),
112 BroadcastSm(BroadcastSm),
115 BroadcastSmResp(BroadcastSmResp),
116 QueryBroadcastSm(QueryBroadcastSm),
130 QueryBroadcastSmResp(QueryBroadcastSmResp),
131 CancelBroadcastSm(CancelBroadcastSm),
149 Unbind,
152 UnbindResp,
157 EnquireLink,
161 EnquireLinkResp,
164 GenericNack,
170 CancelSmResp,
173 ReplaceSmResp,
176 CancelBroadcastSmResp,
182 Other {
183 command_id: CommandId,
184 body: AnyOctetString,
185 },
186}
187
188impl Pdu {
189 pub const fn command_id(&self) -> CommandId {
190 match self {
191 Pdu::BindTransmitter(_) => CommandId::BindTransmitter,
192 Pdu::BindTransmitterResp(_) => CommandId::BindTransmitterResp,
193 Pdu::BindReceiver(_) => CommandId::BindReceiver,
194 Pdu::BindReceiverResp(_) => CommandId::BindReceiverResp,
195 Pdu::BindTransceiver(_) => CommandId::BindTransceiver,
196 Pdu::BindTransceiverResp(_) => CommandId::BindTransceiverResp,
197 Pdu::Outbind(_) => CommandId::Outbind,
198 Pdu::AlertNotification(_) => CommandId::AlertNotification,
199 Pdu::SubmitSm(_) => CommandId::SubmitSm,
200 Pdu::SubmitSmResp(_) => CommandId::SubmitSmResp,
201 Pdu::QuerySm(_) => CommandId::QuerySm,
202 Pdu::QuerySmResp(_) => CommandId::QuerySmResp,
203 Pdu::DeliverSm(_) => CommandId::DeliverSm,
204 Pdu::DeliverSmResp(_) => CommandId::DeliverSmResp,
205 Pdu::DataSm(_) => CommandId::DataSm,
206 Pdu::DataSmResp(_) => CommandId::DataSmResp,
207 Pdu::CancelSm(_) => CommandId::CancelSm,
208 Pdu::ReplaceSm(_) => CommandId::ReplaceSm,
209 Pdu::SubmitMulti(_) => CommandId::SubmitMulti,
210 Pdu::SubmitMultiResp(_) => CommandId::SubmitMultiResp,
211 Pdu::BroadcastSm(_) => CommandId::BroadcastSm,
212 Pdu::BroadcastSmResp(_) => CommandId::BroadcastSmResp,
213 Pdu::QueryBroadcastSm(_) => CommandId::QueryBroadcastSm,
214 Pdu::QueryBroadcastSmResp(_) => CommandId::QueryBroadcastSmResp,
215 Pdu::CancelBroadcastSm(_) => CommandId::CancelBroadcastSm,
216 Pdu::Other { command_id, .. } => *command_id,
217 Pdu::Unbind => CommandId::Unbind,
220 Pdu::UnbindResp => CommandId::UnbindResp,
221 Pdu::EnquireLink => CommandId::EnquireLink,
222 Pdu::EnquireLinkResp => CommandId::EnquireLinkResp,
223 Pdu::GenericNack => CommandId::GenericNack,
224 Pdu::CancelSmResp => CommandId::CancelSmResp,
225 Pdu::ReplaceSmResp => CommandId::ReplaceSmResp,
226 Pdu::CancelBroadcastSmResp => CommandId::CancelBroadcastSmResp,
227 }
228 }
229}
230
231impl Length for Pdu {
232 fn length(&self) -> usize {
233 match self {
234 Pdu::BindTransmitter(body) => body.length(),
235 Pdu::BindTransmitterResp(body) => body.length(),
236 Pdu::BindReceiver(body) => body.length(),
237 Pdu::BindReceiverResp(body) => body.length(),
238 Pdu::BindTransceiver(body) => body.length(),
239 Pdu::BindTransceiverResp(body) => body.length(),
240 Pdu::Outbind(body) => body.length(),
241 Pdu::AlertNotification(body) => body.length(),
242 Pdu::SubmitSm(body) => body.length(),
243 Pdu::SubmitSmResp(body) => body.length(),
244 Pdu::QuerySm(body) => body.length(),
245 Pdu::QuerySmResp(body) => body.length(),
246 Pdu::DeliverSm(body) => body.length(),
247 Pdu::DeliverSmResp(body) => body.length(),
248 Pdu::DataSm(body) => body.length(),
249 Pdu::DataSmResp(body) => body.length(),
250 Pdu::CancelSm(body) => body.length(),
251 Pdu::ReplaceSm(body) => body.length(),
252 Pdu::SubmitMulti(body) => body.length(),
253 Pdu::SubmitMultiResp(body) => body.length(),
254 Pdu::BroadcastSm(body) => body.length(),
255 Pdu::BroadcastSmResp(body) => body.length(),
256 Pdu::QueryBroadcastSm(body) => body.length(),
257 Pdu::QueryBroadcastSmResp(body) => body.length(),
258 Pdu::CancelBroadcastSm(body) => body.length(),
259 Pdu::Unbind => 0,
260 Pdu::UnbindResp => 0,
261 Pdu::EnquireLink => 0,
262 Pdu::EnquireLinkResp => 0,
263 Pdu::GenericNack => 0,
264 Pdu::CancelSmResp => 0,
265 Pdu::ReplaceSmResp => 0,
266 Pdu::CancelBroadcastSmResp => 0,
267 Pdu::Other { body, .. } => body.length(),
268 }
269 }
270}
271
272impl crate::encode::Encode for Pdu {
273 fn encode(&self, dst: &mut [u8]) -> usize {
274 match self {
275 Pdu::BindTransmitter(body) => body.encode(dst),
276 Pdu::BindTransmitterResp(body) => body.encode(dst),
277 Pdu::BindReceiver(body) => body.encode(dst),
278 Pdu::BindReceiverResp(body) => body.encode(dst),
279 Pdu::BindTransceiver(body) => body.encode(dst),
280 Pdu::BindTransceiverResp(body) => body.encode(dst),
281 Pdu::Outbind(body) => body.encode(dst),
282 Pdu::AlertNotification(body) => body.encode(dst),
283 Pdu::SubmitSm(body) => body.encode(dst),
284 Pdu::SubmitSmResp(body) => body.encode(dst),
285 Pdu::QuerySm(body) => body.encode(dst),
286 Pdu::QuerySmResp(body) => body.encode(dst),
287 Pdu::DeliverSm(body) => body.encode(dst),
288 Pdu::DeliverSmResp(body) => body.encode(dst),
289 Pdu::DataSm(body) => body.encode(dst),
290 Pdu::DataSmResp(body) => body.encode(dst),
291 Pdu::CancelSm(body) => body.encode(dst),
292 Pdu::ReplaceSm(body) => body.encode(dst),
293 Pdu::SubmitMulti(body) => body.encode(dst),
294 Pdu::SubmitMultiResp(body) => body.encode(dst),
295 Pdu::BroadcastSm(body) => body.encode(dst),
296 Pdu::BroadcastSmResp(body) => body.encode(dst),
297 Pdu::QueryBroadcastSm(body) => body.encode(dst),
298 Pdu::QueryBroadcastSmResp(body) => body.encode(dst),
299 Pdu::CancelBroadcastSm(body) => body.encode(dst),
300 Pdu::Unbind
301 | Pdu::UnbindResp
302 | Pdu::EnquireLink
303 | Pdu::EnquireLinkResp
304 | Pdu::GenericNack
305 | Pdu::CancelSmResp
306 | Pdu::ReplaceSmResp
307 | Pdu::CancelBroadcastSmResp => 0,
308 Pdu::Other { body, .. } => body.encode(dst),
309 }
310 }
311}
312
313impl crate::encode::owned::Encode for Pdu {
314 fn encode(&self, dst: &mut bytes::BytesMut) {
315 match self {
316 Pdu::BindTransmitter(body) => body.encode(dst),
317 Pdu::BindTransmitterResp(body) => body.encode(dst),
318 Pdu::BindReceiver(body) => body.encode(dst),
319 Pdu::BindReceiverResp(body) => body.encode(dst),
320 Pdu::BindTransceiver(body) => body.encode(dst),
321 Pdu::BindTransceiverResp(body) => body.encode(dst),
322 Pdu::Outbind(body) => body.encode(dst),
323 Pdu::AlertNotification(body) => body.encode(dst),
324 Pdu::SubmitSm(body) => body.encode(dst),
325 Pdu::SubmitSmResp(body) => body.encode(dst),
326 Pdu::QuerySm(body) => body.encode(dst),
327 Pdu::QuerySmResp(body) => body.encode(dst),
328 Pdu::DeliverSm(body) => body.encode(dst),
329 Pdu::DeliverSmResp(body) => body.encode(dst),
330 Pdu::DataSm(body) => body.encode(dst),
331 Pdu::DataSmResp(body) => body.encode(dst),
332 Pdu::CancelSm(body) => body.encode(dst),
333 Pdu::ReplaceSm(body) => body.encode(dst),
334 Pdu::SubmitMulti(body) => body.encode(dst),
335 Pdu::SubmitMultiResp(body) => body.encode(dst),
336 Pdu::BroadcastSm(body) => body.encode(dst),
337 Pdu::BroadcastSmResp(body) => body.encode(dst),
338 Pdu::QueryBroadcastSm(body) => body.encode(dst),
339 Pdu::QueryBroadcastSmResp(body) => body.encode(dst),
340 Pdu::CancelBroadcastSm(body) => body.encode(dst),
341 Pdu::Unbind
342 | Pdu::UnbindResp
343 | Pdu::EnquireLink
344 | Pdu::EnquireLinkResp
345 | Pdu::GenericNack
346 | Pdu::CancelSmResp
347 | Pdu::ReplaceSmResp
348 | Pdu::CancelBroadcastSmResp => {}
349 Pdu::Other { body, .. } => body.encode(dst),
350 }
351 }
352}
353
354impl DecodeWithKeyOptional for Pdu {
355 type Key = CommandId;
356
357 fn decode(
358 key: Self::Key,
359 src: &mut BytesMut,
360 length: usize,
361 ) -> Result<Option<(Self, usize)>, DecodeError> {
362 if length == 0 {
363 let body = match key {
364 CommandId::Unbind => Pdu::Unbind,
365 CommandId::UnbindResp => Pdu::UnbindResp,
366 CommandId::EnquireLink => Pdu::EnquireLink,
367 CommandId::EnquireLinkResp => Pdu::EnquireLinkResp,
368 CommandId::GenericNack => Pdu::GenericNack,
369 CommandId::CancelSmResp => Pdu::CancelSmResp,
370 CommandId::ReplaceSmResp => Pdu::ReplaceSmResp,
371 CommandId::CancelBroadcastSmResp => Pdu::CancelBroadcastSmResp,
372 _ => return Ok(None),
373 };
374
375 return Ok(Some((body, 0)));
376 }
377
378 let (body, size) = match key {
379 CommandId::BindTransmitter => Decode::decode(src).map_decoded(Self::BindTransmitter)?,
380 CommandId::BindTransmitterResp => {
381 DecodeWithLength::decode(src, length).map_decoded(Self::BindTransmitterResp)?
382 }
383 CommandId::BindReceiver => Decode::decode(src).map_decoded(Self::BindReceiver)?,
384 CommandId::BindReceiverResp => {
385 DecodeWithLength::decode(src, length).map_decoded(Self::BindReceiverResp)?
386 }
387 CommandId::BindTransceiver => Decode::decode(src).map_decoded(Self::BindTransceiver)?,
388 CommandId::BindTransceiverResp => {
389 DecodeWithLength::decode(src, length).map_decoded(Self::BindTransceiverResp)?
390 }
391 CommandId::Outbind => Decode::decode(src).map_decoded(Self::Outbind)?,
392 CommandId::AlertNotification => {
393 DecodeWithLength::decode(src, length).map_decoded(Self::AlertNotification)?
394 }
395 CommandId::SubmitSm => SubmitSm::decode(src, length).map_decoded(Self::SubmitSm)?,
396 CommandId::SubmitSmResp => {
397 DecodeWithLength::decode(src, length).map_decoded(Self::SubmitSmResp)?
398 }
399 CommandId::QuerySm => Decode::decode(src).map_decoded(Self::QuerySm)?,
400 CommandId::QuerySmResp => Decode::decode(src).map_decoded(Self::QuerySmResp)?,
401 CommandId::DeliverSm => {
402 DecodeWithLength::decode(src, length).map_decoded(Self::DeliverSm)?
403 }
404 CommandId::DeliverSmResp => {
405 DecodeWithLength::decode(src, length).map_decoded(Self::DeliverSmResp)?
406 }
407 CommandId::DataSm => DecodeWithLength::decode(src, length).map_decoded(Self::DataSm)?,
408 CommandId::DataSmResp => {
409 DecodeWithLength::decode(src, length).map_decoded(Self::DataSmResp)?
410 }
411 CommandId::CancelSm => Decode::decode(src).map_decoded(Self::CancelSm)?,
412 CommandId::ReplaceSm => {
413 DecodeWithLength::decode(src, length).map_decoded(Self::ReplaceSm)?
414 }
415 CommandId::SubmitMulti => {
416 DecodeWithLength::decode(src, length).map_decoded(Self::SubmitMulti)?
417 }
418 CommandId::SubmitMultiResp => {
419 DecodeWithLength::decode(src, length).map_decoded(Self::SubmitMultiResp)?
420 }
421 CommandId::BroadcastSm => {
422 DecodeWithLength::decode(src, length).map_decoded(Self::BroadcastSm)?
423 }
424 CommandId::BroadcastSmResp => {
425 DecodeWithLength::decode(src, length).map_decoded(Self::BroadcastSmResp)?
426 }
427 CommandId::QueryBroadcastSm => {
428 DecodeWithLength::decode(src, length).map_decoded(Self::QueryBroadcastSm)?
429 }
430 CommandId::QueryBroadcastSmResp => {
431 DecodeWithLength::decode(src, length).map_decoded(Self::QueryBroadcastSmResp)?
432 }
433 CommandId::CancelBroadcastSm => {
434 DecodeWithLength::decode(src, length).map_decoded(Self::CancelBroadcastSm)?
435 }
436 CommandId::Other(_) => {
437 DecodeWithLength::decode(src, length).map_decoded(|body| Pdu::Other {
438 command_id: key,
439 body,
440 })?
441 }
442 CommandId::Unbind
444 | CommandId::UnbindResp
445 | CommandId::EnquireLink
446 | CommandId::EnquireLinkResp
447 | CommandId::GenericNack
448 | CommandId::CancelSmResp
449 | CommandId::ReplaceSmResp
450 | CommandId::CancelBroadcastSmResp => return Ok(None),
451 };
452
453 Ok(Some((body, size)))
454 }
455}