start ping work
authorminima <minima>
Mon, 7 Mar 2005 14:36:18 +0000 (14:36 +0000)
committerminima <minima>
Mon, 7 Mar 2005 14:36:18 +0000 (14:36 +0000)
perl/Aranea.pm
perl/DXCommandmode.pm
perl/DXProt.pm
perl/Thingy.pm
perl/Thingy/Ping.pm

index 75fcee8e07519bff04faa5d341f3ad24c62eb07a..e31b7984ffcb59914dc9bdb63a2bdfbffd65633b 100644 (file)
@@ -247,7 +247,7 @@ sub disconnect
        DXProt::route_pc21($self, $main::mycall, undef, @rout) if @rout;
 
        # remove outstanding pings
-#      delete $pings{$call};
+       Thingy::Ping::forget($call);
        
        # I was the last node visited
     $self->user->node($main::mycall);
index 753f59f79e4788e5211c77353c3d891de8b38789..9b3b09e3f4e24572f5ee5e45462c09eff0d41346 100644 (file)
@@ -559,6 +559,9 @@ sub disconnect
        # send info to all logged in thingies
        $self->tell_login('logoutu');
 
+       # remove any outstanding pings I have sent
+       Thingy::Ping::forget($call);
+       
        Log('DXCommand', "$call disconnected");
 
        $self->SUPER::disconnect;
index 1d28e4024ced3cc3a71554ccd7f33aa08477b90d..78c39f1635639091235e15a9b78b79e9172b6485 100644 (file)
@@ -1540,70 +1540,16 @@ sub handle_51
        my $pcno = shift;
        my $line = shift;
        my $origin = shift;
-       my $to = $_[1];
-       my $from = $_[2];
-       my $flag = $_[3];
 
