use super::enums::{BayFeatures, BayStatus, EdidProfile, MxrSignalType, RcType};
use super::frame::cstr;
pub(crate) const BAY_CONFIG_SIZE: usize = 61;
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub(crate) struct BayConfig {
pub(crate) port: u8,
pub(crate) modenum: u8,
pub(crate) bay: u8,
pub(crate) video_source: u8,
pub(crate) audio_source: u8,
pub(crate) edid_profile: EdidProfile,
pub(crate) rc_type: RcType,
pub(crate) bay_name: String,
pub(crate) user_name: String,
pub(crate) signal_type: String,
pub(crate) signal_mode: MxrSignalType,
pub(crate) status: BayStatus,
pub(crate) features: BayFeatures,
}
pub(crate) fn parse_bay_config(p: &[u8]) -> Option<BayConfig> {
let p = p.get(..BAY_CONFIG_SIZE)?;
let u8_at = |i: usize| p.get(i).copied().unwrap_or(0);
let u16_at = |i: usize| {
p.get(i..i + 2)
.and_then(|b| <[u8; 2]>::try_from(b).ok())
.map(u16::from_le_bytes)
.unwrap_or(0)
};
let u32_at = |i: usize| {
p.get(i..i + 4)
.and_then(|b| <[u8; 4]>::try_from(b).ok())
.map(u32::from_le_bytes)
.unwrap_or(0)
};
let str_at = |from: usize, to: usize| cstr(p.get(from..to).unwrap_or_default());
let video_source = u8_at(3);
let audio_source = u8_at(4);
Some(BayConfig {
port: u8_at(0),
modenum: u8_at(1),
bay: u8_at(2),
video_source,
audio_source,
edid_profile: EdidProfile::from_wire(
(u16::from(audio_source & 0x0F) << 8) | u16::from(video_source),
),
rc_type: RcType::from_wire((audio_source >> 4) & 0x0F),
bay_name: str_at(5, 21),
user_name: str_at(21, 37),
signal_type: str_at(37, 51),
signal_mode: MxrSignalType::from_wire(u16_at(51)),
status: BayStatus::from_bits(u32_at(53)),
features: BayFeatures::from_bits(u32_at(57)),
})
}