1use thiserror::Error;
5
6#[derive(Debug, PartialEq, Eq, Clone, Copy)]
7#[repr(u8)]
8pub enum LlapType {
9 DdpShort = 1,
10 DdpLong = 2,
11 Enquiry = 0x81,
12 Acknowledge = 0x82,
13 Other(u8),
14}
15
16impl From<u8> for LlapType {
17 fn from(orig: u8) -> Self {
18 match orig {
19 1 => LlapType::DdpShort,
20 2 => LlapType::DdpLong,
21 0x81 => LlapType::Enquiry,
22 0x82 => LlapType::Acknowledge,
23 n => LlapType::Other(n),
24 }
25 }
26}
27
28#[derive(Debug)]
29pub struct LlapPacket {
30 pub dst_node: u8,
31 pub src_node: u8,
32 pub type_: LlapType,
33}
34
35#[derive(Error, Debug)]
36pub enum LlapError {
37 #[error("packet too short")]
38 TooShort,
39}
40
41impl LlapPacket {
42 pub const LEN: usize = 3;
43
44 pub fn parse(buf: &[u8]) -> Result<Self, LlapError> {
45 if buf.len() < Self::LEN {
46 return Err(LlapError::TooShort);
47 }
48 Ok(Self {
49 dst_node: buf[0],
50 src_node: buf[1],
51 type_: buf[2].into(),
52 })
53 }
54
55 pub fn to_bytes(&self, buf: &mut [u8]) -> Result<usize, LlapError> {
56 if buf.len() < Self::LEN {
57 return Err(LlapError::TooShort);
58 }
59 buf[0] = self.dst_node;
60 buf[1] = self.src_node;
61 buf[2] = match self.type_ {
62 LlapType::DdpShort => 1,
63 LlapType::DdpLong => 2,
64 LlapType::Enquiry => 0x81,
65 LlapType::Acknowledge => 0x82,
66 LlapType::Other(n) => n,
67 };
68 Ok(Self::LEN)
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn test_ethernet() {
78 let packet = LlapPacket {
79 dst_node: 0x42,
80 src_node: 0x24,
81 type_: LlapType::DdpShort,
82 };
83 let mut buf = [0u8; 3];
84 let len = packet.to_bytes(&mut buf).unwrap();
85 assert_eq!(len, 3);
86 assert_eq!(buf, [0x42, 0x24, 1]);
87
88 let parsed = LlapPacket::parse(&buf).unwrap();
89 assert_eq!(parsed.dst_node, 0x42);
90 assert_eq!(parsed.src_node, 0x24);
91 assert_eq!(parsed.type_, LlapType::DdpShort);
92 }
93
94 #[test]
95 fn test_localtalk_data() {
96 let packet = LlapPacket {
97 dst_node: 0x42,
98 src_node: 0x24,
99 type_: LlapType::DdpLong,
100 };
101 let mut buf = [0u8; 3];
102 let len = packet.to_bytes(&mut buf).unwrap();
103 assert_eq!(len, 3);
104 assert_eq!(buf[0], 0x42);
105 assert_eq!(buf[1], 0x24);
106 assert_eq!(buf[2], 2);
107
108 let parsed = LlapPacket::parse(&buf).unwrap();
109 assert_eq!(parsed.dst_node, 0x42);
110 assert_eq!(parsed.src_node, 0x24);
111 assert_eq!(parsed.type_, LlapType::DdpLong);
112 }
113
114 #[test]
115 fn test_localtalk_control() {
116 let packet = LlapPacket {
117 dst_node: 0xFF,
118 src_node: 0x11,
119 type_: LlapType::Enquiry, };
121 let mut buf = [0u8; 3];
122 let len = packet.to_bytes(&mut buf).unwrap();
123 assert_eq!(len, 3);
124 assert_eq!(buf, [0xFF, 0x11, 0x81]);
125
126 let parsed = LlapPacket::parse(&buf).unwrap();
127 assert_eq!(parsed.dst_node, 0xFF);
128 assert_eq!(parsed.src_node, 0x11);
129 assert_eq!(parsed.type_, LlapType::Enquiry);
130 }
131}