smpp_codec/pdus/submission_pdus/
submit_multi_response.rs1use crate::common::{
2 get_status_code, get_status_description, read_c_string, write_c_string, Npi, PduError, Ton,
3 CMD_SUBMIT_MULTI_SM_RESP, HEADER_LEN,
4};
5
6use std::io::{Cursor, Read, Write};
7
8#[derive(Debug, Clone, PartialEq)]
10pub struct UnsuccessfulDelivery {
11 pub ton: Ton,
13 pub npi: Npi,
15 pub address: String,
17 pub error_status: u32,
19}
20
21#[derive(Debug, Clone, PartialEq)]
25pub struct SubmitMultiResp {
26 pub sequence_number: u32,
28 pub command_status: u32, pub status_description: String, pub message_id: String,
34 pub unsuccess_smes: Vec<UnsuccessfulDelivery>,
36}
37
38impl SubmitMultiResp {
39 pub fn new(
54 sequence_number: u32,
55 status_name: &str,
56 message_id: String,
57 unsuccess_smes: Vec<UnsuccessfulDelivery>,
58 ) -> Self {
59 let command_status = get_status_code(status_name);
60 Self {
61 sequence_number,
62 command_status,
63 status_description: status_name.to_string(),
64 message_id,
65 unsuccess_smes,
66 }
67 }
68
69 pub fn encode(&self, writer: &mut impl Write) -> Result<(), PduError> {
75 let mut body = Vec::new();
76
77 if self.command_status == 0 || self.command_status == 0x00000405 {
80 write_c_string(&mut body, &self.message_id)?;
81 body.write_all(&[self.unsuccess_smes.len() as u8])?;
82
83 for sme in &self.unsuccess_smes {
84 body.write_all(&[sme.ton as u8, sme.npi as u8])?;
85 write_c_string(&mut body, &sme.address)?;
86 body.write_all(&sme.error_status.to_be_bytes())?;
87 }
88 }
89
90 let command_len = (HEADER_LEN + body.len()) as u32;
91 writer.write_all(&command_len.to_be_bytes())?;
92 writer.write_all(&CMD_SUBMIT_MULTI_SM_RESP.to_be_bytes())?;
93 writer.write_all(&self.command_status.to_be_bytes())?;
94 writer.write_all(&self.sequence_number.to_be_bytes())?;
95 writer.write_all(&body)?;
96
97 Ok(())
98 }
99
100 pub fn decode(buffer: &[u8]) -> Result<Self, PduError> {
106 if buffer.len() < HEADER_LEN {
107 return Err(PduError::BufferTooShort);
108 }
109 let mut cursor = Cursor::new(buffer);
110 cursor.set_position(8);
111
112 let mut bytes = [0u8; 4];
113 cursor.read_exact(&mut bytes)?;
114 let command_status = u32::from_be_bytes(bytes);
115 cursor.read_exact(&mut bytes)?;
116 let sequence_number = u32::from_be_bytes(bytes);
117
118 let mut message_id = String::new();
119 let mut unsuccess_smes = Vec::new();
120
121 if command_status == 0 || command_status == 0x00000405 {
122 message_id = read_c_string(&mut cursor)?;
124 let mut u8_buf = [0u8; 1];
125 cursor.read_exact(&mut u8_buf)?;
126 let count = u8_buf[0];
127
128 for _ in 0..count {
129 cursor.read_exact(&mut u8_buf)?;
130 let ton = Ton::from(u8_buf[0]);
131 cursor.read_exact(&mut u8_buf)?;
132 let npi = Npi::from(u8_buf[0]);
133 let address = read_c_string(&mut cursor)?;
134
135 let mut err_bytes = [0u8; 4];
136 cursor.read_exact(&mut err_bytes)?;
137 let error_status = u32::from_be_bytes(err_bytes);
138
139 unsuccess_smes.push(UnsuccessfulDelivery {
140 ton,
141 npi,
142 address,
143 error_status,
144 });
145 }
146 }
147
148 let status_description = get_status_description(command_status);
149
150 Ok(Self {
151 sequence_number,
152 command_status,
153 status_description,
154 message_id,
155 unsuccess_smes,
156 })
157 }
158}