use std::sync::Arc;
use std::time::Duration;
use can_transport::CanBus;
use tokio::time::MissedTickBehavior;
use tokio_util::sync::CancellationToken;
use crate::canopen::heartbeat::build_heartbeat_frame;
use crate::canopen::nmt::NmtState;
pub(crate) async fn run_hb_broadcast(
bus: Arc<dyn CanBus>,
hb_node_id: u8,
period: Duration,
cancel: CancellationToken,
) {
let mut tick = tokio::time::interval(period);
tick.set_missed_tick_behavior(MissedTickBehavior::Delay);
tick.tick().await;
loop {
let frame = match build_heartbeat_frame(hb_node_id, NmtState::Operational) {
Ok(f) => f,
Err(e) => {
log::error!("HB build failed (hb_node_id=0x{hb_node_id:02X}): {e}");
return;
}
};
if let Err(e) = bus.send(frame).await {
log::warn!("HB broadcast send failed: {e}");
}
tokio::select! {
_ = cancel.cancelled() => {
log::debug!("HB broadcaster cancelled");
return;
}
_ = tick.tick() => {}
}
}
}