use Filter;
use Local;
use DXDb;
+use Time::HiRes qw(gettimeofday tv_interval);
use Carp;
$decode_dk0wcy = undef; # if set use this callsign to decode announces from the EU WWV data beacon
$pc11_max_age = 1*3600; # the maximum age for an incoming 'real-time' pc11
$pc23_max_age = 1*3600; # the maximum age for an incoming 'real-time' pc23
-$pc11_dup_age = 24*3600; # the maximum time to keep the spot dup list for
-$pc23_dup_age = 24*3600; # the maximum time to keep the wwv dup list for
-$pc12_dup_age = 12*3600; # the maximum time to keep the ann dup list for
-$pc12_dup_lth = 72; # the length of ANN text to save for deduping
+$pc11_dup_age = 3*3600; # the maximum time to keep the spot dup list for
+$pc23_dup_age = 3*3600; # the maximum time to keep the wwv dup list for
+$pc12_dup_age = 24*3600; # the maximum time to keep the ann dup list for
+$pc12_dup_lth = 60; # the length of ANN text to save for deduping
%spotdup = (); # the pc11 and 26 dup hash
%wwvdup = (); # the pc23 and 27 dup hash
%anndup = (); # the PC12 dup hash
%nodehops = (); # node specific hop control
@baddx = (); # list of illegal spotted callsigns
+
$baddxfn = "$main::data/baddx.pl";
sub init
$self->send_now('B',"0");
$self->send_now('E',"0");
+ # ping neighbour node stuff
+ my $ping = $user->pingint;
+ $ping = 5*60 unless defined $ping;
+ $self->{pingint} = $ping;
+ $self->{nopings} = $user->nopings || 2;
+ $self->{pingtime} = [ ];
+ $self->{pingave} = 0;
+
# send initialisation string
- if (!$self->{outbound}) {
+ unless ($self->{outbound}) {
$self->send(pc38()) if DXNode->get_all();
$self->send(pc18());
+ $self->{lastping} = $main::systime;
+ } else {
+ # remove from outstanding connects queue
+ @main::outstanding_connects = grep {$_->{call} ne $call} @main::outstanding_connects;
+ $self->{lastping} = $main::systime + $self->pingint / 2;
}
$self->state('init');
$self->pc50_t(time);
+ # send info to all logged in thingies
+ $self->tell_login('loginn');
+
Log('DXProt', "$call connected");
}
# is it for me or one of mine?
my $call = ($field[5] gt ' ') ? $field[5] : $field[2];
- if ($call eq $main::mycall || grep $_ eq $call, get_all_user_calls()) {
+ if ($call eq $main::mycall || grep $_ eq $call, DXChannel::get_all_user_calls()) {
# yes, it is
my $text = unpad($field[3]);
}
if ($pcno == 39) { # incoming disconnect
- $self->disconnect();
+ $self->disconnect(1);
return;
}
if ($pcno == 43) {
last SWITCH;
}
- if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47) {
+ if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47 || $pcno == 48) {
DXDb::process($self, $line);
return;
}
# it's a reply, look in the ping list for this one
my $ref = $pings{$field[2]};
if ($ref) {
+ my $tochan = DXChannel->get($field[2]);
while (@$ref) {
my $r = shift @$ref;
my $dxchan = DXChannel->get($r->{call});
- $dxchan->send($dxchan->msg('pingi', $field[2], atime($main::systime), $main::systime - $r->{t})) if $dxchan;
+ next unless $dxchan;
+ my $t = tv_interval($r->{t}, [ gettimeofday ]);
+ if ($dxchan->is_user) {
+ my $s = sprintf "%.2f", $t;
+ my $ave = sprintf "%.2f", $tochan ? ($tochan->{pingave} || $t) : $t;
+ $dxchan->send($dxchan->msg('pingi', $field[2], $s, $ave))
+ } elsif ($dxchan->is_ak1a) {
+ if ($tochan) {
+ $tochan->{nopings} = 2; # pump up the timer
+ push @{$tochan->{pingtime}}, $t;
+ shift @{$tochan->{pingtime}} if @{$tochan->{pingtime}} > 6;
+ my $st;
+ for (@{$tochan->{pingtime}}) {
+ $st += $_;
+ }
+ $tochan->{pingave} = $st / @{$tochan->{pingtime}};
+ }
+ }
}
}
}
-
} else {
# route down an appropriate thingy
$self->route($field[1], $line);
# send a pc50 out on this channel
if ($t >= $dxchan->pc50_t + $DXProt::pc50_interval) {
- $dxchan->send(pc50());
+ $dxchan->send(pc50(scalar DXChannel::get_all_users));
$dxchan->pc50_t($t);
}
+
+ # send a ping out on this channel
+ if ($dxchan->{pingint} && $t >= $dxchan->{pingint} + $dxchan->{lastping}) {
+ if ($dxchan->{nopings} <= 0) {
+ $dxchan->disconnect;
+ } else {
+ addping($main::mycall, $dxchan->call);
+ $dxchan->{nopings} -= 1;
+ $dxchan->{lastping} = $t;
+ }
+ }
}
my $key;
{
my $self = shift;
my $call = $self->call;
+ my $nopc39 = shift;
my $ref = DXCluster->get_exact($call);
+ $self->send_now("D", DXProt::pc39($main::mycall, $self->msg('disc1', "System Op"))) unless $nopc39;
+
# unbusy and stop and outgoing mail
my $mref = DXMsg::get_busy($call);
$mref->stop_msg($call) if $mref;
# now broadcast to all other ak1a nodes that I have gone
broadcast_ak1a(pc21($call, 'Gone.'), $self) unless $self->{isolate};
-
+
+ # I was the last node visited
+ $self->user->node($main::mycall);
+
+ # send info to all logged in thingies
+ $self->tell_login('logoutn');
+
Log('DXProt', $call . " Disconnected");
$ref->del() if $ref;
}
{
my $s = shift; # the line to be rebroadcast
my @except = @_; # to all channels EXCEPT these (dxchannel refs)
- my @dxchan = get_all_ak1a();
+ my @dxchan = DXChannel::get_all_ak1a();
my $dxchan;
# send it if it isn't the except list and isn't isolated and still has a hop count
{
my $s = shift; # the line to be rebroadcast
my @except = @_; # to all channels EXCEPT these (dxchannel refs)
- my @dxchan = get_all_ak1a();
+ my @dxchan = DXChannel::get_all_ak1a();
my $dxchan;
# send it if it isn't the except list and isn't isolated and still has a hop count
my $sort = shift; # the type of transmission
my $fref = shift; # a reference to an object to filter on
my @except = @_; # to all channels EXCEPT these (dxchannel refs)
- my @dxchan = get_all_users();
+ my @dxchan = DXChannel::get_all_users();
my $dxchan;
my @out;
}
}
-#
-# gimme all the ak1a nodes
-#
-sub get_all_ak1a
-{
- my @list = DXChannel->get_all();
- my $ref;
- my @out;
- foreach $ref (@list) {
- push @out, $ref if $ref->is_ak1a;
- }
- return @out;
-}
-
-# return a list of all users
-sub get_all_users
-{
- my @list = DXChannel->get_all();
- my $ref;
- my @out;
- foreach $ref (@list) {
- push @out, $ref if $ref->is_user;
- }
- return @out;
-}
-
-# return a list of all user callsigns
-sub get_all_user_calls
-{
- my @list = DXChannel->get_all();
- my $ref;
- my @out;
- foreach $ref (@list) {
- push @out, $ref->call if $ref->is_user;
- }
- return @out;
-}
#
# obtain the hops from the list for this callsign and pc no
sub addping
{
my ($from, $to) = @_;
- my $ref = $pings{$to};
- $ref = $pings{$to} = [] if !$ref;
+ my $ref = $pings{$to} || [];
my $r = {};
$r->{call} = $from;
- $r->{t} = $main::systime;
+ $r->{t} = [ gettimeofday ];
route(undef, $to, pc51($to, $main::mycall, 1));
push @$ref, $r;
+ $pings{$to} = $ref;
}
# add a rcmd request to the rcmd queues