smpp_codec/pdus/delivery_pdus/
data_sm_request.rs1use crate::common::{read_c_string, write_c_string, Npi, PduError, Ton, CMD_DATA_SM, HEADER_LEN};
2use crate::tlv::{tags, Tlv};
3use std::io::{Cursor, Read, Write};
4
5#[derive(Debug, Clone, PartialEq)]
10pub struct DataSm {
11 pub sequence_number: u32,
13 pub service_type: String,
15 pub source_addr_ton: Ton,
17 pub source_addr_npi: Npi,
19 pub source_addr: String,
21 pub dest_addr_ton: Ton,
23 pub dest_addr_npi: Npi,
25 pub dest_addr: String,
27 pub esm_class: u8,
29 pub registered_delivery: u8,
31 pub data_coding: u8,
33 pub optional_params: Vec<Tlv>, }
36
37impl DataSm {
38 pub fn new(
53 sequence_number: u32,
54 source_addr: String,
55 dest_addr: String,
56 payload: Vec<u8>,
57 ) -> Self {
58 let mut pdu = Self {
59 sequence_number,
60 service_type: String::new(),
61 source_addr_ton: Ton::Unknown,
62 source_addr_npi: Npi::Unknown,
63 source_addr,
64 dest_addr_ton: Ton::Unknown,
65 dest_addr_npi: Npi::Unknown,
66 dest_addr,
67 esm_class: 0,
68 registered_delivery: 0,
69 data_coding: 0,
70 optional_params: Vec::new(),
71 };
72
73 pdu.add_tlv(Tlv::new(tags::MESSAGE_PAYLOAD, payload));
75 pdu
76 }
77
78 pub fn add_tlv(&mut self, tlv: Tlv) {
80 self.optional_params.push(tlv);
81 }
82
83 pub fn encode(&self, writer: &mut impl Write) -> Result<(), PduError> {
89 let tlvs_len: usize = self
96 .optional_params
97 .iter()
98 .map(|tlv| 4 + tlv.length as usize)
99 .sum();
100
101 let body_len = self.service_type.len() + 1 +
102 1 + 1 + self.source_addr.len() + 1 +
103 1 + 1 + self.dest_addr.len() + 1 +
104 1 + 1 + 1 + tlvs_len;
106
107 let command_len = (HEADER_LEN + body_len) as u32;
108
109 writer.write_all(&command_len.to_be_bytes())?;
110 writer.write_all(&CMD_DATA_SM.to_be_bytes())?;
111 writer.write_all(&0u32.to_be_bytes())?;
112 writer.write_all(&self.sequence_number.to_be_bytes())?;
113
114 write_c_string(writer, &self.service_type)?;
115
116 writer.write_all(&[self.source_addr_ton as u8, self.source_addr_npi as u8])?;
117 write_c_string(writer, &self.source_addr)?;
118
119 writer.write_all(&[self.dest_addr_ton as u8, self.dest_addr_npi as u8])?;
120 write_c_string(writer, &self.dest_addr)?;
121
122 writer.write_all(&[self.esm_class, self.registered_delivery, self.data_coding])?;
123
124 for tlv in &self.optional_params {
125 tlv.encode(writer)?;
126 }
127 Ok(())
128 }
129
130 pub fn decode(buffer: &[u8]) -> Result<Self, PduError> {
136 if buffer.len() < HEADER_LEN {
137 return Err(PduError::BufferTooShort);
138 }
139 let mut cursor = Cursor::new(buffer);
140 cursor.set_position(12);
141
142 let mut bytes = [0u8; 4];
143 cursor.read_exact(&mut bytes)?;
144 let sequence_number = u32::from_be_bytes(bytes);
145
146 let service_type = read_c_string(&mut cursor)?;
147
148 let mut u8_buf = [0u8; 1];
149
150 cursor.read_exact(&mut u8_buf)?;
152 let source_addr_ton = Ton::from(u8_buf[0]);
153 cursor.read_exact(&mut u8_buf)?;
154 let source_addr_npi = Npi::from(u8_buf[0]);
155 let source_addr = read_c_string(&mut cursor)?;
156
157 cursor.read_exact(&mut u8_buf)?;
159 let dest_addr_ton = Ton::from(u8_buf[0]);
160 cursor.read_exact(&mut u8_buf)?;
161 let dest_addr_npi = Npi::from(u8_buf[0]);
162 let dest_addr = read_c_string(&mut cursor)?;
163
164 cursor.read_exact(&mut u8_buf)?;
166 let esm_class = u8_buf[0];
167 cursor.read_exact(&mut u8_buf)?;
168 let registered_delivery = u8_buf[0];
169 cursor.read_exact(&mut u8_buf)?;
170 let data_coding = u8_buf[0];
171
172 let mut optional_params = Vec::new();
173 while let Some(tlv) = Tlv::decode(&mut cursor)? {
174 optional_params.push(tlv);
175 }
176
177 Ok(Self {
178 sequence_number,
179 service_type,
180 source_addr_ton,
181 source_addr_npi,
182 source_addr,
183 dest_addr_ton,
184 dest_addr_npi,
185 dest_addr,
186 esm_class,
187 registered_delivery,
188 data_coding,
189 optional_params,
190 })
191 }
192}