From f3b3ecd5270a9870052b07706e44c8d53e6fb56d Mon Sep 17 00:00:00 2001 From: Richard Wendel Date: Fri, 22 Jan 2021 22:40:29 -0500 Subject: [PATCH 1/3] Support new networking setup --- src/common.rs | 8 +++++--- src/main.rs | 4 ++-- src/shell_executor.rs | 34 ++++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/common.rs b/src/common.rs index ec2547e..940c703 100644 --- a/src/common.rs +++ b/src/common.rs @@ -100,9 +100,10 @@ pub fn color_from_string(s: &str) -> Result bool { - let response = ureq::get("http://clients3.google.com/generate_204").call(); - info!("Checking connection, status is {:?}", response.status()); - response.status() == 204 + true + //let response = ureq::get("http://clients3.google.com/generate_204").call(); + //info!("Checking connection, status is {:?}", response.status()); + //response.status() == 204 } pub fn get_ip_address() -> Option { @@ -110,6 +111,7 @@ pub fn get_ip_address() -> Option { Ok(output) if output.status.success() => { let string = std::str::from_utf8(&output.stdout).expect("Failed to parse hostname"); let mut ips = string.split(" "); + info!("hostname we got: {}", string); match ips.next() { Some(ip) => Some(ip.parse().unwrap()), None => None, diff --git a/src/main.rs b/src/main.rs index 30eb621..e2cf329 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,8 +90,8 @@ fn main() -> Result<(), Box> { .unwrap(); if matches.is_present("wait") { - info!("Waiting 90 seconds"); - sleep(Duration::from_secs(90)); + info!("Waiting 5 seconds"); + sleep(Duration::from_secs(5)); } else { info!("Starting up now"); } diff --git a/src/shell_executor.rs b/src/shell_executor.rs index 013c5c0..2eb92c6 100644 --- a/src/shell_executor.rs +++ b/src/shell_executor.rs @@ -6,6 +6,7 @@ use std::sync::mpsc; use std::thread; use std::time::Duration; extern crate system_shutdown; +use std::thread::sleep; use system_shutdown::reboot; use users::{get_current_uid, get_user_by_uid}; @@ -39,11 +40,12 @@ impl CommandExecutor { self.execute( "sudo", &[ - "ip", - "link", - "set", - interface, - if enable { "up" } else { "down" }, + "echo" + //"ip", + //"link", + //"set", + //interface, + //if enable { "up" } else { "down" }, ], ) .expect("Failed to run set interfaces") @@ -78,19 +80,23 @@ network={{ info!("Attempting to connect with supplicant:\n{}\n", supplicant); fs::write("/etc/wpa_supplicant/wpa_supplicant.conf", supplicant)?; - let daemon_reload = self.execute("systemctl", &["daemon-reload"])?; - if !daemon_reload.success() { - error!("Failed to systemctl daemon reload"); - return Ok(daemon_reload); - } + //let daemon_reload = self.execute("systemctl", &["daemon-reload"])?; + //if !daemon_reload.success() { + // error!("Failed to systemctl daemon reload"); + // return Ok(daemon_reload); + //} + + //self.execute("sudo", &["dhclient", "-r", "wlan0"])?; - self.execute("sudo", &["dhclient", "-r", "wlan0"])?; + self.set_interface("wlan0", true); - self.execute("sudo", &["ifdown", "wlan0"])?; + let output = self.execute("sudo", &["systemctl", "restart", "wpa_supplicant.service"])?; - self.execute("sudo", &["ifup", "wlan0"])?; + info!("Sleeping for a little bit to allow wpa to catch up after being restarted."); + sleep(Duration::from_secs(15)); + info!("Done sleeping"); - let output = self.execute("sudo", &["dhclient", "-v", "wlan0"])?; + //let output = self.execute("sudo", &["dhclient", "-v", "wlan0"])?; Ok(output) } From 1258b1ac694178a57adeed72c0b7757c5894e94f Mon Sep 17 00:00:00 2001 From: Richard Wendel Date: Sat, 23 Jan 2021 16:23:47 -0500 Subject: [PATCH 2/3] Add Readme --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1e14c91 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# Mark should add a readme here + +TODO + +## Raspberry Pi OS configuration + +This setup focuses on getting the network configured properly. +Assuming the Scoreboard hardware is pluged in correctly, the scoreboard app +built from this repo should "just work". + +I'll need to redo these steps again on a clean image to verify, but this is close enough. + +- I used the January 11th 2021 release of the Raspberry Pi OS Lite +- Modify `/boot/config.txt` to contain `enable_uart=1` if you want to use the serial port console. +- enable ssh and rsync + - `sudo systemctl enable ssh` + - `sudo systemctl start ssh` + - `sudo systemctl enable rsync` + - `sudo systemctl start rsync` +- make the scoreboard directory & copy over config files + - `mkdir /var/lib/scoreboard` + - `chown pi /var/lib/scorboard` + - copy over `secrets.txt`, `scoreboard_settings.json`, and `environment.conf`. + - `environment.conf` contains two lines `RUST_LOG="debug"` and `RUST_BACKTRACE=full` +- run the installer in this repo to copy over the scoreboard binary +- `ln -s /var/lib/scoreboard/scoreboard /usr/local/bin/scoreboard` +- Unblock built-in wlan `rfkill unblock wlan` +- Follow this guide: [https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md](https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md) + - Skip the Enable routing and IP masquerading section + - Substitute your own IP addresses for the Access point + - Use wlan1 as access point + - Use wlan0 as internet connection +- Modify the wpa systemctl service such that wpa_supplicant will actually get wlan0 to connect to the internet. + - Change the exec line to specifiy the drivers, the interface, and the wpa_supplicant.conf file to use + - `/etc/systemd/system/dbus-fi.w1.wpa_supplicant1.service` + - `ExecStart=/sbin/wpa_supplicant -u -D wext -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -s -O /run/wpa_supplicant` From b30aea63c12105dd899ac2223f4f06619b7fa1b9 Mon Sep 17 00:00:00 2001 From: Richard Wendel Date: Sun, 24 Jan 2021 13:15:10 -0500 Subject: [PATCH 3/3] Kill the carrier, not the interface --- src/shell_executor.rs | 56 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/src/shell_executor.rs b/src/shell_executor.rs index 2eb92c6..8500bc7 100644 --- a/src/shell_executor.rs +++ b/src/shell_executor.rs @@ -36,19 +36,29 @@ impl CommandExecutor { self.matrix_sender.send(response).unwrap(); } - fn set_interface(self: &Self, interface: &str, enable: bool) -> ExitStatus { + // DHCPCD configures the `wlan0` or `wlan1` interfaces + // See /etc/dhcpcd.conf + // However, DHCPCD requires a "carrier" to actually use the interface for anything + // WPA_SUPPLICANT is for the usual wifi where you are a client connecting to another access point to get internet access + // HOSTAPD is for when you are hosting the wifi access point + fn carrier_control(self: &Self, enable: bool, service: &str) -> ExitStatus { self.execute( "sudo", &[ - "echo" - //"ip", - //"link", - //"set", - //interface, - //if enable { "up" } else { "down" }, + "systemctl", + if enable { "restart" } else { "stop" }, + service, ], ) - .expect("Failed to run set interfaces") + .expect("Failed to run systemctl on service") + } + + fn set_wifi(self: &Self, enable: bool) -> ExitStatus { + self.carrier_control(enable, "wpa_supplicant.service") + } + + fn set_access_point(self: &Self, enable: bool) -> ExitStatus { + self.carrier_control(enable, "hostapd.service") } fn execute(self: &Self, command: &str, args: &[&str]) -> io::Result { @@ -80,23 +90,11 @@ network={{ info!("Attempting to connect with supplicant:\n{}\n", supplicant); fs::write("/etc/wpa_supplicant/wpa_supplicant.conf", supplicant)?; - //let daemon_reload = self.execute("systemctl", &["daemon-reload"])?; - //if !daemon_reload.success() { - // error!("Failed to systemctl daemon reload"); - // return Ok(daemon_reload); - //} - - //self.execute("sudo", &["dhclient", "-r", "wlan0"])?; - - self.set_interface("wlan0", true); - - let output = self.execute("sudo", &["systemctl", "restart", "wpa_supplicant.service"])?; - - info!("Sleeping for a little bit to allow wpa to catch up after being restarted."); - sleep(Duration::from_secs(15)); - info!("Done sleeping"); + let output = self.set_wifi(true); - //let output = self.execute("sudo", &["dhclient", "-v", "wlan0"])?; + info!("Sleeping to allow wpa_supplicant to catch up after being restarted"); + sleep(Duration::from_secs(10)); + info!("Done waiting for wpa_supplicant to catch up"); Ok(output) } @@ -127,7 +125,7 @@ network={{ from_webserver, } => { // Enable wifi hotspot - let status = self.set_interface("wlan1", true); + let status = self.set_access_point(true); if status.success() { info!("Successfully enabled hotspot"); } else { @@ -142,7 +140,7 @@ network={{ thread::sleep(Duration::from_secs(1)); info!("Resetting wifi"); // Just disable wlan0 - let status = self.set_interface("wlan0", false); + let status = self.set_wifi(false); if status.success() { info!("Successfully disabled primary nic"); } else { @@ -158,7 +156,7 @@ network={{ } } common::ShellCommand::SetHotspot(on) => { - let status = self.set_interface("wlan1", on); + let status = self.set_access_point(on); if status.success() { info!("Successfully set hotspot {}", on); } else { @@ -190,7 +188,7 @@ network={{ if success { // If we've successfully connected, disable the hotspot - let hotspot_result = self.set_interface("wlan1", false); + let hotspot_result = self.set_access_point(false); if hotspot_result.success() { info!("Successfully disabled hotspot"); } else { @@ -206,7 +204,7 @@ network={{ } if !success { - self.set_interface("wlan1", true); + self.set_access_point(true); } self.send_matrix_response(common::MatrixCommand::FinishedWifiConnection(