1use crate::encoding;
2#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum EncodingType {
6 Gsm7Bit,
7 Latin1,
8 Ucs2,
9}
10
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub enum SplitMode {
13 Udh,
14 Sar,
15 Payload,
16}
17
18pub struct MessageSplitter;
19
20impl MessageSplitter {
21 pub fn split(
28 text: String,
29 encoding: EncodingType,
30 mode: SplitMode,
31 ) -> Result<(Vec<Vec<u8>>, u8), String> {
32 let (encoded_bytes, data_coding) = match encoding {
34 EncodingType::Gsm7Bit => (encoding::gsm_7bit_encode(&text)?, 0x00),
35 EncodingType::Latin1 => (encoding::encode_8bit(&text), 0x03),
36 EncodingType::Ucs2 => (encoding::encode_16bit(&text), 0x08),
37 };
38
39 let (single_max, multipart_max) = match mode {
41 SplitMode::Udh => match encoding {
42 EncodingType::Gsm7Bit => (160, 153),
43 _ => (140, 134),
44 },
45 SplitMode::Sar => (254, 254),
46 SplitMode::Payload => (65535, 65535),
47 };
48
49 if encoded_bytes.len() <= single_max || matches!(mode, SplitMode::Payload) {
51 return Ok((vec![encoded_bytes], data_coding));
52 }
53
54 let mut temp_chunks = Vec::new();
56 let mut offset = 0;
57
58 while offset < encoded_bytes.len() {
59 let remaining = encoded_bytes.len() - offset;
60 let mut chunk_len = std::cmp::min(multipart_max, remaining);
61
62 if encoding == EncodingType::Gsm7Bit && chunk_len < remaining {
64 let last_byte_index = offset + chunk_len - 1;
65 if encoded_bytes[last_byte_index] == 0x1B {
66 chunk_len -= 1; }
68 }
69
70 temp_chunks.push(encoded_bytes[offset..offset + chunk_len].to_vec());
71 offset += chunk_len;
72 }
73
74 let mut final_chunks = Vec::new();
76 let total_segments = temp_chunks.len() as u8;
77 let ref_num = rand::random::<u8>();
78
79 for (i, chunk_payload) in temp_chunks.iter().enumerate() {
80 let mut chunk = Vec::new();
81
82 if mode == SplitMode::Udh {
83 let seq_num = (i + 1) as u8;
85 let udh = vec![0x05, 0x00, 0x03, ref_num, total_segments, seq_num];
86 chunk.extend(udh);
87 }
88
89 chunk.extend_from_slice(chunk_payload);
90 final_chunks.push(chunk);
91 }
92
93 Ok((final_chunks, data_coding))
94 }
95}