#!/usr/bin/perl -w
use strict;

#
#  Create basic BPQ config file for TNC-Pi or TNC-BLack
#

#  Only create the system files if bpq32.cfg does not exist
my $init = !(-e 'bpq32.cfg');
#  Only create system files
my $cfg = !(@ARGV>0 && $ARGV[0] eq '-s');


#  Is this a Beaglebone?
my $bb = (-e '/etc/dogtag') ? 1 : 0;
my $tty = $bb ? '/dev/ttyO1' : '/dev/ttyAMA0';
my $pwd = `pwd`;
chomp $pwd;

#
#  Read value from the command line and validate
#
sub ReadLine
{
   my ($txt,$val,$def) = @_;
   my $res = '';
   while (length($res)==0)
   {
      if ($def)
      {
         print "Enter $txt: [Default $def]\n";
      }
      else
      {
         print "Enter $txt:\n";
      }
      $res = <>;
      chomp $res;
      $res =~ s/^\s*//;
      $res =~ s/\s*$//;
      length($res)==0 && $def && ($res = $def);
      $val && ($res !~ /$val/) && (print "\nInvalid Entry\n\n") && ($res = '');
   }
   return $res;
}

#
#  Write line to config file
#
sub WriteLine
{
   my ($cmd,$rem) = @_;
   if ($rem)
   {
      printf CFG "%-36s ; %s\n" , $cmd , $rem;
   }
   else
   {
      print CFG "$cmd\n";
   }
}

