From 95a65f981c24c0eeb2174f8f7624bad0f8e73526 Mon Sep 17 00:00:00 2001 From: Martin Brodbeck Date: Tue, 3 Oct 2023 17:35:43 +0200 Subject: [PATCH] =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 129 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 120 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 43821cb..06dd61f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,114 @@ use chrono::{DateTime, Local}; -use std::{collections::HashSet, net::UdpSocket}; +use std::{ + collections::{HashMap, HashSet}, + net::UdpSocket, +}; const MAX_CLIENTS: usize = 10; const CLIENT_TIMEOUT: u32 = 300; -#[derive(Hash, Eq, PartialEq, Debug)] +#[derive(Hash, Eq, PartialEq, Debug, Clone)] struct Client { name: String, time: DateTime, } +fn print_msg(msg: &[u8]) { + for elem in msg { + print!("{:08b} ", elem); + } + println!(""); +} + +fn strip_header(msg: &[u8]) -> Vec { + //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 { + 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<()> { let socket = UdpSocket::bind("0.0.0.0:7373")?; socket @@ -22,19 +121,31 @@ fn main() -> std::io::Result<()> { let mut buf = [0; 64]; 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 = 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) { - } 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 { - let time = Local::now(); - println!("New client: {client_addr}"); - receivers.insert(Client { - name: client_addr, - time, - }); + receivers.insert(client.clone()); // TODO: welcome + socket + .send_to(mopp(speed, b"hi").as_slice(), &client.name) + .unwrap(); } else { // TODO: reject + println!("Unknown client - Ignoring"); } } }