3 # An RBN deduping filter
5 # Copyright (c) 2017 Dirk Koopman G1TLH
10 use IO::Socket::IP -register;
11 use Math::Round qw(nearest);
13 my $host = 'telnet.reversebeacon.net';
15 my $mycall = shift or die "usage:rbn.pl <callsign> [debug] [<time between repeat spots in minutes>]\n";
17 my $minspottime = 15*60; # minimum length of time between successive spots
26 ++$dbg if $arg =~ /^deb/i;
27 $minspottime = $arg * 60 if $arg =~ /^\d+$/;
30 for ($attempts = 1; $attempts <= 5; ++$attempts) {
31 say "admin,connecting to $host $port.. (attempt $attempts) " if $dbg;
32 $sock = IO::Socket::IP->new(
40 die "admin,Cannot connect to $host:$port after 5 attempts $!" unless $sock;
41 say "admin,connected" if $dbg;
42 print $sock "$mycall\r\n";
43 say "admin,call sent" if $dbg;
55 my (undef, undef, $origin, $qrg, $call, $mode, $s, $m, $spd, $u, $sort, $t) = split /[:\s]+/;
58 # We have an RBN data line, dedupe it very simply on time, ignore QRG completely.
59 # This works because the skimmers are NTP controlled (or should be) and will receive
60 # the spot at the same time (velocity factor of the atmosphere taken into account :-)
66 $qrg = sprintf('%.1f', nearest(.1, $qrg)); # to nearest 100Hz (to catch the odd multiple decpl QRG [eg '7002.07']).
67 say join(',', "RBN", $origin, $qrg, $call, $mode, $s, $m, $spd, $u, $sort, $t) if $dbg;
69 # Determine whether to "SPOT" it based on whether we have not seen it before (near this QRG) or,
70 # if we have, has it been a "while" since the last time we spotted it? If it has been spotted
71 # before then "RESPOT" it.
72 my $nqrg = nearest(1, $qrg); # normalised to nearest Khz
73 my $sp = "$call|$nqrg"; # hopefully the skimmers will be calibrated at least this well!
75 if (!$ts || $tim - $ts >= $minspottime) {
76 my $tag = $ts ? "RESPOT" : "SPOT";
77 say join(',', $tag, $origin, $qrg, $call, $mode, $s, $m, $spd, $u, $sort, $t);
81 say "data,$_" if $dbg;
84 # periodic clearing out of the two caches
85 if ($tim > $last+60) {
89 while (my ($k,$v) = each %d) {
97 say "admin,rbn cache: $removed removed $count remain" if $dbg;
98 $count = $removed = 0;
99 while (my ($k,$v) = each %spot) {
100 if ($tim-$v > $minspottime*2) {
107 say "admin,spot cache: $removed removed $count remain" if $dbg;