use crate::dmx_controller::{DmxController, RdmResponseError};
use crate::dmx_driver::{DiscoveryOption, DmxError, RdmControllerDriver};
use crate::unique_identifier::{PackageAddress, UniqueIdentifier};
pub fn run_full_discovery<Driver: RdmControllerDriver>(
manager: &mut DmxController<Driver>,
uid_array: &mut [UniqueIdentifier],
) -> Result<usize, RdmResponseError<Driver::DriverError>> {
let addresses_found = discover_range(manager, 0x00000001, 0xFFFFFFFFFFFE, uid_array)?;
Ok(addresses_found)
}
fn discover_range<Driver: RdmControllerDriver>(
manager: &mut DmxController<Driver>,
lower_bound: u64,
upper_bound: u64,
uid_array: &mut [UniqueIdentifier],
) -> Result<usize, RdmResponseError<Driver::DriverError>> {
let discovery_option = manager.rdm_discover(lower_bound, upper_bound)?;
if uid_array.is_empty() {
return Ok(0);
}
match discovery_option {
DiscoveryOption::Collision => {
if upper_bound - lower_bound <= 1 {
return Ok(0);
}
let first_lower_bound = lower_bound;
let first_upper_bound = (upper_bound + lower_bound) / 2;
let second_lower_bound = first_upper_bound + 1;
let second_upper_bound = upper_bound;
let upper_addresses_found =
discover_range(manager, second_lower_bound, second_upper_bound, uid_array)?;
let lower_address_found = discover_range(
manager,
first_lower_bound,
first_upper_bound,
&mut uid_array[upper_addresses_found..],
)?;
Ok(upper_addresses_found + lower_address_found)
},
DiscoveryOption::NoDevice => Ok(0),
DiscoveryOption::Found(uid) => {
match manager.rdm_disc_mute(PackageAddress::Device(uid)) {
Err(RdmResponseError::DmxError(DmxError::TimeoutError)) => return Ok(0),
result => result,
}?;
uid_array[0] = uid;
Ok(1)
},
}
}
#[inline]
pub(crate) fn calculate_checksum(data: &[u8]) -> u16 {
let mut checksum = 0u16;
for byte in data {
checksum = checksum.wrapping_add(*byte as u16);
}
checksum
}
pub(crate) fn encode_disc_unique(src: &[u8], dest: &mut [u8]) {
assert!(
src.len() * 2 <= dest.len(),
"Dest has to be twice the size of src."
);
for (index, byte) in src.iter().enumerate() {
dest[index * 2] = byte | 0xAA;
dest[index * 2 + 1] = byte | 0x55;
}
}