1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use iwlib_sys::*;
use std::ffi::CStr;
use std::ffi::CString;
#[derive(PartialEq, PartialOrd, Debug)]
pub struct WirelessInfo {
pub wi_essid: String,
pub wi_quality: u8,
}
pub fn get_wireless_info(interface: String) -> Option<WirelessInfo> {
let interface_name = CString::new(interface).unwrap();
let mut config: wireless_config = Default::default();
let mut statistics: iw_statistics = Default::default();
let mut range: iw_range = Default::default();
let handle = unsafe { iw_sockets_open() };
let basic_config_status =
unsafe { iw_get_basic_config(handle, interface_name.as_ptr(), &mut config) };
if basic_config_status < 0 {
unsafe {
libc::close(handle);
}
return None;
}
let stats_status =
unsafe { iw_get_stats(handle, interface_name.as_ptr(), &mut statistics, &range, 1) };
let range_status = unsafe { iw_get_range_info(handle, interface_name.as_ptr(), &mut range) };
unsafe {
libc::close(handle);
}
let mut quality: f64 = 0.0;
if stats_status >= 0 && range_status >= 0 {
let stats_quality = get_quality(statistics.qual);
let range_quality = get_quality(range.max_qual);
if range_quality != 0 {
quality = stats_quality as f64 / range_quality as f64;
}
}
match compute_essid(config) {
None => None,
Some(essid) => Some(WirelessInfo {
wi_essid: essid,
wi_quality: (quality * 100.0) as u8,
}),
}
}
fn compute_essid(wconfig: wireless_config) -> Option<String> {
if wconfig.has_essid != 0 && wconfig.essid_on != 0 {
let essid = unsafe { CStr::from_ptr(wconfig.essid.as_ptr()) };
return Some(essid.to_owned().into_string().unwrap());
}
None
}
fn get_quality(config: iw_quality) -> u8 {
config.qual
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_does_not_crash() {
let wireless_info = get_wireless_info("wlp0s20f3".to_string());
println!("Wireless info: {:?}", wireless_info);
}
}