use std::io; use log::{error, info, trace, warn}; use domo_proto::commands::node_management::NodeManagementCommand; use domo_proto::identifier::Identifier; use domo_proto::packet::{ToPacket}; use domo_proto::packet::packet_data::PacketData; use crate::{CONFIG, prelude}; use crate::app::master::Devices; use crate::config::node::NodeType; use crate::connection::server::Server; pub mod master; impl NodeType { pub async fn start(self) -> io::Result<()> { match self { NodeType::Master { bind } => { let mut server = Server::new( bind, Some( Identifier::from( hex::decode(CONFIG.with_borrow(|c| c.node.device_id.clone())) .map_err(|_| io::Error::new(io::ErrorKind::InvalidInput, "could not parse hex"))? ) ), ).await?; info!("Started server at {}", server.sock().local_addr()?); let mut devices = Devices::new(); { std::fs::write("./register_packet", Into::>::into(NodeManagementCommand::RegisterNode { device_id: Identifier::from(0x000000AA) }.to_packet( Identifier::random(), server.device_id(), Identifier::random(), Identifier::default(), )))?; std::fs::write("./ping_packet", Into::>::into(NodeManagementCommand::Ping.to_packet( Identifier::from(0x000000AA), server.device_id(), Identifier::random(), Identifier::default(), )))?; } loop { match server.recv_packet().await { (Ok(p), Some(s)) => { if devices.get_device(p.src).is_none() { if let PacketData::NodeManagement(NodeManagementCommand::RegisterNode { device_id }) = p.data { let device_id = devices.add_device_auto(s, Some(device_id)); let _ = server.send(s, NodeManagementCommand::RegisterNode { device_id }.to_packet( server.device_id(), device_id, Identifier::random(), p.packet_id )).await; } else { warn!("{s} is unregistered and tried to send a packet {p:#?}."); let _ = server.send(s, prelude::quick_err::errc_not_registered( server.device_id(), p.src, p.packet_id )).await; continue; } } match p.data { PacketData::NodeManagement(NodeManagementCommand::Ping) => { trace!("ping from: [{s}->{}]", p.src); let _ = server.send(s, NodeManagementCommand::Ping.to_packet( server.device_id(), p.src, Identifier::random(), p.packet_id, )).await; } PacketData::NodeManagement(NodeManagementCommand::RegisterNode { .. }) => (), _ => warn!("dropped packet") } } (Err(e), Some(source)) => { error!("{source} sent intelligible data: {e}"); let device_id = server.device_id(); if let Err(e) = server.send(source, prelude::quick_err::net_broken_packet( device_id, Identifier::random(), ), ).await { error!("could not send error packet: {e}"); } } _ => warn!("dropped packet") } } } NodeType::Bridge { .. } => {} NodeType::Subnet { .. } => {} } Ok(()) } }