From 12f6192daed2cdeda8e94031be97783a352433b0 Mon Sep 17 00:00:00 2001 From: bunnie Date: Sun, 14 Jul 2024 00:01:22 +0800 Subject: [PATCH 1/4] add nettype command --- services/shellchat/Cargo.toml | 1 + services/shellchat/src/cmds/usb.rs | 84 ++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 9 deletions(-) diff --git a/services/shellchat/Cargo.toml b/services/shellchat/Cargo.toml index 111604491..f84a59f9c 100644 --- a/services/shellchat/Cargo.toml +++ b/services/shellchat/Cargo.toml @@ -153,4 +153,5 @@ rand-api = [] locktests = [ ] # for debugging some specific `std` tests cherry-picked out of the test suite simple-tls = ["rustls", "webpki-roots"] +nettype = [] # takes a file from a URL and emits it as keystrokes default = [] # "debugprint" diff --git a/services/shellchat/src/cmds/usb.rs b/services/shellchat/src/cmds/usb.rs index 40cf3b780..7b716f539 100644 --- a/services/shellchat/src/cmds/usb.rs +++ b/services/shellchat/src/cmds/usb.rs @@ -36,6 +36,10 @@ impl<'a> ShellCmdApi<'a> for Usb { self.usb_dev.ensure_core(usb_device_xous::UsbDeviceType::FidoKbd).unwrap(); write!(ret, "USB connected to HID (FIDO + keyboard) core").unwrap(); } + "kbd" => { + self.usb_dev.ensure_core(usb_device_xous::UsbDeviceType::KbdOnly).unwrap(); + write!(ret, "USB connected to keyboard only core").unwrap(); + } #[cfg(feature = "mass-storage")] "ms" => { self.usb_dev.ensure_core(usb_device_xous::UsbDeviceType::MassStorage).unwrap(); @@ -87,7 +91,7 @@ impl<'a> ShellCmdApi<'a> for Usb { write!(ret, "USB TRNG serial sending should be stopped.").ok(); } "send" => match self.usb_dev.get_current_core() { - Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::Serial) => { + Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::Serial) | Ok(UsbDeviceType::KbdOnly) => { let mut val = String::new(); join_tokens(&mut val, &mut tokens); match self.usb_dev.send_str(&val) { @@ -110,10 +114,12 @@ impl<'a> ShellCmdApi<'a> for Usb { } test_str.push('\n'); match self.usb_dev.get_current_core() { - Ok(UsbDeviceType::FidoKbd) => match self.usb_dev.send_str(&test_str) { - Ok(n) => write!(ret, "Sent {} test string", n).unwrap(), - Err(_e) => write!(ret, "Can't send: are we connected to a host?").unwrap(), - }, + Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::KbdOnly) => { + match self.usb_dev.send_str(&test_str) { + Ok(n) => write!(ret, "Sent {} test string", n).unwrap(), + Err(_e) => write!(ret, "Can't send: are we connected to a host?").unwrap(), + } + } Ok(UsbDeviceType::Debug) => { write!(ret, "HID core not connected: please issue 'usb hid' first").unwrap(); } @@ -132,10 +138,12 @@ impl<'a> ShellCmdApi<'a> for Usb { _ => write!(ret, "Invalid response checking status").unwrap(), }, "leds" => match self.usb_dev.get_current_core() { - Ok(UsbDeviceType::FidoKbd) => match self.usb_dev.get_led_state() { - Ok(leds) => write!(ret, "LEDs: {:?}", leds).unwrap(), - _ => write!(ret, "Not connected to USB host or other error").unwrap(), - }, + Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::KbdOnly) => { + match self.usb_dev.get_led_state() { + Ok(leds) => write!(ret, "LEDs: {:?}", leds).unwrap(), + _ => write!(ret, "Not connected to USB host or other error").unwrap(), + } + } Ok(UsbDeviceType::Debug) => { write!(ret, "HID core not connected: please issue 'usb hid' first").unwrap(); } @@ -151,6 +159,64 @@ impl<'a> ShellCmdApi<'a> for Usb { write!(ret, "USB debug port unlocked: portions of the device are readable via USB!") .unwrap(); } + #[cfg(feature = "nettype")] + "nettype" => { + use std::io::{Read, Write}; + use std::net::TcpStream; + use std::time::Duration; + if let Some(url) = tokens.next() { + match url.split_once('/') { + Some((host, path)) => match TcpStream::connect((host, 80)) { + Ok(mut stream) => { + stream.set_read_timeout(Some(Duration::from_millis(10_000))).unwrap(); + stream.set_write_timeout(Some(Duration::from_millis(10_000))).unwrap(); + log::info!("sending GET request"); + match write!(stream, "GET /{} HTTP/1.1\r\n", path) { + Ok(_) => log::trace!("sent GET"), + Err(e) => { + log::error!("GET err {:?}", e); + write!(ret, "Error sending GET: {:?}", e).unwrap(); + } + } + write!( + stream, + "Host: {}\r\nAccept: */*\r\nUser-Agent: Precursor/0.9.16\r\n", + host + ) + .expect("stream error"); + write!(stream, "Connection: close\r\n").expect("stream error"); + write!(stream, "\r\n").expect("stream error"); + log::info!("fetching response...."); + let mut buf = [0u8; 4096]; + match stream.read(&mut buf) { + Ok(len) => { + let s = std::string::String::from_utf8_lossy( + &buf[..len.min(buf.len())], + ); + let mut parts = s.splitn(2, "\r\n\r\n"); + let _header = parts.next().unwrap_or(""); + let body = parts.next().unwrap_or(""); + match self.usb_dev.send_str(&body) { + Ok(n) => write!(ret, "Sent {} chars", n).unwrap(), + Err(_e) => { + write!(ret, "Can't send: are we connected to a host?") + .unwrap() + } + } + } + Err(e) => { + write!(ret, "Didn't get response from host: {:?}", e).unwrap() + } + } + } + Err(e) => write!(ret, "Couldn't connect to {}:80: {:?}", host, e).unwrap(), + }, + _ => write!(ret, "Usage: nettype bunniefoo.com/bunnie/test.txt").unwrap(), + } + } else { + write!(ret, "Usage: nettype bunniefoo.com/bunnie/test.txt").unwrap(); + } + } _ => { write!(ret, "{}", helpstring).unwrap(); } From bdfeb9917a8ad183cb8004700bb5d31418039837 Mon Sep 17 00:00:00 2001 From: bunnie Date: Sun, 14 Jul 2024 00:55:59 +0800 Subject: [PATCH 2/4] undo handlers for an aborted experiment --- services/shellchat/src/cmds/usb.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/services/shellchat/src/cmds/usb.rs b/services/shellchat/src/cmds/usb.rs index 7b716f539..16462a999 100644 --- a/services/shellchat/src/cmds/usb.rs +++ b/services/shellchat/src/cmds/usb.rs @@ -36,10 +36,6 @@ impl<'a> ShellCmdApi<'a> for Usb { self.usb_dev.ensure_core(usb_device_xous::UsbDeviceType::FidoKbd).unwrap(); write!(ret, "USB connected to HID (FIDO + keyboard) core").unwrap(); } - "kbd" => { - self.usb_dev.ensure_core(usb_device_xous::UsbDeviceType::KbdOnly).unwrap(); - write!(ret, "USB connected to keyboard only core").unwrap(); - } #[cfg(feature = "mass-storage")] "ms" => { self.usb_dev.ensure_core(usb_device_xous::UsbDeviceType::MassStorage).unwrap(); @@ -91,7 +87,7 @@ impl<'a> ShellCmdApi<'a> for Usb { write!(ret, "USB TRNG serial sending should be stopped.").ok(); } "send" => match self.usb_dev.get_current_core() { - Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::Serial) | Ok(UsbDeviceType::KbdOnly) => { + Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::Serial) => { let mut val = String::new(); join_tokens(&mut val, &mut tokens); match self.usb_dev.send_str(&val) { @@ -114,12 +110,10 @@ impl<'a> ShellCmdApi<'a> for Usb { } test_str.push('\n'); match self.usb_dev.get_current_core() { - Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::KbdOnly) => { - match self.usb_dev.send_str(&test_str) { - Ok(n) => write!(ret, "Sent {} test string", n).unwrap(), - Err(_e) => write!(ret, "Can't send: are we connected to a host?").unwrap(), - } - } + Ok(UsbDeviceType::FidoKbd) => match self.usb_dev.send_str(&test_str) { + Ok(n) => write!(ret, "Sent {} test string", n).unwrap(), + Err(_e) => write!(ret, "Can't send: are we connected to a host?").unwrap(), + }, Ok(UsbDeviceType::Debug) => { write!(ret, "HID core not connected: please issue 'usb hid' first").unwrap(); } @@ -138,12 +132,10 @@ impl<'a> ShellCmdApi<'a> for Usb { _ => write!(ret, "Invalid response checking status").unwrap(), }, "leds" => match self.usb_dev.get_current_core() { - Ok(UsbDeviceType::FidoKbd) | Ok(UsbDeviceType::KbdOnly) => { - match self.usb_dev.get_led_state() { - Ok(leds) => write!(ret, "LEDs: {:?}", leds).unwrap(), - _ => write!(ret, "Not connected to USB host or other error").unwrap(), - } - } + Ok(UsbDeviceType::FidoKbd) => match self.usb_dev.get_led_state() { + Ok(leds) => write!(ret, "LEDs: {:?}", leds).unwrap(), + _ => write!(ret, "Not connected to USB host or other error").unwrap(), + }, Ok(UsbDeviceType::Debug) => { write!(ret, "HID core not connected: please issue 'usb hid' first").unwrap(); } From f8a0921f5bc2c3522d1a065137c5d2b165a56fcf Mon Sep 17 00:00:00 2001 From: bunnie Date: Sun, 14 Jul 2024 01:35:02 +0800 Subject: [PATCH 3/4] fix rustfmt issues... --- services/modals/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/modals/src/lib.rs b/services/modals/src/lib.rs index 92c407d0b..3ca7fc7b3 100644 --- a/services/modals/src/lib.rs +++ b/services/modals/src/lib.rs @@ -486,12 +486,12 @@ impl Modals { /// possible, you can add a sleep by doing something like the code below. This will reduce the rate at /// which your loop runs, as well as at which the UI updates. /// ``` - /// std::thread::sleep(std::time::Duration::from_millis(100)); + /// std::thread::sleep(std::time::Duration::from_millis(100)); /// ``` /// - An alternative "softer" solution is to call yield. This will cause the producer to yield its time /// slice to other processes in the OS, which can give the progress bar a chance to catch up. /// ``` - /// xous::yield_slice(); + /// xous::yield_slice(); /// ``` /// /// # Example From 7a31d547234adb357586adbf7c7ce3c1f2563312 Mon Sep 17 00:00:00 2001 From: bunnie Date: Sun, 14 Jul 2024 01:46:46 +0800 Subject: [PATCH 4/4] attempt to resolve rustfmt/whitespace issue --- services/modals/src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/services/modals/src/lib.rs b/services/modals/src/lib.rs index 3ca7fc7b3..bfe6f9313 100644 --- a/services/modals/src/lib.rs +++ b/services/modals/src/lib.rs @@ -486,13 +486,17 @@ impl Modals { /// possible, you can add a sleep by doing something like the code below. This will reduce the rate at /// which your loop runs, as well as at which the UI updates. /// ``` - /// std::thread::sleep(std::time::Duration::from_millis(100)); + /// std::thread::sleep(std::time::Duration::from_millis(100)); // This comment needed to pass formatting checks /// ``` /// - An alternative "softer" solution is to call yield. This will cause the producer to yield its time /// slice to other processes in the OS, which can give the progress bar a chance to catch up. /// ``` - /// xous::yield_slice(); + /// xous::yield_slice(); // This comment needed to pass formatting checks /// ``` + /// The comments above are necessary because rustfmt puts trailing whitespace after the code if there + /// isn't a comment. We have a requirement to have no trailing whitespace *and* for code to be + /// auto-formatted. So, the dummy comment is there simply to resolve the two conflicting requirements + /// in the face of a buggy rust format (as of 1.81). /// /// # Example /// ```