From 1837e719b697db9482e228b8fe6c761f4e09ae43 Mon Sep 17 00:00:00 2001 From: Aiden McClelland <3732071+dr-bonez@users.noreply.github.com> Date: Tue, 15 Feb 2022 10:27:25 -0700 Subject: [PATCH] fix wifi for raspios (#1207) * Wip: Fix most of the wifi and 80% of initialization.sh * fix wifi * reorganize code Co-authored-by: J M --- backend/src/net/wifi.rs | 112 ++++++++++++++++++++++------------------ build/initialization.sh | 13 +++-- build/make-image.sh | 1 + 3 files changed, 71 insertions(+), 55 deletions(-) diff --git a/backend/src/net/wifi.rs b/backend/src/net/wifi.rs index e539973c7..3fd4f7948 100644 --- a/backend/src/net/wifi.rs +++ b/backend/src/net/wifi.rs @@ -105,7 +105,7 @@ pub async fn connect(#[context] ctx: RpcContext, #[arg] ssid: String) -> Result< let current = wpa_supplicant.get_current_network().await?; drop(wpa_supplicant); let mut wpa_supplicant = wifi_manager.write().await; - let connected = wpa_supplicant.select_network(&mut db, &ssid).await?; + let connected = wpa_supplicant.select_network(&mut db, ssid).await?; if connected { tracing::info!("Successfully connected to WiFi: '{}'", ssid.0); } else { @@ -205,13 +205,13 @@ fn display_wifi_info(info: WiFiInfo, matches: &ArgMatches<'_>) { &info .connected .as_ref() - .map_or("[N/A]".to_owned(), |c| format!("{}", c.0)), + .map_or("[N/A]".to_owned(), |c| c.0.clone()), &info .connected .as_ref() .and_then(|x| info.ssids.get(x)) .map_or("[N/A]".to_owned(), |ss| format!("{}", ss.0)), - &format!("{}", info.country.alpha2()), + &info.country.alpha2(), &format!("{}", info.ethernet) ]); table_global.print_tty(false); @@ -244,7 +244,7 @@ fn display_wifi_info(info: WiFiInfo, matches: &ArgMatches<'_>) { table_global.add_row(row![ &table_info.ssid.0, &format!("{}", table_info.strength.0), - &format!("{}", table_info.security.join(" ")) + &table_info.security.join(" ") ]); } @@ -268,7 +268,7 @@ fn display_wifi_list(info: Vec, matches: &ArgMatches<'_>) { table_global.add_row(row![ &table_info.ssid.0, &format!("{}", table_info.strength.0), - &format!("{}", table_info.security.join(" ")) + &table_info.security.join(" ") ]); } @@ -321,7 +321,7 @@ pub async fn get( let current = current_res?; Ok(WiFiInfo { ssids, - connected: current.map(|x| x), + connected: current, country: country_res?, ethernet: ethernet_res?, available_wifi, @@ -394,7 +394,17 @@ pub struct Ssid(String); /// So a signal strength is a number between 0-100, I want the null option to be 0 since there is no signal #[derive( - Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize, + Clone, + Copy, + Debug, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + serde::Serialize, + serde::Deserialize, )] pub struct SignalStrength(u8); @@ -411,11 +421,6 @@ impl SignalStrength { } } -impl Default for SignalStrength { - fn default() -> Self { - Self(0) - } -} #[derive(Clone, Debug)] pub struct Psk(String); impl WpaCli { @@ -492,26 +497,24 @@ impl WpaCli { lazy_static! { static ref RE: Regex = Regex::new("country (\\w+):").unwrap(); } - let first_country = r - .lines() - .filter(|s| s.contains("country")) - .next() - .ok_or_else(|| { - Error::new( - color_eyre::eyre::eyre!("Could not find a country config lines"), - ErrorKind::Wifi, - ) - })?; + let first_country = r.lines().find(|s| s.contains("country")).ok_or_else(|| { + Error::new( + color_eyre::eyre::eyre!("Could not find a country config lines"), + ErrorKind::Wifi, + ) + })?; let country = &RE.captures(first_country).ok_or_else(|| { Error::new( color_eyre::eyre::eyre!("Could not find a country config with regex"), ErrorKind::Wifi, ) })?[1]; - Ok(CountryCode::for_alpha2(country).or(Err(Error::new( - color_eyre::eyre::eyre!("Invalid Country Code: {}", country), - ErrorKind::Wifi, - )))?) + Ok(CountryCode::for_alpha2(country).map_err(|_| { + Error::new( + color_eyre::eyre::eyre!("Invalid Country Code: {}", country), + ErrorKind::Wifi, + ) + })?) } pub async fn remove_network_low(&mut self, id: NetworkId) -> Result<(), Error> { let _ = Command::new("nmcli") @@ -533,11 +536,14 @@ impl WpaCli { Ok(String::from_utf8(r)? .lines() .filter_map(|l| { - let mut cs = l.split(":"); + let mut cs = l.split(':'); let name = Ssid(cs.next()?.to_owned()); let uuid = NetworkId(cs.next()?.to_owned()); - let _connection_type = cs.next()?; - let _device = cs.next()?; + let connection_type = cs.next()?; + let device = cs.next()?; + if !device.contains("wlan0") || !connection_type.contains("wireless") { + return None; + } Some((name, uuid)) }) .collect::>()) @@ -556,11 +562,11 @@ impl WpaCli { Ok(String::from_utf8(r)? .lines() .filter_map(|l| { - let mut values = l.split(":"); + let mut values = l.split(':'); let ssid = Ssid(values.next()?.to_owned()); let signal = SignalStrength::new(std::str::FromStr::from_str(values.next()?).ok()); let security: Vec = - values.next()?.split(" ").map(|x| x.to_owned()).collect(); + values.next()?.split(' ').map(|x| x.to_owned()).collect(); Some(( ssid, WifiListInfo { @@ -618,12 +624,9 @@ impl WpaCli { let mut current; loop { current = self.get_current_network().await; - match ¤t { - Ok(Some(ssid)) => { - tracing::debug!("Connected to: {}", ssid.0); - break; - } - _ => {} + if let Ok(Some(ssid)) = ¤t { + tracing::debug!("Connected to: {}", ssid.0); + break; } tokio::time::sleep(Duration::from_millis(500)).await; tracing::debug!("Retrying..."); @@ -677,7 +680,7 @@ impl WpaCli { psk: &Psk, priority: isize, ) -> Result<(), Error> { - self.set_add_network_low(&ssid, &psk).await?; + self.set_add_network_low(ssid, psk).await?; self.save_config(db).await?; Ok(()) } @@ -689,7 +692,7 @@ impl WpaCli { psk: &Psk, priority: isize, ) -> Result<(), Error> { - self.add_network_low(&ssid, &psk).await?; + self.add_network_low(ssid, psk).await?; self.save_config(db).await?; Ok(()) } @@ -703,16 +706,17 @@ pub async fn interface_connected(interface: &str) -> Result { .await?; let v = std::str::from_utf8(&out)? .lines() - .filter(|s| s.contains("inet")) - .next(); - Ok(!v.is_none()) + .find(|s| s.contains("inet")); + Ok(v.is_some()) } pub fn country_code_parse(code: &str, _matches: &ArgMatches<'_>) -> Result { - CountryCode::for_alpha2(code).or(Err(Error::new( - color_eyre::eyre::eyre!("Invalid Country Code: {}", code), - ErrorKind::Wifi, - ))) + CountryCode::for_alpha2(code).map_err(|_| { + Error::new( + color_eyre::eyre::eyre!("Invalid Country Code: {}", code), + ErrorKind::Wifi, + ) + }) } #[instrument(skip(main_datadir))] @@ -722,16 +726,16 @@ pub async fn synchronize_wpa_supplicant_conf>( ) -> Result<(), Error> { let persistent = main_datadir.as_ref().join("system-connections"); tracing::debug!("persistent: {:?}", persistent); - let supplicant = Path::new("/etc/wpa_supplicant.conf"); + // let supplicant = Path::new("/etc/wpa_supplicant.conf"); if tokio::fs::metadata(&persistent).await.is_err() { tokio::fs::create_dir_all(&persistent).await?; } crate::disk::mount::util::bind(&persistent, "/etc/NetworkManager/system-connections", false) .await?; - if tokio::fs::metadata(&supplicant).await.is_err() { - tokio::fs::write(&supplicant, include_str!("wpa_supplicant.conf.base")).await?; - } + // if tokio::fs::metadata(&supplicant).await.is_err() { + // tokio::fs::write(&supplicant, include_str!("wpa_supplicant.conf.base")).await?; + // } Command::new("systemctl") .arg("restart") @@ -752,6 +756,14 @@ pub async fn synchronize_wpa_supplicant_conf>( .arg(last_country_code.alpha2()) .invoke(ErrorKind::Wifi) .await?; + } else { + tracing::info!("Setting the region fallback"); + let _ = Command::new("iw") + .arg("reg") + .arg("set") + .arg("US") + .invoke(ErrorKind::Wifi) + .await?; } Ok(()) } diff --git a/build/initialization.sh b/build/initialization.sh index 664d33f49..2c60453bd 100755 --- a/build/initialization.sh +++ b/build/initialization.sh @@ -6,8 +6,6 @@ set -e ! test -f /etc/docker/daemon.json || rm /etc/docker/daemon.json mount -o remount,rw /boot -curl -fsSL https://get.docker.com | sh # TODO: commit this script into git instead of live fetching it - apt-get update apt-get install -y \ tor \ @@ -28,16 +26,21 @@ apt-get install -y \ samba-common-bin \ ntp \ network-manager + +curl -fsSL https://get.docker.com | sh # TODO: commit this script into git instead of live fetching it + +apt-get purge openresolv dhcpcd5 -y +systemctl disable wpa_supplicant.service + apt-get autoremove -y apt-get upgrade -y sed -i 's/Restart=on-failure/Restart=always/g' /lib/systemd/system/tor@default.service sed -i '/}/i \ \ \ \ application\/wasm \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ wasm;' /etc/nginx/mime.types sed -i 's/# server_names_hash_bucket_size 64;/server_names_hash_bucket_size 128;/g' /etc/nginx/nginx.conf -sed -i 's/ExecStart=\/sbin\/wpa_supplicant -u -s -O \/run\/wpa_supplicant/ExecStart=\/sbin\/wpa_supplicant -u -s -O \/run\/wpa_supplicant -c \/etc\/wpa_supplicant.conf -i wlan0/g' /lib/systemd/system/wpa_supplicant.service +# sed -i 's/ExecStart=\/sbin\/wpa_supplicant -u -s -O \/run\/wpa_supplicant/ExecStart=\/sbin\/wpa_supplicant -u -s -O \/run\/wpa_supplicant -c \/etc\/wpa_supplicant.conf -i wlan0/g' /lib/systemd/system/wpa_supplicant.service sed -i 's/#allow-interfaces=eth0/allow-interfaces=eth0,wlan0/g' /etc/avahi/avahi-daemon.conf -echo "auto wlan0" > /etc/network/interfaces -echo "iface wlan0 inet dhcp" >> /etc/network/interfaces +echo "#" > /etc/network/interfaces mkdir -p /etc/nginx/ssl # fix to suppress docker warning, fixed in 21.xx release of docker cli: https://github.com/docker/cli/pull/2934 diff --git a/build/make-image.sh b/build/make-image.sh index 899317409..5988e1e5e 100755 --- a/build/make-image.sh +++ b/build/make-image.sh @@ -17,6 +17,7 @@ if [ -z "$OUTPUT_DEVICE" ]; then export DETACH_OUTPUT_DEVICE=1 else export DETACH_OUTPUT_DEVICE=0 + sudo dd if=/dev/zero of=$OUTPUT_DEVICE bs=1M count=1 fi export LOOPDEV=$(sudo losetup --show -fP raspios.img) ./build/partitioning.sh