Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use core::str::FromStr;
use arrayvec::ArrayString;
#[derive(Debug, PartialEq, Eq)]
pub struct Destination {
ack: u8,
callsign: ArrayString<253>,
ssid: u8,
}
impl Destination {
/// Returns none if the ack number is > 127
/// Returns none if the dest callsign is too long
/// Returns none is is_ack is true and ack_num is 0
pub fn new(is_ack: bool, ack_num: u8, dest_callsign: &str, dest_ssid: u8) -> Option<Self> {
if ack_num > 127 {
return None;
}
if is_ack && ack_num == 0 {
return None;
}
let ack = if is_ack { (1 << 7) | ack_num } else { ack_num };
let callsign = ArrayString::from_str(dest_callsign).ok()?;
let ssid = dest_ssid;
Some(Self {
ack,
callsign,
ssid,
})
}
pub fn is_ack(&self) -> bool {
self.ack & (1 << 7) > 0
}
pub fn ack_num(&self) -> u8 {
self.ack
}
pub fn callsign(&self) -> &str {
self.callsign.as_str()
}
pub fn ssid(&self) -> u8 {
self.ssid
}
pub fn encode<'a>(&self, buf: &'a mut [u8]) -> Option<&'a [u8]> {
let n = self.callsign.len() + 2;
*buf.get_mut(0)? = n.try_into().unwrap();
*buf.get_mut(1)? = self.ack;
buf.get_mut(2..n)?.copy_from_slice(self.callsign.as_bytes());
*buf.get_mut(n)? = self.ssid;
Some(&buf[0..(n + 1)])
}
pub fn decode(data: &[u8]) -> Option<Self> {
let n = data.first()?;
let call_length: usize = n.checked_sub(2)?.into();
let ack = *data.get(1)?;
if ack == 0b10000000 {
// is_ack is true and # is 0
return None;
}
let callsign = core::str::from_utf8(data.get(2..(call_length + 2))?).ok()?;
let callsign = ArrayString::from_str(callsign).ok()?;
let ssid = *data.get(call_length + 2)?;
Some(Self {
ack,
callsign,
ssid,
})
}
}