1use std::{collections::HashMap, str::FromStr};
2
3use dbus::arg::{self, prop_cast, PropMap, RefArg, Variant};
4
5
6pub trait PropMapConvert: Sized {
7 fn from_propmap(map: PropMap) -> Self;
8 fn to_propmap(&self, map: &mut PropMap);
9}
10
11pub trait Enum: Sized {
12 fn from_i32(num: i32) -> Self;
13 fn to_i32(&self) -> i32;
14}
15
16#[derive(Debug)]
17#[allow(dead_code)]
18pub struct ConversionError {
19 message: &'static str,
20}
21
22#[derive(Debug, Default)]
23pub struct Connection {
24 pub settings: ConnectionSettings,
25 pub device: TypeSettings,
27 pub ipv4: IPV4Settings,
28 pub ipv6: IPV6Settings,
29 }
32
33impl Connection {
34 pub fn convert_from_propmap(
35 map: HashMap<
36 std::string::String,
37 HashMap<std::string::String, dbus::arg::Variant<Box<dyn RefArg>>>,
38 >,
39 ) -> Result<Self, ConversionError> {
40 let mut settings: Option<ConnectionSettings> = None;
41 let mut device: Option<TypeSettings> = None;
43 let mut ipv4: Option<IPV4Settings> = None;
44 let mut ipv6: Option<IPV6Settings> = None;
45 for (category, submap) in map {
46 match category.as_str() {
47 "802-11-wireless" => {
48 device = Some(TypeSettings::WIFI(WifiSettings::from_propmap(submap)))
49 }
50 "802-3-ethernet" => {
51 device = Some(TypeSettings::ETHERNET(EthernetSettings::from_propmap(
52 submap,
53 )))
54 }
55 "vpn" => device = Some(TypeSettings::VPN(VPNSettings::from_propmap(submap))),
56 "ipv6" => ipv6 = Some(IPV6Settings::from_propmap(submap)),
57 "ipv4" => ipv4 = Some(IPV4Settings::from_propmap(submap)),
58 "connection" => settings = Some(ConnectionSettings::from_propmap(submap)),
59 _ => continue,
61 }
62 }
63 if settings.is_none() | device.is_none() | ipv4.is_none() | ipv6.is_none() {
64 return Err(ConversionError {
65 message: "could not convert propmap",
66 });
67 }
68 let settings = settings.unwrap();
69 let device = device.unwrap();
71 let ipv4 = ipv4.unwrap();
72 let ipv6 = ipv6.unwrap();
73 Ok(Self {
74 settings,
75 device,
77 ipv4,
78 ipv6,
79 })
80 }
81
82 pub fn convert_to_propmap(&self) -> PropMap {
83 let mut map = PropMap::new();
84 self.settings.to_propmap(&mut map);
85 match &self.device {
86 TypeSettings::WIFI(wifi) => wifi.to_propmap(&mut map),
87 TypeSettings::ETHERNET(ethernet) => ethernet.to_propmap(&mut map),
88 TypeSettings::VPN(vpn) => vpn.to_propmap(&mut map),
89 TypeSettings::None => (),
90 }
91 self.ipv4.to_propmap(&mut map);
92 self.ipv6.to_propmap(&mut map);
93 map
94 }
95}
96
97#[derive(Clone, Copy, Default, Debug)]
98pub enum Trust {
99 HOME,
100 WORK,
101 PUBLIC,
102 #[default]
103 DEFAULT,
104}
105
106impl FromStr for Trust {
107 type Err = ConversionError;
108
109 fn from_str(s: &str) -> Result<Self, Self::Err> {
110 match s {
111 "Home" => Ok(Trust::HOME),
112 "Work" => Ok(Trust::WORK),
113 "Public" => Ok(Trust::PUBLIC),
114 _ => Ok(Trust::DEFAULT),
115 }
116 }
117}
118
119impl ToString for Trust {
120 fn to_string(&self) -> String {
121 match self {
122 Trust::HOME => String::from("Home"),
123 Trust::WORK => String::from("Work"),
124 Trust::PUBLIC => String::from("Public"),
125 Trust::DEFAULT => String::from("null"),
126 }
127 }
128}
129
130impl Enum for Trust {
131 fn from_i32(num: i32) -> Self {
132 match num {
133 0 => Trust::HOME,
134 1 => Trust::WORK,
135 2 => Trust::PUBLIC,
136 _ => Trust::DEFAULT,
137 }
138 }
139
140 fn to_i32(&self) -> i32 {
141 match self {
142 Trust::HOME => 0,
143 Trust::WORK => 1,
144 Trust::PUBLIC => 2,
145 Trust::DEFAULT => 3,
146 }
147 }
148}
149
150#[derive(Default, Debug, Clone)]
151pub enum Mode {
152 #[default]
153 INFRASTRUCTURE,
154 ADHOC,
155 AP,
156}
157
158impl FromStr for Mode {
159 type Err = ConversionError;
160
161 fn from_str(s: &str) -> Result<Self, Self::Err> {
162 match s {
163 "adhoc" => Ok(Mode::ADHOC),
164 "ap" => Ok(Mode::AP),
165 _ => Ok(Mode::INFRASTRUCTURE),
166 }
167 }
168}
169
170impl ToString for Mode {
171 fn to_string(&self) -> String {
172 match self {
173 Mode::ADHOC => String::from("adhoc"),
174 Mode::AP => String::from("ap"),
175 Mode::INFRASTRUCTURE => String::from("infrastructure"),
176 }
177 }
178}
179
180impl Enum for Mode {
181 fn from_i32(num: i32) -> Self {
182 match num {
183 0 => Mode::INFRASTRUCTURE,
184 1 => Mode::ADHOC,
185 _ => Mode::AP,
186 }
187 }
188
189 fn to_i32(&self) -> i32 {
190 match self {
191 Mode::INFRASTRUCTURE => 0,
192 Mode::ADHOC => 1,
193 Mode::AP => 2,
194 }
195 }
196}
197
198#[derive(Default, Debug, Clone)]
199pub enum Band {
200 _5GHZ,
201 _24GHZ,
202 #[default]
203 DYN,
204}
205
206impl FromStr for Band {
207 type Err = ConversionError;
208
209 fn from_str(s: &str) -> Result<Self, Self::Err> {
210 match s {
211 "a" => Ok(Band::_5GHZ),
212 "bg" => Ok(Band::_24GHZ),
213 _ => Ok(Band::DYN),
214 }
215 }
216}
217
218impl ToString for Band {
219 fn to_string(&self) -> String {
220 match self {
221 Band::_5GHZ => String::from("bg"),
222 Band::_24GHZ => String::from("a"),
223 Band::DYN => String::from(""),
224 }
225 }
226}
227
228impl Enum for Band {
229 fn from_i32(num: i32) -> Self {
230 match num {
231 0 => Band::_5GHZ,
232 1 => Band::_24GHZ,
233 _ => Band::DYN,
234 }
235 }
236
237 fn to_i32(&self) -> i32 {
238 match self {
239 Band::_5GHZ => 0,
240 Band::_24GHZ => 1,
241 Band::DYN => 2,
242 }
243 }
244}
245
246#[derive(Default, Debug, Clone)]
247pub enum Duplex {
248 HALF,
249 #[default]
250 FULL,
251}
252
253impl FromStr for Duplex {
254 type Err = ConversionError;
255
256 fn from_str(s: &str) -> Result<Self, Self::Err> {
257 match s {
258 "half" => Ok(Duplex::HALF),
259 _ => Ok(Duplex::FULL),
260 }
261 }
262}
263
264impl ToString for Duplex {
265 fn to_string(&self) -> String {
266 match self {
267 Duplex::HALF => String::from("half"),
268 Duplex::FULL => String::from("full"),
269 }
270 }
271}
272
273impl Enum for Duplex {
274 fn from_i32(num: i32) -> Self {
275 match num {
276 0 => Duplex::HALF,
277 _ => Duplex::FULL,
278 }
279 }
280
281 fn to_i32(&self) -> i32 {
282 match self {
283 Duplex::HALF => 0,
284 Duplex::FULL => 1,
285 }
286 }
287}
288
289#[derive(Debug, Default)]
290pub enum TypeSettings {
291 WIFI(WifiSettings),
292 ETHERNET(EthernetSettings),
293 VPN(VPNSettings),
294 #[default]
295 None,
296}
297
298impl ToString for TypeSettings {
299 fn to_string(&self) -> String {
300 match self {
301 TypeSettings::WIFI(_) => String::from("wifi"),
302 TypeSettings::ETHERNET(_) => String::from("ethernet"),
303 TypeSettings::VPN(_) => String::from("vpn"),
304 TypeSettings::None => String::from(""),
305 }
306 }
307}
308
309#[derive(Debug, Clone, Default)]
310pub struct EthernetSettings {
311 pub auto_negotiate: bool,
312 pub cloned_mac_address: String,
313 pub duplex: Duplex,
314 pub mtu: u32,
315 pub name: String,
316 pub speed: u32,
317}
318
319impl PropMapConvert for EthernetSettings {
320 fn from_propmap(map: PropMap) -> Self {
321 let auto_negotiate: Option<&bool> = prop_cast(&map, "auto-negotiate");
322 let cloned_mac_address: String;
323 let cloned_address_opt: Option<&String> = prop_cast(&map, "cloned-mac-address");
324 if cloned_address_opt.is_none() {
325 cloned_mac_address = String::from("");
326 } else {
327 cloned_mac_address = cloned_address_opt.unwrap().clone();
328 }
329 let duplex: Duplex;
330 let duplex_opt: Option<&String> = prop_cast(&map, "mode");
331 if duplex_opt.is_none() {
332 duplex = Duplex::FULL;
333 } else {
334 duplex = Duplex::from_str(duplex_opt.unwrap().as_str()).ok().unwrap();
335 }
336 let mtu: Option<&u32> = prop_cast(&map, "mtu");
337 let name: String;
338 let name_opt: Option<&String> = prop_cast(&map, "name");
339 if name_opt.is_none() {
340 name = String::from("");
341 } else {
342 name = name_opt.unwrap().clone();
343 }
344 let speed: Option<&u32> = prop_cast(&map, "speed");
345 Self {
346 auto_negotiate: *auto_negotiate.unwrap_or(&true),
347 cloned_mac_address,
348 duplex,
349 mtu: *mtu.unwrap_or(&0),
350 name,
351 speed: *speed.unwrap_or(&0),
352 }
353 }
354
355 fn to_propmap(&self, map: &mut PropMap) {
356 map.insert(
357 "auto-negotiate".into(),
358 Variant(Box::new(self.auto_negotiate)),
359 );
360 map.insert("duplex".into(), Variant(Box::new(self.duplex.to_i32())));
361 map.insert("mtu".into(), Variant(Box::new(self.mtu)));
362 map.insert("name".into(), Variant(Box::new(self.name.clone())));
363 map.insert("speed".into(), Variant(Box::new(self.speed)));
364 }
365}
366
367#[derive(Debug, Clone)]
368pub struct VPNSettings {
369 pub data: HashMap<String, String>,
370 pub name: String,
371 pub persistent: bool,
372 pub secrets: HashMap<String, String>,
373 pub service_type: String,
374 pub timeout: u32,
375 pub user_name: String,
376}
377
378impl PropMapConvert for VPNSettings {
379 fn from_propmap(map: PropMap) -> Self {
380 let data: HashMap<String, String>;
381 let name: String;
382 let secrets: HashMap<String, String>;
383 let service_type: String;
384 let user_name: String;
385
386 let data_opt: Option<&HashMap<String, String>> = prop_cast(&map, "data");
387 if data_opt.is_none() {
388 data = HashMap::new();
389 } else {
390 data = data_opt.unwrap().clone();
391 }
392 let name_opt: Option<&String> = prop_cast(&map, "name");
393 if name_opt.is_none() {
394 name = String::from("vpn");
395 } else {
396 name = name_opt.unwrap().clone();
397 }
398 let persistent: Option<&bool> = prop_cast(&map, "persistent");
399 let secrets_opt: Option<&HashMap<String, String>> = prop_cast(&map, "secrets");
400 if secrets_opt.is_none() {
401 secrets = HashMap::new();
402 } else {
403 secrets = secrets_opt.unwrap().clone();
404 }
405 let service_type_opt: Option<&String> = prop_cast(&map, "service-type");
406 if service_type_opt.is_none() {
407 service_type = String::from("");
408 } else {
409 service_type = service_type_opt.unwrap().clone();
410 }
411 let timeout: Option<&u32> = prop_cast(&map, "timeout");
412 let user_name_opt: Option<&String> = prop_cast(&map, "user-name");
413 if user_name_opt.is_none() {
414 user_name = String::from("");
415 } else {
416 user_name = user_name_opt.unwrap().clone();
417 }
418 Self {
419 data,
420 name,
421 persistent: *persistent.unwrap_or(&false),
422 secrets,
423 service_type,
424 timeout: *timeout.unwrap_or(&0),
425 user_name,
426 }
427 }
428
429 fn to_propmap(&self, map: &mut PropMap) {
430 map.insert("data".into(), Variant(Box::new(self.data.clone())));
431 map.insert("name".into(), Variant(Box::new(self.name.clone())));
432 map.insert("persistent".into(), Variant(Box::new(self.persistent)));
433 map.insert("secrets".into(), Variant(Box::new(self.secrets.clone())));
434 map.insert(
435 "service-type".into(),
436 Variant(Box::new(self.service_type.clone())),
437 );
438 map.insert("timeout".into(), Variant(Box::new(self.timeout)));
439 map.insert(
440 "user-name".into(),
441 Variant(Box::new(self.user_name.clone())),
442 );
443 }
444}
445
446#[derive(Debug, Clone)]
447pub struct WifiSettings {
448 pub band: Band,
449 pub channel: u32,
450 pub cloned_mac_address: String,
451 pub mode: Mode,
452 pub mtu: u32,
453 pub powersave: u32,
454 pub rate: u32,
455 pub ssid: Vec<u8>,
456 pub security_settings: WifiSecuritySettings,
457}
458
459impl PropMapConvert for WifiSettings {
460 fn from_propmap(map: PropMap) -> Self {
461 println!("wifi debug");
462 for (key, val) in map.iter() {
463 dbg!(key);
464 dbg!(val);
465 }
466 let mode: Mode;
467 let band: Band;
468 let mode_opt: Option<&String> = prop_cast(&map, "mode");
469 if mode_opt.is_none() {
470 mode = Mode::from_str("").ok().unwrap();
471 } else {
472 mode = Mode::from_str(mode_opt.unwrap().as_str()).ok().unwrap();
473 }
474 let channel_opt: Option<&u32> = prop_cast(&map, "channel");
475 let channel = *channel_opt.unwrap_or(&0);
476 let band_opt: Option<&String> = prop_cast(&map, "band");
477 if band_opt.is_none() {
478 band = Band::from_str("").ok().unwrap();
479 } else {
480 band = Band::from_str(band_opt.unwrap().as_str()).ok().unwrap();
481 }
482 let cloned_mac_address: String;
483 let cloned_address_opt: Option<&String> = prop_cast(&map, "cloned-mac-address");
484 if cloned_address_opt.is_none() {
485 cloned_mac_address = String::from("");
486 } else {
487 cloned_mac_address = cloned_address_opt.unwrap().clone();
488 }
489 let mtu_opt: Option<&u32> = prop_cast(&map, "mtu");
490 let mtu = *mtu_opt.unwrap_or(&0);
491 let powersave_opt: Option<&u32> = prop_cast(&map, "powersave");
492 let powersave = *powersave_opt.unwrap_or(&0);
493 let rate_opt: Option<&u32> = prop_cast(&map, "rate");
494 let rate = *rate_opt.unwrap_or(&0);
495 let ssid: Vec<u8>;
496 let ssid_opt: Option<&Vec<u8>> = prop_cast(&map, "ssid");
497 if ssid_opt.is_none() {
498 ssid = Vec::new();
499 } else {
500 ssid = ssid_opt.unwrap().clone();
501 }
502 let security_settings = WifiSecuritySettings::from_propmap(map);
503 Self {
504 band,
505 channel,
506 cloned_mac_address,
507 mode,
508 mtu,
509 powersave,
510 rate,
511 ssid,
512 security_settings,
513 }
514 }
515
516 fn to_propmap(&self, map: &mut PropMap) {
517 map.insert("band".into(), Variant(Box::new(self.band.to_i32())));
518 map.insert("channel".into(), Variant(Box::new(self.channel)));
519 map.insert("mode".into(), Variant(Box::new(self.mode.to_i32())));
520 map.insert("mtu".into(), Variant(Box::new(self.mtu)));
521 map.insert("powersave".into(), Variant(Box::new(self.powersave)));
522 map.insert("rate".into(), Variant(Box::new(self.rate)));
523 map.insert("ssid".into(), Variant(Box::new(self.ssid.clone())));
524 self.security_settings.to_propmap(map);
525 }
526}
527
528#[derive(Debug)]
529#[allow(dead_code)]
530pub struct X802Settings {
531 pub ca_cert: Vec<u8>,
532 pub ca_cert_string: String,
533 pub client_cert: Vec<u8>,
534 pub domain_suffix: String,
535 pub eap: Vec<String>,
536 pub identity: String,
537 pub pac_file: String,
538 pub password: String,
539 pub password_flags: u32,
540 pub password_raw_flags: Vec<u8>,
541}
542
543#[derive(Debug, Default)]
630pub struct Address {
631 pub address: String,
632 pub prefix_length: u32,
633 pub gateway: Option<String>,
634 pub metric: Option<u32>,
635}
636
637impl Address {
638 pub fn new(address: String, prefix_length: u32, gateway: Option<String>, metric: Option<u32>) -> Self {
639 Address { address, prefix_length, gateway, metric }
640 }
641
642 pub fn theBetterNew(address: String, prefix_length: u32) -> Self {
643 Address { address, prefix_length, gateway: None, metric: None }
644 }
645
646 pub fn to_map(&self) -> PropMap {
647 let mut map = PropMap::new();
648 map.insert("address".into(), Variant(Box::new(self.address.clone())));
649 map.insert(
650 "prefix-length".into(),
651 Variant(Box::new(self.prefix_length)),
652 );
653 if self.gateway.is_some() {
654 map.insert(
655 "gateway".into(),
656 Variant(Box::new(self.gateway.clone().unwrap())),
657 );
658 }
659 if self.metric.is_some() {
660 map.insert("metric".into(), Variant(Box::new(self.metric.unwrap())));
661 }
662 map
663 }
664}
665
666#[derive(Debug, Default)]
667pub enum DNSMethod4 {
668 #[default]
669 AUTO,
670 MANUAL,
671 LINKLOCAL,
672 SHARED,
673 DISABLED,
674}
675
676impl FromStr for DNSMethod4 {
677 type Err = ConversionError;
678
679 fn from_str(s: &str) -> Result<Self, Self::Err> {
680 match s {
681 "auto" => Ok(DNSMethod4::AUTO),
682 "manual" => Ok(DNSMethod4::MANUAL),
683 "link-local" => Ok(DNSMethod4::LINKLOCAL),
684 "shared" => Ok(DNSMethod4::SHARED),
685 _ => Ok(DNSMethod4::DISABLED),
686 }
687 }
688}
689
690impl ToString for DNSMethod4 {
691 fn to_string(&self) -> String {
692 match self {
693 DNSMethod4::AUTO => String::from("auto"),
694 DNSMethod4::MANUAL => String::from("manual"),
695 DNSMethod4::LINKLOCAL => String::from("link-local"),
696 DNSMethod4::SHARED => String::from("shared"),
697 DNSMethod4::DISABLED => String::from("disabled"),
698 }
699 }
700}
701
702impl Enum for DNSMethod4 {
703 fn from_i32(num: i32) -> Self {
704 match num {
705 0 => DNSMethod4::AUTO,
706 1 => DNSMethod4::MANUAL,
707 2 => DNSMethod4::LINKLOCAL,
708 3 => DNSMethod4::SHARED,
709 _ => DNSMethod4::DISABLED,
710 }
711 }
712
713 fn to_i32(&self) -> i32 {
714 match self {
715 DNSMethod4::AUTO => 0,
716 DNSMethod4::MANUAL => 1,
717 DNSMethod4::LINKLOCAL => 2,
718 DNSMethod4::SHARED => 3,
719 DNSMethod4::DISABLED => 4,
720 }
721 }
722}
723
724#[derive(Debug, Default)]
725pub enum DNSMethod6 {
726 #[default]
727 AUTO,
728 DHCP,
729 MANUAL,
730 LINKLOCAL,
731 SHARED,
732 DISABLED,
733}
734
735impl FromStr for DNSMethod6 {
736 type Err = ConversionError;
737
738 fn from_str(s: &str) -> Result<Self, Self::Err> {
739 match s {
740 "auto" => Ok(DNSMethod6::AUTO),
741 "dhcp" => Ok(DNSMethod6::DHCP),
742 "manual" => Ok(DNSMethod6::MANUAL),
743 "link-local" => Ok(DNSMethod6::LINKLOCAL),
744 "shared" => Ok(DNSMethod6::SHARED),
745 _ => Ok(DNSMethod6::DISABLED),
746 }
747 }
748}
749
750impl ToString for DNSMethod6 {
751 fn to_string(&self) -> String {
752 match self {
753 DNSMethod6::AUTO => String::from("auto"),
754 DNSMethod6::DHCP => String::from("dhcp"),
755 DNSMethod6::MANUAL => String::from("manual"),
756 DNSMethod6::LINKLOCAL => String::from("link-local"),
757 DNSMethod6::SHARED => String::from("shared"),
758 DNSMethod6::DISABLED => String::from("disabled"),
759 }
760 }
761}
762
763impl Enum for DNSMethod6 {
764 fn from_i32(num: i32) -> Self {
765 match num {
766 0 => DNSMethod6::AUTO,
767 1 => DNSMethod6::DHCP,
768 2 => DNSMethod6::MANUAL,
769 3 => DNSMethod6::LINKLOCAL,
770 4 => DNSMethod6::SHARED,
771 _ => DNSMethod6::DISABLED,
772 }
773 }
774
775 fn to_i32(&self) -> i32 {
776 match self {
777 DNSMethod6::AUTO => 0,
778 DNSMethod6::DHCP => 1,
779 DNSMethod6::MANUAL => 2,
780 DNSMethod6::LINKLOCAL => 3,
781 DNSMethod6::SHARED => 4,
782 DNSMethod6::DISABLED => 5,
783 }
784 }
785}
786
787#[derive(Debug, Default)]
788pub struct IPV4Settings {
789 pub address_data: Vec<Address>,
790 pub dns: Vec<Vec<u8>>,
791 pub dns_options: Vec<String>,
792 pub dns_priority: i32,
793 pub dns_search: Vec<String>,
794 pub gateway: String,
795 pub ignore_auto_dns: bool,
796 pub ignore_auto_dns_routes: bool,
797 pub may_fail: bool,
798 pub dns_method: DNSMethod4,
799 pub never_default: bool,
800 pub route_data: Vec<Address>,
801}
802
803impl PropMapConvert for IPV4Settings {
804 fn from_propmap(map: PropMap) -> Self {
805 println!("ipv4 debug");
806 for (key, val) in map.iter() {
807 dbg!(key);
808 dbg!(val);
809 }
810 let address_data = get_addresses(&map, "address-data");
811 let dns: Vec<Vec<u8>>;
812 let dns_opt: Option<&Vec<Vec<u8>>> = prop_cast(&map, "dns");
813 if dns_opt.is_none() {
814 dns = Vec::new();
815 } else {
816 dns = dns_opt.unwrap().clone();
817 }
818 let dns_options: Vec<String>;
819 let dns_options_opt: Option<&Vec<String>> = prop_cast(&map, "dns-options");
820 if dns_options_opt.is_none() {
821 dns_options = Vec::new();
822 } else {
823 dns_options = dns_options_opt.unwrap().clone();
824 }
825 let dns_priority = *prop_cast(&map, "dns-priority").unwrap_or(&0);
826 let dns_search: Vec<String>;
827 let dns_search_opt: Option<&Vec<String>> = prop_cast(&map, "dns-search");
828 if dns_search_opt.is_none() {
829 dns_search = Vec::new();
830 } else {
831 dns_search = dns_search_opt.unwrap().clone();
832 }
833 let gateway: String;
834 let gateway_opt: Option<&String> = prop_cast(&map, "gateway");
835 if gateway_opt.is_none() {
836 gateway = String::from("");
837 } else {
838 gateway = gateway_opt.unwrap().clone();
839 }
840 let ignore_auto_dns = *prop_cast(&map, "ignore-auto-dns").unwrap_or(&false);
841 let ignore_auto_dns_routes = *prop_cast(&map, "ignore-auto-dns-routes").unwrap_or(&false);
842 let may_fail = *prop_cast(&map, "may-fail").unwrap_or(&true);
843 let dns_method: DNSMethod4;
844 let method_opt: Option<&String> = prop_cast(&map, "method");
845 if method_opt.is_none() {
846 dns_method = DNSMethod4::DISABLED;
847 } else {
848 dns_method = DNSMethod4::from_str(method_opt.unwrap().as_str()).unwrap();
849 }
850 let never_default = *prop_cast(&map, "never-default").unwrap_or(&true);
851 let route_data = get_addresses(&map, "route-data");
852 Self {
853 address_data,
854 dns,
855 dns_options,
856 dns_priority,
857 dns_search,
858 gateway,
859 ignore_auto_dns,
860 ignore_auto_dns_routes,
861 may_fail,
862 dns_method,
863 never_default,
864 route_data,
865 }
866 }
867
868 fn to_propmap(&self, map: &mut PropMap) {
869 let mut addresses = Vec::new();
870 for address in self.address_data.iter() {
871 addresses.push(address.to_map());
872 }
873 map.insert("address-data".into(), Variant(Box::new(addresses)));
874 map.insert("dns".into(), Variant(Box::new(self.dns.clone())));
875 map.insert(
876 "dns-options".into(),
877 Variant(Box::new(self.dns_options.clone())),
878 );
879 map.insert("dns-priority".into(), Variant(Box::new(self.dns_priority)));
880 map.insert(
881 "dns-search".into(),
882 Variant(Box::new(self.dns_search.clone())),
883 );
884 map.insert("gateway".into(), Variant(Box::new(self.gateway.clone())));
885 map.insert(
886 "ignore-auto-dns".into(),
887 Variant(Box::new(self.ignore_auto_dns)),
888 );
889 map.insert(
890 "ignore-auto-dns-routes".into(),
891 Variant(Box::new(self.ignore_auto_dns_routes)),
892 );
893 map.insert("may-fail".into(), Variant(Box::new(self.may_fail)));
894 map.insert(
895 "dns-method".into(),
896 Variant(Box::new(self.dns_method.to_i32())),
897 );
898 map.insert(
899 "never-default".into(),
900 Variant(Box::new(self.never_default)),
901 );
902 let mut data = Vec::new();
903 for address in self.route_data.iter() {
904 data.push(address.to_map());
905 }
906 map.insert("route-data".into(), Variant(Box::new(data)));
907 }
908}
909
910#[derive(Debug, Default)]
911pub enum IPV6PrivacyMode {
912 DISABLED,
913 ENABLEDPEFERPUBLIC,
914 ENABLEDPEFERTEMPORARY,
915 #[default]
916 UNKNOWN,
917}
918
919impl FromStr for IPV6PrivacyMode {
920 type Err = ConversionError;
921
922 fn from_str(s: &str) -> Result<Self, Self::Err> {
923 match s {
924 "disabled" => Ok(IPV6PrivacyMode::DISABLED),
925 "enabled-prefer-public" => Ok(IPV6PrivacyMode::ENABLEDPEFERPUBLIC),
926 "enabled-prefer-temporary" => Ok(IPV6PrivacyMode::ENABLEDPEFERTEMPORARY),
927 _ => Ok(IPV6PrivacyMode::UNKNOWN),
928 }
929 }
930}
931
932impl ToString for IPV6PrivacyMode {
933 fn to_string(&self) -> String {
934 match self {
935 IPV6PrivacyMode::UNKNOWN => String::from("unknown"),
936 IPV6PrivacyMode::DISABLED => String::from("disabled"),
937 IPV6PrivacyMode::ENABLEDPEFERPUBLIC => String::from("enabled-prefer-public"),
938 IPV6PrivacyMode::ENABLEDPEFERTEMPORARY => String::from("enabled-prefer-temporary"),
939 }
940 }
941}
942
943impl Enum for IPV6PrivacyMode {
944 fn from_i32(num: i32) -> Self {
945 match num {
946 -1 => IPV6PrivacyMode::UNKNOWN,
947 0 => IPV6PrivacyMode::DISABLED,
948 1 => IPV6PrivacyMode::ENABLEDPEFERPUBLIC,
949 _ => IPV6PrivacyMode::ENABLEDPEFERTEMPORARY,
950 }
951 }
952
953 fn to_i32(&self) -> i32 {
954 match self {
955 IPV6PrivacyMode::UNKNOWN => -1,
956 IPV6PrivacyMode::DISABLED => 0,
957 IPV6PrivacyMode::ENABLEDPEFERPUBLIC => 1,
958 IPV6PrivacyMode::ENABLEDPEFERTEMPORARY => 2,
959 }
960 }
961}
962
963#[derive(Debug, Default)]
964pub struct IPV6Settings {
965 pub address_data: Vec<Address>,
966 pub dns: Vec<Vec<u8>>,
967 pub dns_options: Vec<String>,
968 pub dns_priority: i32,
969 pub dns_search: Vec<String>,
970 pub gateway: String,
971 pub ignore_auto_dns: bool,
972 pub ignore_auto_dns_routes: bool,
973 pub ipv6_privacy: IPV6PrivacyMode,
974 pub may_fail: bool,
975 pub dns_method: DNSMethod6,
976 pub never_default: bool,
977 pub route_data: Vec<Address>,
978}
979
980impl PropMapConvert for IPV6Settings {
981 fn from_propmap(map: PropMap) -> Self {
982 println!("ipv6 debug");
983 for (key, val) in map.iter() {
984 dbg!(key);
985 dbg!(val);
986 }
987 let address_data = get_addresses(&map, "address-data");
988 let dns: Vec<Vec<u8>>;
989 let dns_opt: Option<&Vec<Vec<u8>>> = prop_cast(&map, "dns");
990 if dns_opt.is_none() {
991 dns = Vec::new();
992 } else {
993 dns = dns_opt.unwrap().clone();
994 }
995 let dns_options: Vec<String>;
996 let dns_options_opt: Option<&Vec<String>> = prop_cast(&map, "dns-options");
997 if dns_options_opt.is_none() {
998 dns_options = Vec::new();
999 } else {
1000 dns_options = dns_options_opt.unwrap().clone();
1001 }
1002 let dns_priority = *prop_cast(&map, "dns-priority").unwrap_or(&0);
1003 let dns_search: Vec<String>;
1004 let dns_search_opt: Option<&Vec<String>> = prop_cast(&map, "dns-search");
1005 if dns_search_opt.is_none() {
1006 dns_search = Vec::new();
1007 } else {
1008 dns_search = dns_search_opt.unwrap().clone();
1009 }
1010 let gateway: String;
1011 let gateway_opt: Option<&String> = prop_cast(&map, "gateway");
1012 if gateway_opt.is_none() {
1013 gateway = String::from("");
1014 } else {
1015 gateway = gateway_opt.unwrap().clone();
1016 }
1017 let ignore_auto_dns = *prop_cast(&map, "ignore-auto-dns").unwrap_or(&false);
1018 let ignore_auto_dns_routes = *prop_cast(&map, "ignore-auto-dns-routes").unwrap_or(&false);
1019 let ipv6_privacy = IPV6PrivacyMode::from_i32(*prop_cast(&map, "ip6-privacy").unwrap_or(&-1));
1020 let may_fail = *prop_cast(&map, "may-fail").unwrap_or(&true);
1021 let dns_method: DNSMethod6;
1022 let method_opt: Option<&String> = prop_cast(&map, "method");
1023 if method_opt.is_none() {
1024 dns_method = DNSMethod6::DISABLED;
1025 } else {
1026 dns_method = DNSMethod6::from_str(method_opt.unwrap().as_str()).unwrap();
1027 }
1028 let never_default = *prop_cast(&map, "never-default").unwrap_or(&true);
1029 let route_data = get_addresses(&map, "route-data");
1030 Self {
1031 address_data,
1032 dns,
1033 dns_options,
1034 dns_priority,
1035 dns_search,
1036 gateway,
1037 ignore_auto_dns,
1038 ignore_auto_dns_routes,
1039 ipv6_privacy,
1040 may_fail,
1041 dns_method,
1042 never_default,
1043 route_data,
1044 }
1045 }
1046
1047 fn to_propmap(&self, map: &mut PropMap) {
1048 let mut addresses = Vec::new();
1049 for address in self.address_data.iter() {
1050 addresses.push(address.to_map());
1051 }
1052 map.insert("address-data".into(), Variant(Box::new(addresses)));
1053 map.insert("dns".into(), Variant(Box::new(self.dns.clone())));
1054 map.insert(
1055 "dns-options".into(),
1056 Variant(Box::new(self.dns_options.clone())),
1057 );
1058 map.insert("dns-priority".into(), Variant(Box::new(self.dns_priority)));
1059 map.insert(
1060 "dns-search".into(),
1061 Variant(Box::new(self.dns_search.clone())),
1062 );
1063 map.insert("gateway".into(), Variant(Box::new(self.gateway.clone())));
1064 map.insert(
1065 "ignore-auto-dns".into(),
1066 Variant(Box::new(self.ignore_auto_dns)),
1067 );
1068 map.insert(
1069 "ignore-auto-dns-routes".into(),
1070 Variant(Box::new(self.ignore_auto_dns_routes)),
1071 );
1072 map.insert(
1073 "ipv6-privacy".into(),
1074 Variant(Box::new(self.ipv6_privacy.to_i32())),
1075 );
1076 map.insert("may-fail".into(), Variant(Box::new(self.may_fail)));
1077 map.insert(
1078 "dns-method".into(),
1079 Variant(Box::new(self.dns_method.to_i32())),
1080 );
1081 map.insert(
1082 "never-default".into(),
1083 Variant(Box::new(self.never_default)),
1084 );
1085 let mut data = Vec::new();
1086 for address in self.route_data.iter() {
1087 data.push(address.to_map());
1088 }
1089 map.insert("route-data".into(), Variant(Box::new(data)));
1090 }
1091}
1092
1093fn get_addresses(map: &PropMap, address_type: &'static str) -> Vec<Address> {
1094 let mut address_data: Vec<Address> = Vec::new();
1095 let address_data_opt: Option<&Vec<PropMap>> = prop_cast(map, address_type);
1096 if address_data_opt.is_some() {
1097 for entry in address_data_opt.unwrap() {
1098 let address: String;
1099 let prefix_length: u32;
1100 let gateway: Option<String>;
1101 let metric: Option<u32>;
1102 let address_opt = entry.get("address");
1103 let prefix_length_opt = entry.get("prefix");
1104 let gateway_opt = entry.get("gateway");
1105 let metric_opt = entry.get("metric");
1106 if address_data_opt.is_none() {
1107 address = String::from("");
1108 } else {
1109 address = arg::cast::<String>(address_opt.unwrap()).unwrap().clone();
1110 }
1111 if prefix_length_opt.is_none() {
1112 prefix_length = 0;
1113 } else {
1114 prefix_length = *arg::cast::<u32>(prefix_length_opt.unwrap()).unwrap();
1115 }
1116 if gateway_opt.is_none() {
1117 gateway = None;
1118 } else {
1119 gateway = arg::cast::<Option<String>>(address_opt.unwrap()).unwrap().clone();
1120 }
1121 if metric_opt.is_none() {
1122 metric = None;
1123 } else {
1124 metric = *arg::cast::<Option<u32>>(gateway_opt.unwrap()).unwrap();
1125 }
1126
1127 address_data.push(Address {
1128 address,
1129 prefix_length,
1130 gateway,
1131 metric,
1132 })
1133 }
1134 }
1135 address_data
1136}
1137
1138#[derive(Debug, Default)]
1139pub struct ConnectionSettings {
1140 pub autoconnect: bool,
1141 pub autoconnect_priority: i32,
1142 pub metered: i32,
1143 pub name: String,
1144 pub device_type: String,
1145 pub uuid: String,
1146 pub zone: Trust,
1147}
1148
1149impl PropMapConvert for ConnectionSettings {
1150 fn from_propmap(map: PropMap) -> Self {
1151 println!("settings debug");
1152 for (key, val) in map.iter() {
1153 dbg!(key);
1154 dbg!(val);
1155 }
1156 let autoconnect = prop_cast(&map, "autoconnect");
1157 let autoconnect_priority = prop_cast(&map, "autoconnect-priority");
1158 let uuid: String;
1159 let name: String;
1160 let device_type: String;
1161 let metered = prop_cast(&map, "metered");
1162 let zone: Trust;
1163 let zone_opt: Option<&String> = prop_cast(&map, "trust");
1164 if zone_opt.is_none() {
1165 zone = Trust::from_str("").ok().unwrap();
1166 } else {
1167 zone = Trust::from_str(zone_opt.unwrap().as_str()).ok().unwrap();
1168 }
1169
1170 let uuid_opt: Option<&String> = prop_cast(&map, "uuid");
1171 if uuid_opt.is_none() {
1172 uuid = String::from("");
1173 } else {
1174 uuid = uuid_opt.unwrap().clone();
1175 }
1176 let name_opt: Option<&String> = prop_cast(&map, "name");
1177 if name_opt.is_none() {
1178 name = String::from("");
1179 } else {
1180 name = name_opt.unwrap().clone();
1181 }
1182 let device_type_opt: Option<&String> = prop_cast(&map, "type");
1183 if device_type_opt.is_none() {
1184 device_type = String::from("");
1185 } else {
1186 device_type = device_type_opt.unwrap().clone();
1187 }
1188 Self {
1189 autoconnect: *autoconnect.unwrap_or(&false),
1190 autoconnect_priority: *autoconnect_priority.unwrap_or(&-1),
1191 metered: *metered.unwrap_or(&-1),
1192 name,
1193 device_type,
1194 uuid,
1195 zone,
1196 }
1197 }
1198
1199 fn to_propmap(&self, map: &mut PropMap) {
1200 map.insert("autoconnect".into(), Variant(Box::new(self.autoconnect)));
1201 map.insert(
1202 "autoconnect-priority".into(),
1203 Variant(Box::new(self.autoconnect_priority)),
1204 );
1205 map.insert("metered".into(), Variant(Box::new(self.metered)));
1206 map.insert("name".into(), Variant(Box::new(self.name.clone())));
1207 map.insert(
1208 "device-type".into(),
1209 Variant(Box::new(self.device_type.clone())),
1210 );
1211 map.insert("uuid".into(), Variant(Box::new(self.uuid.clone())));
1212 map.insert("zone".into(), Variant(Box::new(self.zone.to_i32())));
1213 }
1214}
1215
1216#[derive(Debug, Default, Clone)]
1217pub enum SecretSettingsFlag {
1218 #[default]
1219 NONE,
1220 AGENT_OWNED,
1221 NOT_SAVED,
1222 NOT_REQUIRED,
1223}
1224
1225impl Enum for SecretSettingsFlag {
1226 fn from_i32(num: i32) -> Self {
1227 match num {
1228 0 => SecretSettingsFlag::NONE,
1229 1 => SecretSettingsFlag::AGENT_OWNED,
1230 2 => SecretSettingsFlag::NOT_SAVED,
1231 _ => SecretSettingsFlag::NOT_REQUIRED,
1232 }
1233 }
1234
1235 fn to_i32(&self) -> i32 {
1236 match self {
1237 SecretSettingsFlag::NONE => 0,
1238 SecretSettingsFlag::AGENT_OWNED => 1,
1239 SecretSettingsFlag::NOT_SAVED => 2,
1240 SecretSettingsFlag::NOT_REQUIRED => 3,
1241 }
1242 }
1243}
1244
1245#[derive(Debug, Default, Clone)]
1246pub enum WEPKeyType {
1247 #[default]
1248 UNKNOWN,
1249 KEY,
1250 PASSPHRASE,
1251 LAST,
1252}
1253
1254impl Enum for WEPKeyType {
1255 fn from_i32(num: i32) -> Self {
1256 match num {
1257 0 => WEPKeyType::UNKNOWN,
1258 1 => WEPKeyType::KEY,
1259 2 => WEPKeyType::PASSPHRASE,
1260 _ => WEPKeyType::LAST,
1261 }
1262 }
1263
1264 fn to_i32(&self) -> i32 {
1265 match self {
1266 WEPKeyType::UNKNOWN => 0,
1267 WEPKeyType::KEY => 1,
1268 WEPKeyType::PASSPHRASE => 2,
1269 WEPKeyType::LAST => 3,
1270 }
1271 }
1272}
1273
1274#[derive(Debug, Default, Clone)]
1275pub struct WifiSecuritySettings {
1276 pub authentication_algorithm: String,
1277 pub group: Vec<String>,
1278 pub key_management: String,
1279 pub leap_password: String,
1280 pub leap_password_flags: SecretSettingsFlag,
1281 pub leap_username: String,
1282 pub name: String,
1283 pub pairwise: Vec<String>,
1284 pub proto: Vec<String>,
1285 pub psk: String,
1286 pub psk_flags: SecretSettingsFlag,
1287 pub wep_key_flags: SecretSettingsFlag,
1288 pub wep_key_type: WEPKeyType,
1289 pub wep_key0: String,
1290 pub wep_key1: String,
1291 pub wep_key2: String,
1292 pub wep_key3: String,
1293 pub wep_tx_keyidx: u32,
1294}
1295
1296impl PropMapConvert for WifiSecuritySettings {
1297 fn from_propmap(map: PropMap) -> Self {
1298 println!("secret settings debug");
1299 let authentication_algorithm: String;
1300 let authentication_algorithm_opt: Option<&String> = prop_cast(&map, "auth-alg");
1301 if authentication_algorithm_opt.is_none() {
1302 authentication_algorithm = String::from("");
1303 } else {
1304 authentication_algorithm = authentication_algorithm_opt.unwrap().clone();
1305 }
1306 let group: Vec<String>;
1307 let group_opt: Option<&Vec<String>> = prop_cast(&map, "group");
1308 if group_opt.is_none() {
1309 group = Vec::new();
1310 } else {
1311 group = group_opt.unwrap().clone();
1312 }
1313 let key_management: String;
1314 let key_management_opt: Option<&String> = prop_cast(&map, "key-mgmt");
1315 if key_management_opt.is_none() {
1316 key_management = String::from("");
1317 } else {
1318 key_management = key_management_opt.unwrap().clone();
1319 }
1320 let leap_password: String;
1321 let leap_password_opt: Option<&String> = prop_cast(&map, "leap-password");
1322 if leap_password_opt.is_none() {
1323 leap_password = String::from("");
1324 } else {
1325 leap_password = leap_password_opt.unwrap().clone();
1326 }
1327 let leap_password_flags_opt: Option<&u32> = prop_cast(&map, "leap-password-flags");
1328 let leap_password_flags = SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
1329 let leap_username: String;
1330 let leap_username_opt: Option<&String> = prop_cast(&map, "leap-username");
1331 if leap_username_opt.is_none() {
1332 leap_username = String::from("");
1333 } else {
1334 leap_username = leap_username_opt.unwrap().clone();
1335 }
1336 let name: String;
1337 let name_opt: Option<&String> = prop_cast(&map, "name");
1338 if name_opt.is_none() {
1339 name = String::from("");
1340 } else {
1341 name = name_opt.unwrap().clone();
1342 }
1343 let pairwise: Vec<String>;
1344 let pairwise_opt: Option<&Vec<String>> = prop_cast(&map, "pairwise");
1345 if pairwise_opt.is_none() {
1346 pairwise = Vec::new();
1347 } else {
1348 pairwise = pairwise_opt.unwrap().clone();
1349 }
1350 let proto: Vec<String>;
1351 let proto_opt: Option<&Vec<String>> = prop_cast(&map, "proto");
1352 if proto_opt.is_none() {
1353 proto = Vec::new();
1354 } else {
1355 proto = proto_opt.unwrap().clone();
1356 }
1357 let psk: String;
1358 let psk_opt: Option<&String> = prop_cast(&map, "psk");
1359 if psk_opt.is_none() {
1360 psk = String::from("");
1361 } else {
1362 psk = psk_opt.unwrap().clone();
1363 }
1364 let _psk_flags_opt: Option<&u32> = prop_cast(&map, "psk-flags");
1365 let psk_flags = SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
1366 let _wep_key_flags_opt: Option<&u32> = prop_cast(&map, "wep-key-flags");
1367 let wep_key_flags = SecretSettingsFlag::from_i32(*leap_password_flags_opt.unwrap_or(&0) as i32);
1368 let wep_key_type_opt: Option<&u32> = prop_cast(&map, "wep-key-type");
1369 let wep_key_type = WEPKeyType::from_i32(*wep_key_type_opt.unwrap_or(&0) as i32);
1370 let wep_key0: String;
1371 let wep_key0_opt: Option<&String> = prop_cast(&map, "wep-key0");
1372 if wep_key0_opt.is_none() {
1373 wep_key0 = String::from("");
1374 } else {
1375 wep_key0 = wep_key0_opt.unwrap().clone();
1376 }
1377 let wep_key1: String;
1378 let wep_key1_opt: Option<&String> = prop_cast(&map, "wep-key1");
1379 if wep_key1_opt.is_none() {
1380 wep_key1 = String::from("");
1381 } else {
1382 wep_key1 = wep_key1_opt.unwrap().clone();
1383 }
1384 let wep_key2: String;
1385 let wep_key2_opt: Option<&String> = prop_cast(&map, "wep-key2");
1386 if wep_key2_opt.is_none() {
1387 wep_key2 = String::from("");
1388 } else {
1389 wep_key2 = wep_key2_opt.unwrap().clone();
1390 }
1391 let wep_key3: String;
1392 let wep_key3_opt: Option<&String> = prop_cast(&map, "wep-key3");
1393 if wep_key3_opt.is_none() {
1394 wep_key3 = String::from("");
1395 } else {
1396 wep_key3 = wep_key3_opt.unwrap().clone();
1397 }
1398 let wep_tx_keyidx: Option<&u32> = prop_cast(&map, "wep-tx-keyidx");
1399 Self {
1400 authentication_algorithm,
1401 group,
1402 key_management,
1403 leap_password,
1404 leap_password_flags,
1405 leap_username,
1406 name,
1407 pairwise,
1408 proto,
1409 psk,
1410 psk_flags,
1411 wep_key_flags,
1412 wep_key_type,
1413 wep_key0,
1414 wep_key1,
1415 wep_key2,
1416 wep_key3,
1417 wep_tx_keyidx: *wep_tx_keyidx.unwrap_or(&0),
1418 }
1419 }
1420
1421 fn to_propmap(&self, map: &mut PropMap) {
1422 map.insert(
1423 "auth-alg".into(),
1424 Variant(Box::new(self.authentication_algorithm.clone())),
1425 );
1426 map.insert("group".into(), Variant(Box::new(self.group.clone())));
1427 map.insert(
1428 "key-mgmt".into(),
1429 Variant(Box::new(self.key_management.clone())),
1430 );
1431 map.insert(
1432 "leap-password".into(),
1433 Variant(Box::new(self.leap_password.clone())),
1434 );
1435 map.insert(
1436 "leap-password-flags".into(),
1437 Variant(Box::new(self.leap_password_flags.to_i32())),
1438 );
1439 map.insert(
1440 "leap-username".into(),
1441 Variant(Box::new(self.leap_username.clone())),
1442 );
1443 map.insert("name".into(), Variant(Box::new(self.name.clone())));
1444 map.insert("pairwise".into(), Variant(Box::new(self.pairwise.clone())));
1445 map.insert("proto".into(), Variant(Box::new(self.proto.clone())));
1446 map.insert("psk".into(), Variant(Box::new(self.psk.clone())));
1447 map.insert(
1448 "psk-flags".into(),
1449 Variant(Box::new(self.psk_flags.to_i32())),
1450 );
1451 map.insert(
1452 "wep-key-type".into(),
1453 Variant(Box::new(self.wep_key_type.to_i32())),
1454 );
1455 map.insert("wep-key0".into(), Variant(Box::new(self.wep_key0.clone())));
1456 map.insert("wep-key1".into(), Variant(Box::new(self.wep_key1.clone())));
1457 map.insert("wep-key2".into(), Variant(Box::new(self.wep_key2.clone())));
1458 map.insert("wep-key3".into(), Variant(Box::new(self.wep_key3.clone())));
1459 map.insert(
1460 "wep-tx-keyidx".into(),
1461 Variant(Box::new(self.wep_tx_keyidx)),
1462 );
1463 }
1464}