diff options
Diffstat (limited to 'lib/network/monitor.pm')
-rw-r--r-- | lib/network/monitor.pm | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/network/monitor.pm b/lib/network/monitor.pm new file mode 100644 index 0000000..c0ed8f8 --- /dev/null +++ b/lib/network/monitor.pm @@ -0,0 +1,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; |