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
|
package network::monitor;
use common;
use dbus_object;
our @ISA = qw(dbus_object);
sub new {
my ($type, $bus) = @_;
dbus_object::new($type,
$bus,
"com.mandriva.monitoring",
"/com/mandriva/monitoring/wireless",
"com.mandriva.monitoring.wireless");
}
sub list_wireless {
my ($monitor, $o_intf) = @_;
my ($results, $list, %networks);
#- first try to use mandi
eval {
$results = $monitor->call_method('ScanResults');
$list = $monitor->call_method('ListNetworks');
};
my $has_roaming = defined $results && defined $list;
#- try wpa_cli if we're root
if ($@ && !$>) {
$results = `/usr/sbin/wpa_cli scan_results 2>/dev/null`;
$list = `/usr/sbin/wpa_cli list_networks 2>/dev/null`;
}
if ($results && $list) {
#- bssid / frequency / signal level / flags / ssid
while ($results =~ /^((?:[0-9a-f]{2}:){5}[0-9a-f]{2})\t(\d+)\t(\d+)\t(.*?)\t(.*)$/mg) {
#- wpa_supplicant may list the network two times, use ||=
$networks{$1}{frequency} ||= $2;
#- signal level is really too high in wpa_supplicant
#- this should be standardized at some point
$networks{$1}{signal_level} ||= int($3/3.5);
$networks{$1}{flags} ||= $4;
$networks{$1}{essid} ||= $5 if $5 ne '<hidden>';
}
#- network id / ssid / bssid / flags
while ($list =~ /^(\d+)\t(.*?)\t(.*?)\t(.*)$/mg) {
if (my $net = $networks{$3} || find { $_->{essid} eq $2 } values(%networks)) {
$net->{id} = $1;
$net->{essid} ||= $2;
$net->{current} = to_bool($4 eq '[CURRENT]');
}
}
} elsif ($o_intf) {
#- else use iwlist
my $current_essid = chomp_(`/sbin/iwgetid -r $o_intf`);
my $current_ap = lc(chomp_(`/sbin/iwgetid -r -a $o_intf`));
my @list = `/sbin/iwlist $o_intf scanning`;
my $net = {};
foreach (@list) {
if ((/^\s*$/ || /Cell/) && exists $net->{ap}) {
$net->{current} = to_bool($net->{essid} && $net->{essid} eq $current_essid || $net->{ap} eq $current_ap);
$networks{$net->{ap}} = $net;
$net = {};
}
/Address: (.*)/ and $net->{ap} = lc($1);
/ESSID:"(.*?)"/ and $net->{essid} = $1;
/Mode:(\S*)/ and $net->{mode} = $1;
if (m!Quality[:=](\S*)/!) {
my $qual = $1;
$net->{signal_level} = $qual =~ m!/! ? eval($qual)*100 : $qual;
}
/Extra:wpa_ie=/ and $net->{flags} = '[WPA]';
/key:(\S*)\s/ and $net->{flags} ||= $1 eq 'on' && '[WEP]';
}
}
$networks{$_}{approx_level} = 20 + min(80, int($networks{$_}{signal_level}/20)*20) foreach keys %networks;
(\%networks, $has_roaming);
}
sub select_network {
my ($o, $id) = @_;
$o->call_method('SelectNetwork', Net::DBus::dbus_uint32($id));
}
1;
|