+ # handle PC90 frames in a special way.
+ #
+ # PC90 frames are normal frames that that are wrapped in inside a PC90
+ # The extra fields are "originating node" and a sequence number.
+ # The sequence number is checked against the nodes 'last one' to see if
+ # it is a duplicate and, if so, is dropped at this stage; before any
+ # other processing.
+ #
+ # This is done here simply for efficiency. Adding another function would
+ # add more copying and so on.
+ #
+
+ my $origin = $self->call;
+
+ if ($pcno >= 90) {
+ $origin = $field[1];
+ if ($origin eq $main::mycall) {
+ dbg("PCPROT: loop dupe") if isdbg('chanerr');
+ return;
+ }
+ my $seq = $field[2];
+ my $node = Route::Node::get($origin);
+ if ($node) {
+ if (my $lid = $node->lid) {
+ my $cmp = $seq >= $lid ? $seq : $seq + 9999;
+ if ($cmp <= $lid) {
+ dbg("PCPROT: sequence dupe $seq ($cmp) <= $lid") if isdbg('chanerr');
+ return;
+ }
+ }
+ $node->lid($seq);
+ }
+
+ # do a recheck on the contents of the PC90
+ if ($pcno == 90) {
+ shift @field;
+ shift @field;
+ shift @field;
+
+ ($pcno) = $field[0] =~ /^PC(\d\d)/; # just get the number
+ return unless $pcno;
+ return if $pcno < 10 || $pcno > 99;
+
+ # check for and dump bad protocol messages
+ my $n = check($pcno, @field);
+ if ($n) {
+ dbg("PCPROT: bad field $n, dumped (" . parray($checklist[$pcno-10]) . ")") if isdbg('chanerr');
+ return;
+ }
+ }
+ }
+