feat: new stuff
This commit is contained in:
parent
3eece7ecd9
commit
f88706bac8
20 changed files with 232 additions and 77 deletions
|
@ -1,5 +1,5 @@
|
|||
[node.type.master]
|
||||
bind = "127.0.0.1:4480"
|
||||
bind = "0.0.0.0:4480"
|
||||
|
||||
[node]
|
||||
device_id = "ffffffff"
|
||||
|
|
BIN
domo_node/ping_packet
Normal file
BIN
domo_node/ping_packet
Normal file
Binary file not shown.
BIN
domo_node/register_packet
Normal file
BIN
domo_node/register_packet
Normal file
Binary file not shown.
72
domo_node/src/app/master.rs
Normal file
72
domo_node/src/app/master.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
use log::{info, trace};
|
||||
use domo_proto::data_types::DataType;
|
||||
use domo_proto::identifier::Identifier;
|
||||
|
||||
pub struct Device {
|
||||
/// Device identifier
|
||||
pub device_id: Identifier,
|
||||
/// Device socket address
|
||||
pub socket_addr: SocketAddr,
|
||||
/// List of properties and last state.
|
||||
pub properties: HashMap<String, DataType>
|
||||
}
|
||||
|
||||
pub struct Devices {
|
||||
devices: HashMap<Identifier, Device>
|
||||
}
|
||||
|
||||
impl Devices {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
devices: HashMap::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_device_random(&mut self, socket_addr: SocketAddr) -> Identifier {
|
||||
let random_id = loop {
|
||||
// TODO: random should avoid 0xFFFF----
|
||||
let id = Identifier::random();
|
||||
trace!("checking if id is taken: {}", id);
|
||||
if !self.devices.contains_key(&id) { break id; }
|
||||
};
|
||||
self.devices.insert(random_id, Device {
|
||||
device_id: random_id,
|
||||
socket_addr,
|
||||
properties: HashMap::new()
|
||||
});
|
||||
info!("Registered new device: {}", random_id);
|
||||
random_id
|
||||
}
|
||||
|
||||
pub fn add_device(&mut self, socket_addr: SocketAddr, identifier: Identifier) -> Identifier {
|
||||
self.devices.insert(identifier, Device {
|
||||
device_id: identifier,
|
||||
socket_addr,
|
||||
properties: HashMap::new()
|
||||
});
|
||||
identifier
|
||||
}
|
||||
|
||||
pub fn add_device_auto(&mut self, socket_addr: SocketAddr, identifier: Option<Identifier>) -> Identifier {
|
||||
let identifier = if identifier == Some(Identifier::default()) {
|
||||
None
|
||||
} else {
|
||||
identifier
|
||||
};
|
||||
if let Some(identifier) = identifier {
|
||||
match (identifier, self.devices.contains_key(&identifier)) {
|
||||
(identifier, false) => self.add_device(socket_addr, identifier),
|
||||
_ => self.add_device_random(socket_addr)
|
||||
}
|
||||
} else {
|
||||
self.add_device_random(socket_addr)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_device(&self, identifier: Identifier) -> Option<&Device> {
|
||||
self.devices.get(&identifier)
|
||||
}
|
||||
}
|
|
@ -1,20 +1,21 @@
|
|||
use std::io;
|
||||
use log::{error, trace, warn};
|
||||
use tokio::sync::mpsc::channel;
|
||||
use log::{error, info, trace, warn};
|
||||
use domo_proto::commands::node_management::NodeManagementCommand;
|
||||
use domo_proto::identifier::Identifier;
|
||||
use domo_proto::packet::{Packet, ToPacket};
|
||||
use domo_proto::packet::{ToPacket};
|
||||
use domo_proto::packet::packet_data::PacketData;
|
||||
use domo_proto::packet::raw_packet::RawPacket;
|
||||
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 server = Server::new(
|
||||
let mut server = Server::new(
|
||||
bind,
|
||||
Some(
|
||||
Identifier::from(
|
||||
|
@ -24,24 +25,50 @@ impl NodeType {
|
|||
),
|
||||
).await?;
|
||||
|
||||
info!("Started server at {}", server.sock().local_addr()?);
|
||||
|
||||
let mut devices = Devices::new();
|
||||
|
||||
{
|
||||
let p = NodeManagementCommand::Ping.to_packet(
|
||||
std::fs::write("./register_packet", Into::<Vec<u8>>::into(NodeManagementCommand::RegisterNode {
|
||||
device_id: Identifier::from(0x000000AA)
|
||||
}.to_packet(
|
||||
Identifier::random(),
|
||||
server.device_id(),
|
||||
Identifier::random(),
|
||||
Identifier::default(),
|
||||
);
|
||||
std::fs::write("./packet", Into::<Vec<u8>>::into(p))?;
|
||||
)))?;
|
||||
std::fs::write("./ping_packet", Into::<Vec<u8>>::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 p.dest != server.device_id() {
|
||||
if let Some(d) = server.devices().get(&p.dest) {
|
||||
let _ = &server.send(d.socket_addr, p).await;
|
||||
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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
match p.data {
|
||||
PacketData::NodeManagement(NodeManagementCommand::Ping) => {
|
||||
|
@ -53,7 +80,7 @@ impl NodeType {
|
|||
p.packet_id,
|
||||
)).await;
|
||||
}
|
||||
_ => {}
|
||||
_ => warn!("dropped packet")
|
||||
}
|
||||
}
|
||||
(Err(e), Some(source)) => {
|
|
@ -5,20 +5,15 @@ use std::net::SocketAddr;
|
|||
use std::io;
|
||||
use domo_proto::packet::{FULL_PACKET_SIZE, Packet};
|
||||
use std::io::ErrorKind;
|
||||
use log::error;
|
||||
use log::{error, trace};
|
||||
use domo_proto::data_types::DataType;
|
||||
use domo_proto::packet::raw_packet::RawPacket;
|
||||
|
||||
pub struct Device {
|
||||
/// Device identifier
|
||||
pub device_id: Identifier,
|
||||
/// Device socket address
|
||||
pub socket_addr: SocketAddr,
|
||||
}
|
||||
|
||||
|
||||
pub struct Server {
|
||||
sock: UdpSocket,
|
||||
device_id: Identifier,
|
||||
devices: HashMap<Identifier, Device>
|
||||
}
|
||||
|
||||
impl Server {
|
||||
|
@ -26,7 +21,6 @@ impl Server {
|
|||
Ok(Self {
|
||||
sock: UdpSocket::bind(socket_addr).await?,
|
||||
device_id: device_id.unwrap_or(Identifier::random()),
|
||||
devices: HashMap::new()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -38,6 +32,8 @@ impl Server {
|
|||
Err(e) => return (Err(e), None)
|
||||
};
|
||||
|
||||
trace!("received: {} bytes from {}", size, socket_addr);
|
||||
|
||||
(
|
||||
Packet::try_from(buf[..size].to_vec()),
|
||||
Some(socket_addr)
|
||||
|
@ -59,8 +55,4 @@ impl Server {
|
|||
pub fn sock(&self) -> &UdpSocket {
|
||||
&self.sock
|
||||
}
|
||||
|
||||
pub fn devices(&self) -> &HashMap<Identifier, Device> {
|
||||
&self.devices
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,16 @@ pub mod quick_err {
|
|||
reply_to
|
||||
)
|
||||
}
|
||||
|
||||
pub fn errc_not_registered(src: Identifier, dest: Identifier, reply_to: Identifier) -> Packet {
|
||||
NodeManagementCommand::Error {
|
||||
error_code: NodeManagementError::errc_not_registered.into(),
|
||||
metadata: "this node is not registered".to_string().into_bytes()
|
||||
}.to_packet(
|
||||
src,
|
||||
dest,
|
||||
Identifier::random(),
|
||||
reply_to
|
||||
)
|
||||
}
|
||||
}
|
36
domo_node/test.py
Normal file
36
domo_node/test.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
import socket
|
||||
import sys
|
||||
|
||||
# Create a UDP socket
|
||||
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
|
||||
def send_file_contents(filename):
|
||||
try:
|
||||
print(f"reading {filename}...")
|
||||
with open(filename, 'rb') as file:
|
||||
file_contents = file.read()
|
||||
except FileNotFoundError:
|
||||
print(f"File '{filename}' not found.")
|
||||
return
|
||||
|
||||
print(f"sending content len: {len(file_contents)}...")
|
||||
# Send the file contents to the UDP socket
|
||||
udp_socket.sendto(file_contents, ('0.0.0.0', 4480))
|
||||
|
||||
print("waiting for response...")
|
||||
# Receive and display the response
|
||||
response, server_address = udp_socket.recvfrom(1024)
|
||||
print(f"Received response from {server_address}:")
|
||||
print(response.hex())
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
while True:
|
||||
filename = input("Enter a file name (or 'exit' to quit): ")
|
||||
if filename == 'exit':
|
||||
break
|
||||
send_file_contents(filename)
|
||||
except KeyboardInterrupt:
|
||||
print("\nExiting the program.")
|
||||
finally:
|
||||
udp_socket.close()
|
Loading…
Add table
Add a link
Reference in a new issue