rusmpp/pdus/
bind.rs

1use crate::{
2    Pdu,
3    types::COctetString,
4    values::{InterfaceVersion, Npi, Ton},
5};
6
7macro_rules! declare_bind {
8    ($name:ident, $builder_name:ident) => {
9        crate::create! {
10            @[skip_test]
11            #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
12            #[cfg_attr(feature = "arbitrary", derive(::arbitrary::Arbitrary))]
13            pub struct $name {
14                /// Identifies the ESME system
15                /// requesting to bind with the MC.
16                pub system_id: COctetString<1, 16>,
17                /// The password may be used by the
18                /// MC to authenticate the ESME
19                /// requesting to bind.
20                pub password: COctetString<1, 9>,
21                /// Identifies the type of ESME system
22                /// requesting to bind with the MC.
23                pub system_type: COctetString<1, 13>,
24                /// Identifies the version of the `SMPP`
25                /// protocol supported by the ESME.
26                pub interface_version: InterfaceVersion,
27                /// Type of Number (TON) for ESME
28                /// address(es) served via this `SMPP` session.
29                ///
30                /// Set to NULL (Unknown) if not known.
31                pub addr_ton: Ton,
32                /// Numbering Plan Indicator (NPI) for
33                /// ESME address(es) served via this `SMPP` session.
34                ///
35                /// Set to NULL (Unknown) if not known.
36                pub addr_npi: Npi,
37                /// A single ESME address or a range of
38                /// ESME addresses served via this `SMPP` session.
39                ///
40                /// Set to NULL if not known.
41                pub address_range: COctetString<1, 41>,
42            }
43        }
44
45        impl $name {
46            pub fn new(
47                system_id: COctetString<1, 16>,
48                password: COctetString<1, 9>,
49                system_type: COctetString<1, 13>,
50                interface_version: InterfaceVersion,
51                addr_ton: Ton,
52                addr_npi: Npi,
53                address_range: COctetString<1, 41>,
54            ) -> Self {
55                Self {
56                    system_id,
57                    password,
58                    system_type,
59                    interface_version,
60                    addr_ton,
61                    addr_npi,
62                    address_range,
63                }
64            }
65
66            pub fn builder() -> $builder_name {
67                $builder_name::new()
68            }
69        }
70
71        #[derive(Debug, Default)]
72        pub struct $builder_name {
73            inner: $name,
74        }
75
76        impl $builder_name {
77            pub fn new() -> Self {
78                Self::default()
79            }
80
81            pub fn system_id(mut self, system_id: COctetString<1, 16>) -> Self {
82                self.inner.system_id = system_id;
83                self
84            }
85
86            pub fn password(mut self, password: COctetString<1, 9>) -> Self {
87                self.inner.password = password;
88                self
89            }
90
91            pub fn system_type(mut self, system_type: COctetString<1, 13>) -> Self {
92                self.inner.system_type = system_type;
93                self
94            }
95
96            pub fn interface_version(mut self, interface_version: InterfaceVersion) -> Self {
97                self.inner.interface_version = interface_version;
98                self
99            }
100
101            pub fn addr_ton(mut self, addr_ton: Ton) -> Self {
102                self.inner.addr_ton = addr_ton;
103                self
104            }
105
106            pub fn addr_npi(mut self, addr_npi: Npi) -> Self {
107                self.inner.addr_npi = addr_npi;
108                self
109            }
110
111            pub fn address_range(mut self, address_range: COctetString<1, 41>) -> Self {
112                self.inner.address_range = address_range;
113                self
114            }
115
116            pub fn build(self) -> $name {
117                self.inner
118            }
119        }
120    };
121}
122
123declare_bind!(BindTransmitter, BindTransmitterBuilder);
124declare_bind!(BindReceiver, BindReceiverBuilder);
125declare_bind!(BindTransceiver, BindTransceiverBuilder);
126
127impl From<BindTransmitter> for Pdu {
128    fn from(value: BindTransmitter) -> Self {
129        Self::BindTransmitter(value)
130    }
131}
132
133impl From<BindReceiver> for Pdu {
134    fn from(value: BindReceiver) -> Self {
135        Self::BindReceiver(value)
136    }
137}
138
139impl From<BindTransceiver> for Pdu {
140    fn from(value: BindTransceiver) -> Self {
141        Self::BindTransceiver(value)
142    }
143}
144
145#[cfg(test)]
146mod tests {
147    use std::str::FromStr;
148
149    use crate::tests::TestInstance;
150
151    use super::*;
152
153    impl TestInstance for BindTransmitter {
154        fn instances() -> alloc::vec::Vec<Self> {
155            alloc::vec![
156                Self::default(),
157                Self::builder()
158                    .system_id(COctetString::from_str("system_id").unwrap())
159                    .password(COctetString::from_str("password").unwrap())
160                    .system_type(COctetString::from_str("system_type").unwrap())
161                    .interface_version(InterfaceVersion::Smpp5_0)
162                    .addr_ton(Ton::International)
163                    .addr_npi(Npi::Isdn)
164                    .address_range(COctetString::from_str("address_range").unwrap())
165                    .build(),
166            ]
167        }
168    }
169
170    impl TestInstance for BindReceiver {
171        fn instances() -> alloc::vec::Vec<Self> {
172            alloc::vec![
173                Self::default(),
174                Self::builder()
175                    .system_id(COctetString::from_str("system_id").unwrap())
176                    .password(COctetString::from_str("password").unwrap())
177                    .system_type(COctetString::from_str("system_type").unwrap())
178                    .interface_version(InterfaceVersion::Smpp3_4)
179                    .addr_ton(Ton::Alphanumeric)
180                    .addr_npi(Npi::Ermes)
181                    .address_range(COctetString::from_str("address_range").unwrap())
182                    .build(),
183            ]
184        }
185    }
186
187    impl TestInstance for BindTransceiver {
188        fn instances() -> alloc::vec::Vec<Self> {
189            alloc::vec![
190                Self::default(),
191                Self::builder()
192                    .system_id(COctetString::from_str("system_id").unwrap())
193                    .password(COctetString::from_str("password").unwrap())
194                    .system_type(COctetString::from_str("system_type").unwrap())
195                    .interface_version(InterfaceVersion::Smpp3_3OrEarlier(2))
196                    .addr_ton(Ton::International)
197                    .addr_npi(Npi::Ermes)
198                    .address_range(COctetString::from_str("address_range").unwrap())
199                    .build(),
200            ]
201        }
202    }
203
204    #[test]
205    fn encode_decode() {
206        crate::tests::encode_decode_test_instances::<BindTransmitter>();
207        crate::tests::encode_decode_test_instances::<BindReceiver>();
208        crate::tests::encode_decode_test_instances::<BindTransceiver>();
209    }
210}