2 # This module impliments the new protocal mode for a dx cluster
4 # Copyright (c) 2001 Dirk Koopman G1TLH
11 @ISA = qw(DXChannel DXProt);
25 use Time::HiRes qw(gettimeofday tv_interval);
41 use vars qw($VERSION $BRANCH);
42 $VERSION = sprintf( "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/ );
43 $BRANCH = sprintf( "%d.%03d", q$Revision$ =~ /\d+\.\d+\.(\d+)\.(\d+)/ || (0,0));
44 $main::build += $VERSION;
45 $main::branch += $BRANCH;
49 my $user = DXUser->get($main::mycall);
50 $DXProt::myprot_version += $main::version*100;
51 $main::me = QXProt->new($main::mycall, 0, $user);
52 $main::me->{here} = 1;
53 $main::me->{state} = "indifferent";
54 $main::me->{sort} = 'S'; # S for spider
55 $main::me->{priv} = 9;
56 $main::me->{metric} = 0;
57 $main::me->{pingave} = 0;
58 $main::me->{registered} = 1;
59 $main::me->{version} = $main::version;
60 $main::me->{build} = $main::build;
62 # $Route::Node::me->adddxchan($main::me);
68 $self->SUPER::start(@_);
75 $self->send($self->QXI::gen);
80 if ($_[1] =~ /^PC\d\d\^/) {
84 my ($sort, $tonode, $fromnode, $msgid, $line, $incs);
85 return unless ($sort, $tonode, $fromnode, $msgid, $line, $incs) = $_[1] =~ /^QX([A-Z])\^(\*|[-A-Z0-9]+)\^([-A-Z0-9]+)\^([0-9A-F]{1,4})\^(.*)\^([0-9A-F]{2})$/;
88 my $noderef = Route::Node::get($fromnode);
89 $noderef = Route::Node::new($fromnode) unless $noderef;
91 my $il = length $incs;
92 my $cs = sprintf("%02X", unpack("%32C*", substr($_[1], 0, length($_[1]) - ($il+1))) & 255);
94 dbg("QXPROT: Checksum fail in: $incs ne calc: $cs" ) if isdbg('chanerr');
98 return unless $noderef->newid($msgid);
102 my $sub = "QX${sort}::handle";
103 $_[0]->$sub($tonode, $fromnode, $msgid, $line) if $_[0]->can($sub);
108 my $last_node_update = 0;
109 my $node_update_interval = 60*15;
114 my $t = $main::systime;
116 foreach my $dxchan (DXChannel->get_all()) {
117 next unless $dxchan->is_np;
118 next if $dxchan == $main::me;
120 # send a ping out on this channel
121 if ($dxchan->{pingint} && $t >= $dxchan->{pingint} + $dxchan->{lastping}) {
122 if ($dxchan->{nopings} <= 0) {
125 $dxchan->addping($main::mycall, $dxchan->call);
126 $dxchan->{nopings} -= 1;
127 $dxchan->{lastping} = $t;
132 if ($t >= $last_node_update+$node_update_interval) {
135 $last_node_update = $main::systime;
147 $self->DXProt::disconnect(@_);
156 my $to = shift || "*";
159 $ht = sprintf "%X", $msgid;
160 my $line = join '^', "QX$sort", $to, $main::mycall, $ht, @_;
161 my $cs = sprintf "%02X", unpack("%32C*", $line) & 255;
162 $msgid = 1 if ++$msgid > 0xffff;
166 # add a ping request to the ping queues
169 my ($self, $usercall, $to) = @_;
170 my $ref = $DXChannel::pings{$to} || [];
172 $r->{call} = $usercall;
173 $r->{t} = [ gettimeofday ];
174 DXChannel::route(undef, $to, $self->QXP::gen($to, 1, $usercall, @{$r->{t}}));
176 $DXCHannel::pings{$to} = $ref;