huawei_modem/gsm_encoding/
udh.rs1use std::convert::TryFrom;
8use crate::errors::*;
9
10#[derive(Debug, Clone)]
12pub struct UdhComponent {
13 pub id: u8,
15 pub data: Vec<u8>
17}
18#[derive(Debug, Clone)]
23pub struct UserDataHeader {
24 pub components: Vec<UdhComponent>
25}
26#[derive(Debug, Clone)]
28pub struct ConcatenatedSmsData {
29 pub reference: u16,
32 pub parts: u8,
34 pub sequence: u8
36}
37impl UserDataHeader {
38 pub fn get_concatenated_sms_data(&self) -> Option<ConcatenatedSmsData> {
40 for comp in self.components.iter() {
41 if comp.id == 0 && comp.data.len() == 3 {
42 return Some(ConcatenatedSmsData {
43 reference: comp.data[0] as _,
44 parts: comp.data[1],
45 sequence: comp.data[2]
46 });
47 }
48 if comp.id == 8 && comp.data.len() == 4 {
49 let reference = ((comp.data[0] as u16) << 8) | (comp.data[1] as u16);
50 return Some(ConcatenatedSmsData {
51 reference,
52 parts: comp.data[2],
53 sequence: comp.data[3]
54 });
55 }
56 }
57 None
58 }
59 pub fn as_bytes(&self) -> Vec<u8> {
61 let mut ret = vec![];
62 for comp in self.components.iter() {
63 ret.push(comp.id);
64 ret.push(comp.data.len() as u8);
65 ret.extend(comp.data.clone());
66 }
67 let len = ret.len() as u8;
68 ret.insert(0, len);
69 ret
70 }
71}
72impl<'a> TryFrom<&'a [u8]> for UserDataHeader {
73 type Error = HuaweiError;
74 fn try_from(b: &[u8]) -> HuaweiResult<Self> {
76 let mut offset = 0;
77 let mut ret = vec![];
78 loop {
79 if b.get(offset).is_none() {
80 break;
81 }
82 let id = b[offset];
83 offset += 1;
84 check_offset!(b, offset, "UDH component length");
85 let len = b[offset];
86 let end = offset + len as usize + 1;
87 offset += 1;
88 let o = end - 1;
89 check_offset!(b, o, "UDH component data");
90 let data = b[offset..end].to_owned();
91 offset = end;
92 ret.push(UdhComponent { id, data });
93 }
94 Ok(UserDataHeader {
95 components: ret
96 })
97 }
98}
99