feat: Added wan info, status info and devices info
Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
parent
65f1b0bc5e
commit
ffc315f3c8
@ -8,7 +8,7 @@ use serde_json::{json, Value};
|
||||
use hyper::{Method, Request, body::Body, header::{CONTENT_TYPE, SET_COOKIE, AUTHORIZATION, COOKIE}, client::HttpConnector};
|
||||
use log::{trace, debug};
|
||||
|
||||
use crate::router_info::Status;
|
||||
use crate::{status::Status, wan::WANConfiguration, devices::Device};
|
||||
|
||||
/// A structure to hold all the necessary data to connect to the router.
|
||||
pub struct Client {
|
||||
@ -112,6 +112,76 @@ impl Client {
|
||||
return status;
|
||||
}
|
||||
|
||||
/// Get WAN configuration data from the router.
|
||||
pub async fn get_wan_config(&self) -> WANConfiguration {
|
||||
assert!(!self.cookies.is_empty() && self.context_id.is_some(),
|
||||
"Cannot get status without logging in beforehand.");
|
||||
trace!("Getting router status.");
|
||||
let post_data = json!({
|
||||
"service": "NMC",
|
||||
"method": "getWANStatus",
|
||||
"parameters": {}
|
||||
});
|
||||
|
||||
let req = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri(format!("http://{}/ws", self.ip))
|
||||
.header(CONTENT_TYPE, "application/x-sah-ws-4-call+json")
|
||||
.header("X-Context", self.context_id.clone().unwrap())
|
||||
.header(COOKIE, self.cookies.join("; "))
|
||||
.body(Body::from(post_data.to_string()))
|
||||
.expect("Could not build request.");
|
||||
let (parts, body) = self.client.request(req).await
|
||||
.expect("There was an issue contacting the router.").into_parts();
|
||||
|
||||
debug!("Status is {}.", parts.status.as_str());
|
||||
let body_bytes = hyper::body::to_bytes(body).await.unwrap();
|
||||
let json: Value = serde_json::from_slice(&body_bytes)
|
||||
.expect("Could not parse JSON.");
|
||||
debug!("Body was: '{}'.", std::str::from_utf8(&body_bytes).unwrap());
|
||||
assert!(parts.status.is_success() && json["status"].as_bool().unwrap(),
|
||||
"Router answered with something else than a success code.");
|
||||
let wan_config: WANConfiguration = serde_json::from_value(json["data"].clone())
|
||||
.expect("Looks like the deserialized data is incomplete.");
|
||||
debug!("Deserialized settings is: {:?}", wan_config);
|
||||
return wan_config;
|
||||
}
|
||||
|
||||
/// Get various settings data from the router.
|
||||
pub async fn get_devices(&self) -> Vec<Device> {
|
||||
assert!(!self.cookies.is_empty() && self.context_id.is_some(),
|
||||
"Cannot get status without logging in beforehand.");
|
||||
trace!("Getting router status.");
|
||||
let post_data = json!({
|
||||
"service": "Devices",
|
||||
"method": "get",
|
||||
"parameters": {}
|
||||
});
|
||||
|
||||
let req = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri(format!("http://{}/ws", self.ip))
|
||||
.header(CONTENT_TYPE, "application/x-sah-ws-4-call+json")
|
||||
.header("X-Context", self.context_id.clone().unwrap())
|
||||
.header(COOKIE, self.cookies.join("; "))
|
||||
.body(Body::from(post_data.to_string()))
|
||||
.expect("Could not build request.");
|
||||
let (parts, body) = self.client.request(req).await
|
||||
.expect("There was an issue contacting the router.").into_parts();
|
||||
|
||||
debug!("Status is {}.", parts.status.as_str());
|
||||
let body_bytes = hyper::body::to_bytes(body).await.unwrap();
|
||||
let json: Value = serde_json::from_slice(&body_bytes)
|
||||
.expect("Could not parse JSON.");
|
||||
debug!("Body was: '{}'.", std::str::from_utf8(&body_bytes).unwrap());
|
||||
assert!(parts.status.is_success() && json["status"].is_array(),
|
||||
"Router answered with something else than a success code.");
|
||||
let devices: Vec<Device> = serde_json::from_value(json["status"].clone())
|
||||
.expect("Looks like the deserialized data is incomplete.");
|
||||
debug!("Deserialized settings is: {:?}", devices);
|
||||
return devices;
|
||||
}
|
||||
|
||||
/// Logout from the router.
|
||||
pub async fn logout(&mut self) {
|
||||
trace!("Logging out.");
|
||||
|
22
src/devices.rs
Normal file
22
src/devices.rs
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
///! All the necessary struct elements to store the router devices information.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
/// The Device structure is used to store status data from the devices that are
|
||||
/// or have been connected to the router at some point.
|
||||
#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all="PascalCase")]
|
||||
pub struct Device {
|
||||
pub key: String,
|
||||
pub name: String,
|
||||
pub discovery_source: String,
|
||||
pub active: bool,
|
||||
pub device_type: String,
|
||||
pub tags: String,
|
||||
#[serde(rename(deserialize = "IPAddress"))]
|
||||
pub ip_address: Option<String>,
|
||||
#[serde(rename(deserialize = "SSID"))]
|
||||
pub ssid: Option<String>,
|
||||
pub channel: Option<u32>,
|
||||
}
|
@ -2,4 +2,6 @@
|
||||
//! A crate aimed to gather (read only) data from a Livebox 4 or more recent.
|
||||
|
||||
pub mod client;
|
||||
pub mod router_info;
|
||||
pub mod status;
|
||||
pub mod wan;
|
||||
pub mod devices;
|
||||
|
@ -6,60 +6,37 @@ use serde::Deserialize;
|
||||
/// The Status structure is used to store status data from the router.
|
||||
#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all="PascalCase")]
|
||||
pub struct Status {
|
||||
#[serde(rename(deserialize = "Manufacturer"))]
|
||||
pub manufacturer: String,
|
||||
#[serde(rename(deserialize = "ManufacturerOUI"))]
|
||||
pub manufacturer_oui: String,
|
||||
#[serde(rename(deserialize = "ModelName"))]
|
||||
pub model_name: String,
|
||||
#[serde(rename(deserialize = "Description"))]
|
||||
pub description: String,
|
||||
#[serde(rename(deserialize = "ProductClass"))]
|
||||
pub product_class: String,
|
||||
#[serde(rename(deserialize = "SerialNumber"))]
|
||||
pub serial_number: String,
|
||||
#[serde(rename(deserialize = "HardwareVersion"))]
|
||||
pub hardware_version: String,
|
||||
#[serde(rename(deserialize = "SoftwareVersion"))]
|
||||
pub software_version: String,
|
||||
#[serde(rename(deserialize = "RescueVersion"))]
|
||||
pub rescue_version: String,
|
||||
#[serde(rename(deserialize = "ModemFirmwareVersion"))]
|
||||
pub modem_firmware_version: String,
|
||||
#[serde(rename(deserialize = "EnabledOptions"))]
|
||||
pub enabled_options: String,
|
||||
#[serde(rename(deserialize = "AdditionalHardwareVersion"))]
|
||||
pub additional_hardware_version: String,
|
||||
#[serde(rename(deserialize = "AdditionalSoftwareVersion"))]
|
||||
pub additional_software_version: String,
|
||||
#[serde(rename(deserialize = "SpecVersion"))]
|
||||
pub spec_version: String,
|
||||
#[serde(rename(deserialize = "ProvisioningCode"))]
|
||||
pub provisioning_code: String,
|
||||
#[serde(rename(deserialize = "UpTime"))]
|
||||
pub uptime: u32,
|
||||
#[serde(rename(deserialize = "FirstUseDate"))]
|
||||
pub up_time: u32,
|
||||
pub first_use_date: String,
|
||||
#[serde(rename(deserialize = "DeviceLog"))]
|
||||
pub device_log: String,
|
||||
#[serde(rename(deserialize = "VendorConfigFileNumberOfEntries"))]
|
||||
pub vendor_configfile_number_of_entries: u32,
|
||||
pub vendor_config_file_number_of_entries: u32,
|
||||
#[serde(rename(deserialize = "ManufacturerURL"))]
|
||||
pub manufacturer_url: String,
|
||||
#[serde(rename(deserialize = "Country"))]
|
||||
pub country: String,
|
||||
#[serde(rename(deserialize = "ExternalIPAddress"))]
|
||||
pub external_ip_address: String,
|
||||
#[serde(rename(deserialize = "DeviceStatus"))]
|
||||
pub device_status: String,
|
||||
#[serde(rename(deserialize = "NumberOfReboots"))]
|
||||
pub number_of_reboots: u32,
|
||||
#[serde(rename(deserialize = "UpgradeOccurred"))]
|
||||
pub upgrade_occured: bool,
|
||||
#[serde(rename(deserialize = "ResetOccurred"))]
|
||||
pub upgrade_occurred: bool,
|
||||
pub reset_occurred: bool,
|
||||
#[serde(rename(deserialize = "RestoreOccurred"))]
|
||||
pub restore_occurred: bool,
|
||||
#[serde(rename(deserialize = "X_SOFTATHOME-COM_AdditionalSoftwareVersions"))]
|
||||
pub softathome_additional_software_versions: String,
|
28
src/wan.rs
Normal file
28
src/wan.rs
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
///! The WAN configuration that you can read from the router.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
/// The WANConfiguration structure is used to store WAN configuration data from
|
||||
/// the router.
|
||||
#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all="PascalCase")]
|
||||
pub struct WANConfiguration {
|
||||
pub wan_state: String,
|
||||
pub link_type: String,
|
||||
pub link_state: String,
|
||||
#[serde(rename(deserialize = "MACAddress"))]
|
||||
pub mac_address: String,
|
||||
pub protocol: String,
|
||||
pub connection_state: String,
|
||||
pub last_connection_error: String,
|
||||
#[serde(rename(deserialize = "IPAddress"))]
|
||||
pub ip_address: String,
|
||||
pub remote_gateway: String,
|
||||
#[serde(rename(deserialize = "DNSServers"))]
|
||||
pub dns_servers: String,
|
||||
#[serde(rename(deserialize = "IPv6Address"))]
|
||||
pub ipv6_address: String,
|
||||
#[serde(rename(deserialize = "IPv6DelegatedPrefix"))]
|
||||
pub ipv6_delegated_prefix: String
|
||||
}
|
Loading…
Reference in New Issue
Block a user