This commit is contained in:
Martin Brodbeck 2023-10-03 17:35:43 +02:00
parent 4d760871bd
commit 95a65f981c

View file

@ -1,15 +1,114 @@
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};
use std::{collections::HashSet, net::UdpSocket}; use std::{
collections::{HashMap, HashSet},
net::UdpSocket,
};
const MAX_CLIENTS: usize = 10; const MAX_CLIENTS: usize = 10;
const CLIENT_TIMEOUT: u32 = 300; const CLIENT_TIMEOUT: u32 = 300;
#[derive(Hash, Eq, PartialEq, Debug)] #[derive(Hash, Eq, PartialEq, Debug, Clone)]
struct Client { struct Client {
name: String, name: String,
time: DateTime<Local>, time: DateTime<Local>,
} }
fn print_msg(msg: &[u8]) {
for elem in msg {
print!("{:08b} ", elem);
}
println!("");
}
fn strip_header(msg: &[u8]) -> Vec<u8> {
//print_msg(msg);
let mut stripped = Vec::new();
stripped.push(msg[1] & 3);
stripped.append(msg[2..].to_vec().as_mut());
print_msg(&stripped);
stripped.to_owned()
}
fn mopp(speed: u8, data: &[u8]) -> Vec<u8> {
let serial = 1u8;
let morse = HashMap::from([
(b'0', "-----"),
(b'1', ".----"),
(b'2', "..---"),
(b'3', "...--"),
(b'4', "....-"),
(b'5', "....."),
(b'6', "-...."),
(b'7', "--..."),
(b'8', "---.."),
(b'9', "----."),
(b'a', ".-"),
(b'b', "-..."),
(b'c', "-.-."),
(b'd', "-.."),
(b'e', "."),
(b'f', "..-."),
(b'g', "--."),
(b'h', "...."),
(b'i', ".."),
(b'j', ".---"),
(b'k', "-.-"),
(b'l', ".-.."),
(b'm', "--"),
(b'n', "-."),
(b'o', "---"),
(b'p', ".--."),
(b'q', "--.-"),
(b'r', ".-."),
(b's', "..."),
(b't', "-"),
(b'u', "..-"),
(b'v', "...-"),
(b'w', ".--"),
(b'x', "-..-"),
(b'y', "-.--"),
(b'z', "--.."),
(b'=', "-...-"),
(b'/', "-..-."),
(b'+', ".-.-."),
(b'-', "-....-"),
(b'.', ".-.-.-"),
(b',', "--..--"),
(b'?', "..--.."),
(b':', "---..."),
(b'!', "-.-.--"),
(b'\'', ".----."),
]);
let mut m = "01".to_owned();
m.push_str(&format!("{:06b}", serial));
m.push_str(&format!("{:06b}", speed));
for &char in data {
if char == b' ' {
continue;
}
for b in morse.get(&char).unwrap().as_bytes() {
if *b == b'.' {
m.push_str("01");
} else {
m.push_str("10");
}
}
m.push_str("00"); // EOC
}
m.push_str("11"); // EOW
println!("MOPP: {1:0$}", (8 as f32 * (m.len() as f32 / 8 as f32).ceil()) as usize, m);
m.as_bytes().to_owned()
}
fn broadcast(socket: &UdpSocket, client: &Client, data: &[u8]) {}
fn main() -> std::io::Result<()> { fn main() -> std::io::Result<()> {
let socket = UdpSocket::bind("0.0.0.0:7373")?; let socket = UdpSocket::bind("0.0.0.0:7373")?;
socket socket
@ -22,19 +121,31 @@ fn main() -> std::io::Result<()> {
let mut buf = [0; 64]; let mut buf = [0; 64];
let (number_of_bytes, src_addr) = socket.recv_from(&mut buf).expect("Didn't receive data"); let (number_of_bytes, src_addr) = socket.recv_from(&mut buf).expect("Didn't receive data");
let client_addr = src_addr.to_string(); let client_addr = src_addr.to_string();
let client = Client {
name: client_addr.clone(),
time: Local::now(),
};
let speed = buf[1] >> 2;
println!("Speed: {speed} WPM");
let data = &buf[0..number_of_bytes];
println!("Data: {:?}", strip_header(data));
println!("Repl: {:?}", strip_header(mopp(speed, b"hi").as_slice()));
if receivers.iter().any(|x| x.name == client_addr) { if receivers.iter().any(|x| x.name == client_addr) {
} else { println!("Client already known.");
} else if strip_header(data) == strip_header(mopp(speed, b"hi").as_slice()) {
println!("Welcome!");
if receivers.len() < MAX_CLIENTS { if receivers.len() < MAX_CLIENTS {
let time = Local::now(); receivers.insert(client.clone());
println!("New client: {client_addr}");
receivers.insert(Client {
name: client_addr,
time,
});
// TODO: welcome // TODO: welcome
socket
.send_to(mopp(speed, b"hi").as_slice(), &client.name)
.unwrap();
} else { } else {
// TODO: reject // TODO: reject
println!("Unknown client - Ignoring");
} }
} }
} }