diff --git a/Cargo.toml b/Cargo.toml index ea3ce22..260ec49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,3 @@ version = "0.1.0" authors = ["Tochukwu Nkemdilim "] [dependencies] -tempfile = "3.0.2" diff --git a/README.md b/README.md new file mode 100644 index 0000000..38bdf8c --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# WiFi-rs + +A rust crate to interface and manage Wi-Fi networks. + +## How it works + +- The command creates a new connection and then activates it on a device. +- This is a command-line counterpart of clicking an SSID in a GUI client. +- The command always creates a new connection and thus it is mainly useful for connecting to new Wi-Fi networks. +- If a connection for the network already exists, it is better to bring up (activate) the existing connection as follows: `WiFi::connection_up("SSID")`. + +## Currently supported network types + +Note that only **open**, **WEP** and **WPA-PSK** networks are supported at the moment. + +> It is also supposed that IP configuration is obtained via DHCP. + +## Supported Operating Systems + +- Windows +- Linux +- OSx + +## Example + +```RUST +extern crate wifi_rs; +use wifi_rs::{WiFi, Config, NetworkError}; + +fn main() -> Result<(), NetworkError> { + let config = Some(Config { + interface: Some("wlo1"), // interface : None would default to `wlan0`. + }); + + let wifi = WiFi::new("AndroidAPSD", config)?; + + match wifi.connect("belm4235") { + Ok(result) => println!( + "{}", + if result == true { + "Connection Successfull." + } else { + "Invalid password." + } + ), + Err(err) => println!("The following error occurred: {:?}", err), + } + + Ok(()) +} + +} +``` + +## To do + +- [x] Bundle windows profile sample as literals +- [x] Add support for Windows +- [x] Add support for linux +- [x] Add disconnect feature +- [ ] Use `tempfile` crate on windows to generate windows profile temporary file. +- [ ] Add support for OSX +- [ ] Fix the implementation for `check_if_wifi_is_enabled` for windows. +- [ ] Add get network type feature +- [ ] Add create hotspot functionality +- [ ] Write documentation +- [ ] Write tests +- [ ] Add multi-threaded support + +# Contribution + +Any feature you feel is missing, why not send in a Pull Request, and let's help make this project better. Or are there any bugs, kindly create an issue, so we could work towards fixing it. + +# Support + +Love this project, and you'll love to buy me a coffee, kindly visit: diff --git a/examples/wifi-cli/src/main.rs b/examples/wifi-cli/src/main.rs index 69bd7eb..42cca58 100644 --- a/examples/wifi-cli/src/main.rs +++ b/examples/wifi-cli/src/main.rs @@ -46,7 +46,7 @@ fn main() -> Result<(), io::Error> { let ssid = matches.value_of("ssid").unwrap(); // Get Wireless Interface - let ssid = matches.value_of("ssid").unwrap(); + let interface = matches.value_of("interface").unwrap(); let wifi = WiFi::new(ssid)?; println!("Connection Status: {}", wifi.connect(password)); diff --git a/src/connectivity/mod.rs b/src/connectivity/mod.rs index 98edea6..0519963 100644 --- a/src/connectivity/mod.rs +++ b/src/connectivity/mod.rs @@ -9,6 +9,7 @@ pub trait Network: fmt::Debug { /// Makes an attempt to connect to a selected wireless network with password specified. fn connect(&self, password: &str) -> Result; fn disconnect(&self) -> Result; + fn is_wifi_enabled(&self) -> bool; } // #[derive(Debug)] @@ -33,6 +34,7 @@ pub enum NetworkError { IoError(io::Error), FailedToConnect(String), FailedToDisconnect(String), + WiFiInterfaceDisabled, } impl From for NetworkError { diff --git a/src/connectivity/profile_network.rs b/src/connectivity/profile_network.rs index 4a7e959..dad49c0 100644 --- a/src/connectivity/profile_network.rs +++ b/src/connectivity/profile_network.rs @@ -14,7 +14,7 @@ impl ProfileNetwork { let handler = Machine::new( name, - config.map_or(None, |cfg| cfg.interface.map_or(None, |x| Some(&x))), + config.map_or(None, |cfg| cfg.interface.map_or(None, |x| Some(x))), ); Ok(ProfileNetwork { @@ -23,6 +23,10 @@ impl ProfileNetwork { } pub fn connect(&self, password: &str) -> Result { + if !self.handler.is_wifi_enabled() { + return Err(NetworkError::WiFiInterfaceDisabled); + } + self.handler.connect(password) } } diff --git a/src/connectivity/providers/linux.rs b/src/connectivity/providers/linux.rs index 0a7c9aa..af00815 100644 --- a/src/connectivity/providers/linux.rs +++ b/src/connectivity/providers/linux.rs @@ -47,4 +47,17 @@ impl Network for Linux { .as_ref() .contains("disconnect")) } + + fn is_wifi_enabled(&self) -> bool { + let output = Command::new("nmcli").args(&["radio", "wifi"]).output(); + + if let Err(_) = output { + return false; + } + + String::from_utf8_lossy(&output.unwrap().stdout) + .replace(" ", "") + .replace("\n", "") + .contains("enabled") + } } diff --git a/src/connectivity/providers/windows.rs b/src/connectivity/providers/windows.rs index fc4e304..b86dcaf 100644 --- a/src/connectivity/providers/windows.rs +++ b/src/connectivity/providers/windows.rs @@ -69,4 +69,18 @@ impl Network for Windows { .as_ref() .contains("disconnect")) } + + fn is_wifi_enabled(&self) -> bool { + // let output = Command::new("nmcli").args(&["radio", "wifi"]).output(); + + // if let Err(_) = output { + // return false; + // } + + // match String::from_utf8_lossy(&output.unwrap().stdout).as_ref() { + // "enabled" => true, + // _ => false, + // } + false + } } diff --git a/src/main.rs b/src/main.rs index 17e5fa3..11c084b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ fn main() -> Result<(), NetworkError> { interface: Some("wlo1"), }); - let wifi = WiFi::new("AndroidAPSD", config)?; + let wifi = WiFi::new("AndroidAPSD22", config)?; match wifi.connect("belm4235") { Ok(result) => println!(