1use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
7pub struct SmsStoredMessage {
8 pub message_id: i64,
10
11 pub phone_number: String,
13
14 pub message_content: String,
16
17 pub message_reference: Option<u8>,
20
21 pub is_outgoing: bool,
23
24 pub status: String,
26
27 pub created_at: Option<u32>,
29
30 pub completed_at: Option<u32>,
32}
33
34#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
36pub struct SmsPartialDeliveryReport {
37 phone_number: String,
39
40 reference_id: u8,
43
44 status: u8,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50#[repr(u8)]
51pub enum SmsDeliveryReportStatus {
52 ReceivedBySme = 0x00,
55 ForwardedButUnconfirmed = 0x01,
57 ReplacedBySc = 0x02,
59 Congestion = 0x20,
65 SmeBusy = 0x21,
67 NoResponseFromSme = 0x22,
69 ServiceRejected = 0x23,
71 QualityOfServiceNotAvailable = 0x24,
73 ErrorInSme = 0x25,
75 RemoteProcedureError = 0x40,
81 IncompatibleDestination = 0x41,
83 ConnectionRejectedBySme = 0x42,
85 NotObtainable = 0x43,
87 QualityOfServiceNotAvailablePermanent = 0x44,
89 NoInterworkingAvailable = 0x45,
91 SmValidityPeriodExpired = 0x46,
93 SmDeletedByOriginatingSme = 0x47,
95 SmDeletedByScAdministration = 0x48,
97 SmDoesNotExist = 0x49,
99 CongestionNoRetry = 0x60,
105 SmeBusyNoRetry = 0x61,
107 NoResponseFromSmeNoRetry = 0x62,
109 ServiceRejectedNoRetry = 0x63,
111 QualityOfServiceNotAvailableNoRetry = 0x64,
113 ErrorInSmeNoRetry = 0x65,
115 Unknown(u8),
120}
121impl From<u8> for SmsDeliveryReportStatus {
122 fn from(value: u8) -> Self {
123 use SmsDeliveryReportStatus::{
124 Congestion, CongestionNoRetry, ConnectionRejectedBySme, ErrorInSme, ErrorInSmeNoRetry,
125 ForwardedButUnconfirmed, IncompatibleDestination, NoInterworkingAvailable,
126 NoResponseFromSme, NoResponseFromSmeNoRetry, NotObtainable,
127 QualityOfServiceNotAvailable, QualityOfServiceNotAvailableNoRetry,
128 QualityOfServiceNotAvailablePermanent, ReceivedBySme, RemoteProcedureError,
129 ReplacedBySc, ServiceRejected, ServiceRejectedNoRetry, SmDeletedByOriginatingSme,
130 SmDeletedByScAdministration, SmDoesNotExist, SmValidityPeriodExpired, SmeBusy,
131 SmeBusyNoRetry, Unknown,
132 };
133
134 match value {
135 0x00 => ReceivedBySme,
137 0x01 => ForwardedButUnconfirmed,
138 0x02 => ReplacedBySc,
139
140 0x20 => Congestion,
142 0x21 => SmeBusy,
143 0x22 => NoResponseFromSme,
144 0x23 => ServiceRejected,
145 0x24 => QualityOfServiceNotAvailable,
146 0x25 => ErrorInSme,
147
148 0x40 => RemoteProcedureError,
150 0x41 => IncompatibleDestination,
151 0x42 => ConnectionRejectedBySme,
152 0x43 => NotObtainable,
153 0x44 => QualityOfServiceNotAvailablePermanent,
154 0x45 => NoInterworkingAvailable,
155 0x46 => SmValidityPeriodExpired,
156 0x47 => SmDeletedByOriginatingSme,
157 0x48 => SmDeletedByScAdministration,
158 0x49 => SmDoesNotExist,
159
160 0x60 => CongestionNoRetry,
162 0x61 => SmeBusyNoRetry,
163 0x62 => NoResponseFromSmeNoRetry,
164 0x63 => ServiceRejectedNoRetry,
165 0x64 => QualityOfServiceNotAvailableNoRetry,
166 0x65 => ErrorInSmeNoRetry,
167
168 _ => Unknown(value),
170 }
171 }
172}
173impl SmsDeliveryReportStatus {
174 #[must_use]
176 pub fn is_successful(&self) -> bool {
177 matches!(
178 self,
179 Self::ReceivedBySme | Self::ForwardedButUnconfirmed | Self::ReplacedBySc
180 )
181 }
182
183 #[must_use]
185 pub fn is_temporary_retrying(&self) -> bool {
186 use SmsDeliveryReportStatus::{
187 Congestion, ErrorInSme, NoResponseFromSme, QualityOfServiceNotAvailable,
188 ServiceRejected, SmeBusy, Unknown,
189 };
190
191 matches!(
192 self,
193 Congestion
194 | SmeBusy
195 | NoResponseFromSme
196 | ServiceRejected
197 | QualityOfServiceNotAvailable
198 | ErrorInSme
199 ) || matches!(self, Unknown(val) if *val >= 0x20 && *val <= 0x3F)
200 }
201
202 #[must_use]
204 pub fn is_permanent_error(&self) -> bool {
205 use SmsDeliveryReportStatus::{
206 ConnectionRejectedBySme, IncompatibleDestination, NoInterworkingAvailable,
207 NotObtainable, QualityOfServiceNotAvailablePermanent, RemoteProcedureError,
208 SmDeletedByOriginatingSme, SmDeletedByScAdministration, SmDoesNotExist,
209 SmValidityPeriodExpired, Unknown,
210 };
211
212 matches!(
213 self,
214 RemoteProcedureError
215 | IncompatibleDestination
216 | ConnectionRejectedBySme
217 | NotObtainable
218 | QualityOfServiceNotAvailablePermanent
219 | NoInterworkingAvailable
220 | SmValidityPeriodExpired
221 | SmDeletedByOriginatingSme
222 | SmDeletedByScAdministration
223 | SmDoesNotExist
224 ) || matches!(self, Unknown(val) if *val >= 0x40 && *val <= 0x5F)
225 }
226
227 #[must_use]
229 pub fn is_temporary_no_retry(&self) -> bool {
230 use SmsDeliveryReportStatus::{
231 CongestionNoRetry, ErrorInSmeNoRetry, NoResponseFromSmeNoRetry,
232 QualityOfServiceNotAvailableNoRetry, ServiceRejectedNoRetry, SmeBusyNoRetry, Unknown,
233 };
234
235 matches!(
236 self,
237 CongestionNoRetry
238 | SmeBusyNoRetry
239 | NoResponseFromSmeNoRetry
240 | ServiceRejectedNoRetry
241 | QualityOfServiceNotAvailableNoRetry
242 | ErrorInSmeNoRetry
243 ) || matches!(self, Unknown(val) if *val >= 0x60 && *val <= 0x7F)
244 }
245
246 #[must_use]
248 pub fn to_status_group(&self) -> SmsDeliveryReportStatusGroup {
249 if self.is_successful() {
250 SmsDeliveryReportStatusGroup::Received
251 } else if self.is_temporary_retrying() {
252 SmsDeliveryReportStatusGroup::Sent
253 } else if self.is_permanent_error() || self.is_temporary_no_retry() {
254 if self.is_permanent_error() {
256 SmsDeliveryReportStatusGroup::PermanentFailure
257 } else {
258 SmsDeliveryReportStatusGroup::TemporaryFailure
259 }
260 } else {
261 match self {
263 Self::Unknown(val) if *val >= 0x20 && *val <= 0x3F => {
264 SmsDeliveryReportStatusGroup::Sent
265 }
266 Self::Unknown(val) if *val >= 0x40 && *val <= 0x5F => {
267 SmsDeliveryReportStatusGroup::PermanentFailure
268 }
269 Self::Unknown(val) if *val >= 0x60 && *val <= 0x7F => {
270 SmsDeliveryReportStatusGroup::TemporaryFailure
271 }
272 _ => SmsDeliveryReportStatusGroup::PermanentFailure, }
274 }
275 }
276}
277
278#[derive(Debug, Clone, Copy, PartialEq, Eq)]
280pub enum SmsDeliveryReportStatusGroup {
281 Sent,
283 Received,
285 TemporaryFailure,
287 PermanentFailure,
289}
290impl From<SmsDeliveryReportStatus> for SmsDeliveryReportStatusGroup {
291 fn from(status: SmsDeliveryReportStatus) -> Self {
292 status.to_status_group()
293 }
294}
295
296#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
298pub enum ModemStatusUpdateState {
299 Startup,
301
302 Online,
304
305 ShuttingDown,
307
308 Offline,
310}
311impl std::fmt::Display for ModemStatusUpdateState {
312 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
313 match self {
314 ModemStatusUpdateState::Startup => write!(f, "Startup"),
315 ModemStatusUpdateState::Online => write!(f, "Online"),
316 ModemStatusUpdateState::ShuttingDown => write!(f, "ShuttingDown"),
317 ModemStatusUpdateState::Offline => write!(f, "Offline"),
318 }
319 }
320}
321
322#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
324pub enum GnssFixStatus {
325 Unknown,
327
328 NotFix,
330
331 Fix2D,
333
334 Fix3D,
336}
337
338#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
340pub struct GnssPositionReport {
341 pub run_status: bool,
343
344 pub fix_status: bool,
346
347 pub utc_time: String,
349
350 pub latitude: Option<f64>,
352
353 pub longitude: Option<f64>,
355
356 pub msl_altitude: Option<f64>,
358
359 pub ground_speed: Option<f32>,
361
362 pub ground_course: Option<f32>,
364
365 pub fix_mode: GnssFixStatus,
367
368 pub hdop: Option<f32>,
370
371 pub pdop: Option<f32>,
373
374 pub vdop: Option<f32>,
376
377 pub gps_in_view: Option<u8>,
379
380 pub gnss_used: Option<u8>,
382
383 pub glonass_in_view: Option<u8>,
385}