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