1use crate::encoding;
6#[derive(Debug, Clone, Copy, PartialEq)]
10pub enum EncodingType {
11 Gsm7Bit,
13 Latin1,
15 Ucs2,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq)]
21pub enum SplitMode {
22 Udh,
24 Sar,
26 Payload,
28}
29
30pub struct MessageSplitter;
32
33impl MessageSplitter {
34 pub fn split(
41 text: String,
42 encoding: EncodingType,
43 mode: SplitMode,
44 ) -> Result<(Vec<Vec<u8>>, u8), String> {
45 let (encoded_bytes, data_coding) = match encoding {
47 EncodingType::Gsm7Bit => (encoding::gsm_7bit_encode(&text)?, 0x00),
48 EncodingType::Latin1 => (encoding::encode_8bit(&text), 0x03),
49 EncodingType::Ucs2 => (encoding::encode_16bit(&text), 0x08),
50 };
51
52 let (single_max, multipart_max) = match mode {
54 SplitMode::Udh => match encoding {
55 EncodingType::Gsm7Bit => (160, 153),
56 _ => (140, 134),
57 },
58 SplitMode::Sar => (254, 254),
59 SplitMode::Payload => (65535, 65535),
60 };
61
62 if encoded_bytes.len() <= single_max || matches!(mode, SplitMode::Payload) {
64 return Ok((vec![encoded_bytes], data_coding));
65 }
66
67 let mut temp_chunks = Vec::new();
69 let mut offset = 0;
70
71 while offset < encoded_bytes.len() {
72 let remaining = encoded_bytes.len() - offset;
73 let mut chunk_len = std::cmp::min(multipart_max, remaining);
74
75 if encoding == EncodingType::Gsm7Bit && chunk_len < remaining {
77 let last_byte_index = offset + chunk_len - 1;
78 if encoded_bytes[last_byte_index] == 0x1B {
79 chunk_len -= 1; }
81 }
82
83 temp_chunks.push(encoded_bytes[offset..offset + chunk_len].to_vec());
84 offset += chunk_len;
85 }
86
87 let mut final_chunks = Vec::new();
89 let total_segments = temp_chunks.len() as u8;
90 let ref_num = rand::random::<u8>();
91
92 for (i, chunk_payload) in temp_chunks.iter().enumerate() {
93 let mut chunk = Vec::new();
94
95 if mode == SplitMode::Udh {
96 let seq_num = (i + 1) as u8;
98 let udh = vec![0x05, 0x00, 0x03, ref_num, total_segments, seq_num];
99 chunk.extend(udh);
100 }
101
102 chunk.extend_from_slice(chunk_payload);
103 final_chunks.push(chunk);
104 }
105
106 Ok((final_chunks, data_coding))
107 }
108}