leodos_protocols/misc/sle/
types.rs1#[derive(Copy, Clone, Debug, PartialEq, Eq)]
8pub struct Time {
9 pub cds: [u8; 8],
11}
12
13impl Time {
14 pub const SIZE: usize = 8;
16
17 pub const fn from_bytes(bytes: [u8; 8]) -> Self {
19 Self { cds: bytes }
20 }
21
22 pub fn day(&self) -> u16 {
24 u16::from_be_bytes([self.cds[0], self.cds[1]])
25 }
26
27 pub fn ms_of_day(&self) -> u32 {
29 u32::from_be_bytes([
30 self.cds[2], self.cds[3], self.cds[4], self.cds[5],
31 ])
32 }
33
34 pub fn microseconds(&self) -> u16 {
36 u16::from_be_bytes([self.cds[6], self.cds[7]])
37 }
38
39 pub fn encode(&self, buf: &mut [u8]) -> Result<usize, SleError> {
42 if buf.len() < Self::SIZE {
43 return Err(SleError::BufferTooSmall);
44 }
45 buf[..Self::SIZE].copy_from_slice(&self.cds);
46 Ok(Self::SIZE)
47 }
48
49 pub fn decode(buf: &[u8]) -> Result<(Self, usize), SleError> {
52 if buf.len() < Self::SIZE {
53 return Err(SleError::BufferTooSmall);
54 }
55 let mut cds = [0u8; 8];
56 cds.copy_from_slice(&buf[..Self::SIZE]);
57 Ok((Self { cds }, Self::SIZE))
58 }
59}
60
61#[derive(Copy, Clone, Debug, PartialEq, Eq)]
63#[repr(u8)]
64pub enum ServiceType {
65 RafOnline = 0,
67 RafOffline = 1,
69 FCltu = 2,
71}
72
73impl ServiceType {
74 pub fn from_u8(v: u8) -> Result<Self, SleError> {
76 match v {
77 0 => Ok(Self::RafOnline),
78 1 => Ok(Self::RafOffline),
79 2 => Ok(Self::FCltu),
80 _ => Err(SleError::InvalidEnumValue),
81 }
82 }
83}
84
85#[derive(Copy, Clone, Debug, PartialEq, Eq)]
87#[repr(u8)]
88pub enum BindResult {
89 Success = 0,
91 AccessDenied = 1,
93 ServiceTypeNotSupported = 2,
95 VersionNotSupported = 3,
97}
98
99impl BindResult {
100 pub fn from_u8(v: u8) -> Result<Self, SleError> {
102 match v {
103 0 => Ok(Self::Success),
104 1 => Ok(Self::AccessDenied),
105 2 => Ok(Self::ServiceTypeNotSupported),
106 3 => Ok(Self::VersionNotSupported),
107 _ => Err(SleError::InvalidEnumValue),
108 }
109 }
110}
111
112#[derive(Clone, Debug, PartialEq, Eq)]
118pub struct ServiceInstanceId {
119 buf: [u8; 64],
122 len: usize,
124}
125
126impl ServiceInstanceId {
127 pub const MAX_LEN: usize = 64;
129
130 pub fn from_bytes(data: &[u8]) -> Result<Self, SleError> {
132 if data.len() > Self::MAX_LEN {
133 return Err(SleError::BufferTooSmall);
134 }
135 let mut buf = [0u8; Self::MAX_LEN];
136 buf[..data.len()].copy_from_slice(data);
137 Ok(Self {
138 buf,
139 len: data.len(),
140 })
141 }
142
143 pub fn as_bytes(&self) -> &[u8] {
145 &self.buf[..self.len]
146 }
147
148 pub fn len(&self) -> usize {
150 self.len
151 }
152
153 pub fn is_empty(&self) -> bool {
155 self.len == 0
156 }
157}
158
159#[derive(Copy, Clone, Debug, PartialEq, Eq, thiserror::Error)]
161pub enum SleError {
162 #[error("buffer too small")]
164 BufferTooSmall,
165 #[error("truncated or malformed input")]
167 Truncated,
168 #[error("unexpected BER tag")]
170 UnexpectedTag,
171 #[error("invalid enum value")]
173 InvalidEnumValue,
174 #[error("integer out of range")]
176 IntegerOverflow,
177 #[error("value too long")]
179 TooLong,
180 #[error("missing required field")]
182 MissingField,
183}