1use dbus::{
2 arg::Variant,
3 blocking::{stdintf::org_freedesktop_dbus::Properties, Connection},
4};
5use std::{collections::HashMap, time::Duration};
6
7fn ip_to_u32(ip: &str) -> Result<u32, String> {
9 let parts: Result<Vec<u32>, _> = ip.split('.').map(|s| s.parse::<u32>()).collect();
10
11 match parts {
12 Ok(parts) if parts.len() == 4 && parts.iter().all(|&x| x <= 255) => {
13 Ok(((parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3]).to_be())
14 }
15 _ => Err(format!("Invalid IP address format: {}", ip)),
16 }
17}
18
19pub fn send_wifi_to_network_manager(ssid: &str, password: &str) {
52 let conn = Connection::new_system().unwrap();
53 let proxy = conn.with_proxy(
54 "org.freedesktop.NetworkManager",
55 "/org/freedesktop/NetworkManager",
56 Duration::from_secs(10),
57 );
58 let connection_path = dbus::Path::new("/").unwrap();
59 let (devices,): (Vec<dbus::Path>,) = proxy
60 .method_call("org.freedesktop.NetworkManager", "GetDevices", ())
61 .unwrap();
62
63 let mut wifi_device_path: Option<dbus::Path> = None;
64
65 for device in devices {
66 let device_proxy = conn.with_proxy(
67 "org.freedesktop.NetworkManager",
68 &device,
69 Duration::from_secs(10),
70 );
71 let device_type: u32 = device_proxy
72 .get("org.freedesktop.NetworkManager.Device", "DeviceType")
73 .unwrap();
74
75 if device_type == 2 {
77 wifi_device_path = Some(device);
78 break;
79 }
80 }
81
82 if wifi_device_path.is_none() {
83 eprintln!("Wi-Fi device not found.");
84 return;
85 }
86
87 let device_path = wifi_device_path.unwrap();
88 let mut connection_settings: HashMap<&str, HashMap<&str, Variant<Box<dyn dbus::arg::RefArg>>>> =
90 HashMap::new();
91
92 let mut wifi_settings: HashMap<&str, Variant<Box<dyn dbus::arg::RefArg>>> = HashMap::new();
94 wifi_settings.insert("ssid", Variant(Box::new(ssid.as_bytes().to_vec())));
95 wifi_settings.insert("mode", Variant(Box::new(String::from("infrastructure"))));
96 connection_settings.insert("802-11-wireless", wifi_settings);
97
98 let mut wifi_security: HashMap<&str, Variant<Box<dyn dbus::arg::RefArg>>> = HashMap::new();
100 wifi_security.insert("key-mgmt", Variant(Box::new(String::from("wpa-psk"))));
101 wifi_security.insert("psk", Variant(Box::new(String::from(password))));
102 connection_settings.insert("802-11-wireless-security", wifi_security);
103
104 let result: Result<(), _> = proxy.method_call(
105 "org.freedesktop.NetworkManager",
106 "AddAndActivateConnection",
107 (connection_settings, device_path, connection_path),
108 );
109
110 match result {
111 Ok(_) => println!("Wi-Fi configuration successfully sent."),
112 Err(e) => eprintln!("Failed to configure Wi-Fi: {}", e),
113 }
114}
115
116pub fn send_static_wifi_to_network_manager(
159 ssid: &str,
160 password: &str,
161 ip: &str,
162 prefix: u32,
163 gateway: &str,
164) {
165 let conn = Connection::new_system().unwrap();
167 let proxy = conn.with_proxy(
168 "org.freedesktop.NetworkManager",
169 "/org/freedesktop/NetworkManager",
170 Duration::from_secs(10),
171 );
172
173 let (devices,): (Vec<dbus::Path<'static>>,) = proxy
175 .method_call("org.freedesktop.NetworkManager", "GetDevices", ())
176 .unwrap();
177
178 let mut wifi_device_path: Option<dbus::Path<'static>> = None;
179 for device in devices {
180 let device_proxy = conn.with_proxy(
181 "org.freedesktop.NetworkManager",
182 &device,
183 Duration::from_secs(10),
184 );
185 let device_type: u32 = device_proxy
186 .get("org.freedesktop.NetworkManager.Device", "DeviceType")
187 .unwrap();
188
189 if device_type == 2 {
190 wifi_device_path = Some(device);
191 break;
192 }
193 }
194
195 if wifi_device_path.is_none() {
196 eprintln!("Wi-Fi device not found.");
197 return;
198 }
199
200 let device_path = wifi_device_path.unwrap();
201 let connection_path = dbus::Path::new("/").unwrap();
202
203 let mut connection_settings: HashMap<&str, HashMap<&str, Variant<Box<dyn dbus::arg::RefArg>>>> =
205 HashMap::new();
206
207 let mut wifi_settings: HashMap<&str, Variant<Box<dyn dbus::arg::RefArg>>> = HashMap::new();
208 wifi_settings.insert("ssid", Variant(Box::new(ssid.as_bytes().to_vec())));
209 wifi_settings.insert("mode", Variant(Box::new(String::from("infrastructure"))));
210 connection_settings.insert("802-11-wireless", wifi_settings);
211
212 let mut wifi_security: HashMap<&str, Variant<Box<dyn dbus::arg::RefArg>>> = HashMap::new();
214 wifi_security.insert("key-mgmt", Variant(Box::new(String::from("wpa-psk"))));
215 wifi_security.insert("psk", Variant(Box::new(String::from(password))));
216 connection_settings.insert("802-11-wireless-security", wifi_security);
217
218 let mut ipv4_settings: HashMap<&str, Variant<Box<dyn dbus::arg::RefArg>>> = HashMap::new();
220 ipv4_settings.insert("method", Variant(Box::new(String::from("manual"))));
221 let ip_u32 = match ip_to_u32(ip) {
223 Ok(addr) => addr,
224 Err(e) => {
225 eprintln!("❌ {}", e);
226 return;
227 }
228 };
229 let gateway_u32 = match ip_to_u32(gateway) {
230 Ok(addr) => addr,
231 Err(e) => {
232 eprintln!("❌ {}", e);
233 return;
234 }
235 };
236
237 let address_array: Vec<u32> = vec![ip_u32, prefix, gateway_u32];
239 let addresses: Vec<Vec<u32>> = vec![address_array];
240
241 ipv4_settings.insert("addresses", Variant(Box::new(addresses)));
242
243 connection_settings.insert("ipv4", ipv4_settings);
244
245 let result: Result<(), _> = proxy.method_call(
247 "org.freedesktop.NetworkManager",
248 "AddAndActivateConnection",
249 (connection_settings, device_path, connection_path),
250 );
251
252 match result {
253 Ok(_) => println!("Wi-Fi configuration with static IP sent."),
254 Err(e) => eprintln!("❌ Failed to connect to Wi-Fi: {}", e),
255 }
256}
257
258#[cfg(test)]
260mod tests {
261 use super::*;
262
263 #[test]
264 fn test_check() {
265 assert!(true);
266 }
267}