+ return;
+ }
+
+ } elsif ($sort eq 'K') {
+ $pc92Kin += length $line;
+
+ # remember the last channel we arrived on
+ $parent->PC92C_dxchan($self->{call}, $hops) unless $self->{call} eq $parent->call;
+
+ my @ent = _decode_pc92_call($pc->[4]);
+
+ if (@ent) {
+ my $add;
+
+ ($parent, $add) = $self->pc92_handle_first_slot(\@ent, $parent, $t, $hops);
+ return unless $parent; # dupe
+
+ push @radd, $add if $add;
+ $parent->reset_obs;
+ my $call = $parent->call;
+ my $version = $ent[4] || 0;
+ my $build = $ent[5] || 0;
+ $build =~ s/^0\.//;
+ my $oldbuild = $parent->build || 0;
+ my $oldversion = $parent->version || 0;
+ my $user = check_add_user($parent->call, 'S');
+ my $oldsort = $user->sort // '';
+
+ dbg("PCPROT: PC92 K v: $version ov: $oldversion b: $build ob: $oldbuild pk: " . ($parent->K || '0') . " uk: " . ($user->K || 0)) if isdbg('pc92k');
+
+ if (is_numeric($version) || is_numeric($build)) {
+ my $changed = 0;
+ if (($oldversion ne $version || $build ne $oldbuild)) {
+ dbg("PCPROT: PC92 K rec, node $call updated version: $version (was $oldversion) build: $build (was $oldbuild)");
+ $user->version($parent->version($version));
+ $user->build($parent->build($build));
+ ++$changed;
+ }
+
+ if ($oldsort ne 'S') {
+ $user->sort('S');
+ dbg(sprintf "PCPROT: PC92 K rec, node $call updated sort: $oldsort->S");
+ ++$changed;
+ }
+
+ unless (DXChannel::get($user->call)) { # only do this if not connected
+ my $oldpriv = $user->priv;
+ my $oldlock = $user->lockout;
+ my $lastchanged = $changed;
+ $user->priv(1), ++$changed unless defined $oldpriv && $oldpriv;
+ $user->lockout(1), ++$changed unless defined $oldlock;
+ dbg(sprintf "PCPROT: PC92 K rec, node $call updated priv: '$oldpriv'->%d lockout: '$oldlock'->%s", $user->priv || 0, $user->lockout || 0) if $lastchanged != $changed;
+ }
+ unless ($user->K) {
+ dbg(sprintf "PCPROT: PC92 K rec, node $call updated - marked as sending PC92 K records priv: %d lockout: %d ", $user->priv || 0, $user->lockout || 0);
+ $user->K(1);
+ ++$changed;
+ }
+ $user->put if $changed;
+ $parent->K(1); # mark this as come in on a K
+ } else {
+ dbg("DXProt PC92 K rec, version call $call: invalid version: '$version' or build: '$version', ignored");
+ }
+ dbg("ROUTE: reset obscount on $call now " . $parent->obscount) if isdbg('obscount');
+ }
+ } elsif ($sort eq 'A' || $sort eq 'D' || $sort eq 'C') {
+
+ $pc92Ain += length $line if $sort eq 'A';
+ $pc92Cin += length $line if $sort eq 'C';
+ $pc92Din += length $line if $sort eq 'D';
+
+ # remember the last channel we arrived on
+ $parent->PC92C_dxchan($self->{call}, $hops) unless $self->{call} eq $parent->call;
+
+ # this is the main route section
+ # here is where all the routes are created and destroyed
+
+ # cope with missing duplicate node calls in the first slot
+ my $me = $pc->[4] || '';
+ $me ||= _encode_pc92_call($parent) unless $me ;
+
+ my @ent = map {my @a = _decode_pc92_call($_); @a ? \@a : ()} grep {$_ && /^[0-7]/} $me, @$pc[5 .. $#$pc];
+
+ if (@ent) {
+
+ # look at the first one which will always be a node of some sort
+ # except in the case of 'A' or 'D' in which the $pcall is used
+ # otherwise use the node call and update any information
+ # that needs to be done.
+ my $add;
+
+ ($parent, $add) = $self->pc92_handle_first_slot($ent[0], $parent, $t, $hops);
+ return unless $parent; # dupe
+
+ shift @ent;
+ push @radd, $add if $add;
+ }
+
+ # do a pass through removing any references to either mycall
+ my @nent;
+ for (@ent) {
+ my $dxc;
+ next unless $_ && @$_;
+ if ($_->[0] eq $main::mycall) {
+ dbg("PCPROT: $self->{call} : type $sort $_->[0] refers to me, ignored") if isdbg('route');
+ next;
+ }
+
+ my $isnode = ($_->[1] | $_->[2]);
+ if (($_->[0] eq $main::myalias && $isnode) || ($_->[0] eq $main::mycall && !$isnode)) {
+ LogDbg('err',"PCPROT: $self->{call} : type $sort $_->[0] trying to change type to " . $_->[1]?"Node":"User" . ", ignored");
+ next;
+ }
+
+ push @nent, $_;
+ }
+
+ if ($sort eq 'A') {
+ for (@nent) {
+ push @radd, _add_thingy($parent, $_, $self, $hops);
+ }
+ } elsif ($sort eq 'D') {
+ for (@nent) {
+ push @rdel, _del_thingy($parent, $_, $self);
+ }
+ } elsif ($sort eq 'C') {
+ my (@nodes, @users);
+
+ # we reset obscounts on config records as well as K records
+ $parent->reset_obs;
+ dbg("ROUTE: reset obscount on $parent->{call} now " . $parent->obscount) if isdbg('obscount');
+
+ #
+ foreach my $r (@nent) {
+ # my ($call, $is_node, $is_extnode, $here, $version, $build) = _decode_pc92_call($_);
+ if ($r->[0]) {
+ if ($r->[1]) {
+ push @nodes, $r->[0];
+ } else {
+ push @users, $r->[0];
+ }
+ } else {
+ dbg("PCPROT: $self->{call} : pc92 call entry '$_' not decoded, ignored") if isdbg('chanerr') || isdbg('route');
+ }
+ }
+
+ my ($dnodes, $dusers, $nnodes, $nusers) = $parent->calc_config_changes(\@nodes, \@users);
+
+ # add users here
+ foreach my $r (@nent) {
+ my $call = $r->[0];
+ if ($call) {
+ push @radd,_add_thingy($parent, $r, $self, $hops) if grep $call eq $_, (@$nnodes, @$nusers);
+ }
+ }
+ # del users here
+ foreach my $r (@$dnodes) {
+ push @rdel,_del_thingy($parent, [$r, 1], $self);
+ }
+ foreach my $r (@$dusers) {
+ push @rdel,_del_thingy($parent, [$r, 0], $self);
+ }
+
+ # remember this last PC92C for rebroadcast on demand
+ $parent->last_PC92C($line);