diff --git a/peach-network/README.md b/peach-network/README.md index c8babd0..2959f20 100644 --- a/peach-network/README.md +++ b/peach-network/README.md @@ -1,178 +1,32 @@ # peach-network -[![Build Status](https://travis-ci.com/peachcloud/peach-network.svg?branch=master)](https://travis-ci.com/peachcloud/peach-network) ![Generic badge](https://img.shields.io/badge/version-0.2.13-.svg) +![Generic badge](https://img.shields.io/badge/version-0.3.0-.svg) -Networking microservice module for PeachCloud. Query and configure device interfaces using [JSON-RPC](https://www.jsonrpc.org/specification) over http. +Network interface state query and modification library. Interaction with wireless interfaces occurs primarily through the [wpactrl crate](https://docs.rs/wpactrl/0.3.1/wpactrl/) which provides "a pure-Rust lowlevel library for controlling wpasupplicant remotely". This approach is akin to using `wpa_cli` (a WPA command line client). -_Note: This module is a work-in-progress._ +## API Documentation -### JSON-RPC API +API documentation can be built and served with `cargo doc --no-deps --open`. The full set of available data structures and functions is listed in the `peach_network::network` module. A custom error type (`NetworkError`) is also publically exposed for library users; it encapsulates all possible error variants. -Methods for **retrieving data**: +## Example Usage -| Method | Parameters | Description | -| --- | --- | --- | -| `available_networks` | `iface` | List SSID, flags (security), frequency and signal level for all networks in range of given interface | -| `id` | `iface`, `ssid` | Return ID of given SSID | -| `ip` | `iface` | Return IP of given network interface | -| `ping` | | Respond with `success` if microservice is running | -| `rssi` | `iface` | Return average signal strength (dBm) for given interface | -| `rssi_percent` | `iface` | Return average signal strength (%) for given interface | -| `saved_networks` | | List all networks saved in wpasupplicant config | -| `ssid` | `iface` | Return SSID of currently-connected network for given interface | -| `state` | `iface` | Return state of given interface | -| `status` | `iface` | Return status parameters for given interface | -| `traffic` | `iface` | Return network traffic for given interface | +```rust +use peach_network::{network, NetworkError}; -Methods for **modifying state**: +fn main() -> Result<(), NetworkError> { + let ip = network::ip("wlan0")?; + let ssid = network::ssid("wlan0")?; -| Method | Parameters | Description | -| --- | --- | --- | -| `activate_ap` | | Activate WiFi access point (start `wpa_supplicant@ap0.service`) | -| `activate_client` | | Activate WiFi client connection (start `wpa_supplicant@wlan0.service`) | -| `add` | `ssid`, `pass` | Add WiFi credentials to `wpa_supplicant-wlan0.conf` | -| `check_iface` | | Activate WiFi access point if client mode is active without a connection | -| `connect` | `id`, `iface` | Disable other networks and attempt connection with AP represented by given id | -| `delete` | `id`, `iface` | Remove WiFi credentials for given network id and interface | -| `disable` | `id`, `iface` | Disable connection with AP represented by given id | -| `disconnect` | `iface` | Disconnect given interface | -| `modify` | `id`, `iface`, `password` | Set a new password for given network id and interface | -| `reassociate` | `iface` | Reassociate with current AP for given interface | -| `reconfigure` | | Force wpa_supplicant to re-read its configuration file | -| `reconnect` | `iface` | Disconnect and reconnect given interface | -| `save` | | Save configuration changes to `wpa_supplicant-wlan0.conf` | + let new_ap = Wifi { ssid: "Home".to_string(), pass: "SuperSecret".to_string() }; + network::add(new_ap)?; + network::save()?; -### API Documentation + Ok(()) +} +``` -API documentation can be built and served with `cargo doc --no-deps --open`. This set of documentation is intended for developers who wish to work on the project or better understand the API of the `src/network.rs` module. - -### Environment - -The JSON-RPC HTTP server address and port can be configured with the `PEACH_NETWORK_SERVER` environment variable: - -`export PEACH_NETWORK_SERVER=127.0.0.1:5000` - -When not set, the value defaults to `127.0.0.1:5110`. - -Logging is made available with `env_logger`: - -`export RUST_LOG=info` - -Other logging levels include `debug`, `warn` and `error`. - -### Setup - -Clone this repo: - -`git clone https://github.com/peachcloud/peach-network.git` - -Move into the repo and compile: - -`cd peach-network` -`cargo build --release` - -Run the binary (sudo needed to satisfy permission requirements): - -`sudo ./target/release/peach-network` - -### Debian Packaging - -A `systemd` service file and Debian maintainer scripts are included in the `debian` directory, allowing `peach-network` to be easily bundled as a Debian package (`.deb`). The `cargo-deb` [crate](https://crates.io/crates/cargo-deb) can be used to achieve this. - -Install `cargo-deb`: - -`cargo install cargo-deb` - -Move into the repo: - -`cd peach-network` - -Build the package: - -`cargo deb` - -The output will be written to `target/debian/peach-network_0.2.4_arm64.deb` (or similar). - -Build the package (aarch64): - -`cargo deb --target aarch64-unknown-linux-gnu` - -Install the package as follows: - -`sudo dpkg -i target/debian/peach-network_0.2.4_arm64.deb` - -The service will be automatically enabled and started. - -Uninstall the service: - -`sudo apt-get remove peach-network` - -Remove configuration files (not removed with `apt-get remove`): - -`sudo apt-get purge peach-network` - -### Example Usage - -**Retrieve IP address for wlan0** - -With microservice running, open a second terminal window and use `curl` to call server methods: - -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "ip", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5110` - -Server responds with: - -`{"jsonrpc":"2.0","result":"192.168.1.21","id":1}` - -**Retrieve SSID of connected access point for wlan1** - -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "ssid", "params" : {"iface": "wlan1" }, "id":1 }' 127.0.0.1:5110` - -Server response when interface is connected: - -`{"jsonrpc":"2.0","result":"Home","id":1}` - -Server response when interface is not connected: - -`{"jsonrpc":"2.0","error":{"code":-32003,"message":"Failed to retrieve SSID for wlan1. Interface may not be connected."},"id":1}` - -**Retrieve list of SSIDs for all networks in range of wlan0** - -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "available_networks", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5110` - -Server response when interface is connected: - -`{"jsonrpc":"2.0","result":"[{\"frequency\":\"2412\",\"signal_level\":\"-72\",\"ssid\":\"Home\",\"flags\":\"[WPA2-PSK-CCMP][ESS]\"},{\"frequency\":\"2472\",\"signal_level\":\"-56\",\"ssid\":\"podetium\",\"flags\":\"[WPA2-PSK-CCMP+TKIP][ESS]\"}]","id":1}` - -Server response when interface is not connected: - -`{"jsonrpc":"2.0","error":{"code":-32006,"message":"No networks found in range of wlan0"},"id":1}` - -**Retrieve network traffic statistics for wlan1** - -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "traffic", "params" : {"iface": "wlan1" }, "id":1 }' 127.0.0.1:5110` - -Server response if interface exists: - -`{"jsonrpc":"2.0","result":"{\"received\":26396361,\"transmitted\":22352530}","id":1}` - -Server response when interface is not found: - -`{"jsonrpc":"2.0","error":{"code":-32004,"message":"Failed to retrieve network traffic for wlan3. Interface may not be connected"},"id":1}` - -**Retrieve status information for wlan0** - -`curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "status", "params" : {"iface": "wlan0" }, "id":1 }' 127.0.0.1:5110` - -Server response if interface exists: - -`{"jsonrpc":"2.0","result":"{\"address\":\"b8:27:eb:9b:5d:5f\",\"bssid\":\"f4:8c:eb:cd:31:81\",\"freq\":\"2412\",\"group_cipher\":\"CCMP\",\"id\":\"0\",\"ip_address\":\"192.168.0.162\",\"key_mgmt\":\"WPA2-PSK\",\"mode\":\"station\",\"pairwise_cipher\":\"CCMP\",\"ssid\":\"Home\",\"wpa_state\":\"COMPLETED\"}","id":1}` - -Server response when interface is not found: - -`{"jsonrpc":"2.0","error":{"code":-32013,"message":"Failed to open control interface for wpasupplicant: No such file or directory (os error 2)"},"id":1}` - -### Licensing +## Licensing AGPL-3.0 diff --git a/peach-network/src/network.rs b/peach-network/src/network.rs index e579729..1a0874d 100644 --- a/peach-network/src/network.rs +++ b/peach-network/src/network.rs @@ -1,6 +1,6 @@ //! Retrieve network data and modify interface state. //! -//! This module contains the core logic of the `peach-network` microservice and +//! This module contains the core logic of the `peach-network` and //! provides convenience wrappers for a range of `wpasupplicant` commands, //! many of which are ordinarily executed using `wpa_cli` (a WPA command line //! client). @@ -12,7 +12,7 @@ //! system calls to systemd (via `systemctl`). Further networking functionality //! is provided by making system calls to retrieve interface state and write //! access point credentials to `wpa_supplicant-wlan0.conf`. -//! + use std::{ fs::OpenOptions, io::prelude::*, @@ -21,68 +21,67 @@ use std::{ str, }; -use crate::error::NetworkError; use probes::network; + +#[cfg(feature = "miniserde_support")] +use miniserde::{Deserialize, Serialize}; + +#[cfg(feature = "serde_support")] use serde::{Deserialize, Serialize}; +use crate::error::NetworkError; use crate::utils; -/// Network interface name. -#[derive(Debug, Deserialize)] -pub struct Iface { - pub iface: String, -} - -/// Network interface name and network identifier. -#[derive(Debug, Deserialize)] -pub struct IfaceId { - pub iface: String, - pub id: String, -} - -/// Network interface name, network identifier and password. -#[derive(Debug, Deserialize)] -pub struct IfaceIdPass { - pub iface: String, - pub id: String, - pub pass: String, -} - -/// Network interface name and network SSID. -#[derive(Debug, Deserialize)] -pub struct IfaceSsid { - pub iface: String, - pub ssid: String, -} - /// Network SSID. -#[derive(Debug, Serialize)] +#[derive(Debug)] +#[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct Network { + /// Service Set Identifier (SSID). pub ssid: String, } /// Access point data retrieved via scan. -#[derive(Debug, Serialize)] +#[derive(Debug)] +#[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct Scan { + /// Frequency. pub frequency: String, + /// Protocol. pub protocol: String, + /// Signal strength. pub signal_level: String, + /// SSID. pub ssid: String, } /// Status data for a network interface. -#[derive(Debug, Serialize)] +#[derive(Debug)] +#[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct Status { + /// MAC address. pub address: Option, + /// Basic Service Set Identifier (BSSID). pub bssid: Option, + /// Frequency. pub freq: Option, + /// Group cipher. pub group_cipher: Option, + /// Local ID. pub id: Option, + /// IP address. pub ip_address: Option, + /// Key management. pub key_mgmt: Option, + /// Mode. pub mode: Option, + /// Pairwise cipher. pub pairwise_cipher: Option, + /// SSID. pub ssid: Option, + /// WPA state. pub wpa_state: Option, } @@ -105,24 +104,27 @@ impl Status { } /// Received and transmitted network traffic (bytes). -#[derive(Debug, Serialize)] +#[derive(Debug)] +#[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct Traffic { + /// Total bytes received. pub received: u64, + /// Total bytes transmitted. pub transmitted: u64, } /// SSID and password for a wireless access point. -#[derive(Debug, Deserialize)] +#[derive(Debug)] +#[cfg_attr(feature = "miniserde_support", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))] pub struct WiFi { + /// SSID. pub ssid: String, + /// Password. pub pass: String, } -// TODO: wrap this into a helper function: -// -// let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); -// let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; - /* GET - Methods for retrieving data */ /// Retrieve list of available wireless access points for a given network @@ -133,15 +135,11 @@ pub struct WiFi { /// * `iface` - A string slice holding the name of a wireless network interface /// /// If the scan results include one or more access points for the given network -/// interface, an `Ok` `Result` type is returned containing `Some(String)` - -/// where `String` is a serialized vector of `Scan` structs containing -/// data for the in-range access points. If no access points are found, -/// a `None` type is returned in the `Result`. In the event of an error, a -/// `NetworkError` is returned in the `Result`. The `NetworkError` is then -/// enumerated to a specific error type and an appropriate JSON RPC response is -/// sent to the caller. -/// -pub fn available_networks(iface: &str) -> Result, NetworkError> { +/// interface, an `Ok` `Result` type is returned containing `Some(Vec)`. +/// The vector of `Scan` structs contains data for the in-range access points. +/// If no access points are found, a `None` type is returned in the `Result`. +/// In the event of an error, a `NetworkError` is returned in the `Result`. +pub fn available_networks(iface: &str) -> Result>, NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; wpa.request("SCAN")?; @@ -176,8 +174,7 @@ pub fn available_networks(iface: &str) -> Result, NetworkError> { if scan.is_empty() { Ok(None) } else { - let results = serde_json::to_string(&scan)?; - Ok(Some(results)) + Ok(Some(scan)) } } @@ -193,10 +190,7 @@ pub fn available_networks(iface: &str) -> Result, NetworkError> { /// found in the list of saved networks, an `Ok` `Result` type is returned /// containing `Some(String)` - where `String` is the network identifier. /// If no match is found, a `None` type is returned in the `Result`. In the -/// event of an error, a `NetworkError` is returned in the `Result`. The -/// `NetworkError` is then enumerated to a specific error type and an -/// appropriate JSON RPC response is sent to the caller. -/// +/// event of an error, a `NetworkError` is returned in the `Result`. pub fn id(iface: &str, ssid: &str) -> Result, NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -228,10 +222,7 @@ pub fn id(iface: &str, ssid: &str) -> Result, NetworkError> { /// an `Ok` `Result` type is returned containing `Some(String)` - where `String` /// is the IP address of the interface. If no match is found, a `None` type is /// returned in the `Result`. In the event of an error, a `NetworkError` is -/// returned in the `Result`. The `NetworkError` is then enumerated to a -/// specific error type and an appropriate JSON RPC response is sent to the -/// caller. -/// +/// returned in the `Result`. pub fn ip(iface: &str) -> Result, NetworkError> { let net_if: String = iface.to_string(); let ifaces = get_if_addrs::get_if_addrs().map_err(|source| NetworkError::NoIp { @@ -258,9 +249,7 @@ pub fn ip(iface: &str) -> Result, NetworkError> { /// is the RSSI (Received Signal Strength Indicator) of the connection measured /// in dBm. If signal strength is not found, a `None` type is returned in the /// `Result`. In the event of an error, a `NetworkError` is returned in the -/// `Result`. The `NetworkError` is then enumerated to a specific error type and -/// an appropriate JSON RPC response is sent to the caller. -/// +/// `Result`. pub fn rssi(iface: &str) -> Result, NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -287,9 +276,7 @@ pub fn rssi(iface: &str) -> Result, NetworkError> { /// is the RSSI (Received Signal Strength Indicator) of the connection measured /// as a percentage. If signal strength is not found, a `None` type is returned /// in the `Result`. In the event of an error, a `NetworkError` is returned in -/// the `Result`. The `NetworkError` is then enumerated to a specific error type -/// and an appropriate JSON RPC response is sent to the caller. -/// +/// the `Result`. pub fn rssi_percent(iface: &str) -> Result, NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -319,14 +306,11 @@ pub fn rssi_percent(iface: &str) -> Result, NetworkError> { /// /// If the wpasupplicant configuration file contains credentials for one or /// more access points, an `Ok` `Result` type is returned containing -/// `Some(String)` - where `String` is a serialized vector of `Network` structs -/// containing the SSIDs of all saved networks. If no network credentials are -/// found, a `None` type is returned in the `Result`. In the event of an error, -/// a `NetworkError` is returned in the `Result`. The `NetworkError` is then -/// enumerated to a specific error type and an appropriate JSON RPC response is -/// sent to the caller. -/// -pub fn saved_networks() -> Result, NetworkError> { +/// `Some(Vec)`. The vector of `Network` structs contains the SSIDs +/// of all saved networks. If no network credentials are found, a `None` type +/// is returned in the `Result`. In the event of an error, a `NetworkError` is +/// returned in the `Result`. +pub fn saved_networks() -> Result>, NetworkError> { let mut wpa = wpactrl::WpaCtrl::builder().open()?; let networks = wpa.request("LIST_NETWORKS")?; let mut ssids = Vec::new(); @@ -343,8 +327,7 @@ pub fn saved_networks() -> Result, NetworkError> { if ssids.is_empty() { Ok(None) } else { - let results = serde_json::to_string(&ssids)?; - Ok(Some(results)) + Ok(Some(ssids)) } } @@ -358,10 +341,7 @@ pub fn saved_networks() -> Result, NetworkError> { /// an `Ok` `Result` type is returned containing `Some(String)` - where `String` /// is the SSID of the associated network. If SSID is not found, a `None` type /// is returned in the `Result`. In the event of an error, a `NetworkError` is -/// returned in the `Result`. The `NetworkError` is then enumerated to a -/// specific error type and an appropriate JSON RPC response is sent to the -/// caller. -/// +/// returned in the `Result`. pub fn ssid(iface: &str) -> Result, NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -383,9 +363,7 @@ pub fn ssid(iface: &str) -> Result, NetworkError> { /// returned containing `Some(String)` - where `String` is the state of the /// network interface. If state is not found, a `None` type is returned in the /// `Result`. In the event of an error, a `NetworkError` is returned in the -/// `Result`. The `NetworkError` is then enumerated to a specific error type and -/// an appropriate JSON RPC response is sent to the caller. -/// +/// `Result`. pub fn state(iface: &str) -> Result, NetworkError> { // construct the interface operstate path let iface_path: String = format!("/sys/class/net/{}/operstate", iface); @@ -419,10 +397,7 @@ pub fn state(iface: &str) -> Result, NetworkError> { /// returned containing `Some(Status)` - where `Status` is a `struct` /// containing the aggregated interface data in named fields. If status is not /// found, a `None` type is returned in the `Result`. In the event of an error, -/// a `NetworkError` is returned in the `Result`. The `NetworkError` is then -/// enumerated to a specific error type and an appropriate JSON RPC response is -/// sent to the caller. -/// +/// a `NetworkError` is returned in the `Result`. pub fn status(iface: &str) -> Result, NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -475,15 +450,12 @@ pub fn status(iface: &str) -> Result, NetworkError> { /// * `iface` - A string slice holding the name of a wireless network interface /// /// If the network traffic statistics are found for the given interface, an `Ok` -/// `Result` type is returned containing `Some(String)` - where `String` is a -/// serialized `Traffic` `struct` with fields for received and transmitted -/// network data statistics. If network traffic statistics are not found for the -/// given interface, a `None` type is returned in the `Result`. In the event of -/// an error, a `NetworkError` is returned in the `Result`. The `NetworkError` -/// is then enumerated to a specific error type and an appropriate JSON RPC -/// response is sent to the caller. -/// -pub fn traffic(iface: &str) -> Result, NetworkError> { +/// `Result` type is returned containing `Some(Traffic)`. The `Traffic` `struct` +/// includes fields for received and transmitted network data statistics. If +/// network traffic statistics are not found for the given interface, a `None` +/// type is returned in the `Result`. In the event of an error, a `NetworkError` +/// is returned in the `Result`. +pub fn traffic(iface: &str) -> Result, NetworkError> { let network = network::read().map_err(|source| NetworkError::NoTraffic { iface: iface.to_string(), source, @@ -497,9 +469,7 @@ pub fn traffic(iface: &str) -> Result, NetworkError> { received, transmitted, }; - // TODO: add test for SerdeSerialize error - let t = serde_json::to_string(&traffic)?; - return Ok(Some(t)); + return Ok(Some(traffic)); } } @@ -513,9 +483,6 @@ pub fn traffic(iface: &str) -> Result, NetworkError> { /// A `systemctl `command is invoked which starts the `ap0` interface service. /// If the command executes successfully, an `Ok` `Result` type is returned. /// In the event of an error, a `NetworkError` is returned in the `Result`. -/// The `NetworkError` is then enumerated to a specific error type and an -/// appropriate JSON RPC response is sent to the caller. -/// pub fn activate_ap() -> Result<(), NetworkError> { // start the ap0 interface service Command::new("sudo") @@ -533,9 +500,6 @@ pub fn activate_ap() -> Result<(), NetworkError> { /// A `systemctl` command is invoked which starts the `wlan0` interface service. /// If the command executes successfully, an `Ok` `Result` type is returned. /// In the event of an error, a `NetworkError` is returned in the `Result`. -/// The `NetworkError` is then enumerated to a specific error type and an -/// appropriate JSON RPC response is sent to the caller. -/// pub fn activate_client() -> Result<(), NetworkError> { // start the wlan0 interface service Command::new("sudo") @@ -557,10 +521,7 @@ pub fn activate_client() -> Result<(), NetworkError> { /// If configuration parameters are successfully generated from the provided /// SSID and password and appended to `wpa_supplicant-wlan0.conf`, an `Ok` /// `Result` type is returned. In the event of an error, a `NetworkError` is -/// returned in the `Result`. The `NetworkError` is then enumerated to a -/// specific error type and an appropriate JSON RPC response is sent to the -/// caller. -/// +/// returned in the `Result`. pub fn add(wifi: &WiFi) -> Result<(), NetworkError> { // generate configuration based on provided ssid & password let output = Command::new("wpa_passphrase") @@ -609,7 +570,6 @@ pub fn add(wifi: &WiFi) -> Result<(), NetworkError> { /// are checked. If the service is active but the interface is down (ie. not /// currently connected to an access point), then the access point is activated /// by calling the `activate_ap()` function. -/// pub fn check_iface() -> Result<(), NetworkError> { // returns 0 if the service is currently active let wlan0_status = Command::new("/usr/bin/systemctl") @@ -646,10 +606,7 @@ pub fn check_iface() -> Result<(), NetworkError> { /// If the network connection is successfully activated for the access point /// represented by the given network identifier on the given wireless interface, /// an `Ok` `Result`type is returned. In the event of an error, a `NetworkError` -/// is returned in the `Result`. The `NetworkError` is then enumerated to a -/// specific error type and an appropriate JSON RPC response is sent to the -/// caller. -/// +/// is returned in the `Result`. pub fn connect(id: &str, iface: &str) -> Result<(), NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -668,10 +625,7 @@ pub fn connect(id: &str, iface: &str) -> Result<(), NetworkError> { /// If the network configuration parameters are successfully deleted for /// the access point represented by the given network identifier, an `Ok` /// `Result`type is returned. In the event of an error, a `NetworkError` is -/// returned in the `Result`. The `NetworkError` is then enumerated to a -/// specific error type and an appropriate JSON RPC response is sent to the -/// caller. -/// +/// returned in the `Result`. pub fn delete(id: &str, iface: &str) -> Result<(), NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -690,9 +644,7 @@ pub fn delete(id: &str, iface: &str) -> Result<(), NetworkError> { /// If the network connection is successfully disabled for the access point /// represented by the given network identifier, an `Ok` `Result`type is /// returned. In the event of an error, a `NetworkError` is returned in the -/// `Result`. The `NetworkError` is then enumerated to a specific error type and -/// an appropriate JSON RPC response is sent to the caller. -/// +/// `Result`. pub fn disable(id: &str, iface: &str) -> Result<(), NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -709,10 +661,7 @@ pub fn disable(id: &str, iface: &str) -> Result<(), NetworkError> { /// /// If the network connection is successfully disconnected for the given /// wireless interface, an `Ok` `Result` type is returned. In the event of an -/// error, a `NetworkError` is returned in the `Result`. The `NetworkError` is -/// then enumerated to a specific error type and an appropriate JSON RPC -/// response is sent to the caller. -/// +/// error, a `NetworkError` is returned in the `Result`. pub fn disconnect(iface: &str) -> Result<(), NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -731,10 +680,7 @@ pub fn disconnect(iface: &str) -> Result<(), NetworkError> { /// /// If the password is successfully updated for the access point represented by /// the given network identifier, an `Ok` `Result` type is returned. In the -/// event of an error, a `NetworkError` is returned in the `Result`. The -/// `NetworkError` is then enumerated to a specific error type and an -/// appropriate JSON RPC response is sent to the caller. -/// +/// event of an error, a `NetworkError` is returned in the `Result`. pub fn modify(id: &str, iface: &str, pass: &str) -> Result<(), NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -751,10 +697,7 @@ pub fn modify(id: &str, iface: &str, pass: &str) -> Result<(), NetworkError> { /// /// If the network connection is successfully reassociated for the given /// wireless interface, an `Ok` `Result` type is returned. In the event of an -/// error, a `NetworkError` is returned in the `Result`. The `NetworkError` is -/// then enumerated to a specific error type and an appropriate JSON RPC -/// response is sent to the caller. -/// +/// error, a `NetworkError` is returned in the `Result`. pub fn reassociate(iface: &str) -> Result<(), NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -767,10 +710,7 @@ pub fn reassociate(iface: &str) -> Result<(), NetworkError> { /// If the reconfigure command is successfully executed, indicating a reread /// of the `wpa_supplicant.conf` file by the `wpa_supplicant` process, an `Ok` /// `Result` type is returned. In the event of an error, a `NetworkError` is -/// returned in the `Result`. The `NetworkError` is then enumerated to a -/// specific error type and an appropriate JSON RPC response is sent to the -/// caller. -/// +/// returned in the `Result`. pub fn reconfigure() -> Result<(), NetworkError> { let mut wpa = wpactrl::WpaCtrl::builder().open()?; wpa.request("RECONFIGURE")?; @@ -785,10 +725,7 @@ pub fn reconfigure() -> Result<(), NetworkError> { /// /// If the network connection is successfully disconnected and reconnected for /// the given wireless interface, an `Ok` `Result` type is returned. In the -/// event of an error, a `NetworkError` is returned in the `Result`. The -/// `NetworkError` is then enumerated to a specific error type and an -/// appropriate JSON RPC response is sent to the caller. -/// +/// event of an error, a `NetworkError` is returned in the `Result`. pub fn reconnect(iface: &str) -> Result<(), NetworkError> { let wpa_path: String = format!("/var/run/wpa_supplicant/{}", iface); let mut wpa = wpactrl::WpaCtrl::builder().ctrl_path(wpa_path).open()?; @@ -801,10 +738,7 @@ pub fn reconnect(iface: &str) -> Result<(), NetworkError> { /// /// If wireless network configuration updates are successfully save to the /// `wpa_supplicant.conf` file, an `Ok` `Result` type is returned. In the -/// event of an error, a `NetworkError` is returned in the `Result`. The -/// `NetworkError` is then enumerated to a specific error type and an -/// appropriate JSON RPC response is sent to the caller. -/// +/// event of an error, a `NetworkError` is returned in the `Result`. pub fn save() -> Result<(), NetworkError> { let mut wpa = wpactrl::WpaCtrl::builder().open()?; wpa.request("SAVE_CONFIG")?;