#
#  Get parameters from command line
#
if ($cfg)
{
   my $call  = ReadLine('Node Callsign (e.g. K0NTS [no -1 or -10])','^[A-Za-z]+[0-9]+[A-Za-z]+$');
   my $tla   = ReadLine('Owner Acronym (1-4 letters, e.g. CTN, used in prompts)','^[\S]+$');
   my $own   = ReadLine('Owner Name (e.g. Colorado Traffic Net, used in prompts)');
   my $loc   = ReadLine('Grid Square (e.g. DM79gr)','^[A-Z][A-Z][0-9][0-9][a-z][a-z]$');
   my $freq  = ReadLine('Frequency in kHz (e.g. 145050)','^[1-9][0-9][0-9][0-9][0-9][0-9]$');
   my $sysop = ReadLine('Sysop Callsign (e.g. AC0KQ)','^[A-Za-z]+[0-9]+[A-Za-z]+$',$call);
   my $user  = ReadLine('Sysop Username (e.g. willem)');
   my $pass  = ReadLine('Sysop Password (e.g. XyZ123)');
   my $cms   = ReadLine('Winlink Username (callsign of authorized station, - for no winlink)',undef,$call);
   my $cmpw;
   if ($cms eq '-')
   {
      $cms = '';
   }
   else
   {
      $cmpw  = ReadLine('Winlink Password');
   }
   my $http = $bb ? 8008 : 8080;
   my $MHz = sprintf "%.3f" , $freq/1000+0.0001;

   #  Write configuration file
   open(CFG , ">bpq32.cfg") || die "Cannot open file bpq32.cfg\n";
   WriteLine("; $tla RMS Gateway Config File");
   WriteLine("");
   WriteLine("SIMPLE","This set a whole load of paramters to reasonable defaults");
   WriteLine("NODECALL=$call","Default node callsign");
   WriteLine("LOCATOR=$loc","Defailt node location");
   WriteLine("LINMAIL","Enable BBS");
   WriteLine("");
   WriteLine("IDINTERVAL=10","UI broadcast interval (minutes)");
   WriteLine("IDMSG:","UI broadcast text");
   if ($cms)
   {
      WriteLine("$own BBS & RMS.  Connect to $call-1 & $call-10");
   }
   else
   {
      WriteLine("$own BBS.  Connect to $call-1");
   }
   WriteLine("***");
   WriteLine("");
   WriteLine("CTEXT:","Connect Message");
   WriteLine("Welcome to the $own BPQ32 Node.");
   if ($cms)
   {
      WriteLine("$call> BBS RMS CONNECT BYE INFO NODES ROUTES PORTS USERS MHEARD");
   }
   else
   {
      WriteLine("$call> BBS CONNECT BYE INFO NODES ROUTES PORTS USERS MHEARD");
   }
   WriteLine("***");
   WriteLine("");
   WriteLine("BTINTERVAL=10","Beacon interval (minutes)");
   WriteLine("BTEXT:","Beacon text");
   if ($cms)
   {
      WriteLine("$own BBS & RMS.  Connect to $call-1 & $call-10");
   }
   else
   {
      WriteLine("$own BBS.  Connect to $call-1");
   }
   WriteLine("***");
   WriteLine("");
   WriteLine("INFOMSG:","Text for INFO command");
   WriteLine("This is the BPQ32 Node for the $own.");
   WriteLine("Sysop $sysop.");
   WriteLine("Traffic left on this node will be forwarded");
   WriteLine("using the National Traffic System.");
   WriteLine("Type BBS to connect to the BBS.");
   $cms && WriteLine("Type RMS to connect to WinLink.");
   WriteLine("***");
   WriteLine("");
   WriteLine("TNCPORT","Host Port");
   WriteLine("   COMPORT=$pwd/com10","Serial connection (created by BPQ)");
   WriteLine("   TYPE=TNC2","TNC2,KANT,SCS,DED");
   WriteLine("   APPLNUM=32","Last Application");
   WriteLine("   APPLFLAGS=6","Display Connected Message");
   WriteLine("ENDPORT");
   WriteLine("");
   WriteLine("PORT");
   WriteLine("   ID=$MHz MHz 1200 bps","PORTS command text");
   WriteLine("   TYPE=ASYNC","RS232 connection");
   WriteLine("   PROTOCOL=KISS","KISS protocol");
   WriteLine("   KISSOPTIONS=PITNC,NOPARAMS","KISS options for TNC");
   WriteLine("   COMPORT=$tty","Serial port");
   WriteLine("   SPEED=19200","Serial port speed");
   WriteLine("   CHANNEL=A","TNC channel");
   WriteLine("   MAXFRAME=2","Max outstanding frames");
   WriteLine("   FRACK=7000","Level 2 timeout (ms)");
   WriteLine("   RESPTIME=1000","Level 2 delayed ACK (ms)");
   WriteLine("   RETRIES=10","Level 2 max retries");
   WriteLine("   PACLEN=128","Max packet length (bytes)");
   WriteLine("   TXDELAY=500","Transmit keyup delay (ms)");
   WriteLine("   SLOTTIME=100","CMSA interval timer (ms)");
   WriteLine("   PERSIST=64","Persistence (256/(# transmissions-1)");
   WriteLine("   DIGIFLAG=1","Allow Digipeat on this port");
   if ($cms eq $call)
   {
      WriteLine("   WL2KREPORT PUBLIC,server.winlink.org,8085,$call-10,$loc,00-23,${freq}000,PKT1200,50,25,9,0");
   }
   WriteLine("ENDPORT");
   WriteLine("");
   WriteLine("PORT");
   WriteLine("   ID=Telnet Server","PORTS command text");
   WriteLine("   DRIVER=TELNET","TCP/IP connection");
   WriteLine("   CONFIG","Driver specific configuration from here to ENDPORT");
   WriteLine("   LOGGING=1","Log all connections");
   WriteLine("   DisconnectOnClose=1","Disconnect on close");
   WriteLine("   TCPPORT=8010","Port for telnet connections");
   WriteLine("   FBBPORT=8011","Port for FBB protocol BBS connections");
   WriteLine("   HTTPPORT=$http","Port for web interface");
   WriteLine("   LOGINPROMPT=user:","Telnet login prompt");
   WriteLine("   PASSWORDPROMPT=password:","Telnet password prompt");
   WriteLine("   LOCALECHO=NO","Do not echo input");
   WriteLine("   MAXSESSIONS=10","Maxmimum simultaneous connections");
   WriteLine("   CTEXT=$tla BPQ32 Telnet Server\\nEnter ? for list of commands\\n\\n","Telnet connect message");
   WriteLine("   USER=$user,$pass,$sysop,,SYSOP","Telnet user");
   if ($cms)
   {
      WriteLine("   CMS=1","Enable WinLink CMS connection");
      WriteLine("   CMSCALL=$cms","Callsign for WinLink");
      WriteLine("   CMSPASS=$cmpw","Password for WinLink");
   }
   WriteLine("ENDPORT");
   WriteLine("");
   WriteLine("PORT");
   WriteLine("   ID=AX/IP/UDP","Displayed by PORTS command");
   WriteLine("   DRIVER=BPQAXIP","Uses BPQAXIP");
   WriteLine("   QUALITY=220","Quality factor applied to node broadcasts heard on");
   WriteLine("   MINQUAL=165","Entries in the nodes table with qualities greater or");
   WriteLine("   MAXFRAME=5","Max outstanding frames (1 thru 7)");
   WriteLine("   FRACK=3000","Level 2 timeout in milliseconds");
   WriteLine("   RESPTIME=1000","Level 2 delayed ack timer in milliseconds");
   WriteLine("   RETRIES=5","Level 2 maximum retry value");
   WriteLine("   PACLEN=236","Maximum packet length");
   WriteLine("   CONFIG","Driver specific configuration from here to ENDPORT");
   WriteLine("   MHEARD","Keep heard stats");
   WriteLine("   UDP 10093","UDP port");
   WriteLine("   AUTOADDMAP","Automatically add new connections");
   WriteLine("   BROADCAST NODES","Broadcast");
   WriteLine("   MAP K0NTS argon.schreuder.us UDP 10093 B","AXIP to K0NTS");
   WriteLine("   MAP N4ATA n4ata.dyndns.org   UDP 10093 B","AXIP to N4ATA");
   WriteLine("ENDPORT");
   WriteLine("");
   WriteLine("APPLICATION 1,BBS,,$call-1,${tla}BBS,255","BBS Application");
   $cms && WriteLine("APPLICATION 2,RMS,C 2 CMS,$call-10,${tla}RMS,255","CMS Application");
   WriteLine("APPLICATION 32,TALK,,$call","Node Application");
   close(CFG);
   print "bpq32.cfg written\n";

   #  End here if this is a remake of bpq32.cfg
   $init || exit;
}

