sms_pdu_decoder/
easy.rs

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                        // For 8-bit reference, the reference is a single u8, but combine it with parts_count
44                        // as per the Python logic's string reference format 'reference-parts_count'
45                        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}