On-air testing of APRS digipeater with a crafted suite of test records

It is one thing to read code, and perform traces of live traffic to test proper function of a digipeater. This is a more valid technique than injecting test records directly into the software as for instance, viscous digi depends on the neighbour digis.

Having found and fixed, and made some enhancements to aprx, a test of externally supplied test records crafted to test various cases, including cases that are not well handled in other common solutions is appropriate.

To provide freedom to create not just simulated originating packets, but intermediate packets, direct creation of AX.25 packets is necessary. The method used here was to create packets in TNC2 format and convert them to KISS format to be sent to a KISS modem (TNC) for radio transmission. This was achieved in a two stage process:

  1. a suite of TNC2 format test cases was drafted in a text file and converted to a file of KISS records; and
  2. the file of KISS records is transmitted to a KISS modem, record at a time with a pause to allow network processing of the record and to avoid network congestion.

The test transmitter system comprised a RPi running Linux, a KISS modem, and hand held radio transceiver.

#generic digiok
TEST-9>TEST,WIDE1-1,WIDE2-1:!3430.00SI15000.00E#1
TEST-9>TEST,WIDE1-1,WIDE2-2:!3430.00SI15000.00E#2
TEST-9>TEST,WIDE2-2:!3430.00SI15000.00E#3
TEST-9>TEST,WIDE1-1,TEST*,WIDE2-1:!3430.00SI15000.00E#4
TEST-9>TEST,WIDE1*,WIDE2-1:!3430.00SI15000.00E#5
TEST-9>TEST,TEST*,WIDE1*,WIDE2-1:!3430.00SI15000.00E#6
#specific digiok
TEST-9>TEST,VK2AMW-1,WIDE2-1:!3430.00SI15000.00E#10
TEST-9>TEST,VK2RHR-1,WIDE2-1:!3430.00SI15000.00E#11
#should digi as fault, all *
TEST-9>TEST,WIDE1-1,WIDE2-4:!3430.00SI15000.00E#51
#should digi as fault for hopsreq<7, all *
TEST-9>TEST,WIDE1-1,WIDE2-2,WIDE2-2:!3430.00SI15000.00E#52
#should not digi for maxhops<1
TEST-9>TEST,TEST*,WIDE1*,WIDE2-1:!3430.00SI15000.00E#53

Above is small example suite of test records in TNC2 format. The conversion utility will treat lines starting with # as comments and ignore them.

#!/usr/bin/perl

use Ham::APRS::FAP qw(tnc2_to_kiss);

sub writekiss{
($tnc2frame)=@_;
$kissframe=tnc2_to_kiss($tnc2frame);
printf("%s\n",$kissframe);
}

while(<>){
  if(/^#/){ next;}
  writekiss($_);
}

Above is a PERL utility to convert the file of TNC2 records to KISS records. KISS records potentially contain arbitrary binary content, but in this case they will not contain CR or LF and so they are used as record delimiters.

#!/usr/bin/expect
#script to send KISS frames

set wt 10000

encoding system iso8859-1
fconfigure stdin -encoding iso8859-1
source [file dirname [info script]]/log.expect
set line "\n***** "
append line [timestamp -format "%Y-%m-%d %H:%M:%S" -gmt]
append line " $argv0 starting...\n\n"
send_log $line

if {[lindex $argv 0] == ""} {
  set port /dev/ttyUSB0
} else {
  set port [lindex $argv 0]
}

set spawned [spawn -open [open $port RDWR]]
set baud 9600
# -parenb means don't use a parity bit
# -cstopb means "not 2 stop bits, but 1"
# cs8 means 8 bits
# -echo means no echo (full duplex?)
stty ispeed $baud ospeed $baud raw -echo cs8 -parenb -cstopb -onlcr < $port

set recno 0
set timeout 2
after 1000

#  Process data file
while {[gets stdin record]>=0} {
  if {$recno>0} {send_tty "Wait ${wt}ms ...\n"; after $wt}
  incr recno
  send_tty "Send kiss record $recno\n"
  send $record
  send_log $record
  }

send_log "\nAll done!\n"
send_log "==========================================================\n"
exit

Above is an expect script for *nix to read the KISS records from file and send them to the KISS modem.

#!/usr/bin/perl
#a script to send a file of KISS records to a TNC, record at a time

use FileHandle;

$PORT='COM4';

system("mode $PORT: baud=9600 parity=n data=8 stop=1");
open com,'>',$PORT;
com->autoflush(1);
$|=1;

while(<>){
  chomp;
  printf("Write...\n");
  printf(com "$_");
  printf("Wait...\n");
  sleep 10;
  }

close com;

EXPECT is a bit crippled on Windows, so a simple PERL script above can suffice.

A log is kept of records received by a node and the handling of each of the test cases for various configuration options can be checked for compliance.