#
#  Run minicom
#
open(RUN , ">bterm") || die "Cannot open file bterm\n";
print RUN "minicom -S $pwd/minicombpq\n";
close(RUN);
print "bterm written\n";
chmod 0755 , 'bterm';

#
#  Minicom default configuration
#
open(RUN , ">../.minirc.dfl") || die "Cannot open file ../.minirc.dfl\n";
print RUN "pu port $pwd/com10\n";
close(RUN);
print "../.minirc.dfl written\n";

#
#  minicom initialization
#
open(RUN , ">minicombpq") || die "Cannot open file minicombpq\n";
print RUN "send \"^C\"\n";
print RUN "send \"D\"\n";
print RUN "send \"\"\n";
print RUN "send \"auto on\"\n";
print RUN "send \"echo on\"\n";
print RUN "send \"conok on\"\n";
print RUN "send \"cbell on\"\n";
close(RUN);
print "minicombpq written\n";

#
#  Write file to start BPQ automatically
#
#  Older style init method
if (!$bb && -e '/etc/inittab')
{
   open(RUN , ">restartbpq") || die "Cannot open file restartbpq\n";
   print RUN "#!/bin/bash\n";
   print RUN "# Make sure only root can run our script\n";
   print RUN "if [ \$EUID -ne 0 ]; then\n";
   print RUN "   echo \"This script must be run as root\" 1>&2\n";
   print RUN "   exit 1\n";
   print RUN "fi\n";
   print RUN "#  Find PID for pilinbpq and kill it\n";
   print RUN "ps auxww |grep pilinbpq|grep -v grep|awk '{print \$2}'|xargs kill\n";
   close(RUN);
   print "restartbpq written\n";
   chmod 0755 , 'restartbpq';

   open(RUN , ">runbpq") || die "Cannot open file runbpq\n";
   print RUN "#!/bin/bash\n";
   print RUN "# Make sure only root can run our script\n";
   print RUN "if [ \$EUID -ne 0 ]; then\n";
   print RUN "   echo \"This script must be run as root\" 1>&2\n";
   print RUN "   exit 1\n";
   print RUN "fi\n";
   print RUN "# Start pilinbpq in the BPQ directory\n";
   print RUN "cd $pwd\n";
   print RUN "$pwd/pilinbpq\n";
   close(RUN);
   print "runbpq written\n";
   chmod 0755 , 'runbpq';
}
#  Newer systemd method
else
{
   open(RUN , ">bpq.service") || die "Cannot open file bpq.service\n";
   print RUN "[Unit]\n";
   print RUN "Description=BPQ\n";
   print RUN "ConditionPathExists=|$pwd\n";
   print RUN "After=network.target\n";
   print RUN "\n";
   print RUN "[Service]\n";
   print RUN "WorkingDirectory=$pwd\n";
   print RUN "ExecStart=$pwd/pilinbpq\n";
   print RUN "Restart=always\n";
   print RUN "SyslogIdentifier=BPQ\n";
   print RUN "\n";
   print RUN "[Install]\n";
   print RUN "WantedBy=multi-user.target\n";
   close(RUN);
   print "bpq.service written\n";
}
