1use crate::consts::{
2 RDM_DEVICE_INFO_SIZE, RDM_MAX_STATUS_PACKAGES_PER_REQUEST,
3 RDM_MAX_SUPPORTED_PARAMETERS_PER_REQUEST, RDM_STATUS_MESSAGE_SIZE,
4};
5use crate::layouts::{rdm_device_info_layout, rdm_status_message_layout};
6use crate::types::DataPack;
7use crate::unique_identifier::{PackageAddress, UniqueIdentifier};
8use modular_bitfield::bitfield;
9use modular_bitfield::prelude::B12;
10
11#[derive(Debug)]
12#[cfg_attr(feature = "defmt", derive(defmt::Format))]
13pub struct DeserializationError;
14
15impl core::fmt::Display for DeserializationError {
16 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17 write!(f, "There was a deserialization error.")
18 }
19}
20
21#[cfg(feature = "std")]
22impl std::error::Error for DeserializationError {}
23
24#[derive(Debug, Clone)]
25#[cfg_attr(feature = "defmt", derive(defmt::Format))]
26pub enum DmxStartAddress {
27 NoAddress,
29 Address(u16),
31}
32
33impl DmxStartAddress {
34 pub fn as_u16(&self) -> u16 {
35 match self {
36 DmxStartAddress::Address(address) => *address,
37 DmxStartAddress::NoAddress => 0xFFFF,
38 }
39 }
40
41 pub fn deserialize(data: &[u8]) -> Result<Self, DeserializationError> {
42 let start_address = u16::from_be_bytes(data.try_into().map_err(|_| DeserializationError)?);
43
44 start_address.try_into().map_err(|_| DeserializationError)
45 }
46
47 pub fn serialize(&self) -> DataPack {
48 DataPack::from_slice(&self.as_u16().to_be_bytes()).unwrap()
49 }
50}
51
52impl TryFrom<u16> for DmxStartAddress {
53 type Error = DeserializationError;
54
55 fn try_from(start_address: u16) -> Result<Self, Self::Error> {
56 if start_address == 0xFFFF {
57 return Ok(Self::NoAddress);
58 }
59
60 if !(1..=512).contains(&start_address) {
61 return Err(DeserializationError);
62 }
63
64 Ok(Self::Address(start_address))
65 }
66}
67
68#[derive(Debug, Eq, PartialEq)]
70pub struct DiscoveryMuteResponse {
71 pub managed_proxy: bool,
73 pub sub_device: bool,
75 pub boot_loader: bool,
77 pub proxy_device: bool,
79 pub binding_uid: Option<UniqueIdentifier>,
82}
83
84#[bitfield]
85struct DiscControlField {
86 pub managed_proxy: bool,
88 pub sub_device: bool,
90 pub boot_loader: bool,
92 pub proxy_device: bool,
94 #[skip]
95 reserved: B12,
96}
97
98impl DiscoveryMuteResponse {
99 pub fn deserialize(data: &[u8]) -> Result<Self, DeserializationError> {
100 if data.len() < 2 {
101 return Err(DeserializationError);
102 }
103
104 let control_field = DiscControlField::from_bytes((&data[0..2]).try_into().unwrap());
105 let mut discovery_mute_response = Self {
106 managed_proxy: control_field.managed_proxy(),
107 sub_device: control_field.sub_device(),
108 boot_loader: control_field.boot_loader(),
109 proxy_device: control_field.proxy_device(),
110 binding_uid: None,
111 };
112
113 if data.len() == 8 {
114 let binding_uuid = match PackageAddress::from_bytes((&data[2..8]).try_into().unwrap()) {
115 PackageAddress::Device(uid) => uid,
116 _ => return Err(DeserializationError),
117 };
118
119 discovery_mute_response.binding_uid = Some(binding_uuid);
120 }
121
122 Ok(discovery_mute_response)
123 }
124
125 pub fn serialize(&self) -> DataPack {
126 let mut data_pack = DataPack::new();
127 let disc_control_field = DiscControlField::new()
128 .with_managed_proxy(self.managed_proxy)
129 .with_sub_device(self.sub_device)
130 .with_boot_loader(self.boot_loader)
131 .with_proxy_device(self.proxy_device);
132
133 data_pack
134 .extend_from_slice(&disc_control_field.into_bytes())
135 .unwrap();
136
137 match self.binding_uid {
138 None => {},
139 Some(uid) => data_pack.extend_from_slice(&uid.to_bytes()).unwrap(),
140 }
141
142 data_pack
143 }
144}
145
146#[derive(Debug, Copy, Clone, Eq, PartialEq)]
147#[cfg_attr(feature = "defmt", derive(defmt::Format))]
148#[repr(u8)]
149pub enum StatusType {
150 StatusNone = 0x00,
151 StatusGetLastMessage = 0x01,
152 StatusAdvisory = 0x02,
153 StatusWarning = 0x03,
154 StatusError = 0x04,
155 StatusAdvisoryCleared = 0x12,
156 StatusWarningCleared = 0x13,
157 StatusErrorCleared = 0x14,
158}
159
160impl StatusType {
161 pub fn deserialize(data: &[u8]) -> Result<Self, DeserializationError> {
162 if data.len() != 1 {
163 return Err(DeserializationError);
164 }
165
166 let status_type_requested: StatusType = match data[0].try_into() {
167 Ok(status_type) => status_type,
168 Err(_) => {
169 return Err(DeserializationError);
170 },
171 };
172
173 Ok(status_type_requested)
174 }
175}
176
177impl TryFrom<u8> for StatusType {
178 type Error = DeserializationError;
179
180 fn try_from(value: u8) -> Result<Self, Self::Error> {
181 Ok(match value {
182 0x00 => Self::StatusNone,
183 0x01 => Self::StatusGetLastMessage,
184 0x02 => Self::StatusAdvisory,
185 0x03 => Self::StatusWarning,
186 0x04 => Self::StatusError,
187 0x12 => Self::StatusAdvisoryCleared,
188 0x13 => Self::StatusWarningCleared,
189 0x14 => Self::StatusWarningCleared,
190 _ => return Err(DeserializationError),
191 })
192 }
193}
194
195#[derive(Debug, Copy, Clone)]
196#[cfg_attr(feature = "defmt", derive(defmt::Format))]
197pub struct StatusMessage {
198 pub sub_device_id: u16,
199 pub status_type: StatusType,
200 pub status_message_id: u16,
202 pub data_value_1: u16,
203 pub data_value_2: u16,
204}
205
206impl StatusMessage {
207 pub fn deserialize(buffer: &[u8]) -> Result<Self, DeserializationError> {
208 let status_message_view = rdm_status_message_layout::View::new(buffer);
209
210 Ok(Self {
211 sub_device_id: status_message_view.sub_device_id().read(),
212 status_type: status_message_view.status_type().read().try_into()?,
213 status_message_id: status_message_view.status_message_id().read(),
214 data_value_1: status_message_view.data_value_1().read(),
215 data_value_2: status_message_view.data_value_2().read(),
216 })
217 }
218
219 pub fn serialize(&self) -> [u8; RDM_STATUS_MESSAGE_SIZE] {
220 let mut resp_buffer = [0u8; RDM_STATUS_MESSAGE_SIZE];
221 let mut status_message_view = rdm_status_message_layout::View::new(&mut resp_buffer);
222
223 status_message_view
224 .sub_device_id_mut()
225 .write(self.sub_device_id);
226 status_message_view
227 .status_type_mut()
228 .write(self.status_type as u8);
229 status_message_view
230 .status_message_id_mut()
231 .write(self.status_message_id);
232 status_message_view
233 .data_value_1_mut()
234 .write(self.data_value_1);
235 status_message_view
236 .data_value_2_mut()
237 .write(self.data_value_2);
238
239 resp_buffer
240 }
241}
242
243pub type StatusMessages = heapless::Vec<StatusMessage, RDM_MAX_STATUS_PACKAGES_PER_REQUEST>;
244pub type SupportedParameters = heapless::Vec<u16, RDM_MAX_SUPPORTED_PARAMETERS_PER_REQUEST>;
245
246#[derive(Debug, Clone)]
247#[cfg_attr(feature = "defmt", derive(defmt::Format))]
248pub struct DeviceInfo {
249 pub device_model_id: u16,
250 pub product_category: u16,
251 pub software_version: u32,
252 pub dmx_footprint: u16,
253 pub dmx_personality: u16,
254 pub dmx_start_address: DmxStartAddress,
255 pub sub_device_count: u16,
256 pub sensor_count: u8,
257}
258
259impl DeviceInfo {
260 pub fn deserialize(buffer: &[u8]) -> Result<Self, DeserializationError> {
261 if buffer.len() != rdm_device_info_layout::SIZE.unwrap() {
262 return Err(DeserializationError);
263 }
264
265 let device_info_view = rdm_device_info_layout::View::new(buffer);
266 Ok(DeviceInfo {
267 device_model_id: device_info_view.device_model_id().read(),
268 product_category: device_info_view.product_category().read(),
269 software_version: device_info_view.software_version_id().read(),
270 dmx_footprint: device_info_view.dmx_footprint().read(),
271 dmx_personality: device_info_view.dmx_personality().read(),
272 dmx_start_address: device_info_view.dmx_start_address().read().try_into()?,
273 sub_device_count: device_info_view.sub_device_count().read(),
274 sensor_count: device_info_view.sensor_count().read(),
275 })
276 }
277
278 pub fn serialize(&self) -> DataPack {
279 let mut resp_buffer = [0u8; RDM_DEVICE_INFO_SIZE];
280 let mut device_info_view = rdm_device_info_layout::View::new(&mut resp_buffer);
281
282 device_info_view.protocol_version_mut().write(0x01_00);
283 device_info_view
284 .device_model_id_mut()
285 .write(self.device_model_id);
286 device_info_view
287 .product_category_mut()
288 .write(self.product_category);
289 device_info_view
290 .software_version_id_mut()
291 .write(self.software_version);
292 device_info_view
293 .dmx_footprint_mut()
294 .write(self.dmx_footprint);
295 device_info_view
296 .dmx_personality_mut()
297 .write(self.dmx_personality);
298 device_info_view
299 .dmx_start_address_mut()
300 .write(self.dmx_start_address.as_u16());
301 device_info_view
302 .sub_device_count_mut()
303 .write(self.sub_device_count);
304 device_info_view.sensor_count_mut().write(self.sensor_count);
305
306 DataPack::from_slice(&resp_buffer).unwrap()
307 }
308}
309
310pub enum OverflowMessageResp<T> {
312 Complete(T),
314 Incomplete(T),
317}