my $from = shift;
my $date = ((($dayno << 1) | $ntpflag) << 18) | ($main::systime % 86400);
- my $r = "$mycall,$to," . sprintf('%6X%04X,0', $date, $seqno);
+ my $r = "$mycall," . sprintf('%6X%04X,0', $date, $seqno);
+ $r .= ",$to" if $to;
$r .= ",$from" if $from;
$seqno++;
$seqno = 0 if $seqno > 0x0ffff;
my ($head, $data) = split /\|/, $line, 2;
return unless $head && $data;
- my ($origin, $group, $dts, $hop, $user) = split /,/, $head;
+ my ($origin, $dts, $hop, $group, $user) = split /,/, $head;
return if DXDupe::check("Ara,$origin,$dts", $dupeage);
my $err;
- $err .= "incomplete header," unless $origin && defined $group && $dts && defined $hop;
+ $err .= "incomplete header," unless $origin && $dts && defined $hop;
my ($cmd, $rdata) = split /,/, $data, 2;
# validate it further
$err .= "missing cmd or data," unless $cmd && $data;
$err .= "invalid command ($cmd)," unless $cmd =~ /^[A-Z][A-Z0-9]*$/;
- $err .= "invalid group ($group)," unless $group =~ /^[-A-Z0-9\/:]{2,}$/;
+ my ($gp, $tus) = split /:/, $group, 2;
+
+ $err .= "invalid group ($gp)," unless $gp =~ /^[A-Z0-9]{2,}$/;
+ $err .= "invalid tocall ($tus)," if $tus && !is_callsign($tus);
+ $err .= "invalid fromcall ($user)," if $user && !is_callsign($user);
my $class = 'Thingy::' . ucfirst(lc $cmd);
my $thing;
# store useful data
$thing->{origin} = $origin;
- ($thing->{group}, $thing->{touser}) = split /:/, $group, 2;
$thing->{time} = $t;
+ $thing->{group} = $gp if $gp;
+ $thing->{touser} = $tus if $tus;
$thing->{user} = $user if $user;
$thing->{hopsaway} = $hop;
return;
}
+
RouteDB::update($ncall, $origin);
# do we believe this call?
# if there is a parent, proceed, otherwise if there is a latent PC19 in the PC19list,
# fix it up in the routing tables and issue it forth before the PC16
- unless ($parent) {
- my $nl = $pc19list{$ncall};
-
- if ($nl && @_ > 3) { # 3 because of the hop count!
-
- # this is a new (remembered) node, now attach it to me if it isn't in filtered
- # and we haven't disallowed it
- my $user = DXUser->get_current($ncall);
- if (!$user) {
- $user = DXUser->new($ncall);
- $user->sort('A');
- $user->priv(1); # I have relented and defaulted nodes
- $user->lockout(1);
- $user->homenode($ncall);
- $user->node($ncall);
- }
+ if ($parent) {
- my $wantpc19 = $user->wantroutepc19;
- if ($wantpc19 || !defined $wantpc19) {
- my $new = Route->new($ncall); # throw away
- if ($self->in_filter_route($new)) {
- my @nrout;
- for (@$nl) {
- $parent = Route::Node::get($_->[0]);
- $dxchan = $parent->dxchan if $parent;
- if ($dxchan && $dxchan ne $self) {
- dbg("PCPROT: PC19 from $origin trying to alter locally connected $ncall, ignored!") if isdbg('chanerr');
- $parent = undef;
- }
- if ($parent) {
- my $r = $parent->add($ncall, $_->[1], $_->[2]);
- push @nrout, $r unless @nrout;
- }
- }
- $user->wantroutepc19(1) unless defined $wantpc19; # for now we work on the basis that pc16 = real route
- $user->lastin($main::systime) unless DXChannel->get($ncall);
- $user->put;
-
- # route the pc19 - this will cause 'stuttering PC19s' for a while
- $self->route_pc19($origin, $line, @nrout) if @nrout ;
- $parent = Route::Node::get($ncall);
- unless ($parent) {
- dbg("PCPROT: lost $ncall after sending PC19 for it?");
- return;
- }
- } else {
- return;
- }
- delete $pc19list{$ncall};
- }
- } else {
- dbg("PCPROT: Node $ncall not in config") if isdbg('chanerr');
- return;
- }
- } else {
-
$dxchan = $parent->dxchan;
if ($dxchan && $dxchan ne $self) {
dbg("PCPROT: PC16 from $origin trying to alter locally connected $ncall, ignored!") if isdbg('chanerr');
return;
}
- # input filter if required
- return unless $self->in_filter_route($parent);
- }
-
- my $i;
- my @rout;
- for ($i = 2; $i < $#_; $i++) {
- my ($call, $conf, $here) = $_[$i] =~ /^(\S+) (\S) (\d)/o;
- next unless $call && $conf && defined $here && is_callsign($call);
- next if $call eq $main::mycall;
-
- eph_del_regex("^PC17\\^$call\\^$ncall");
+
+ my $i;
+ my @rout;
+ for ($i = 2; $i < $#_; $i++) {
+ my ($call, $conf, $here) = $_[$i] =~ /^(\S+) (\S) (\d)/o;
+ next unless $call && $conf && defined $here && is_callsign($call);
+ next if $call eq $main::mycall;
+
+ eph_del_regex("^PC17\\^$call\\^$ncall");
- $conf = $conf eq '*';
-
- # reject this if we think it is a node already
- my $r = Route::Node::get($call);
- my $u = DXUser->get_current($call) unless $r;
- if ($r || ($u && $u->is_node)) {
- dbg("PCPROT: $call is a node") if isdbg('chanerr');
- next;
- }
+ $conf = 1;
- $r = Route::User::get($call);
- my $flags = Route::here($here)|Route::conf($conf);
+ my $r = Route::User::get($call);
+ my $flags = Route::here($here)|Route::conf($conf);
- if ($r) {
- my $au = $r->addparent($parent);
- if ($r->flags != $flags) {
- $r->flags($flags);
- $au = $r;
+ if ($r) {
+ my $au = $r->addparent($parent);
+ if ($r->flags != $flags) {
+ $r->flags($flags);
+ $au = $r;
+ }
+ push @rout, $r if $au;
+ } else {
+ push @rout, $parent->add_user($call, $flags);
}
- push @rout, $r if $au;
- } else {
- push @rout, $parent->add_user($call, $flags);
- }
- # add this station to the user database, if required
- $call =~ s/-\d+$//o; # remove ssid for users
- my $user = DXUser->get_current($call);
- $user = DXUser->new($call) if !$user;
- $user->homenode($parent->call) if !$user->homenode;
- $user->node($parent->call);
- $user->lastin($main::systime) unless DXChannel->get($call);
- $user->put;
+ # add this station to the user database, if required
+ $call =~ s/-\d+$//o; # remove ssid for users
+ my $user = DXUser->get_current($call);
+ $user = DXUser->new($call) if !$user;
+ $user->homenode($parent->call) if !$user->homenode;
+ $user->node($parent->call);
+ $user->lastin($main::systime) unless DXChannel->get($call);
+ $user->put;
+ }
+
+ if (@rout) {
+ my $thing = Thingy::Dx->new(origin=>$main::mycall);
+ $thing->from_DXProt(DXProt=>$line,originref=>$parent);
+ $thing->queue($self);
+ } else {
+ dbg("PCPROT: No usable users") if isdbg('chanerr');
+ }
}
- $self->route_pc16($origin, $line, $parent, @rout) if @rout;
}
# remove a user
my $thing = shift;
unless ($thing->{Aranea}) {
my @items;
- $thing->{Aranea} = Aranea::genmsg($thing, 'Rloc', @items);
+ $thing->{Aranea} = Aranea::genmsg($thing, 'Rt', @items);
}
return $thing->{Aranea};
}
return $thing->{DXProt};
}
-sub gen_DXCommandmode
-{
- my $thing = shift;
- my $dxchan = shift;
- my $buf;
-
- return $buf;
-}
+#sub gen_DXCommandmode
+#{
+# my $thing = shift;
+# my $dxchan = shift;
+# my $buf;
+#
+# return $buf;
+#}
sub from_DXProt
{
# global route filtering on INPUT
if ($dxchan->{inroutefilter}) {
- my ($filter, $hops) = $dxchan->{inroutefilter}->it($thing->{routedata});
+ my $ref = Route::Node::get($thing->{origin});
+ my ($filter, $hops) = $dxchan->{inroutefilter}->it($ref);
unless ($filter) {
dbg("PCPROT: Rejected by input route filter") if isdbg('chanerr');
return;
my $thing = shift;
my $dxchan = shift;
- # global route filtering on INPUT
+ # global route filtering on OUTPUT
if ($dxchan->{routefilter}) {
- my ($filter, $hops) = $dxchan->{routefilter}->it($thing->{routedata});
+ my $ref = Route::Node::get($thing->{origin});
+ my ($filter, $hops) = $dxchan->{routefilter}->it($ref);
unless ($filter) {
dbg("PCPROT: Rejected by output route filter") if isdbg('chanerr');
return;