diff --git a/Cargo.lock b/Cargo.lock index 81122ce..ceb23e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -596,7 +596,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -809,6 +809,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctrlc-async" +version = "3.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598e9d68e769aa1283460a3b0ec0d049ccfb6170277aea37089fa3f58fd721a1" +dependencies = [ + "nix 0.23.2", + "tokio", + "winapi", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -1671,9 +1682,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libloading" @@ -1763,6 +1774,15 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "memsec" version = "0.6.3" @@ -1848,6 +1868,19 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "nix" version = "0.27.1" @@ -2114,6 +2147,7 @@ dependencies = [ "chacha20poly1305", "chrono", "clap", + "ctrlc-async", "futures", "lazy_static", "ncurses", @@ -3781,7 +3815,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -3799,7 +3833,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -3819,17 +3853,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -3840,9 +3875,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -3852,9 +3887,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -3864,9 +3899,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -3876,9 +3917,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -3888,9 +3929,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -3900,9 +3941,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -3912,9 +3953,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -4262,7 +4303,7 @@ checksum = "264c2f84adb7cafaf19ca1e4f184e2a1df3477b5b239ce116ff4ae0ad1e01700" dependencies = [ "async-trait", "futures", - "nix", + "nix 0.27.1", "tokio", "tokio-util", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 17d0846..22dd3ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,3 +30,4 @@ async-trait = "0.1.81" async-recursion = "1.1.1" sha2 = "0.10.8" once_cell = "1.19.0" +ctrlc-async = "3.2.2" diff --git a/src/client.rs b/src/client.rs index 4a8ddf0..5c59940 100644 --- a/src/client.rs +++ b/src/client.rs @@ -69,12 +69,9 @@ struct Cli { } // Create a global instance of WindowManager -static WINDOW_MANAGER: Lazy = Lazy::new(|| { - let manager = WindowManager::init(2); - manager -}); +static WINDOW_MANAGER: Lazy = Lazy::new(|| WindowManager::init(2)); -fn test_cb_chat(public_key: &str, message: &str) { +fn cb_chat(public_key: &str, message: &str) { let pub_key_decoded = match base64::decode(public_key) { Err(_) => { return; @@ -97,7 +94,7 @@ fn test_cb_chat(public_key: &str, message: &str) { } } -fn test_cb_chat_input( +fn cb_chat_input( _pub_key_fingerprint: &str, session_id: &str, topic_out: &str, @@ -106,15 +103,23 @@ fn test_cb_chat_input( let input = WINDOW_MANAGER.getch(1, &prompt); let input = input.trim(); let topic = Topic::Internal.as_str(); - let msg = SessionMessage::new_internal( + let mut msg = SessionMessage::new_internal( session_id.to_string(), input.to_string(), topic_out.to_string(), ); - (topic.to_string(), msg.serialize().unwrap()) + if input == "!exit" { + // Special message that terminate the session + msg = SessionMessage::new_internal( + "internal".to_owned(), + "terminate".to_owned(), + topic.to_string(), + ); + } + return (topic.to_string(), msg.serialize().unwrap()); } -fn test_cb_discovered(public_key: &str) -> bool { +fn cb_discovered(public_key: &str) -> bool { let pub_key_decoded = match base64::decode(public_key) { Err(_) => { return false; @@ -137,7 +142,11 @@ fn test_cb_discovered(public_key: &str) -> bool { } } -fn test_cb_initialized(public_key: &str) -> bool { +fn cb_terminate() { + WINDOW_MANAGER.cleanup(); +} + +fn cb_initialized(public_key: &str) -> bool { let pub_key_decoded = match base64::decode(public_key) { Err(_) => { return false; @@ -160,6 +169,7 @@ fn test_cb_initialized(public_key: &str) -> bool { ); let input = WINDOW_MANAGER.getch(1, ">> "); if input.to_lowercase().starts_with('y') { + WINDOW_MANAGER.printw(1, "-- Chat initialized, exit by typing '!exit'"); return true; } else { WINDOW_MANAGER.printw(1, "-- chat not accepted"); @@ -173,6 +183,18 @@ fn test_cb_initialized(public_key: &str) -> bool { } } +fn terminate(tx: mpsc::Sender<(String, String)>) { + tokio::spawn(async move { + let topic = Topic::Internal.as_str(); + let msg = SessionMessage::new_internal( + "internal".to_owned(), + "terminate".to_owned(), + topic.to_string(), + ); + tx.send((topic.to_string(), msg.to_string())).await; + }); +} + #[tokio::main] async fn main() { let cli = Cli::parse(); @@ -255,15 +277,18 @@ async fn main() { }; } - session.register_callback_chat(Box::new(test_cb_chat)).await; + session.register_callback_chat(Box::new(cb_chat)).await; session - .register_callback_initialized(Box::new(test_cb_initialized)) + .register_callback_initialized(Box::new(cb_initialized)) .await; session - .register_callback_discovered(Box::new(test_cb_discovered)) + .register_callback_discovered(Box::new(cb_discovered)) .await; session - .register_callback_chat_input(Box::new(test_cb_chat_input)) + .register_callback_chat_input(Box::new(cb_chat_input)) + .await; + session + .register_callback_terminate(Box::new(cb_terminate)) .await; let mut i = 0; @@ -358,5 +383,12 @@ async fn main() { WINDOW_MANAGER.printw(1, &format!("-- Awaiting connection requests from peers...")); } + let tx = session.get_tx().await; + ctrlc_async::set_handler(move || { + let tx_clone = tx.clone(); + terminate(tx_clone); + }) + .expect("Error setting Ctrl-C handler"); + session.serve().await; } diff --git a/src/session/mod.rs b/src/session/mod.rs index b4cc2f0..10f0d95 100644 --- a/src/session/mod.rs +++ b/src/session/mod.rs @@ -76,6 +76,7 @@ where pub callbacks_chat: Arc>>>, pub callbacks_discovered: Arc bool + Send>>>>, pub callbacks_initialized: Arc bool + Send>>>>, + pub callbacks_terminate: Arc>>>, pub callbacks_chat_input: Arc (String, String) + Send + Sync>>>>, @@ -93,6 +94,7 @@ impl<'a> Session> { callbacks_chat: Arc::new(Mutex::new(Vec::new())), callbacks_discovered: Arc::new(Mutex::new(Vec::new())), callbacks_initialized: Arc::new(Mutex::new(Vec::new())), + callbacks_terminate: Arc::new(Mutex::new(Vec::new())), callbacks_chat_input: Arc::new(Mutex::new(Vec::new())), middleware_config, } @@ -108,6 +110,10 @@ impl<'a> Session> { } } + pub async fn get_tx(&self) -> mpsc::Sender<(String, String)> { + self.tx.clone() + } + pub async fn encrypt_msg( &mut self, session_id: &str, @@ -171,6 +177,10 @@ impl<'a> Session> { let mut callbacks = self.callbacks_initialized.lock().await; callbacks.push(callback); } + pub async fn register_callback_terminate(&self, callback: Box) { + let mut callbacks = self.callbacks_terminate.lock().await; + callbacks.push(callback); + } pub async fn register_callback_chat_input( &self, callback: Box (String, String) + Send + Sync>, @@ -185,6 +195,12 @@ impl<'a> Session> { callback(arg1, arg2); } } + async fn call_callbacks_terminate(&self) { + let callbacks = self.callbacks_terminate.lock().await; + for callback in callbacks.iter() { + callback(); + } + } async fn call_callbacks_initialized(&self, arg1: &str) -> bool { let callbacks = self.callbacks_initialized.lock().await; for callback in callbacks.iter() { @@ -346,10 +362,19 @@ impl<'a> Session> { let t = topic.clone(); let zc = self.middleware_config.clone(); + let terminate_callbacks = self.callbacks_terminate.clone(); let h = tokio::spawn(async move { let zenoh_config = Config::from_file(zc).unwrap(); - let zenoh_session = - Arc::new(Mutex::new(zenoh::open(zenoh_config).res().await.unwrap())); + let zenoh_session = zenoh::open(zenoh_config.clone()).res().await; + + if zenoh_session.is_err() { + let callbacks = terminate_callbacks.lock().await; + for callback in callbacks.iter() { + callback(); + } + return false; + } + let zenoh_session = Arc::new(Mutex::new(zenoh_session.unwrap())); let handler = ZenohHandler::new(zenoh_session); let mut keep_alive = true; while keep_alive { @@ -561,16 +586,6 @@ impl<'a> Session> { let not_ignore = self.call_callbacks_discovered(&pub_key).await; if not_ignore { pub_keys.push(disc_msg.pub_key); - /*if let Ok(session_id) = - self.initialize_session_zenoh(pub_key.clone()).await - { - self.chat( - session_id.clone(), - &discovered_pub_key_fingerprint, - false, - ) - .await; - }*/ } } } @@ -656,6 +671,11 @@ impl<'a> Session> { match message.message { Internal(msg) => { if topic == Topic::Internal.as_str() { + if message.session_id == "internal" && msg.message == "terminate" { + self.call_callbacks_terminate().await; + exit(0); + } + let session_id = message.session_id.clone(); let message = Message { message: MessageData::Chat(ChatMsg { diff --git a/src/terminal.rs b/src/terminal.rs index 8e43276..da5594c 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -68,11 +68,11 @@ impl WindowManager { // Move the cursor to just inside the box, 1 line down, 1 column in wmove(*subwin, getcury(*subwin), 1); - self.printw(window_number, prompt); wmove(*subwin, getcury(*subwin), (prompt.len() + 1) as i32); + self.printw(window_number, prompt); wrefresh(*subwin); - let mut input = String::new(); + let mut input = Vec::::new(); nocbreak(); echo(); curs_set(CURSOR_VISIBILITY::CURSOR_VISIBLE); @@ -86,14 +86,14 @@ impl WindowManager { wdelch(*subwin); } } else { - input.push(char::from_u32(ch as u32).unwrap()); + input.push(ch as u8); } wrefresh(*subwin); ch = wgetch(*subwin); } // Exit condition (optional) - return input; + return std::str::from_utf8(input.as_slice()).unwrap().to_string(); } } else { println!("Window number {} does not exist.", window_number); diff --git a/zenoh/config-ricardicus-digitalocean-zenohd.json5 b/zenoh/config-ricardicus-digitalocean-zenohd.json5 new file mode 100644 index 0000000..2bcd262 --- /dev/null +++ b/zenoh/config-ricardicus-digitalocean-zenohd.json5 @@ -0,0 +1,6 @@ +{ + "mode": "client", + "connect": { + "endpoints": ["tcp/174.138.5.172:443"] + } +}