mirror of
				https://github.com/Djeeberjr/fw-anwesenheit.git
				synced 2025-11-04 07:34:10 +00:00 
			
		
		
		
	improved hotspot functions
with better error handeling & logging
This commit is contained in:
		
							parent
							
								
									2da2eb9583
								
							
						
					
					
						commit
						56981d5f23
					
				
							
								
								
									
										102
									
								
								src/hotspot.rs
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								src/hotspot.rs
									
									
									
									
									
								
							@ -1,4 +1,8 @@
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
use log::trace;
 | 
			
		||||
use std::{
 | 
			
		||||
    fmt::{self},
 | 
			
		||||
    process::Output,
 | 
			
		||||
};
 | 
			
		||||
use tokio::process::Command;
 | 
			
		||||
 | 
			
		||||
const SSID: &str = "fwa";
 | 
			
		||||
@ -6,10 +10,36 @@ const CON_NAME: &str = "fwa-hotspot";
 | 
			
		||||
const PASSWORD: &str = "hunter22";
 | 
			
		||||
const IPV4_ADDRES: &str = "192.168.4.1/24";
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub enum HotspotError {
 | 
			
		||||
    IoError(std::io::Error),
 | 
			
		||||
    NonZeroExit(Output),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Display for HotspotError {
 | 
			
		||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            HotspotError::IoError(err) => {
 | 
			
		||||
                write!(f, "Failed to run hotspot command. I/O error: {err}")
 | 
			
		||||
            }
 | 
			
		||||
            HotspotError::NonZeroExit(output) => {
 | 
			
		||||
                let stdout = String::from_utf8_lossy(&output.stdout);
 | 
			
		||||
                let stderr = String::from_utf8_lossy(&output.stderr);
 | 
			
		||||
                write!(
 | 
			
		||||
                    f,
 | 
			
		||||
                    "Failed to run hotspot command.\nStdout: {stdout}\nStderr: {stderr}",
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl std::error::Error for HotspotError {}
 | 
			
		||||
 | 
			
		||||
/// Create the connection in NM
 | 
			
		||||
/// Will fail if already exists
 | 
			
		||||
async fn create_hotspot() -> Result<(), Box<dyn Error>> {
 | 
			
		||||
    let mut cmd = Command::new("nmcli")
 | 
			
		||||
async fn create_hotspot() -> Result<(), HotspotError> {
 | 
			
		||||
    let cmd = Command::new("nmcli")
 | 
			
		||||
        .args(["device", "wifi", "hotspot"])
 | 
			
		||||
        .arg("con-name")
 | 
			
		||||
        .arg(CON_NAME)
 | 
			
		||||
@ -17,15 +47,18 @@ async fn create_hotspot() -> Result<(), Box<dyn Error>> {
 | 
			
		||||
        .arg(SSID)
 | 
			
		||||
        .arg("password")
 | 
			
		||||
        .arg(PASSWORD)
 | 
			
		||||
        .spawn()?;
 | 
			
		||||
        .output()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(HotspotError::IoError)?;
 | 
			
		||||
 | 
			
		||||
    let status = cmd.wait().await?;
 | 
			
		||||
    trace!("nmcli (std): {}", String::from_utf8_lossy(&cmd.stdout));
 | 
			
		||||
    trace!("nmcli (err): {}", String::from_utf8_lossy(&cmd.stderr));
 | 
			
		||||
 | 
			
		||||
    if !status.success() {
 | 
			
		||||
        return Err("Failed to create hotspot".into());
 | 
			
		||||
    if !cmd.status.success() {
 | 
			
		||||
        return Err(HotspotError::NonZeroExit(cmd));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut cmd = Command::new("nmcli")
 | 
			
		||||
    let cmd = Command::new("nmcli")
 | 
			
		||||
        .arg("connection")
 | 
			
		||||
        .arg("modify")
 | 
			
		||||
        .arg(CON_NAME)
 | 
			
		||||
@ -33,58 +66,67 @@ async fn create_hotspot() -> Result<(), Box<dyn Error>> {
 | 
			
		||||
        .arg("shared")
 | 
			
		||||
        .arg("ipv4.addresses")
 | 
			
		||||
        .arg(IPV4_ADDRES)
 | 
			
		||||
        .spawn()?;
 | 
			
		||||
        .output()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(HotspotError::IoError)?;
 | 
			
		||||
 | 
			
		||||
    let status = cmd.wait().await?;
 | 
			
		||||
 | 
			
		||||
    if !status.success() {
 | 
			
		||||
        return Err("Failed to create hotspot".into());
 | 
			
		||||
    if !cmd.status.success() {
 | 
			
		||||
        return Err(HotspotError::NonZeroExit(cmd));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Checks if the connection already exists
 | 
			
		||||
async fn exists() -> Result<bool, Box<dyn Error>> {
 | 
			
		||||
    let mut cmd = Command::new("nmcli")
 | 
			
		||||
async fn exists() -> Result<bool, HotspotError> {
 | 
			
		||||
    let cmd = Command::new("nmcli")
 | 
			
		||||
        .args(["connection", "show"])
 | 
			
		||||
        .arg(CON_NAME)
 | 
			
		||||
        .spawn()?;
 | 
			
		||||
        .output()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(HotspotError::IoError)?;
 | 
			
		||||
 | 
			
		||||
    let status = cmd.wait().await?;
 | 
			
		||||
    trace!("nmcli (std): {}", String::from_utf8_lossy(&cmd.stdout));
 | 
			
		||||
    trace!("nmcli (err): {}", String::from_utf8_lossy(&cmd.stderr));
 | 
			
		||||
 | 
			
		||||
    Ok(status.success())
 | 
			
		||||
    Ok(cmd.status.success())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn enable_hotspot() -> Result<(), Box<dyn Error>> {
 | 
			
		||||
pub async fn enable_hotspot() -> Result<(), HotspotError> {
 | 
			
		||||
    if !exists().await? {
 | 
			
		||||
        create_hotspot().await?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut cmd = Command::new("nmcli")
 | 
			
		||||
    let cmd = Command::new("nmcli")
 | 
			
		||||
        .args(["connection", "up"])
 | 
			
		||||
        .arg(CON_NAME)
 | 
			
		||||
        .spawn()?;
 | 
			
		||||
        .output()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(HotspotError::IoError)?;
 | 
			
		||||
 | 
			
		||||
    let status = cmd.wait().await?;
 | 
			
		||||
    trace!("nmcli (std): {}", String::from_utf8_lossy(&cmd.stdout));
 | 
			
		||||
    trace!("nmcli (err): {}", String::from_utf8_lossy(&cmd.stderr));
 | 
			
		||||
 | 
			
		||||
    if !status.success() {
 | 
			
		||||
        return Err("Failed to enable hotspot".into());
 | 
			
		||||
    if !cmd.status.success() {
 | 
			
		||||
        return Err(HotspotError::NonZeroExit(cmd));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn disable_hotspot() -> Result<(), Box<dyn Error>> {
 | 
			
		||||
    let mut cmd = Command::new("nmcli")
 | 
			
		||||
pub async fn disable_hotspot() -> Result<(), HotspotError> {
 | 
			
		||||
    let cmd = Command::new("nmcli")
 | 
			
		||||
        .args(["connection", "down"])
 | 
			
		||||
        .arg(CON_NAME)
 | 
			
		||||
        .spawn()?;
 | 
			
		||||
        .output()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(HotspotError::IoError)?;
 | 
			
		||||
 | 
			
		||||
    let status = cmd.wait().await?;
 | 
			
		||||
    trace!("nmcli (std): {}", String::from_utf8_lossy(&cmd.stdout));
 | 
			
		||||
    trace!("nmcli (err): {}", String::from_utf8_lossy(&cmd.stderr));
 | 
			
		||||
 | 
			
		||||
    if !status.success() {
 | 
			
		||||
        return Err("Failed to enable hotspot".into());
 | 
			
		||||
    if !cmd.status.success() {
 | 
			
		||||
        return Err(HotspotError::NonZeroExit(cmd));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user