1package App::Netdisco::Worker::Plugin::Macsuck::WirelessNodes;
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';
9use Time::HiRes 'gettimeofday';
10
11register_worker({ phase => 'main', driver => 'snmp' }, sub {
12  my ($job, $workerconf) = @_;
13
14  my $device = $job->device;
15  my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
16    or return Status->defer("macsuck failed: could not SNMP connect to $device");
17
18  my $now = 'to_timestamp('. (join '.', gettimeofday) .')';
19
20  my $cd11_txrate = $snmp->cd11_txrate;
21  return unless $cd11_txrate and scalar keys %$cd11_txrate;
22
23  return Status->info(sprintf ' [%s] macsuck - dot11 info available but skipped due to config',
24    $device->ip) unless setting('store_wireless_clients');
25
26  my $cd11_rateset = $snmp->cd11_rateset();
27  my $cd11_uptime  = $snmp->cd11_uptime();
28  my $cd11_sigstrength = $snmp->cd11_sigstrength();
29  my $cd11_sigqual = $snmp->cd11_sigqual();
30  my $cd11_mac     = $snmp->cd11_mac();
31  my $cd11_port    = $snmp->cd11_port();
32  my $cd11_rxpkt   = $snmp->cd11_rxpkt();
33  my $cd11_txpkt   = $snmp->cd11_txpkt();
34  my $cd11_rxbyte  = $snmp->cd11_rxbyte();
35  my $cd11_txbyte  = $snmp->cd11_txbyte();
36  my $cd11_ssid    = $snmp->cd11_ssid();
37
38  while (my ($idx, $txrates) = each %$cd11_txrate) {
39    my $rates = $cd11_rateset->{$idx};
40    my $mac   = $cd11_mac->{$idx};
41    next unless defined $mac; # avoid null entries
42          # there can be more rows in txrate than other tables
43
44    my $txrate  = (ref $txrates and defined $txrates->[$#$txrates])
45      ? int($txrates->[$#$txrates])
46      : undef;
47
48    my $maxrate = (ref $rates and defined $rates->[$#$rates])
49      ? int($rates->[$#$rates])
50      : undef;
51
52    my $ssid = $cd11_ssid->{$idx} || 'unknown';
53
54    schema('netdisco')->txn_do(sub {
55      schema('netdisco')->resultset('NodeWireless')
56        ->search({ 'me.mac' => $mac, 'me.ssid' => $ssid })
57        ->update_or_create({
58          txrate  => $txrate,
59          maxrate => $maxrate,
60          uptime  => $cd11_uptime->{$idx},
61          rxpkt   => $cd11_rxpkt->{$idx},
62          txpkt   => $cd11_txpkt->{$idx},
63          rxbyte  => $cd11_rxbyte->{$idx},
64          txbyte  => $cd11_txbyte->{$idx},
65          sigqual => $cd11_sigqual->{$idx},
66          sigstrength => $cd11_sigstrength->{$idx},
67          time_last => \$now,
68        }, {
69          order_by => [qw/mac ssid/],
70          for => 'update',
71        });
72    });
73  }
74
75  return Status->info(sprintf ' [%s] macsuck - processed %s wireless nodes',
76    $device->ip, scalar keys %{ $cd11_txrate });
77});
78
79true;
80