-                       
-       # is it for us?
-       if ($to eq $main::mycall) {
-               if ($flag == 1) {
-                       $self->send(pc51($from, $to, '0'));
-               } else {
-                       # it's a reply, look in the ping list for this one
-                       my $ref = $pings{$from};
-                       if ($ref) {
-                               my $tochan =  DXChannel::get($from);
-                               while (@$ref) {
-                                       my $r = shift @$ref;
-                                       my $dxchan = DXChannel::get($r->{call});
-                                       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', $from, $s, $ave))
-                                       } elsif ($dxchan->is_node) {
-                                               if ($tochan) {
-                                                       my $nopings = $tochan->user->nopings || $obscount;
-                                                       push @{$tochan->{pingtime}}, $t;
-                                                       shift @{$tochan->{pingtime}} if @{$tochan->{pingtime}} > 6;
-                                                       
-                                                       # cope with a missed ping, this means you must set the pingint large enough
-                                                       if ($t > $tochan->{pingint}  && $t < 2 * $tochan->{pingint} ) {
-                                                               $t -= $tochan->{pingint};
-                                                       }
-                                                       
-                                                       # calc smoothed RTT a la TCP
-                                                       if (@{$tochan->{pingtime}} == 1) {
-                                                               $tochan->{pingave} = $t;
-                                                       } else {
-                                                               $tochan->{pingave} = $tochan->{pingave} + (($t - $tochan->{pingave}) / 6);
-                                                       }
-                                                       $tochan->{nopings} = $nopings; # pump up the timer
-                                                       if (my $ivp = Investigate::get($from, $origin)) {
-                                                               $ivp->handle_ping;
-                                                       }
-                                               } elsif (my $rref = Route::Node::get($r->{call})) {
-                                                       if (my $ivp = Investigate::get($from, $origin)) {
-                                                               $ivp->handle_ping;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       } else {
-
-               RouteDB::update($from, $origin);
-
-               if (eph_dup($line)) {
-                       dbg("PCPROT: dup PC51 detected") if isdbg('chanerr');
-                       return;
-               }
-               # route down an appropriate thingy
-               $self->route($to, $line);
+       if (eph_dup($line)) {
+               dbg("PCPROT: dup PC51 detected") if isdbg('chanerr');
+               return;
        }
+
+       my $thing = Thingy::Ping->new(origin=>$main::mycall);
+       $thing->from_DXProt(user=>$_[2], group=>$_[1], out=>$_[3], DXProt=>$line);
+       $thing->process($self);
+       
 }
 
 # dunno but route it
@@ -2159,22 +2105,9 @@ sub load_hops
 sub addping
 {
        my ($from, $to, $via) = @_;
-       my $ref = $pings{$to} || [];
-       my $r = {};
-       $r->{call} = $from;
-       $r->{t} = [ gettimeofday ];
-       if ($via && (my $dxchan = DXChannel::get($via))) {
-               $dxchan->send(pc51($to, $main::mycall, 1));
-       } else {
-               route(undef, $to, pc51($to, $main::mycall, 1));
-       }
-       push @$ref, $r;
-       $pings{$to} = $ref;
-       my $u = DXUser->get_current($to);
-       if ($u) {
-               $u->lastping(($via || $from), $main::systime);
-               $u->put;
-       }
+       my $thing = Thingy::Ping->new_ping($from eq $main::mycall ? () : (user=>$from), $via ? (touser=> $to, group => $via) : (group => $to));
+       $thing->remember;
+       $thing->broadcast;
 }
 
 sub process_rcmd
@@ -2328,7 +2261,7 @@ sub disconnect
        }
 
        # remove outstanding pings
-       delete $pings{$call};
+       Thingy::Ping::forget($call);
        
        # I was the last node visited
     $self->user->node($main::mycall);
index 2361561af527edc43c0f474adfc1bc29236ec1a9..6ab36080596b931c8c4a671c41318537f15225ac 100644 (file)
@@ -132,10 +132,12 @@ sub queue
 sub process
 {
        my $thing;
+
        if (@_ == 2) {
                $thing = shift;
                $thing->queue(shift);
        }
+
        while (@queue) {
                $thing = shift @queue;
                my $dxchan = DXChannel::get($thing->{dxchan});
@@ -205,5 +207,26 @@ sub add_auth
        $thing->{auth} = $auth->challenge($main::me->user->passphrase);
 }
 
+#
+# create a generalised reply to a passed thing, if it isn't replyable 
+# to then undef is returned
+#  
+sub new_reply
+{
+       my $thing = shift;
+       my $out;
+       
+       if ($thing->{group} eq $main::mycall) {
+               $out = $thing->new;
+               $out->{touser} = $thing->{user} if $thing->{user};
+       } elsif (DXChannel::get($thing->{group})) {
+               $out = $thing->new(user => $thing->{group});
+               $out->{touser} = $thing->{user} if $thing->{user};
+       } elsif ($thing->{touser} && DXChannel->{$thing->{touser}}) {
+               $out = $thing->new(user => $thing->{touser});
+               $out->{group} = $thing->{group};
+       }
+       return $out;
+}
 1;
 
index 6fe808b53423a45d23b6712191dba3d9a44bc3ea..09d0e59225c542020f1511d9e8e4114e4c11ab16 100644 (file)
@@ -20,9 +20,11 @@ use DXUtil;
 use Thingy;
 use Spot;
 
-use vars qw(@ISA);
+use vars qw(@ISA @ping);
 @ISA = qw(Thingy);
 
+my $id;
+
 sub gen_Aranea
 {
        my $thing = shift;
@@ -57,7 +59,8 @@ sub gen_DXCommandmode
 
 sub from_DXProt
 {
-       my $thing = shift;
+       my $thing = ref $_[0] ? shift : $thing->SUPER::new();
+       
        while (@_) {
                my $k = shift;
                $thing->{$k} = shift;
@@ -70,7 +73,128 @@ sub handle
        my $thing = shift;
        my $dxchan = shift;
 
-       $thing->broadcast($dxchan);
+       # is it for us?
+       if ($thing->{group} eq $main::mycall) {
+               if ($thing->{out} == 1) {
+                       my $repthing;
+                       if ($thing->{touser}) {
+                               if (my $dxchan = DXChannel::get($thing->{touser})) {
+                                       if ($dxchan->is_node) {
+                                               $thing->send($dxchan);
+                                       } else {
+                                               $repthing = Thingy::Ping->new_reply($thing);
+                                       }
+                               }
+                       } else {
+                               $repthing = Thingy::Ping->new_reply($thing);
+                       }
+                       $repthing->send($dxchan) if $repthing;
+               } else {
+
+                       # it's a reply, look in the ping list for this one
+                       my $ref = $pings{$from};
+                       if ($ref) {
+                               my $tochan =  DXChannel::get($from);
+                               while (@$ref) {
+                                       my $r = shift @$ref;
+                                       my $dxchan = DXChannel::get($r->{call});
+                                       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', $from, $s, $ave))
+                                       } elsif ($dxchan->is_node) {
+                                               if ($tochan) {
+                                                       my $nopings = $tochan->user->nopings || $obscount;
+                                                       push @{$tochan->{pingtime}}, $t;
+                                                       shift @{$tochan->{pingtime}} if @{$tochan->{pingtime}} > 6;
+                                                       
+                                                       # cope with a missed ping, this means you must set the pingint large enough
+                                                       if ($t > $tochan->{pingint}  && $t < 2 * $tochan->{pingint} ) {
+                                                               $t -= $tochan->{pingint};
+                                                       }
+                                                       
+                                                       # calc smoothed RTT a la TCP
+                                                       if (@{$tochan->{pingtime}} == 1) {
+                                                               $tochan->{pingave} = $t;
+                                                       } else {
+                                                               $tochan->{pingave} = $tochan->{pingave} + (($t - $tochan->{pingave}) / 6);
+                                                       }
+                                                       $tochan->{nopings} = $nopings; # pump up the timer
+                                                       if (my $ivp = Investigate::get($from, $origin)) {
+                                                               $ivp->handle_ping;
+                                                       }
+                                               } elsif (my $rref = Route::Node::get($r->{call})) {
+                                                       if (my $ivp = Investigate::get($from, $origin)) {
+                                                               $ivp->handle_ping;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       } else {
+               $thing->broadcast($dxchan);
+       }
+}
+
+# this just creates a ping for onward transmission
+# remember it if you want to ping someone from here    
+sub new_ping
+{
+       my $pkg = shift;
+       my $thing = $pkg->SUPER::new(@_);
 }
 
+# do this for pings we generate ourselves
+sub remember
+{
+       my $thing = shift;
+       $thing->{t} = [ gettimeofday ];
+       $thing->{out} = 1;
+       $thing->{id} = ++$id;
+       my $u = DXUser->get_current($thing->{to});
+       if ($u) {
+               $u->lastping(($thing->{group} || $thing->{user}), $main::systime);
+               $u->put;
+       }
+       push @ping, $thing;
+}
+
+# remove any pings outstanding that we have remembered for this
+# callsign, return the number of forgotten pings
+sub forget
+{
+       my $call = shift;
+       my $count = 0;
+       my @out;        
+       for (@ping) {
+               if ($thing->{user} eq $call) {
+                       $count++;
+               } else {
+                       push @out, $_;
+               }
+       }
+       @ping = @out;
+       return $count;
+}
+
+sub find
+{
+       my $from = shift;
+       my $to = shift;
+       my $via = shift;
+       
+       for (@ping) {
+               if ($_->{user} eq $from && $_->{to} eq $to) {
+                       if ($via) {
+                               return $_ if $_->{group} eq $via;
+                       } else {
+                               return $_;
+                       }
+               }
+       }
+       return undef;
+}
 1;