summaryrefslogtreecommitdiffstats
path: root/lib/network/monitor.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/network/monitor.pm')
-rw-r--r--lib/network/monitor.pm50
1 files changed, 35 insertions, 15 deletions
diff --git a/lib/network/monitor.pm b/lib/network/monitor.pm
index c0ed8f8..7cd1277 100644
--- a/lib/network/monitor.pm
+++ b/lib/network/monitor.pm
@@ -31,28 +31,41 @@ sub list_wireless {
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) {
+ my ($ap, $frequency, $signal_strength, $flags, $essid) = ($1, $2, $3, $4, $5);
+ $networks{$ap}{ap} ||= $ap;
#- wpa_supplicant may list the network two times, use ||=
- $networks{$1}{frequency} ||= $2;
+ $networks{$ap}{frequency} ||= $frequency;
#- 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>';
+ $networks{$ap}{signal_strength} ||= int($signal_strength/3.5);
+ my $adhoc = $flags =~ s/\[ibss\]//i;
+ $networks{$ap}{mode} ||= $adhoc ? "Ad-Hoc" : "Managed";
+ $networks{$ap}{flags} ||= $flags;
+ $networks{$ap}{essid} ||= $essid;
}
#- network id / ssid / bssid / flags
while ($list =~ /^(\d+)\t(.*?)\t(.*?)\t(.*)$/mg) {
- if (my $net = $networks{$3} || find { $_->{essid} eq $2 } values(%networks)) {
+ foreach my $net (uniq(if_($networks{$3}, $networks{$3}), grep { $_->{essid} eq $2 } values(%networks))) {
+ $net->{ap} = $3 if $3 ne 'any';
$net->{id} = $1;
$net->{essid} ||= $2;
$net->{current} = to_bool($4 eq '[CURRENT]');
}
}
- } elsif ($o_intf) {
+ } else {
#- 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`;
+ require network::connection::wireless;
+ my ($current_essid, $current_ap) = network::connection::wireless::get_access_point($o_intf);
+ if ($o_intf && !$> && !`/sbin/ip link show $o_intf up`) {
+ system("/sbin/ip link set $o_intf up");
+ }
+ my @list = `/sbin/iwlist $o_intf scanning 2>/dev/null`;
my $net = {};
+ my $quality_match = qr/Quality[:=](\S*)/;
+ my $eval_quality = sub {
+ my ($qual) = @_;
+ $qual =~ m!/! ? eval($qual)*100 : $qual;
+ };
foreach (@list) {
if ((/^\s*$/ || /Cell/) && exists $net->{ap}) {
$net->{current} = to_bool($net->{essid} && $net->{essid} eq $current_essid || $net->{ap} eq $current_ap);
@@ -62,16 +75,23 @@ sub list_wireless {
/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]';
+ $_ =~ $quality_match and $net->{signal_strength} = $eval_quality->($1);
+ m|Signal level:([0-9]+/[0-9]+)| && !$net->{signal_strength} and $net->{signal_strength} = eval($1)*100;
+ /Extra:wpa_ie=|IE:.*WPA/ and $net->{flags} = '[WPA]';
/key:(\S*)\s/ and $net->{flags} ||= $1 eq 'on' && '[WEP]';
}
+ if ($current_ap && exists $networks{$current_ap}) {
+ foreach (`/sbin/iwconfig $o_intf 2>/dev/null`) {
+ my $quality = $_ =~ $quality_match && $eval_quality->($1);
+ $networks{$current_ap}{signal_strength} = $quality if $quality;
+ }
+ }
}
- $networks{$_}{approx_level} = 20 + min(80, int($networks{$_}{signal_level}/20)*20) foreach keys %networks;
+ foreach (values %networks) {
+ $_->{essid} eq '<hidden>' and undef $_->{essid};
+ $_->{name} = $_->{essid} || "[$_->{ap}]";
+ }
(\%networks, $has_roaming);
}