orb_network_manager/
wifi.rs1use std::rc::Rc;
2use std::net::Ipv4Addr;
3
4use errors::*;
5use dbus_nm::DBusNetworkManager;
6
7use connection::{connect_to_access_point, create_hotspot, Connection, ConnectionState};
8use device::{Device, PathGetter};
9use ssid::{AsSsidSlice, Ssid, SsidSlice};
10
11pub struct WiFiDevice<'a> {
12 dbus_manager: Rc<DBusNetworkManager>,
13 device: &'a Device,
14}
15
16impl<'a> WiFiDevice<'a> {
17 pub fn get_access_points(&self) -> Result<Vec<AccessPoint>> {
32 let mut access_points = Vec::new();
33
34 let paths = self.dbus_manager
35 .get_device_access_points(self.device.path())?;
36
37 for path in paths {
38 if let Some(access_point) = get_access_point(&self.dbus_manager, &path)? {
39 access_points.push(access_point);
40 }
41 }
42
43 access_points.sort_by_key(|ap| ap.strength);
44 access_points.reverse();
45
46 Ok(access_points)
47 }
48
49 pub fn request_scan(&self) -> Result<()> {
50 self.dbus_manager
51 .request_access_point_scan(self.device.path())?;
52 Ok(())
53 }
54
55 pub fn connect(
56 &self,
57 access_point: &AccessPoint,
58 credentials: &AccessPointCredentials,
59 ) -> Result<(Connection, ConnectionState)> {
60 connect_to_access_point(
61 &self.dbus_manager,
62 self.device.path(),
63 access_point,
64 credentials,
65 )
66 }
67
68 pub fn create_hotspot<T>(
69 &self,
70 ssid: &T,
71 password: Option<&str>,
72 address: Option<Ipv4Addr>,
73 ) -> Result<(Connection, ConnectionState)>
74 where
75 T: AsSsidSlice + ?Sized,
76 {
77 create_hotspot(
78 &self.dbus_manager,
79 self.device.path(),
80 self.device.interface(),
81 ssid,
82 password,
83 address,
84 )
85 }
86}
87
88#[derive(Debug)]
89pub struct AccessPoint {
90 pub path: String,
91 pub ssid: Ssid,
92 pub strength: u32,
93 pub security: Security,
94}
95
96impl AccessPoint {
97 pub fn ssid(&self) -> &SsidSlice {
98 &self.ssid
99 }
100}
101
102bitflags! {
103 pub struct Security: u32 {
104 const NONE = 0b0000_0000;
105 const WEP = 0b0000_0001;
106 const WPA = 0b0000_0010;
107 const WPA2 = 0b0000_0100;
108 const ENTERPRISE = 0b0000_1000;
109 }
110}
111
112#[derive(Debug)]
113pub enum AccessPointCredentials {
114 None,
115 Wep {
116 passphrase: String,
117 },
118 Wpa {
119 passphrase: String,
120 },
121 Enterprise {
122 identity: String,
123 passphrase: String,
124 },
125}
126
127bitflags! {
128 pub struct NM80211ApFlags: u32 {
129 const AP_FLAGS_NONE = 0x0000_0000;
131 const AP_FLAGS_PRIVACY = 0x0000_0001;
133 const AP_FLAGS_WPS = 0x0000_0002;
135 const AP_FLAGS_WPS_PBC = 0x0000_0004;
137 const AP_FLAGS_WPS_PIN = 0x0000_0008;
139 }
140}
141
142bitflags! {
143 pub struct NM80211ApSecurityFlags: u32 {
144 const AP_SEC_NONE = 0x0000_0000;
146 const AP_SEC_PAIR_WEP40 = 0x0000_0001;
148 const AP_SEC_PAIR_WEP104 = 0x0000_0002;
150 const AP_SEC_PAIR_TKIP = 0x0000_0004;
152 const AP_SEC_PAIR_CCMP = 0x0000_0008;
154 const AP_SEC_GROUP_WEP40 = 0x0000_0010;
156 const AP_SEC_GROUP_WEP104 = 0x0000_0020;
158 const AP_SEC_GROUP_TKIP = 0x0000_0040;
160 const AP_SEC_GROUP_CCMP = 0x0000_0080;
162 const AP_SEC_KEY_MGMT_PSK = 0x0000_0100;
164 const AP_SEC_KEY_MGMT_802_1X = 0x0000_0200;
166 }
167}
168
169pub fn new_wifi_device<'a>(
170 dbus_manager: &Rc<DBusNetworkManager>,
171 device: &'a Device,
172) -> WiFiDevice<'a> {
173 WiFiDevice {
174 dbus_manager: Rc::clone(dbus_manager),
175 device: device,
176 }
177}
178
179fn get_access_point(manager: &DBusNetworkManager, path: &str) -> Result<Option<AccessPoint>> {
180 if let Some(ssid) = manager.get_access_point_ssid(path) {
181 let strength = manager.get_access_point_strength(path)?;
182
183 let security = get_access_point_security(manager, path)?;
184
185 let access_point = AccessPoint {
186 path: path.to_string(),
187 ssid: ssid,
188 strength: strength,
189 security: security,
190 };
191
192 Ok(Some(access_point))
193 } else {
194 Ok(None)
195 }
196}
197
198fn get_access_point_security(manager: &DBusNetworkManager, path: &str) -> Result<Security> {
199 let flags = manager.get_access_point_flags(path)?;
200
201 let wpa_flags = manager.get_access_point_wpa_flags(path)?;
202
203 let rsn_flags = manager.get_access_point_rsn_flags(path)?;
204
205 let mut security = Security::NONE;
206
207 if flags.contains(NM80211ApFlags::AP_FLAGS_PRIVACY)
208 && wpa_flags == NM80211ApSecurityFlags::AP_SEC_NONE
209 && rsn_flags == NM80211ApSecurityFlags::AP_SEC_NONE
210 {
211 security |= Security::WEP;
212 }
213
214 if wpa_flags != NM80211ApSecurityFlags::AP_SEC_NONE {
215 security |= Security::WPA;
216 }
217
218 if rsn_flags != NM80211ApSecurityFlags::AP_SEC_NONE {
219 security |= Security::WPA2;
220 }
221
222 if wpa_flags.contains(NM80211ApSecurityFlags::AP_SEC_KEY_MGMT_802_1X)
223 || rsn_flags.contains(NM80211ApSecurityFlags::AP_SEC_KEY_MGMT_802_1X)
224 {
225 security |= Security::ENTERPRISE;
226 }
227
228 Ok(security)
229}