use std::{collections::HashMap, str::FromStr};
use dbus::arg::{self, prop_cast, PropMap, RefArg, Variant};
pub trait PropMapConvert: Sized {
fn from_propmap(map: PropMap) -> Self;
fn to_propmap(&self, map: &mut PropMap);
}
pub trait Enum: Sized {
fn from_i32(num: i32) -> Self;
fn to_i32(&self) -> i32;
}
#[derive(Debug)]
#[allow(dead_code)]
pub struct ConversionError {
message: &'static str,
}
#[derive(Debug, Default)]
pub struct Connection {
pub settings: ConnectionSettings,
pub device: TypeSettings,
pub ipv4: IPV4Settings,
pub ipv6: IPV6Settings,
}
impl Connection {
pub fn convert_from_propmap(
map: HashMap<
std::string::String,
HashMap<std::string::String, dbus::arg::Variant<Box<dyn RefArg>>>,
>,
) -> Result<Self, ConversionError> {
let mut settings: Option<ConnectionSettings> = None;
let mut device: Option<TypeSettings> = None;
let mut ipv4: Option<IPV4Settings> = None;
let mut ipv6: Option<IPV6Settings> = None;
for (category, submap) in map {
match category.as_str() {
"802-11-wireless" => {
device = Some(TypeSettings::WIFI(WifiSettings::from_propmap(submap)))
}
"802-3-ethernet" => {
device = Some(TypeSettings::ETHERNET(EthernetSettings::from_propmap(
submap,
)))
}
"vpn" => device = Some(TypeSettings::VPN(VPNSettings::from_propmap(submap))),
"ipv6" => ipv6 = Some(IPV6Settings::from_propmap(submap)),
"ipv4" => ipv4 = Some(IPV4Settings::from_propmap(submap)),
"connection" => settings = Some(ConnectionSettings::from_propmap(submap)),
_ => continue,
}
}
if settings.is_none() | device.is_none() | ipv4.is_none() | ipv6.is_none() {
return Err(ConversionError {
message: "could not convert propmap",
});
}
let settings = settings.unwrap();
let device = device.unwrap();
let ipv4 = ipv4.unwrap();
let ipv6 = ipv6.unwrap();
Ok(Self {
settings,
device,
ipv4,
ipv6,
})
}
pub fn convert_to_propmap(&self) -> PropMap {
let mut map = PropMap::new();
self.settings.to_propmap(&mut map);
match &self.device {
TypeSettings::WIFI(wifi) => wifi.to_propmap(&mut map),
TypeSettings::ETHERNET(ethernet) => ethernet.to_propmap(&mut map),
TypeSettings::VPN(vpn) => vpn.to_propmap(&mut map),
TypeSettings::None => (),
}
self.ipv4.to_propmap(&mut map);
self.ipv6.to_propmap(&mut map);
map
}
}
#[derive(Clone, Copy, Default, Debug)]
pub enum Trust {
HOME,
WORK,
PUBLIC,
#[default]
DEFAULT,
}
impl FromStr for Trust {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Home" => Ok(Trust::HOME),
"Work" => Ok(Trust::WORK),
"Public" => Ok(Trust::PUBLIC),
_ => Ok(Trust::DEFAULT),
}
}
}
impl ToString for Trust {
fn to_string(&self) -> String {
match self {
Trust::HOME => String::from("Home"),
Trust::WORK => String::from("Work"),
Trust::PUBLIC => String::from("Public"),
Trust::DEFAULT => String::from("null"),
}
}
}
impl Enum for Trust {
fn from_i32(num: i32) -> Self {
match num {
0 => Trust::HOME,
1 => Trust::WORK,
2 => Trust::PUBLIC,
_ => Trust::DEFAULT,
}
}
fn to_i32(&self) -> i32 {
match self {
Trust::HOME => 0,
Trust::WORK => 1,
Trust::PUBLIC => 2,
Trust::DEFAULT => 3,
}
}
}
#[derive(Default, Debug, Clone)]
pub enum Mode {
#[default]
INFRASTRUCTURE,
ADHOC,
AP,
}
impl FromStr for Mode {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"adhoc" => Ok(Mode::ADHOC),
"ap" => Ok(Mode::AP),
_ => Ok(Mode::INFRASTRUCTURE),
}
}
}
impl ToString for Mode {
fn to_string(&self) -> String {
match self {
Mode::ADHOC => String::from("adhoc"),
Mode::AP => String::from("ap"),
Mode::INFRASTRUCTURE => String::from("infrastructure"),
}
}
}
impl Enum for Mode {
fn from_i32(num: i32) -> Self {
match num {
0 => Mode::INFRASTRUCTURE,
1 => Mode::ADHOC,
_ => Mode::AP,
}
}
fn to_i32(&self) -> i32 {
match self {
Mode::INFRASTRUCTURE => 0,
Mode::ADHOC => 1,
Mode::AP => 2,
}
}
}
#[derive(Default, Debug, Clone)]
pub enum Band {
_5GHZ,
_24GHZ,
#[default]
DYN,
}
impl FromStr for Band {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"a" => Ok(Band::_5GHZ),
"bg" => Ok(Band::_24GHZ),
_ => Ok(Band::DYN),
}
}
}
impl ToString for Band {
fn to_string(&self) -> String {
match self {
Band::_5GHZ => String::from("bg"),
Band::_24GHZ => String::from("a"),
Band::DYN => String::from(""),
}
}
}
impl Enum for Band {
fn from_i32(num: i32) -> Self {
match num {
0 => Band::_5GHZ,
1 => Band::_24GHZ,
_ => Band::DYN,
}
}
fn to_i32(&self) -> i32 {
match self {
Band::_5GHZ => 0,
Band::_24GHZ => 1,
Band::DYN => 2,
}
}
}
#[derive(Default, Debug, Clone)]
pub enum Duplex {
HALF,
#[default]
FULL,
}
impl FromStr for Duplex {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"half" => Ok(Duplex::HALF),
_ => Ok(Duplex::FULL),
}
}
}
impl ToString for Duplex {
fn to_string(&self) -> String {
match self {
Duplex::HALF => String::from("half"),
Duplex::FULL => String::from("full"),
}
}
}
impl Enum for Duplex {
fn from_i32(num: i32) -> Self {
match num {
0 => Duplex::HALF,
_ => Duplex::FULL,
}
}
fn to_i32(&self) -> i32 {
match self {
Duplex::HALF => 0,
Duplex::FULL => 1,
}
}
}
#[derive(Debug, Default)]
pub enum TypeSettings {
WIFI(WifiSettings),
ETHERNET(EthernetSettings),
VPN(VPNSettings),
#[default]
None,
}
impl ToString for TypeSettings {
fn to_string(&self) -> String {
match self {
TypeSettings::WIFI(_) => String::from("wifi"),
TypeSettings::ETHERNET(_) => String::from("ethernet"),
TypeSettings::VPN(_) => String::from("vpn"),
TypeSettings::None => String::from(""),
}
}
}
#[derive(Debug, Clone, Default)]
pub struct EthernetSettings {
pub auto_negotiate: bool,
pub cloned_mac_address: String,
pub duplex: Duplex,
pub mtu: u32,
pub name: String,
pub speed: u32,
}
impl PropMapConvert for EthernetSettings {
fn from_propmap(map: PropMap) -> Self {
let auto_negotiate: Option<&bool> = prop_cast(&map, "auto-negotiate");
let cloned_mac_address: String;
let cloned_address_opt: Option<&String> = prop_cast(&map, "cloned-mac-address");
if cloned_address_opt.is_none() {
cloned_mac_address = String::from("");
} else {
cloned_mac_address = cloned_address_opt.unwrap().clone();
}
let duplex: Duplex;
let duplex_opt: Option<&String> = prop_cast(&map, "mode");
if duplex_opt.is_none() {
duplex = Duplex::FULL;
} else {
duplex = Duplex::from_str(duplex_opt.unwrap().as_str()).ok().unwrap();
}
let mtu: Option<&u32> = prop_cast(&map, "mtu");
let name: String;
let name_opt: Option<&String> = prop_cast(&map, "name");
if name_opt.is_none() {
name = String::from("");
} else {
name = name_opt.unwrap().clone();
}
let speed: Option<&u32> = prop_cast(&map, "speed");
Self {
auto_negotiate: *auto_negotiate.unwrap_or_else(|| &true),
cloned_mac_address,
duplex,
mtu: *mtu.unwrap_or_else(|| &0),
name,
speed: *speed.unwrap_or_else(|| &0),
}
}
fn to_propmap(&self, map: &mut PropMap) {
map.insert(
"auto-negotiate".into(),
Variant(Box::new(self.auto_negotiate)),
);
map.insert("duplex".into(), Variant(Box::new(self.duplex.to_i32())));
map.insert("mtu".into(), Variant(Box::new(self.mtu)));
map.insert("name".into(), Variant(Box::new(self.name.clone())));
map.insert("speed".into(), Variant(Box::new(self.speed)));
}
}
#[derive(Debug, Clone)]
pub struct VPNSettings {
pub data: HashMap<String, String>,
pub name: String,
pub persistent: bool,
pub secrets: HashMap<String, String>,
pub service_type: String,
pub timeout: u32,
pub user_name: String,
}
impl PropMapConvert for VPNSettings {
fn from_propmap(map: PropMap) -> Self {
let data: HashMap<String, String>;
let name: String;
let secrets: HashMap<String, String>;
let service_type: String;
let user_name: String;
let data_opt: Option<&HashMap<String, String>> = prop_cast(&map, "data");
if data_opt.is_none() {
data = HashMap::new();
} else {
data = data_opt.unwrap().clone();
}
let name_opt: Option<&String> = prop_cast(&map, "name");
if name_opt.is_none() {
name = String::from("vpn");
} else {
name = name_opt.unwrap().clone();
}
let persistent: Option<&bool> = prop_cast(&map, "persistent");
let secrets_opt: Option<&HashMap<String, String>> = prop_cast(&map, "secrets");
if secrets_opt.is_none() {
secrets = HashMap::new();
} else {
secrets = secrets_opt.unwrap().clone();
}
let service_type_opt: Option<&String> = prop_cast(&map, "service-type");
if service_type_opt.is_none() {
service_type = String::from("");
} else {
service_type = service_type_opt.unwrap().clone();
}
let timeout: Option<&u32> = prop_cast(&map, "timeout");
let user_name_opt: Option<&String> = prop_cast(&map, "user-name");
if user_name_opt.is_none() {
user_name = String::from("");
} else {
user_name = user_name_opt.unwrap().clone();
}
Self {
data,
name,
persistent: *persistent.unwrap_or_else(|| &false),
secrets,
service_type,
timeout: *timeout.unwrap_or_else(|| &0),
user_name,
}
}
fn to_propmap(&self, map: &mut PropMap) {
map.insert("data".into(), Variant(Box::new(self.data.clone())));
map.insert("name".into(), Variant(Box::new(self.name.clone())));
map.insert("persistent".into(), Variant(Box::new(self.persistent)));
map.insert("secrets".into(), Variant(Box::new(self.secrets.clone())));
map.insert(
"service-type".into(),
Variant(Box::new(self.service_type.clone())),
);
map.insert("timeout".into(), Variant(Box::new(self.timeout)));
map.insert(
"user-name".into(),
Variant(Box::new(self.user_name.clone())),
);
}
}
#[derive(Debug, Clone)]
pub struct WifiSettings {
pub band: Band,
pub channel: u32,
pub cloned_mac_address: String,
pub mode: Mode,
pub mtu: u32,
pub powersave: u32,
pub rate: u32,
pub ssid: Vec<u8>,
pub security_settings: WifiSecuritySettings,
}
impl PropMapConvert for WifiSettings {
fn from_propmap(map: PropMap) -> Self {
println!("wifi debug");
for (key, val) in map.iter() {
dbg!(key);
dbg!(val);
}
let mode: Mode;
let band: Band;
let mode_opt: Option<&String> = prop_cast(&map, "mode");
if mode_opt.is_none() {
mode = Mode::from_str("").ok().unwrap();
} else {
mode = Mode::from_str(mode_opt.unwrap().as_str()).ok().unwrap();
}
let channel_opt: Option<&u32> = prop_cast(&map, "channel");
let channel = *channel_opt.unwrap_or(&0);
let band_opt: Option<&String> = prop_cast(&map, "band");
if band_opt.is_none() {
band = Band::from_str("").ok().unwrap();
} else {
band = Band::from_str(band_opt.unwrap().as_str()).ok().unwrap();
}
let cloned_mac_address: String;
let cloned_address_opt: Option<&String> = prop_cast(&map, "cloned-mac-address");
if cloned_address_opt.is_none() {
cloned_mac_address = String::from("");
} else {
cloned_mac_address = cloned_address_opt.unwrap().clone();
}
let mtu_opt: Option<&u32> = prop_cast(&map, "mtu");
let mtu = *mtu_opt.unwrap_or(&0);
let powersave_opt: Option<&u32> = prop_cast(&map, "powersave");
let powersave = *powersave_opt.unwrap_or(&0);
let rate_opt: Option<&u32> = prop_cast(&map, "rate");
let rate = *rate_opt.unwrap_or(&0);
let ssid: Vec<u8>;
let ssid_opt: Option<&Vec<u8>> = prop_cast(&map, "ssid");
if ssid_opt.is_none() {
ssid = Vec::new();
} else {
ssid = ssid_opt.unwrap().clone();
}
let security_settings = WifiSecuritySettings::from_propmap(map);
Self {
band,
channel,
cloned_mac_address,
mode,
mtu,
powersave,
rate,
ssid,
security_settings,
}
}
fn to_propmap(&self, map: &mut PropMap) {
map.insert("band".into(), Variant(Box::new(self.band.to_i32())));
map.insert("channel".into(), Variant(Box::new(self.channel)));
map.insert("mode".into(), Variant(Box::new(self.mode.to_i32())));
map.insert("mtu".into(), Variant(Box::new(self.mtu)));
map.insert("powersave".into(), Variant(Box::new(self.powersave)));
map.insert("rate".into(), Variant(Box::new(self.rate)));
map.insert("ssid".into(), Variant(Box::new(self.ssid.clone())));
self.security_settings.to_propmap(map);
}
}
#[derive(Debug)]
#[allow(dead_code)]
pub struct X802Settings {
pub ca_cert: Vec<u8>,
pub ca_cert_string: String,
pub client_cert: Vec<u8>,
pub domain_suffix: String,
pub eap: Vec<String>,
pub identity: String,
pub pac_file: String,
pub password: String,
pub password_flags: u32,
pub password_raw_flags: Vec<u8>,
}
#[derive(Debug)]
pub struct Address {
address: String,
prefix_length: u32,
gateway: Option<String>,
metric: Option<u32>,
}
impl Address {
pub fn to_map(&self) -> PropMap {
let mut map = PropMap::new();
map.insert("address".into(), Variant(Box::new(self.address.clone())));
map.insert(
"prefix-length".into(),
Variant(Box::new(self.prefix_length)),
);
if self.gateway.is_some() {
map.insert(
"gateway".into(),
Variant(Box::new(self.gateway.clone().unwrap())),
);
}
if self.metric.is_some() {
map.insert("metric".into(), Variant(Box::new(self.metric.unwrap())));
}
map
}
}
#[derive(Debug, Default)]
pub enum DNSMethod4 {
#[default]
AUTO,
MANUAL,
LINKLOCAL,
SHARED,
DISABLED,
}
impl FromStr for DNSMethod4 {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"auto" => Ok(DNSMethod4::AUTO),
"manual" => Ok(DNSMethod4::MANUAL),
"link-local" => Ok(DNSMethod4::LINKLOCAL),
"shared" => Ok(DNSMethod4::SHARED),
_ => Ok(DNSMethod4::DISABLED),
}
}
}
impl ToString for DNSMethod4 {
fn to_string(&self) -> String {
match self {
DNSMethod4::AUTO => String::from("auto"),
DNSMethod4::MANUAL => String::from("manual"),
DNSMethod4::LINKLOCAL => String::from("link-local"),
DNSMethod4::SHARED => String::from("shared"),
DNSMethod4::DISABLED => String::from("disabled"),
}
}
}
impl Enum for DNSMethod4 {
fn from_i32(num: i32) -> Self {
match num {
0 => DNSMethod4::AUTO,
1 => DNSMethod4::MANUAL,
2 => DNSMethod4::LINKLOCAL,
3 => DNSMethod4::SHARED,
_ => DNSMethod4::DISABLED,
}
}
fn to_i32(&self) -> i32 {
match self {
DNSMethod4::AUTO => 0,
DNSMethod4::MANUAL => 1,
DNSMethod4::LINKLOCAL => 2,
DNSMethod4::SHARED => 3,
DNSMethod4::DISABLED => 4,
}
}
}
#[derive(Debug, Default)]
pub enum DNSMethod6 {
#[default]
AUTO,
DHCP,
MANUAL,
LINKLOCAL,
SHARED,
DISABLED,
}
impl FromStr for DNSMethod6 {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"auto" => Ok(DNSMethod6::AUTO),
"dhcp" => Ok(DNSMethod6::DHCP),
"manual" => Ok(DNSMethod6::MANUAL),
"link-local" => Ok(DNSMethod6::LINKLOCAL),
"shared" => Ok(DNSMethod6::SHARED),
_ => Ok(DNSMethod6::DISABLED),
}
}
}
impl ToString for DNSMethod6 {
fn to_string(&self) -> String {
match self {
DNSMethod6::AUTO => String::from("auto"),
DNSMethod6::DHCP => String::from("dhcp"),
DNSMethod6::MANUAL => String::from("manual"),
DNSMethod6::LINKLOCAL => String::from("link-local"),
DNSMethod6::SHARED => String::from("shared"),
DNSMethod6::DISABLED => String::from("disabled"),
}
}
}
impl Enum for DNSMethod6 {
fn from_i32(num: i32) -> Self {
match num {
0 => DNSMethod6::AUTO,
1 => DNSMethod6::DHCP,
2 => DNSMethod6::MANUAL,
3 => DNSMethod6::LINKLOCAL,
4 => DNSMethod6::SHARED,
_ => DNSMethod6::DISABLED,
}
}
fn to_i32(&self) -> i32 {
match self {
DNSMethod6::AUTO => 0,
DNSMethod6::DHCP => 1,
DNSMethod6::MANUAL => 2,
DNSMethod6::LINKLOCAL => 3,
DNSMethod6::SHARED => 4,
DNSMethod6::DISABLED => 5,
}
}
}
#[derive(Debug, Default)]
pub struct IPV4Settings {
pub address_data: Vec<Address>,
pub dns: Vec<Vec<u8>>,
pub dns_options: Vec<String>,
pub dns_priority: i32,
pub dns_search: Vec<String>,
pub gateway: String,
pub ignore_auto_dns: bool,
pub ignore_auto_dns_routes: bool,
pub may_fail: bool,
pub dns_method: DNSMethod4,
pub never_default: bool,
pub route_data: Vec<Address>,
}
impl PropMapConvert for IPV4Settings {
fn from_propmap(map: PropMap) -> Self {
println!("ipv4 debug");
for (key, val) in map.iter() {
dbg!(key);
dbg!(val);
}
let address_data = get_addresses(&map, "address-data");
let dns: Vec<Vec<u8>>;
let dns_opt: Option<&Vec<Vec<u8>>> = prop_cast(&map, "dns");
if dns_opt.is_none() {
dns = Vec::new();
} else {
dns = dns_opt.unwrap().clone();
}
let dns_options: Vec<String>;
let dns_options_opt: Option<&Vec<String>> = prop_cast(&map, "dns-options");
if dns_options_opt.is_none() {
dns_options = Vec::new();
} else {
dns_options = dns_options_opt.unwrap().clone();
}
let dns_priority = *prop_cast(&map, "dns-priority").unwrap_or_else(|| &0);
let dns_search: Vec<String>;
let dns_search_opt: Option<&Vec<String>> = prop_cast(&map, "dns-search");
if dns_search_opt.is_none() {
dns_search = Vec::new();
} else {
dns_search = dns_search_opt.unwrap().clone();
}
let gateway: String;
let gateway_opt: Option<&String> = prop_cast(&map, "gateway");
if gateway_opt.is_none() {
gateway = String::from("");
} else {
gateway = gateway_opt.unwrap().clone();
}
let ignore_auto_dns = *prop_cast(&map, "ignore-auto-dns").unwrap_or_else(|| &false);
let ignore_auto_dns_routes =
*prop_cast(&map, "ignore-auto-dns-routes").unwrap_or_else(|| &false);
let may_fail = *prop_cast(&map, "may-fail").unwrap_or_else(|| &true);
let dns_method: DNSMethod4;
let method_opt: Option<&String> = prop_cast(&map, "method");
if method_opt.is_none() {
dns_method = DNSMethod4::DISABLED;
} else {
dns_method = DNSMethod4::from_str(method_opt.unwrap().as_str()).unwrap();
}
let never_default = *prop_cast(&map, "never-default").unwrap_or_else(|| &true);
let route_data = get_addresses(&map, "route-data");
Self {
address_data,
dns,
dns_options,
dns_priority,
dns_search,
gateway,
ignore_auto_dns,
ignore_auto_dns_routes,
may_fail,
dns_method,
never_default,
route_data,
}
}
fn to_propmap(&self, map: &mut PropMap) {
let mut addresses = Vec::new();
for address in self.address_data.iter() {
addresses.push(address.to_map());
}
map.insert("address-data".into(), Variant(Box::new(addresses)));
map.insert("dns".into(), Variant(Box::new(self.dns.clone())));
map.insert(
"dns-options".into(),
Variant(Box::new(self.dns_options.clone())),
);
map.insert("dns-priority".into(), Variant(Box::new(self.dns_priority)));
map.insert(
"dns-search".into(),
Variant(Box::new(self.dns_search.clone())),
);
map.insert("gateway".into(), Variant(Box::new(self.gateway.clone())));
map.insert(
"ignore-auto-dns".into(),
Variant(Box::new(self.ignore_auto_dns)),
);
map.insert(
"ignore-auto-dns-routes".into(),
Variant(Box::new(self.ignore_auto_dns_routes)),
);
map.insert("may-fail".into(), Variant(Box::new(self.may_fail)));
map.insert(
"dns-method".into(),
Variant(Box::new(self.dns_method.to_i32())),
);
map.insert(
"never-default".into(),
Variant(Box::new(self.never_default)),
);
let mut data = Vec::new();
for address in self.route_data.iter() {
data.push(address.to_map());
}
map.insert("route-data".into(), Variant(Box::new(data)));
}
}
#[derive(Debug, Default)]
pub enum IPV6PrivacyMode {
DISABLED,
ENABLEDPEFERPUBLIC,
ENABLEDPEFERTEMPORARY,
#[default]
UNKNOWN,
}
impl FromStr for IPV6PrivacyMode {
type Err = ConversionError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"disabled" => Ok(IPV6PrivacyMode::DISABLED),
"enabled-prefer-public" => Ok(IPV6PrivacyMode::ENABLEDPEFERPUBLIC),
"enabled-prefer-temporary" => Ok(IPV6PrivacyMode::ENABLEDPEFERTEMPORARY),
_ => Ok(IPV6PrivacyMode::UNKNOWN),
}
}
}
impl ToString for IPV6PrivacyMode {
fn to_string(&self) -> String {
match self {
IPV6PrivacyMode::UNKNOWN => String::from("unknown"),
IPV6PrivacyMode::DISABLED => String::from("disabled"),
IPV6PrivacyMode::ENABLEDPEFERPUBLIC => String::from("enabled-prefer-public"),
IPV6PrivacyMode::ENABLEDPEFERTEMPORARY => String::from("enabled-prefer-temporary"),
}
}
}
impl Enum for IPV6PrivacyMode {
fn from_i32(num: i32) -> Self {
match num {
-1 => IPV6PrivacyMode::UNKNOWN,
0 => IPV6PrivacyMode::DISABLED,
1 => IPV6PrivacyMode::ENABLEDPEFERPUBLIC,
_ => IPV6PrivacyMode::ENABLEDPEFERTEMPORARY,
}
}
fn to_i32(&self) -> i32 {
match self {
IPV6PrivacyMode::UNKNOWN => -1,
IPV6PrivacyMode::DISABLED => 0,
IPV6PrivacyMode::ENABLEDPEFERPUBLIC => 1,
IPV6PrivacyMode::ENABLEDPEFERTEMPORARY => 2,
}
}
}
#[derive(Debug, Default)]
pub struct IPV6Settings {
pub address_data: Vec<Address>,
pub dns: Vec<Vec<u8>>,
pub dns_options: Vec<String>,
pub dns_priority: i32,
pub dns_search: Vec<String>,
pub gateway: String,
pub ignore_auto_dns: bool,
pub ignore_auto_dns_routes: bool,
pub ipv6_privacy: IPV6PrivacyMode,
pub may_fail: bool,
pub dns_method: DNSMethod6,
pub never_default: bool,
pub route_data: Vec<Address>,
}
impl PropMapConvert for IPV6Settings {
fn from_propmap(map: PropMap) -> Self {
println!("ipv6 debug");
for (key, val) in map.iter() {
dbg!(key);
dbg!(val);
}
let address_data = get_addresses(&map, "address-data");
let dns: Vec<Vec<u8>>;
let dns_opt: Option<&Vec<Vec<u8>>> = prop_cast(&map, "dns");
if dns_opt.is_none() {
dns = Vec::new();
} else {
dns = dns_opt.unwrap().clone();
}
let dns_options: Vec<String>;
let dns_options_opt: Option<&Vec<String>> = prop_cast(&map, "dns-options");
if dns_options_opt.is_none() {
dns_options = Vec::new();
} else {
dns_options = dns_options_opt.unwrap().clone();
}
let dns_priority = *prop_cast(&map, "dns-priority").unwrap_or_else(|| &0);
let dns_search: Vec<String>;
let dns_search_opt: Option<&Vec<String>> = prop_cast(&map, "dns-search");
if dns_search_opt.is_none() {
dns_search = Vec::new();
} else {
dns_search = dns_search_opt.unwrap().clone();
}
let gateway: String;
let gateway_opt: Option<&String> = prop_cast(&map, "gateway");
if gateway_opt.is_none() {
gateway = String::from("");
} else {
gateway = gateway_opt.unwrap().clone();
}
let ignore_auto_dns = *prop_cast(&map, "ignore-auto-dns").unwrap_or_else(|| &false);
let ignore_auto_dns_routes =
*prop_cast(&map, "ignore-auto-dns-routes").unwrap_or_else(|| &false);
let ipv6_privacy =
IPV6PrivacyMode::from_i32(*prop_cast(&map, "ip6-privacy").unwrap_or_else(|| &-1));
let may_fail = *prop_cast(&map, "may-fail").unwrap_or_else(|| &true);
let dns_method: DNSMethod6;
let method_opt: Option<&String> = prop_cast(&map, "method");
if method_opt.is_none() {
dns_method = DNSMethod6::DISABLED;
} else {
dns_method = DNSMethod6::from_str(method_opt.unwrap().as_str()).unwrap();
}
let never_default = *prop_cast(&map, "never-default").unwrap_or_else(|| &true);
let route_data = get_addresses(&map, "route-data");
Self {
address_data,
dns,
dns_options,
dns_priority,
dns_search,
gateway,
ignore_auto_dns,
ignore_auto_dns_routes,
ipv6_privacy,
may_fail,
dns_method,
never_default,
route_data,
}
}
fn to_propmap(&self, map: &mut PropMap) {
let mut addresses = Vec::new();
for address in self.address_data.iter() {
addresses.push(address.to_map());
}
map.insert("address-data".into(), Variant(Box::new(addresses)));
map.insert("dns".into(), Variant(Box::new(self.dns.clone())));
map.insert(
"dns-options".into(),
Variant(Box::new(self.dns_options.clone())),
);
map.insert("dns-priority".into(), Variant(Box::new(self.dns_priority)));
map.insert(
"dns-search".into(),
Variant(Box::new(self.dns_search.clone())),
);
map.insert("gateway".into(), Variant(Box::new(self.gateway.clone())));
map.insert(
"ignore-auto-dns".into(),
Variant(Box::new(self.ignore_auto_dns)),
);
map.insert(
"ignore-auto-dns-routes".into(),
Variant(Box::new(self.ignore_auto_dns_routes)),
);
map.insert(
"ipv6-privacy".into(),
Variant(Box::new(self.ipv6_privacy.to_i32())),
);
map.insert("may-fail".into(), Variant(Box::new(self.may_fail)));
map.insert(
"dns-method".into(),
Variant(Box::new(self.dns_method.to_i32())),
);
map.insert(
"never-default".into(),
Variant(Box::new(self.never_default)),
);
let mut data = Vec::new();
for address in self.route_data.iter() {
data.push(address.to_map());
}
map.insert("route-data".into(), Variant(Box::new(data)));
}
}
fn get_addresses(map: &PropMap, address_type: &'static str) -> Vec<Address> {
let mut address_data: Vec<Address> = Vec::new();
let address_data_opt: Option<&Vec<PropMap>> = prop_cast(map, address_type);
if address_data_opt.is_some() {
for entry in address_data_opt.unwrap() {
let address: String;
let prefix_length: u32;
let gateway: Option<String>;
let metric: Option<u32>;
let address_opt = entry.get("address");
let prefix_length_opt = entry.get("prefix");
let gateway_opt = entry.get("gateway");
let metric_opt = entry.get("metric");
if address_data_opt.is_none() {
address = String::from("");
} else {
address = arg::cast::<String>(address_opt.unwrap()).unwrap().clone();
}
if prefix_length_opt.is_none() {
prefix_length = 0;
} else {
prefix_length = arg::cast::<u32>(prefix_length_opt.unwrap())
.unwrap()
.clone();
}
if gateway_opt.is_none() {
gateway = None;
} else {
gateway = arg::cast::<Option<String>>(address_opt.unwrap())
.unwrap()
.clone();
}
if metric_opt.is_none() {
metric = None;
} else {
metric = *arg::cast::<Option<u32>>(gateway_opt.unwrap()).unwrap();
}
address_data.push(Address {
address,
prefix_length,
gateway,
metric,
})
}
}
address_data
}
#[derive(Debug, Default)]
pub struct ConnectionSettings {
pub autoconnect: bool,
pub autoconnect_priority: i32,
pub metered: i32,
pub name: String,
pub device_type: String,
pub uuid: String,
pub zone: Trust,
}
impl PropMapConvert for ConnectionSettings {
fn from_propmap(map: PropMap) -> Self {
println!("settings debug");
for (key, val) in map.iter() {
dbg!(key);
dbg!(val);
}
let autoconnect = prop_cast(&map, "autoconnect");
let autoconnect_priority = prop_cast(&map, "autoconnect-priority");
let uuid: String;
let name: String;
let device_type: String;
let metered = prop_cast(&map, "metered");
let zone: Trust;
let zone_opt: Option<&String> = prop_cast(&map, "trust");
if zone_opt.is_none() {
zone = Trust::from_str("").ok().unwrap();
} else {
zone = Trust::from_str(zone_opt.unwrap().as_str()).ok().unwrap();
}
let uuid_opt: Option<&String> = prop_cast(&map, "uuid");
if uuid_opt.is_none() {
uuid = String::from("");
} else {
uuid = uuid_opt.unwrap().clone();
}
let name_opt: Option<&String> = prop_cast(&map, "name");
if name_opt.is_none() {
name = String::from("");
} else {
name = name_opt.unwrap().clone();
}
let device_type_opt: Option<&String> = prop_cast(&map, "type");
if device_type_opt.is_none() {
device_type = String::from("");
} else {
device_type = device_type_opt.unwrap().clone();
}
Self {
autoconnect: *autoconnect.unwrap_or_else(|| &false),
autoconnect_priority: *autoconnect_priority.unwrap_or_else(|| &-1),
metered: *metered.unwrap_or_else(|| &-1),
name,
device_type,
uuid,
zone,
}
}
fn to_propmap(&self, map: &mut PropMap) {
map.insert("autoconnect".into(), Variant(Box::new(self.autoconnect)));
map.insert(
"autoconnect-priority".into(),
Variant(Box::new(self.autoconnect_priority)),
);
map.insert("metered".into(), Variant(Box::new(self.metered)));
map.insert("name".into(), Variant(Box::new(self.name.clone())));
map.insert(
"device-type".into(),
Variant(Box::new(self.device_type.clone())),
);
map.insert("uuid".into(), Variant(Box::new(self.uuid.clone())));
map.insert("zone".into(), Variant(Box::new(self.zone.to_i32())));
}
}
#[derive(Debug, Default, Clone)]
pub enum SecretSettingsFlag {
#[default]
NONE,
AGENT_OWNED,
NOT_SAVED,
NOT_REQUIRED,
}
impl Enum for SecretSettingsFlag {
fn from_i32(num: i32) -> Self {
match num {
0 => SecretSettingsFlag::NONE,
1 => SecretSettingsFlag::AGENT_OWNED,
2 => SecretSettingsFlag::NOT_SAVED,
_ => SecretSettingsFlag::NOT_REQUIRED,
}
}
fn to_i32(&self) -> i32 {
match self {
SecretSettingsFlag::NONE => 0,
SecretSettingsFlag::AGENT_OWNED => 1,
SecretSettingsFlag::NOT_SAVED => 2,
SecretSettingsFlag::NOT_REQUIRED => 3,
}
}
}
#[derive(Debug, Default, Clone)]
pub enum WEPKeyType {
#[default]
UNKNOWN,
KEY,
PASSPHRASE,
LAST,
}
impl Enum for WEPKeyType {
fn from_i32(num: i32) -> Self {
match num {
0 => WEPKeyType::UNKNOWN,
1 => WEPKeyType::KEY,
2 => WEPKeyType::PASSPHRASE,
_ => WEPKeyType::LAST,
}
}
fn to_i32(&self) -> i32 {
match self {
WEPKeyType::UNKNOWN => 0,
WEPKeyType::KEY => 1,
WEPKeyType::PASSPHRASE => 2,
WEPKeyType::LAST => 3,
}
}
}
#[derive(Debug, Default, Clone)]
pub struct WifiSecuritySettings {
pub authentication_algorithm: String,
pub group: Vec<String>,
pub key_management: String,
pub leap_password: String,
pub leap_password_flags: SecretSettingsFlag,
pub leap_username: String,
pub name: String,
pub pairwise: Vec<String>,
pub proto: Vec<String>,
pub psk: String,
pub psk_flags: SecretSettingsFlag,
pub wep_key_flags: SecretSettingsFlag,
pub wep_key_type: WEPKeyType,
pub wep_key0: String,
pub wep_key1: String,
pub wep_key2: String,
pub wep_key3: String,
pub wep_tx_keyidx: u32,
}
impl PropMapConvert for WifiSecuritySettings {
fn from_propmap(map: PropMap) -> Self {
println!("secret settings debug");
let authentication_algorithm: String;
let authentication_algorithm_opt: Option<&String> = prop_cast(&map, "auth-alg");
if authentication_algorithm_opt.is_none() {
authentication_algorithm = String::from("");
} else {
authentication_algorithm = authentication_algorithm_opt.unwrap().clone();
}
let group: Vec<String>;
let group_opt: Option<&Vec<String>> = prop_cast(&map, "group");
if group_opt.is_none() {
group = Vec::new();
} else {
group = group_opt.unwrap().clone();
}
let key_management: String;
let key_management_opt: Option<&String> = prop_cast(&map, "key-mgmt");
if key_management_opt.is_none() {
key_management = String::from("");
} else {
key_management = key_management_opt.unwrap().clone();
}
let leap_password: String;
let leap_password_opt: Option<&String> = prop_cast(&map, "leap-password");
if leap_password_opt.is_none() {
leap_password = String::from("");
} else {
leap_password = leap_password_opt.unwrap().clone();
}
let leap_password_flags_opt: Option<&u32> = prop_cast(&map, "leap-password-flags");
let leap_password_flags =
SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
let leap_username: String;
let leap_username_opt: Option<&String> = prop_cast(&map, "leap-username");
if leap_username_opt.is_none() {
leap_username = String::from("");
} else {
leap_username = leap_username_opt.unwrap().clone();
}
let name: String;
let name_opt: Option<&String> = prop_cast(&map, "name");
if name_opt.is_none() {
name = String::from("");
} else {
name = name_opt.unwrap().clone();
}
let pairwise: Vec<String>;
let pairwise_opt: Option<&Vec<String>> = prop_cast(&map, "pairwise");
if pairwise_opt.is_none() {
pairwise = Vec::new();
} else {
pairwise = pairwise_opt.unwrap().clone();
}
let proto: Vec<String>;
let proto_opt: Option<&Vec<String>> = prop_cast(&map, "proto");
if proto_opt.is_none() {
proto = Vec::new();
} else {
proto = proto_opt.unwrap().clone();
}
let psk: String;
let psk_opt: Option<&String> = prop_cast(&map, "psk");
if psk_opt.is_none() {
psk = String::from("");
} else {
psk = psk_opt.unwrap().clone();
}
let psk_flags_opt: Option<&u32> = prop_cast(&map, "psk-flags");
let psk_flags = SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
let wep_key_flags_opt: Option<&u32> = prop_cast(&map, "wep-key-flags");
let wep_key_flags =
SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
let wep_key_type_opt: Option<&u32> = prop_cast(&map, "wep-key-type");
let wep_key_type = WEPKeyType::from_i32(*wep_key_type_opt.unwrap_or(&0) as i32);
let wep_key0: String;
let wep_key0_opt: Option<&String> = prop_cast(&map, "wep-key0");
if wep_key0_opt.is_none() {
wep_key0 = String::from("");
} else {
wep_key0 = wep_key0_opt.unwrap().clone();
}
let wep_key1: String;
let wep_key1_opt: Option<&String> = prop_cast(&map, "wep-key1");
if wep_key1_opt.is_none() {
wep_key1 = String::from("");
} else {
wep_key1 = wep_key1_opt.unwrap().clone();
}
let wep_key2: String;
let wep_key2_opt: Option<&String> = prop_cast(&map, "wep-key2");
if wep_key2_opt.is_none() {
wep_key2 = String::from("");
} else {
wep_key2 = wep_key2_opt.unwrap().clone();
}
let wep_key3: String;
let wep_key3_opt: Option<&String> = prop_cast(&map, "wep-key3");
if wep_key3_opt.is_none() {
wep_key3 = String::from("");
} else {
wep_key3 = wep_key3_opt.unwrap().clone();
}
let wep_tx_keyidx: Option<&u32> = prop_cast(&map, "wep-tx-keyidx");
Self {
authentication_algorithm,
group,
key_management,
leap_password,
leap_password_flags,
leap_username,
name,
pairwise,
proto,
psk,
psk_flags,
wep_key_flags,
wep_key_type,
wep_key0,
wep_key1,
wep_key2,
wep_key3,
wep_tx_keyidx: *wep_tx_keyidx.unwrap_or(&0),
}
}
fn to_propmap(&self, map: &mut PropMap) {
map.insert(
"auth-alg".into(),
Variant(Box::new(self.authentication_algorithm.clone())),
);
map.insert("group".into(), Variant(Box::new(self.group.clone())));
map.insert(
"key-mgmt".into(),
Variant(Box::new(self.key_management.clone())),
);
map.insert(
"leap-password".into(),
Variant(Box::new(self.leap_password.clone())),
);
map.insert(
"leap-password-flags".into(),
Variant(Box::new(self.leap_password_flags.to_i32())),
);
map.insert(
"leap-username".into(),
Variant(Box::new(self.leap_username.clone())),
);
map.insert("name".into(), Variant(Box::new(self.name.clone())));
map.insert("pairwise".into(), Variant(Box::new(self.pairwise.clone())));
map.insert("proto".into(), Variant(Box::new(self.proto.clone())));
map.insert("psk".into(), Variant(Box::new(self.psk.clone())));
map.insert(
"psk-flags".into(),
Variant(Box::new(self.psk_flags.to_i32())),
);
map.insert(
"wep-key-type".into(),
Variant(Box::new(self.wep_key_type.to_i32())),
);
map.insert("wep-key0".into(), Variant(Box::new(self.wep_key0.clone())));
map.insert("wep-key1".into(), Variant(Box::new(self.wep_key1.clone())));
map.insert("wep-key2".into(), Variant(Box::new(self.wep_key2.clone())));
map.insert("wep-key3".into(), Variant(Box::new(self.wep_key3.clone())));
map.insert(
"wep-tx-keyidx".into(),
Variant(Box::new(self.wep_tx_keyidx)),
);
}
}