1package App::Netdisco::Worker::Plugin::Discover::Wireless; 2 3use Dancer ':syntax'; 4use App::Netdisco::Worker::Plugin; 5use aliased 'App::Netdisco::Worker::Status'; 6 7use App::Netdisco::Transport::SNMP (); 8use Dancer::Plugin::DBIC 'schema'; 9 10register_worker({ phase => 'main', driver => 'snmp' }, sub { 11 my ($job, $workerconf) = @_; 12 13 my $device = $job->device; 14 return unless $device->in_storage; 15 my $snmp = App::Netdisco::Transport::SNMP->reader_for($device) 16 or return Status->defer("discover failed: could not SNMP connect to $device"); 17 18 my $ssidlist = $snmp->i_ssidlist; 19 return unless scalar keys %$ssidlist; 20 21 # cache the device ports to save hitting the database for many single rows 22 my $device_ports = vars->{'device_ports'} 23 || { map {($_->port => $_)} $device->ports->all }; 24 25 my $interfaces = $snmp->interfaces; 26 my $ssidbcast = $snmp->i_ssidbcast; 27 my $ssidmac = $snmp->i_ssidmac; 28 my $channel = $snmp->i_80211channel; 29 my $power = $snmp->dot11_cur_tx_pwr_mw; 30 31 # build device ssid list suitable for DBIC 32 my @ssids; 33 foreach my $entry (keys %$ssidlist) { 34 (my $iid = $entry) =~ s/\.\d+$//; 35 my $port = $interfaces->{$iid}; 36 37 if (not $port) { 38 debug sprintf ' [%s] wireless - ignoring %s (no port mapping)', 39 $device->ip, $iid; 40 next; 41 } 42 43 if (!defined $device_ports->{$port}) { 44 debug sprintf ' [%s] wireless - local port %s already skipped, ignoring', 45 $device->ip, $port; 46 next; 47 } 48 49 push @ssids, { 50 port => $port, 51 ssid => $ssidlist->{$entry}, 52 broadcast => $ssidbcast->{$entry}, 53 bssid => $ssidmac->{$entry}, 54 }; 55 } 56 57 schema('netdisco')->txn_do(sub { 58 my $gone = $device->ssids->delete; 59 debug sprintf ' [%s] wireless - removed %d SSIDs', 60 $device->ip, $gone; 61 $device->ssids->populate(\@ssids); 62 debug sprintf ' [%s] wireless - added %d new SSIDs', 63 $device->ip, scalar @ssids; 64 }); 65 66 # build device channel list suitable for DBIC 67 my @channels; 68 foreach my $entry (keys %$channel) { 69 my $port = $interfaces->{$entry}; 70 71 if (not $port) { 72 debug sprintf ' [%s] wireless - ignoring %s (no port mapping)', 73 $device->ip, $entry; 74 next; 75 } 76 77 if (!defined $device_ports->{$port}) { 78 debug sprintf ' [%s] wireless - local port %s already skipped, ignoring', 79 $device->ip, $port; 80 next; 81 } 82 83 push @channels, { 84 port => $port, 85 channel => $channel->{$entry}, 86 power => $power->{$entry}, 87 }; 88 } 89 90 schema('netdisco')->txn_do(sub { 91 my $gone = $device->wireless_ports->delete; 92 debug sprintf ' [%s] wireless - removed %d wireless channels', 93 $device->ip, $gone; 94 $device->wireless_ports->populate(\@channels); 95 96 return Status->info(sprintf ' [%s] wireless - added %d new wireless channels', 97 $device->ip, scalar @channels); 98 }); 99}); 100 101true; 102