X-Git-Url: http://dxcluster.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2FDXProt.pm;h=7d429b1b7c3aa74375294b23169721742863f2c6;hb=e0278322b79d09a997ed7df948c57b58f02b139c;hp=d9abfad6f3a4d6f17c1ae236a61ed9557aa2687b;hpb=d0bc1d6db90b5f0765b668d1b08062fb99240ca4;p=spider.git diff --git a/perl/DXProt.pm b/perl/DXProt.pm index d9abfad6..7d429b1b 100644 --- a/perl/DXProt.pm +++ b/perl/DXProt.pm @@ -31,7 +31,7 @@ use strict; use vars qw($me $pc11_max_age $pc11_dup_age $pc23_dup_age %spotdup %wwvdup $last_hour %pings %rcmds %nodehops @baddx $baddxfn $pc12_dup_age - %anndup); + %anndup $allowzero); $me = undef; # the channel id for this cluster $pc11_max_age = 1*3600; # the maximum age for an incoming 'real-time' pc11 @@ -149,7 +149,13 @@ sub normal my ($pcno) = $field[0] =~ /^PC(\d\d)/; # just get the number return unless $pcno; return if $pcno < 10 || $pcno > 51; - + + # dump bad protocol messages unless it is a PC29 + if ($line =~ /\%[0-9A-F][0-9A-F]/o && $pcno != 29) { + dbg('chan', "CORRUPT protocol message - dumped"); + return; + } + # local processing 1 my $pcr; eval { @@ -371,9 +377,17 @@ sub normal } if ($pcno == 18) { # link request + $self->state('init'); + + # first clear out any nodes on this dxchannel + my @gonenodes = map { $_->dxchan == $self ? $_ : () } DXNode::get_all(); + foreach my $node (@gonenodes) { + next if $node->dxchan == $DXProt::me; + broadcast_ak1a(pc21($node->call, 'Gone, re-init') , $self) unless $self->{isolate}; + $node->del(); + } $self->send_local_config(); $self->send(pc20()); - $self->state('init'); return; # we don't pass these on } @@ -385,11 +399,13 @@ sub normal my $call = uc $field[$i+1]; my $confmode = $field[$i+2]; my $ver = $field[$i+3]; + + $ver = 5400 if !$ver && $allowzero; # now check the call over my $node = DXCluster->get_exact($call); if ($node) { - my $dxchan; + my $dxchan; if (($dxchan = DXChannel->get($call)) && $dxchan != $self) { dbg('chan', "LOOP: $call connected locally"); } @@ -411,7 +427,7 @@ sub normal # unbusy and stop and outgoing mail (ie if somehow we receive another PC19 without a disconnect) my $mref = DXMsg::get_busy($call); - $mref->stop_msg($self) if $mref; + $mref->stop_msg($call) if $mref; # add this station to the user database, if required (don't remove SSID from nodes) my $user = DXUser->get_current($call); @@ -427,8 +443,6 @@ sub normal $user->put; } - # queue up any messages - DXMsg::queue_msg(0) if $self->state eq 'normal'; return if $newline eq "PC19^"; # add hop count @@ -441,10 +455,6 @@ sub normal $self->send_local_config(); $self->send(pc22()); $self->state('normal'); - - # queue mail - DXMsg::queue_msg(0); - return; } @@ -473,12 +483,9 @@ sub normal if ($pcno == 22) { $self->state('normal'); - - # queue mail - DXMsg::queue_msg(0); return; } - + if ($pcno == 23 || $pcno == 27) { # WWV info # route 'foreign' pc27s @@ -506,11 +513,11 @@ sub normal $wwvdup{$dupkey} = $d; $field[6] =~ s/-\d+$//o; # remove spotter's ssid - my $wwv = Geomag::update($d, $field[2], $sfi, $k, $i, @field[6..$#field]); + my $wwv = Geomag::update($d, $field[2], $sfi, $k, $i, @field[6..8]); my $r; eval { - $r = Local::wwv($self, $field[1], $field[2], $sfi, $k, $i, @field[6..$#field]); + $r = Local::wwv($self, $field[1], $field[2], $sfi, $k, $i, @field[6..8]); }; # dbg('local', "Local::wwv2 error $@") if $@; return if $r; @@ -518,9 +525,9 @@ sub normal # DON'T be silly and send on PC27s! return if $pcno == 27; - # broadcast to the eager users - broadcast_users("WWV de $field[7] <$field[2]>: SFI=$sfi, A=$k, K=$i, $field[6]", 'wwv', $wwv ); - last SWITCH; + # broadcast to the eager world + send_wwv_spot($self, $line, $d, $field[2], $sfi, $k, $i, @field[6..8]); + return; } if ($pcno == 24) { # set here status @@ -535,6 +542,10 @@ sub normal route($field[1], $line); return; } + if ($field[2] eq $main::mycall) { + dbg('chan', "Trying to merge to myself, ignored"); + return; + } Log('DXProt', "Merge request for $field[3] spots and $field[4] WWV from $field[1]"); @@ -559,7 +570,7 @@ sub normal } if (($pcno >= 28 && $pcno <= 33) || $pcno == 40 || $pcno == 42 || $pcno == 49) { # mail/file handling - if ($field[1] eq $main::mycall) { + if ($pcno == 49 || $field[1] eq $main::mycall) { DXMsg::process($self, $line); } else { route($field[1], $line); @@ -649,7 +660,7 @@ sub normal if ($pcno == 43) { last SWITCH; } - if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47 || $pcno == 49) { + if ($pcno == 37 || $pcno == 44 || $pcno == 45 || $pcno == 46 || $pcno == 47) { if ($field[1] eq $main::mycall) { ; } else { @@ -661,6 +672,7 @@ sub normal if ($pcno == 50) { # keep alive/user list my $node = DXCluster->get_exact($field[1]); if ($node) { + return unless $node->isa('DXNode'); return unless $node->dxchan == $self; $node->update_users($field[2]); } @@ -757,7 +769,7 @@ sub finish # unbusy and stop and outgoing mail my $mref = DXMsg::get_busy($call); - $mref->stop_msg($self) if $mref; + $mref->stop_msg($call) if $mref; # broadcast to all other nodes that all the nodes connected to via me are gone my @gonenodes = map { $_->dxchan == $self ? $_ : () } DXNode::get_all(); @@ -821,6 +833,45 @@ sub send_dx_spot } } +sub send_wwv_spot +{ + my $self = shift; + my $line = shift; + my @dxchan = DXChannel->get_all(); + my $dxchan; + + # send it if it isn't the except list and isn't isolated and still has a hop count + # taking into account filtering and so on + foreach $dxchan (@dxchan) { + my $routeit; + my ($filter, $hops) = Filter::it($dxchan->{wwvfilter}, @_, $self->{call} ) if $dxchan->{wwvfilter}; + if ($dxchan->is_ak1a) { + next if $dxchan == $self; + if ($hops) { + $routeit = $line; + $routeit =~ s/\^H\d+\^\~$/\^H$hops\^\~/; + } else { + $routeit = adjust_hops($dxchan, $line); # adjust its hop count by node name + next unless $routeit; + } + if ($filter) { + $dxchan->send($routeit) if $routeit; + } else { + $dxchan->send($routeit) unless $dxchan->{isolate} || $self->{isolate}; + + } + } elsif ($dxchan->is_user && $dxchan->{wwv}) { + my $buf = "WWV de $_[6] <$_[1]>: SFI=$_[2], A=$_[3], K=$_[4], $_[5]"; + $buf .= "\a\a" if $dxchan->{beep}; + if ($dxchan->{state} eq 'prompt' || $dxchan->{state} eq 'convers') { + $dxchan->send($buf) if !$hops || ($hops && $filter); + } else { + $dxchan->delay($buf) if !$hops || ($hops && $filter); + } + } + } +} + sub send_local_config { my $self = shift;