ross_protocol/event/
message.rs

1use alloc::vec;
2use alloc::vec::Vec;
3use core::convert::TryInto;
4
5use crate::convert_packet::{ConvertPacket, ConvertPacketError};
6use crate::event::event_code::*;
7use crate::event::EventError;
8use crate::packet::Packet;
9
10#[repr(C)]
11#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
12pub enum MessageValue {
13    U8(u8),
14    U16(u16),
15    U32(u32),
16    Bool(bool),
17}
18
19impl MessageValue {
20    fn serialize(self) -> Vec<u8> {
21        match self {
22            Self::U8(value) => vec![0x00, value],
23            Self::U16(value) => {
24                let value = value.to_be_bytes();
25                vec![0x01, value[0], value[1]]
26            }
27            Self::U32(value) => {
28                let value = value.to_be_bytes();
29                vec![0x02, value[0], value[1], value[2], value[3]]
30            }
31            Self::Bool(value) => vec![0x03, if value { 0x01 } else { 0x00 }],
32        }
33    }
34
35    fn try_deserialize(data: &[u8]) -> Result<Self, ConvertPacketError> {
36        if data.len() < 2 {
37            return Err(ConvertPacketError::WrongSize);
38        }
39
40        match data[0] {
41            0x00 => {
42                if data.len() != 2 {
43                    return Err(ConvertPacketError::WrongSize);
44                }
45
46                Ok(Self::U8(data[1]))
47            }
48            0x01 => {
49                if data.len() != 3 {
50                    return Err(ConvertPacketError::WrongSize);
51                }
52
53                let value = u16::from_be_bytes(data[1..=2].try_into().unwrap());
54
55                Ok(Self::U16(value))
56            }
57            0x02 => {
58                if data.len() != 5 {
59                    return Err(ConvertPacketError::WrongSize);
60                }
61
62                let value = u32::from_be_bytes(data[1..=4].try_into().unwrap());
63
64                Ok(Self::U32(value))
65            }
66            0x03 => {
67                if data.len() != 2 {
68                    return Err(ConvertPacketError::WrongSize);
69                }
70
71                let value = data[1] != 0;
72
73                Ok(Self::Bool(value))
74            }
75            _ => Err(ConvertPacketError::UnknownEnumVariant),
76        }
77    }
78}
79
80#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
81pub struct MessageEvent {
82    pub receiver_address: u16,
83    pub transmitter_address: u16,
84    pub code: u16,
85    pub value: MessageValue,
86}
87
88impl ConvertPacket<MessageEvent> for MessageEvent {
89    fn try_from_packet(packet: &Packet) -> Result<Self, ConvertPacketError> {
90        if packet.data.len() <= 7 {
91            return Err(ConvertPacketError::WrongSize);
92        }
93
94        if packet.is_error {
95            return Err(ConvertPacketError::WrongType);
96        }
97
98        if u16::from_be_bytes(packet.data[0..=1].try_into().unwrap()) != MESSAGE_EVENT_CODE {
99            return Err(ConvertPacketError::Event(EventError::WrongEventType));
100        }
101
102        let receiver_address = packet.device_address;
103        let transmitter_address = u16::from_be_bytes(packet.data[2..=3].try_into().unwrap());
104        let code = u16::from_be_bytes(packet.data[4..=5].try_into().unwrap());
105        let value = MessageValue::try_deserialize(&packet.data[6..])?;
106
107        Ok(Self {
108            receiver_address,
109            transmitter_address,
110            code,
111            value,
112        })
113    }
114
115    fn to_packet(&self) -> Packet {
116        let mut data = vec![];
117
118        for byte in u16::to_be_bytes(MESSAGE_EVENT_CODE).iter() {
119            data.push(*byte);
120        }
121
122        for byte in u16::to_be_bytes(self.transmitter_address).iter() {
123            data.push(*byte);
124        }
125
126        for byte in u16::to_be_bytes(self.code).iter() {
127            data.push(*byte);
128        }
129
130        for byte in self.value.serialize().iter() {
131            data.push(*byte);
132        }
133
134        Packet {
135            is_error: false,
136            device_address: self.receiver_address,
137            data,
138        }
139    }
140}
141
142#[cfg(test)]
143mod tests {
144    use super::*;
145
146    const EVENT_PACKET: Packet = Packet {
147        is_error: false,
148        device_address: 0xabab,
149        data: vec![],
150    };
151
152    #[test]
153    fn try_from_packet_test() {
154        let mut packet = EVENT_PACKET;
155        packet.data = vec![
156            ((MESSAGE_EVENT_CODE >> 8) & 0xff) as u8, // event code
157            ((MESSAGE_EVENT_CODE >> 0) & 0xff) as u8, // event code
158            0x00,                                     // transmitter address
159            0x00,                                     // transmitter address
160            0x01,                                     // code
161            0x23,                                     // code
162            0x02,                                     // value
163            0xff,                                     // value
164            0xff,                                     // value
165            0xff,                                     // value
166            0xff,                                     // value
167        ];
168
169        let event = MessageEvent::try_from_packet(&packet).unwrap();
170
171        assert_eq!(event.receiver_address, 0xabab);
172        assert_eq!(event.transmitter_address, 0x0000);
173        assert_eq!(event.code, 0x0123);
174    }
175
176    #[test]
177    fn to_packet_test() {
178        let event = MessageEvent {
179            receiver_address: 0xabab,
180            transmitter_address: 0x0000,
181            code: 0x0123,
182            value: MessageValue::U32(0xffff_ffff),
183        };
184
185        let mut packet = EVENT_PACKET;
186        packet.data = vec![
187            ((MESSAGE_EVENT_CODE >> 8) & 0xff) as u8, // event code
188            ((MESSAGE_EVENT_CODE >> 0) & 0xff) as u8, // event code
189            0x00,                                     // transmitter address
190            0x00,                                     // transmitter address
191            0x01,                                     // code
192            0x23,                                     // code
193            0x02,                                     // value
194            0xff,                                     // value
195            0xff,                                     // value
196            0xff,                                     // value
197            0xff,                                     // value
198        ];
199
200        assert_eq!(event.to_packet(), packet);
201    }
202}