1use crate::consts::SC_RDM;
2use crate::dmx_driver::{DmxError, DmxReceiver, RdmControllerDriver};
3use crate::rdm_data::{RdmData, RdmDeserializationError, RdmRequestData, RdmResponseData};
4use crate::rdm_responder::{
5 DmxReceiverContext, RdmAnswer, RdmResponderConfig, RdmResponderHandlerFunc,
6 RdmResponderPackageHandler, RdmResult,
7};
8use crate::rdm_types::StatusMessage;
9use crate::types::NackReason;
10
11pub type DmxFrame = heapless::Vec<u8, 513>;
13
14pub enum ResponseOption {
15 NoResponse,
16 Response(DmxFrame),
17 ResponseNoBreak(DmxFrame),
18}
19
20#[derive(Debug)]
21#[cfg_attr(feature = "defmt", derive(defmt::Format))]
22pub struct HandlePackageError;
23
24impl core::fmt::Display for HandlePackageError {
25 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26 write!(f, "Couldn't handle package.")
27 }
28}
29
30#[cfg(feature = "std")]
31impl std::error::Error for HandlePackageError {}
32
33#[derive(Debug)]
34#[cfg_attr(feature = "defmt", derive(defmt::Format))]
35pub enum PollingError<DriverError, HandlerError> {
37 UartOverflow,
39 TimeoutError,
43 UnknownStartCode,
45 WrongPackageSize,
47 NotMatching,
49 DriverError(DriverError),
51 HandlerError(HandlerError),
53 DeserializationError(RdmDeserializationError),
55}
56
57impl<DriverError, HandlerError> From<DmxError<DriverError>>
58 for PollingError<DriverError, HandlerError>
59{
60 fn from(value: DmxError<DriverError>) -> Self {
61 match value {
62 DmxError::UartOverflow => Self::UartOverflow,
63 DmxError::TimeoutError => Self::TimeoutError,
64 DmxError::DeserializationError(deserialization_error) => {
65 Self::DeserializationError(deserialization_error)
66 },
67 DmxError::DriverError(driver_error) => Self::DriverError(driver_error),
68 }
69 }
70}
71
72impl<DriverError: core::fmt::Display, HandlerError: core::fmt::Display> core::fmt::Display
73 for PollingError<DriverError, HandlerError>
74{
75 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
76 let error_message = match self {
77 PollingError::UartOverflow => "Uart overflow.",
78 PollingError::TimeoutError => "Timeout error.",
79 PollingError::DeserializationError(_) => "Deserialization error.",
80 PollingError::NotMatching => "Received response and not request.",
81 PollingError::UnknownStartCode => "The start code is unknown.",
82 PollingError::WrongPackageSize => "The package size is insufficient.",
83 PollingError::DriverError(error) => {
84 return core::fmt::Display::fmt(error, f);
85 },
86 PollingError::HandlerError(error) => {
87 return core::fmt::Display::fmt(error, f);
88 },
89 };
90
91 write!(f, "{}", error_message)
92 }
93}
94
95#[cfg(feature = "std")]
96impl<
97 DriverError: core::fmt::Display + core::fmt::Debug,
98 HandlerError: core::fmt::Display + core::fmt::Debug,
99 > std::error::Error for PollingError<DriverError, HandlerError>
100{
101}
102
103pub trait DmxResponderHandler {
105 type Error;
106
107 fn handle_rdm(
109 &mut self,
110 _request: &RdmRequestData,
111 _context: &mut DmxReceiverContext,
112 ) -> Result<RdmResult, Self::Error> {
113 Ok(RdmResult::NotAcknowledged(
114 NackReason::UnsupportedCommandClass as u16,
115 ))
116 }
117
118 fn handle_dmx(
121 &mut self,
122 _dmx_frame: DmxFrame,
123 _context: &mut DmxReceiverContext,
124 ) -> Result<(), Self::Error> {
125 Ok(())
126 }
127}
128
129pub struct RdmResponder<D: DmxReceiver + RdmControllerDriver, const MQ_SIZE: usize> {
133 driver: D,
134 rdm_receiver_handler: RdmResponderPackageHandler<MQ_SIZE>,
135}
136
137impl<D: DmxReceiver + RdmControllerDriver, const MQ_SIZE: usize> RdmResponder<D, MQ_SIZE> {
138 pub fn new(driver: D, config: RdmResponderConfig) -> Self {
140 Self {
141 driver,
142 rdm_receiver_handler: RdmResponderPackageHandler::new(config),
143 }
144 }
145
146 pub fn poll<HandlerError>(
151 &mut self,
152 handler: &mut dyn DmxResponderHandler<Error = HandlerError>,
153 ) -> Result<bool, PollingError<D::DriverError, HandlerError>> {
154 let package = match self.driver.receive_package() {
155 Err(DmxError::TimeoutError) => return Ok(false),
156 result => result?,
157 };
158
159 if package.is_empty() {
160 return Err(PollingError::WrongPackageSize);
161 }
162
163 let start_code = package[0];
164 match start_code {
165 SC_RDM => {
166 self.handle_rdm(package, handler)?;
167 },
168 _ => {
169 handler
170 .handle_dmx(package, &mut self.rdm_receiver_handler.get_context())
171 .map_err(|error| PollingError::HandlerError(error))?;
172 },
173 }
174
175 Ok(true)
176 }
177
178 fn handle_rdm<HandlerError>(
179 &mut self,
180 package: DmxFrame,
181 handler: &mut dyn DmxResponderHandler<Error = HandlerError>,
182 ) -> Result<(), PollingError<D::DriverError, HandlerError>> {
183 struct DmxRdmHandlerWrapper<'a, HandlerError> {
184 dmx: &'a mut dyn DmxResponderHandler<Error = HandlerError>,
185 }
186
187 impl<HandlerError> RdmResponderHandlerFunc for DmxRdmHandlerWrapper<'_, HandlerError> {
188 type Error = HandlerError;
189 fn handle_rdm(
190 &mut self,
191 request: &RdmRequestData,
192 context: &mut DmxReceiverContext,
193 ) -> Result<RdmResult, Self::Error> {
194 self.dmx.handle_rdm(request, context)
195 }
196 }
197
198 let rdm_data =
199 RdmData::deserialize(&package).map_err(PollingError::DeserializationError)?;
200
201 let request = match rdm_data {
202 RdmData::Request(request) => request,
203 _ => return Err(PollingError::NotMatching),
204 };
205
206 let response = self
207 .rdm_receiver_handler
208 .handle_rdm_request(request, &mut DmxRdmHandlerWrapper { dmx: handler })
209 .map_err(PollingError::HandlerError)?;
210
211 match response {
212 RdmAnswer::Response(response_data) => {
213 self.driver
214 .send_rdm(RdmData::Response(response_data))
215 .map_err(|error| match error {
216 DmxError::UartOverflow => PollingError::UartOverflow,
217 DmxError::TimeoutError => PollingError::TimeoutError,
218 DmxError::DeserializationError(deserialization_error) => {
219 PollingError::DeserializationError(deserialization_error)
220 },
221 DmxError::DriverError(driver_error) => {
222 PollingError::DriverError(driver_error)
223 },
224 })?;
225 },
226 RdmAnswer::DiscoveryResponse(uid) => {
227 self.driver.send_rdm_discovery_response(uid)?;
228 },
229 RdmAnswer::NoResponse => {},
230 }
231
232 Ok(())
233 }
234
235 pub fn get_message_queue(&self) -> &heapless::Deque<RdmResponseData, MQ_SIZE> {
237 self.rdm_receiver_handler.get_message_queue()
238 }
239
240 pub fn get_message_queue_mut(&mut self) -> &mut heapless::Deque<RdmResponseData, MQ_SIZE> {
242 self.rdm_receiver_handler.get_message_queue_mut()
243 }
244
245 pub fn get_message_count(&self) -> u8 {
247 self.rdm_receiver_handler.get_message_count()
248 }
249
250 pub fn get_status_vec(&self) -> &heapless::Vec<StatusMessage, MQ_SIZE> {
252 self.rdm_receiver_handler.get_status_vec()
253 }
254
255 pub fn get_status_vec_mut(&mut self) -> &mut heapless::Vec<StatusMessage, MQ_SIZE> {
257 self.rdm_receiver_handler.get_status_vec_mut()
258 }
259}