use heapless::Vec as HVec;
use mbus_core::transport::UnitIdOrSlaveAddr;
use mbus_gateway::GatewayRoutingPolicy;
pub const MAX_UNIT_ROUTES: usize = 32;
pub const MAX_RANGE_ROUTES: usize = 8;
#[derive(Clone, Copy)]
struct UnitEntry {
unit: u8,
channel: usize,
}
#[derive(Clone, Copy)]
struct RangeEntry {
min: u8,
max: u8,
channel: usize,
}
pub struct CGatewayRouter {
units: HVec<UnitEntry, MAX_UNIT_ROUTES>,
ranges: HVec<RangeEntry, MAX_RANGE_ROUTES>,
}
impl CGatewayRouter {
pub const fn new() -> Self {
Self {
units: HVec::new(),
ranges: HVec::new(),
}
}
pub fn add_unit(&mut self, unit: u8, channel: usize) -> bool {
if self.units.iter().any(|e| e.unit == unit) {
return false;
}
self.units.push(UnitEntry { unit, channel }).is_ok()
}
pub fn add_range(&mut self, min: u8, max: u8, channel: usize) -> bool {
if min > max {
return false;
}
self.ranges.push(RangeEntry { min, max, channel }).is_ok()
}
}
impl Default for CGatewayRouter {
fn default() -> Self {
Self::new()
}
}
impl GatewayRoutingPolicy for CGatewayRouter {
fn route(&self, unit: UnitIdOrSlaveAddr) -> Option<usize> {
let id = unit.get();
if let Some(entry) = self.units.iter().find(|e| e.unit == id) {
return Some(entry.channel);
}
self.ranges
.iter()
.find(|r| id >= r.min && id <= r.max)
.map(|r| r.channel)
}
}