1use crate::fields::{SMSDeliver, SMSSubmit};
2use crate::Result;
3use chrono::{DateTime, Utc};
4use serde_json::Value;
5
6pub struct IncomingSms {
7 pub date: DateTime<Utc>,
8 pub sender: String,
9 pub content: String,
10 pub partial: Option<PartialSmsInfo>,
11}
12
13pub struct OutgoingSms {
14 pub recipient: String,
15 pub content: String,
16}
17
18pub struct PartialSmsInfo {
19 pub reference: String,
20 pub parts_count: u8,
21 pub part_number: u8,
22}
23
24pub fn read_incoming_sms(data: &str) -> Result<IncomingSms> {
25 let sms = SMSDeliver::decode(data)?;
26
27 let mut sender = sms.sender.number;
28 if sms.sender.toa.ton == "international" {
29 sender = format!("+{}", sender);
30 }
31
32 let date = sms.scts;
33 let content = sms.user_data.data;
34
35 let mut partial: Option<PartialSmsInfo> = None;
36 if let Some(header) = sms.user_data.header {
37 for element in header.elements {
38 if element.iei == 0x00 || element.iei == 0x08 {
39 if let Value::Object(el_data) = element.data {
40 let reference = if element.iei == 0x08 {
41 el_data["reference"].as_u64().unwrap_or(0).to_string()
42 } else {
43 el_data["reference"].as_u64().unwrap_or(0).to_string()
46 };
47
48 partial = Some(PartialSmsInfo {
49 reference: format!(
50 "{}-{}",
51 reference,
52 el_data["parts_count"].as_u64().unwrap_or(0)
53 ),
54 parts_count: el_data["parts_count"].as_u64().unwrap_or(0) as u8,
55 part_number: el_data["part_number"].as_u64().unwrap_or(0) as u8,
56 });
57 }
58 }
59 }
60 }
61
62 Ok(IncomingSms {
63 date,
64 sender,
65 content,
66 partial,
67 })
68}
69
70pub fn read_outgoing_sms(data: &str) -> Result<OutgoingSms> {
71 let sms = SMSSubmit::decode(data)?;
72
73 let mut recipient = sms.recipient.number;
74 if sms.recipient.toa.ton == "international" {
75 recipient = format!("+{}", recipient);
76 }
77 let content = sms.user_data.data;
78
79 Ok(OutgoingSms { recipient, content })
80}