Skip to main content

tailtalk_packets/
asp.rs

1#[derive(Debug)]
2pub enum AspError {
3    UnknownFunction(u8),
4    InvalidSize { expected: usize, found: usize },
5}
6
7pub const ASP_SERVER_BUSY: i32 = -1071;
8
9#[repr(u8)]
10#[derive(Debug, Copy, Clone, PartialEq, Eq)]
11pub enum SPFunction {
12    CloseSess = 0x01,
13    Command = 0x02,
14    GetStatus = 0x03,
15    OpenSess = 0x04,
16    Tickle = 0x05,
17    Write = 0x06,
18    WriteContinue = 0x07,
19    Attention = 0x08,
20}
21
22impl TryFrom<u8> for SPFunction {
23    type Error = AspError;
24
25    fn try_from(value: u8) -> Result<Self, Self::Error> {
26        match value {
27            0x01 => Ok(Self::CloseSess),
28            0x02 => Ok(Self::Command),
29            0x03 => Ok(Self::GetStatus),
30            0x04 => Ok(Self::OpenSess),
31            0x05 => Ok(Self::Tickle),
32            0x06 => Ok(Self::Write),
33            0x07 => Ok(Self::WriteContinue),
34            0x08 => Ok(Self::Attention),
35            _ => Err(AspError::UnknownFunction(value)),
36        }
37    }
38}
39
40#[derive(Debug)]
41pub struct AspHeader {
42    pub function: SPFunction,
43    pub session_id: u8,
44    pub sequence_number: u16,
45}
46
47impl AspHeader {
48    pub fn parse(buf: &[u8]) -> Result<Self, AspError> {
49        if buf.len() < 4 {
50            return Err(AspError::InvalidSize {
51                expected: 4,
52                found: buf.len(),
53            });
54        }
55
56        Ok(Self {
57            function: SPFunction::try_from(buf[0])?,
58            session_id: buf[1],
59            sequence_number: u16::from_be_bytes([buf[2], buf[3]]),
60        })
61    }
62
63    pub fn to_bytes(&self, buf: &mut [u8]) -> Result<usize, AspError> {
64        if buf.len() < 4 {
65            return Err(AspError::InvalidSize {
66                expected: 4,
67                found: buf.len(),
68            });
69        }
70
71        buf[0] = self.function as u8;
72        buf[1] = self.session_id;
73        buf[2..4].copy_from_slice(&self.sequence_number.to_be_bytes());
74
75        Ok(4)
76    }
77}
78
79/// Payload for SPWrite command (server to client)
80#[derive(Debug)]
81pub struct SPWritePayload {
82    pub sequence_number: u16,
83    pub session_id: u8,
84}