1use crate::dmx_controller::{DmxController, RdmResponseError};
2use crate::dmx_driver::{DiscoveryOption, DmxError, RdmControllerDriver};
3use crate::unique_identifier::{PackageAddress, UniqueIdentifier};
4
5pub fn run_full_discovery<Driver: RdmControllerDriver>(
23 manager: &mut DmxController<Driver>,
24 uid_array: &mut [UniqueIdentifier],
25) -> Result<usize, RdmResponseError<Driver::DriverError>> {
26 let addresses_found = discover_range(manager, 0x00000001, 0xFFFFFFFFFFFE, uid_array)?;
27
28 Ok(addresses_found)
29}
30
31fn discover_range<Driver: RdmControllerDriver>(
32 manager: &mut DmxController<Driver>,
33 lower_bound: u64,
34 upper_bound: u64,
35 uid_array: &mut [UniqueIdentifier],
36) -> Result<usize, RdmResponseError<Driver::DriverError>> {
37 let discovery_option = manager.rdm_discover(lower_bound, upper_bound)?;
38
39 if uid_array.is_empty() {
40 return Ok(0);
41 }
42
43 match discovery_option {
44 DiscoveryOption::Collision => {
45 if upper_bound - lower_bound <= 1 {
46 return Ok(0);
47 }
48
49 let first_lower_bound = lower_bound;
50 let first_upper_bound = (upper_bound + lower_bound) / 2;
51
52 let second_lower_bound = first_upper_bound + 1;
53 let second_upper_bound = upper_bound;
54
55 let upper_addresses_found =
56 discover_range(manager, second_lower_bound, second_upper_bound, uid_array)?;
57
58 let lower_address_found = discover_range(
59 manager,
60 first_lower_bound,
61 first_upper_bound,
62 &mut uid_array[upper_addresses_found..],
63 )?;
64
65 Ok(upper_addresses_found + lower_address_found)
66 },
67 DiscoveryOption::NoDevice => Ok(0),
68 DiscoveryOption::Found(uid) => {
69 match manager.rdm_disc_mute(PackageAddress::Device(uid)) {
70 Err(RdmResponseError::DmxError(DmxError::TimeoutError)) => return Ok(0),
71 result => result,
72 }?;
73 uid_array[0] = uid;
74
75 Ok(1)
76 },
77 }
78}
79
80#[inline]
81pub(crate) fn calculate_checksum(data: &[u8]) -> u16 {
82 let mut checksum = 0u16;
83
84 for byte in data {
85 checksum = checksum.wrapping_add(*byte as u16);
86 }
87
88 checksum
89}
90
91pub(crate) fn encode_disc_unique(src: &[u8], dest: &mut [u8]) {
92 assert!(
93 src.len() * 2 <= dest.len(),
94 "Dest has to be twice the size of src."
95 );
96
97 for (index, byte) in src.iter().enumerate() {
98 dest[index * 2] = byte | 0xAA;
99 dest[index * 2 + 1] = byte | 0x55;
100 }
101}