update docs and remove unnecessary structs
This commit is contained in:
parent
287082381e
commit
a824be53b9
|
@ -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-<COLOR>.svg)
|
||||
![Generic badge](https://img.shields.io/badge/version-0.3.0-<COLOR>.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
|
||||
|
|
|
@ -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<String>,
|
||||
/// Basic Service Set Identifier (BSSID).
|
||||
pub bssid: Option<String>,
|
||||
/// Frequency.
|
||||
pub freq: Option<String>,
|
||||
/// Group cipher.
|
||||
pub group_cipher: Option<String>,
|
||||
/// Local ID.
|
||||
pub id: Option<String>,
|
||||
/// IP address.
|
||||
pub ip_address: Option<String>,
|
||||
/// Key management.
|
||||
pub key_mgmt: Option<String>,
|
||||
/// Mode.
|
||||
pub mode: Option<String>,
|
||||
/// Pairwise cipher.
|
||||
pub pairwise_cipher: Option<String>,
|
||||
/// SSID.
|
||||
pub ssid: Option<String>,
|
||||
/// WPA state.
|
||||
pub wpa_state: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -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<Option<String>, NetworkError> {
|
||||
/// interface, an `Ok` `Result` type is returned containing `Some(Vec<Scan>)`.
|
||||
/// 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<Option<Vec<Scan>>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, NetworkError> {
|
||||
/// `Some(Vec<Network>)`. 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<Option<Vec<Network>>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<Status>, 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<Option<Status>, 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<Option<String>, 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<Option<Traffic>, 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<Option<String>, 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<Option<String>, 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")?;
|
||||
|
|
Loading…
Reference in New Issue