2022-08-28 09:35:46 +01:00
/*
2022-11-14 14:02:28 +00:00
Copyright 2001 - 2022 John Wiseman G8BPQ
2022-08-28 09:35:46 +01:00
This file is part of LinBPQ / BPQ32 .
LinBPQ / BPQ32 is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
LinBPQ / BPQ32 is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with LinBPQ / BPQ32 . If not , see http : //www.gnu.org/licenses
*/
// July 2010
// BPQ32 now reads bpqcfg.txt. This module converts it to the original binary format.
// Based on the standalonw bpqcfg.c
/************************************************************************/
/* CONFIG.C Jonathan Naylor G4KLX, 19th November 1988 */
/* */
/* Program to produce configuration file for G8BPQ Network Switch */
/* based on the original written in BASIC by G8BPQ. */
/* */
/* Subsequently extended by G8BPQ */
/* */
/************************************************************************/
//
// 22/11/95 - Add second port alias for digipeating (for APRS)
// - Add PORTMAXDIGIS param
// 1999 - Win32 Version (but should also compile in 16 bit
// 5/12/99 - Add DLLNAME Param for ext driver
// 26/11/02 - Added AUTOSAVE
// Jan 2006
// Add params for input and output names
// Wait before exiting if error detected
// March 2006
// Accept # as comment delimiter
// Display input and output filenames
// Wait before exit, even if ok
// March 2006
// Add L4APPL param
// Jan 2007
// Remove UNPROTO
// Add BTEXT
// Add BCALL
// Nov 2007
// Convert calls and APPLICATIONS string to upper case
// Jan 2008
// Remove trailing space from UNPROTO
// Don't warn BBSCALL etc missing if APPL1CALL etc present
// August 2008
// Add IPGATEWAY Parameter
// Add Port DIGIMASK Parameter
// December 2008
// Add C_IS_CHAT Parameter
// March 2009
// Add C style COmments (/* */ at start of line)
// August 2009
// Add INP3 flag to locked routes
// November 2009
// Add PROTOCOL=PACTOR or WINMOR option
// December 2009
// Add INP3 MAXRTT and MAXHOPS Commands
// March 2010
// Add SIMPLE mode
// March 2010
// Change SIMPLE mode default of Full_CTEXT to 1
// April 2010
// Add NoKeepAlive ROUTE option
// Converted to intenal bpq32 process
// Spetember 2010
// Add option of embedded port configuration
# define _CRT_SECURE_NO_DEPRECATE
# include "CHeaders.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# include <math.h>
# include "configstructs.h"
// KISS Options Equates
# define CHECKSUM 1
# define POLLINGKISS 2 // KISSFLAGS BITS
# define ACKMODE 4 // CAN USE ACK REQURED FRAMES
# define POLLEDKISS 8 // OTHER END IS POLLING US
# define D700 16 // D700 Mode (Escape "C" chars
# define TNCX 32 // TNC-X Mode (Checksum of ACKMODE frames includes ACK bytes
# define PITNC 64 // PITNC Mode - can reset TNC with FEND 15 2
# define NOPARAMS 128 // Don't send SETPARAMS frame
# define FLDIGI 256 // Support FLDIGI COmmand Frames
# define TRACKER 512 // SCS Tracker. Need to set KISS Mode
# define FASTI2C 1024 // Use BLocked I2C Reads (like ARDOP)
# define DRATS 2048
struct WL2KInfo * DecodeWL2KReportLine ( char * buf ) ;
// Dummy file routines - write to buffer instead
2023-05-25 14:17:53 +01:00
char * PortConfig [ 70 ] ;
char * RadioConfigMsg [ 70 ] ;
char * WL2KReportLine [ 70 ] ;
2022-08-28 09:35:46 +01:00
int nextRadioPort = 0 ;
int nextDummyInterlock = 233 ;
2023-05-25 14:17:53 +01:00
BOOL PortDefined [ 70 ] ;
2022-08-28 09:35:46 +01:00
extern BOOL IncludesMail ;
extern BOOL IncludesChat ;
extern int needAIS ;
extern int needADSB ;
extern int AGWPort ;
extern int AGWSessions ;
extern int AGWMask ;
extern BOOL LoopMonFlag ;
extern BOOL Loopflag ;
extern char NodeMapServer [ 80 ] ;
extern char ChatMapServer [ 80 ] ;
2024-11-28 22:33:53 +00:00
double LatFromLOC ;
double LonFromLOC ;
2022-08-28 09:35:46 +01:00
VOID * zalloc ( int len ) ;
int WritetoConsoleLocal ( char * buff ) ;
char * stristr ( char * ch1 , char * ch2 ) ;
2024-11-28 22:33:53 +00:00
int FromLOC ( char * Locator , double * pLat , double * pLon ) ;
2022-08-28 09:35:46 +01:00
VOID Consoleprintf ( const char * format , . . . )
{
char Mess [ 255 ] ;
va_list ( arglist ) ;
va_start ( arglist , format ) ;
vsprintf ( Mess , format , arglist ) ;
strcat ( Mess , " \n " ) ;
WritetoConsoleLocal ( Mess ) ;
return ;
}
# pragma pack()
int tnctypes ( int i , char value [ ] , char rec [ ] ) ;
int do_kiss ( char value [ ] , char rec [ ] ) ;
struct TNCDATA * TNCCONFIGTABLE = NULL ; // malloc'ed
int NUMBEROFTNCPORTS = 0 ;
struct UPNP * UPNPConfig = NULL ;
struct TNCDATA * TNC2ENTRY ;
extern char PWTEXT [ ] ;
extern char HFCTEXT [ ] ;
extern int HFCTEXTLEN ;
extern char LOCATOR [ ] ;
extern char MAPCOMMENT [ ] ;
extern char LOC [ ] ;
extern int RFOnly ;
int decode_rec ( char * rec ) ;
int applcallsign ( int i , char * value , char * rec ) ;
int appl_qual ( int i , char * value , char * rec ) ;
int callsign ( char * val , char * value , char * rec ) ;
int int_value ( short * val , char * value , char * rec ) ;
int hex_value ( int * val , char * value , char * rec ) ;
int bin_switch ( char * val , char * value , char * rec ) ;
int dec_switch ( char * val , char * value , char * rec ) ;
int applstrings ( int i , char * value , char * rec ) ;
int dotext ( char * val , char * key_word , int max ) ;
int dolinked ( int i , char * value , char * rec ) ;
int routes ( int i ) ;
int ports ( int i ) ;
int tncports ( int i ) ;
int dedports ( int i ) ;
int xindex ( char * s , char * t ) ;
int verify ( char * s , char c ) ;
int GetNextLine ( char * rec ) ;
int call_check ( char * callsign , char * val ) ;
int call_check_internal ( char * callsign ) ;
int callstring ( int i , char * value , char * rec ) ;
int decode_port_rec ( char * rec ) ;
int doid ( int i , char * value , char * rec ) ;
int dodll ( int i , char * value , char * rec ) ;
int doDriver ( int i , char * value , char * rec ) ;
int hwtypes ( int i , char * value , char * rec ) ;
int protocols ( int i , char * value , char * rec ) ;
int bbsflag ( int i , char * value , char * rec ) ;
int channel ( int i , char * value , char * rec ) ;
int validcalls ( int i , char * value , char * rec ) ;
int kissoptions ( int i , char * value , char * rec ) ;
int decode_tnc_rec ( char * rec ) ;
int tnctypes ( int i , char * value , char * rec ) ;
int do_kiss ( char * value , char * rec ) ;
int decode_ded_rec ( char * rec ) ;
int simple ( int i ) ;
2024-04-06 02:10:08 +01:00
int64_t int64_value ( int64_t * val , char value [ ] , char rec [ ] ) ;
2022-08-28 09:35:46 +01:00
int C_Q_ADD_NP ( VOID * PQ , VOID * PBUFF ) ;
int doSerialPortName ( int i , char * value , char * rec ) ;
int doPermittedAppls ( int i , char * value , char * rec ) ;
2023-06-21 08:21:04 +01:00
int doKissCommand ( int i , char * value , char * rec ) ;
2022-08-28 09:35:46 +01:00
BOOL ProcessAPPLDef ( char * rec ) ;
BOOL ToLOC ( double Lat , double Lon , char * Locator ) ;
//int i;
//char value[];
//char rec[];
int FIRSTAPPL = 1 ;
BOOL Comment = FALSE ;
int CommentLine = 0 ;
# define MAXLINE 512
# define FILEVERSION 22
extern UCHAR BPQDirectory [ ] ;
struct CONFIGTABLE xxcfg ;
struct PORTCONFIG xxp ;
char inputname [ 250 ] = " bpqcfg.txt " ;
char option [ 250 ] ;
/************************************************************************/
/* STATIC VARIABLES */
/************************************************************************/
static char * keywords [ ] =
{
" OBSINIT " , " OBSMIN " , " NODESINTERVAL " , " L3TIMETOLIVE " , " L4RETRIES " , " L4TIMEOUT " ,
" BUFFERS " , " PACLEN " , " TRANSDELAY " , " T3 " , " IDLETIME " , " BBS " ,
" NODE " , " NODEALIAS " , " BBSALIAS " , " NODECALL " , " BBSCALL " ,
" TNCPORT " , " IDMSG: " , " INFOMSG: " , " ROUTES: " , " PORT " , " MAXLINKS " ,
" MAXNODES " , " MAXROUTES " , " MAXCIRCUITS " , " IDINTERVAL " , " MINQUAL " ,
" HIDENODES " , " L4DELAY " , " L4WINDOW " , " BTINTERVAL " , " UNPROTO " , " BBSQUAL " ,
" APPLICATIONS " , " EMS " , " CTEXT: " , " DESQVIEW " , " HOSTINTERRUPT " , " ENABLE_LINKED " ,
" XXDEDHOST " , " FULL_CTEXT " , " SIMPLE " , " AUTOSAVE " , " L4APPL " ,
" APPL1CALL " , " APPL2CALL " , " APPL3CALL " , " APPL4CALL " ,
" APPL5CALL " , " APPL6CALL " , " APPL7CALL " , " APPL8CALL " ,
" APPL1ALIAS " , " APPL2ALIAS " , " APPL3ALIAS " , " APPL4ALIAS " ,
" APPL5ALIAS " , " APPL6ALIAS " , " APPL7ALIAS " , " APPL8ALIAS " ,
" APPL1QUAL " , " APPL2QUAL " , " APPL3QUAL " , " APPL4QUAL " ,
" APPL5QUAL " , " APPL6QUAL " , " APPL7QUAL " , " APPL8QUAL " ,
" BTEXT: " , " NETROMCALL " , " C_IS_CHAT " , " MAXRTT " , " MAXHOPS " , // IPGATEWAY= no longer allowed
2023-10-10 22:07:04 +01:00
" LogL4Connects " , " LogAllConnects " , " SAVEMH " , " ENABLEADIFLOG " , " ENABLEEVENTS " , " SAVEAPRSMSGS " ,
2024-11-05 21:03:15 +00:00
" EnableM0LTEMap " , " MQTT " , " MQTT_HOST " , " MQTT_PORT " , " MQTT_USER " , " MQTT_PASS "
2022-08-28 09:35:46 +01:00
} ; /* parameter keywords */
static void * offset [ ] =
{
& xxcfg . C_OBSINIT , & xxcfg . C_OBSMIN , & xxcfg . C_NODESINTERVAL , & xxcfg . C_L3TIMETOLIVE , & xxcfg . C_L4RETRIES , & xxcfg . C_L4TIMEOUT ,
& xxcfg . C_BUFFERS , & xxcfg . C_PACLEN , & xxcfg . C_TRANSDELAY , & xxcfg . C_T3 , & xxcfg . C_IDLETIME , & xxcfg . C_BBS ,
& xxcfg . C_NODE , & xxcfg . C_NODEALIAS , & xxcfg . C_BBSALIAS , & xxcfg . C_NODECALL , & xxcfg . C_BBSCALL ,
0 , & xxcfg . C_IDMSG , & xxcfg . C_INFOMSG , & xxcfg . C_ROUTE , & xxcfg . C_PORT , & xxcfg . C_MAXLINKS ,
& xxcfg . C_MAXDESTS , & xxcfg . C_MAXNEIGHBOURS , & xxcfg . C_MAXCIRCUITS , & xxcfg . C_IDINTERVAL , & xxcfg . C_MINQUAL ,
& xxcfg . C_HIDENODES , & xxcfg . C_L4DELAY , & xxcfg . C_L4WINDOW , & xxcfg . C_BTINTERVAL , & xxcfg . C_WASUNPROTO , & xxcfg . C_BBSQUAL ,
& xxcfg . C_APPL , & xxcfg . C_EMSFLAG , & xxcfg . C_CTEXT , & xxcfg . C_DESQVIEW , & xxcfg . C_HOSTINTERRUPT , & xxcfg . C_LINKEDFLAG ,
0 , & xxcfg . C_FULLCTEXT , 0 , & xxcfg . C_AUTOSAVE , & xxcfg . C_L4APPL ,
& xxcfg . C_APPL [ 0 ] . ApplCall , & xxcfg . C_APPL [ 1 ] . ApplCall , & xxcfg . C_APPL [ 2 ] . ApplCall , & xxcfg . C_APPL [ 3 ] . ApplCall ,
& xxcfg . C_APPL [ 4 ] . ApplCall , & xxcfg . C_APPL [ 5 ] . ApplCall , & xxcfg . C_APPL [ 6 ] . ApplCall , & xxcfg . C_APPL [ 7 ] . ApplCall ,
& xxcfg . C_APPL [ 0 ] . ApplAlias , & xxcfg . C_APPL [ 1 ] . ApplAlias , & xxcfg . C_APPL [ 2 ] . ApplAlias , & xxcfg . C_APPL [ 3 ] . ApplAlias ,
& xxcfg . C_APPL [ 4 ] . ApplAlias , & xxcfg . C_APPL [ 5 ] . ApplAlias , & xxcfg . C_APPL [ 6 ] . ApplAlias , & xxcfg . C_APPL [ 7 ] . ApplAlias ,
& xxcfg . C_APPL [ 0 ] . ApplQual , & xxcfg . C_APPL [ 1 ] . ApplQual , & xxcfg . C_APPL [ 2 ] . ApplQual , & xxcfg . C_APPL [ 3 ] . ApplQual ,
& xxcfg . C_APPL [ 4 ] . ApplQual , & xxcfg . C_APPL [ 5 ] . ApplQual , & xxcfg . C_APPL [ 6 ] . ApplQual , & xxcfg . C_APPL [ 7 ] . ApplQual ,
& xxcfg . C_BTEXT , & xxcfg . C_NETROMCALL , & xxcfg . C_C , & xxcfg . C_MAXRTT , & xxcfg . C_MAXHOPS , // IPGATEWAY= no longer allowed
2023-10-10 22:07:04 +01:00
& xxcfg . C_LogL4Connects , & xxcfg . C_LogAllConnects , & xxcfg . C_SaveMH , & xxcfg . C_ADIF , & xxcfg . C_EVENTS , & xxcfg . C_SaveAPRSMsgs ,
2024-11-05 21:03:15 +00:00
& xxcfg . C_M0LTEMap , & xxcfg . C_MQTT , & xxcfg . C_MQTT_HOST , & xxcfg . C_MQTT_PORT , & xxcfg . C_MQTT_USER , & xxcfg . C_MQTT_PASS } ; /* offset for corresponding data in config file */
2022-08-28 09:35:46 +01:00
static int routine [ ] =
{
1 , 1 , 1 , 1 , 1 , 1 ,
1 , 1 , 1 , 1 , 1 , 2 ,
2 , 0 , 0 , 0 , 0 ,
3 , 4 , 20 , 5 , 6 , 1 ,
1 , 1 , 1 , 1 , 1 ,
2 , 1 , 1 , 1 , 7 , 1 ,
8 , 2 , 4 , 2 , 9 , 10 ,
11 , 1 , 12 , 2 , 1 ,
13 , 13 , 13 , 13 ,
13 , 13 , 13 , 13 ,
13 , 13 , 13 , 13 ,
13 , 13 , 13 , 13 ,
14 , 14 , 14 , 14 ,
14 , 14 , 14 , 14 ,
15 , 0 , 2 , 9 , 9 ,
2024-11-28 22:33:53 +00:00
2 , 2 , 1 , 2 , 2 , 2 ,
2024-11-05 21:03:15 +00:00
2 , 2 , 0 , 1 , 20 , 20 } ; // Routine to process param
2022-08-28 09:35:46 +01:00
int PARAMLIM = sizeof ( routine ) / sizeof ( int ) ;
//int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int);
//#define PARAMLIM 74
static char eof_message [ ] = " Unexpected end of file on input \n " ;
static char * pkeywords [ ] =
{
" ID " , " TYPE " , " PROTOCOL " , " IOADDR " , " INTLEVEL " , " SPEED " , " CHANNEL " ,
" BBSFLAG " , " QUALITY " , " MAXFRAME " , " TXDELAY " , " SLOTTIME " , " PERSIST " ,
" FULLDUP " , " SOFTDCD " , " FRACK " , " RESPTIME " , " RETRIES " ,
" PACLEN " , " CWID " , " PORTCALL " , " PORTALIAS " , " ENDPORT " , " VALIDCALLS " ,
" QUALADJUST " , " DIGIFLAG " , " DIGIPORT " , " USERS " , " UNPROTO " , " PORTNUM " ,
" TXTAIL " , " ALIAS_IS_BBS " , " L3ONLY " , " KISSOPTIONS " , " INTERLOCK " , " NODESPACLEN " ,
" TXPORT " , " MHEARD " , " CWIDTYPE " , " MINQUAL " , " MAXDIGIS " , " PORTALIAS2 " , " DLLNAME " ,
" BCALL " , " DIGIMASK " , " NOKEEPALIVES " , " COMPORT " , " DRIVER " , " WL2KREPORT " , " UIONLY " ,
" UDPPORT " , " IPADDR " , " I2CBUS " , " I2CDEVICE " , " UDPTXPORT " , " UDPRXPORT " , " NONORMALIZE " ,
2022-11-14 14:02:28 +00:00
" IGNOREUNLOCKEDROUTES " , " INP3ONLY " , " TCPPORT " , " RIGPORT " , " PERMITTEDAPPLS " , " HIDE " ,
2024-11-05 21:03:15 +00:00
" SMARTID " , " KISSCOMMAND " , " SendtoM0LTEMap " , " PortFreq " , " M0LTEMapInfo " , " QTSMPort " ,
" MQTT " , " MQTT_HOST " , " MQTT_PORT " , " MQTT_USER " , " MQTT_PASS " } ; /* parameter keywords */
2022-08-28 09:35:46 +01:00
static void * poffset [ ] =
{
& xxp . ID , & xxp . TYPE , & xxp . PROTOCOL , & xxp . IOADDR , & xxp . INTLEVEL , & xxp . SPEED , & xxp . CHANNEL ,
& xxp . BBSFLAG , & xxp . QUALITY , & xxp . MAXFRAME , & xxp . TXDELAY , & xxp . SLOTTIME , & xxp . PERSIST ,
& xxp . FULLDUP , & xxp . SOFTDCD , & xxp . FRACK , & xxp . RESPTIME , & xxp . RETRIES ,
& xxp . PACLEN , & xxp . CWID , & xxp . PORTCALL , & xxp . PORTALIAS , 0 , & xxp . VALIDCALLS ,
& xxp . QUALADJUST , & xxp . DIGIFLAG , & xxp . DIGIPORT , & xxp . USERS , & xxp . UNPROTO , & xxp . PORTNUM ,
& xxp . TXTAIL , & xxp . ALIAS_IS_BBS , & xxp . L3ONLY , & xxp . KISSOPTIONS , & xxp . INTERLOCK , & xxp . NODESPACLEN ,
& xxp . TXPORT , & xxp . MHEARD , & xxp . CWIDTYPE , & xxp . MINQUAL , & xxp . MAXDIGIS , & xxp . PORTALIAS2 , & xxp . DLLNAME ,
& xxp . BCALL , & xxp . DIGIMASK , & xxp . DefaultNoKeepAlives , & xxp . IOADDR , & xxp . DLLNAME , & xxp . WL2K , & xxp . UIONLY ,
& xxp . IOADDR , & xxp . IPADDR , & xxp . INTLEVEL , & xxp . IOADDR , & xxp . IOADDR , & xxp . ListenPort , & xxp . NoNormalize ,
2022-11-14 14:02:28 +00:00
& xxp . IGNOREUNLOCKED , & xxp . INP3ONLY , & xxp . TCPPORT , & xxp . RIGPORT , & xxp . PERMITTEDAPPLS , & xxp . Hide ,
2024-10-11 15:37:11 +01:00
& xxp . SmartID , & xxp . KissParams , & xxp . SendtoM0LTEMap , & xxp . PortFreq , & xxp . M0LTEMapInfo , & xxp . QtSMPort } ; /* offset for corresponding data in config file */
2022-08-28 09:35:46 +01:00
static int proutine [ ] =
{
4 , 5 , 8 , 3 , 1 , 1 , 7 ,
6 , 1 , 1 , 1 , 1 , 1 ,
1 , 1 , 1 , 1 , 1 ,
1 , 0 , 0 , 0 , 9 , 10 ,
1 , 13 , 13 , 1 , 11 , 1 ,
1 , 2 , 2 , 12 , 1 , 1 ,
1 , 7 , 7 , 13 , 13 , 0 , 14 ,
0 , 1 , 2 , 18 , 15 , 16 , 2 ,
1 , 17 , 1 , 1 , 1 , 1 , 2 ,
2022-11-14 14:02:28 +00:00
2 , 2 , 1 , 1 , 19 , 2 ,
2024-10-11 15:37:11 +01:00
1 , 20 , 1 , 21 , 22 , 1 } ; /* routine to process parameter */
2022-08-28 09:35:46 +01:00
int PPARAMLIM = sizeof ( proutine ) / sizeof ( int ) ;
static int endport = 0 ;
static int portnum = 1 ;
static int portindex = 0 ;
static int porterror = 0 ;
static int tncporterror = 0 ;
static int dedporterror = 0 ;
static int kissflags = 0 ;
static int NextAppl = 0 ;
static int routeindex = 0 ;
/************************************************************************/
/* Global variables */
/************************************************************************/
2022-11-18 17:03:39 +00:00
int paramok [ 100 ] = { 0 } ; /* PARAMETER OK FLAG */
2022-08-28 09:35:46 +01:00
FILE * fp1 ; /* TEXT INPUT FILE */
static char s1 [ 80 ] ;
static char s2 [ 80 ] ;
static char s3 [ 80 ] ;
static char s4 [ 80 ] ;
static char s5 [ 80 ] ;
static char s6 [ 80 ] ;
static char s7 [ 80 ] ;
static char s8 [ 80 ] ;
char commas [ ] = " ,,,,,,,,,,,,,,,, " ;
char bbscall [ 11 ] ;
char bbsalias [ 11 ] ;
int bbsqual ;
2023-10-10 22:07:04 +01:00
extern UCHAR ConfigDirectory [ 260 ] ;
2022-08-28 09:35:46 +01:00
BOOL LocSpecified = FALSE ;
/************************************************************************/
/* MAIN PROGRAM */
/************************************************************************/
VOID WarnThread ( ) ;
int LineNo = 0 ;
int heading = 0 ;
BOOL ProcessConfig ( )
{
int i ;
char rec [ MAXLINE ] ;
int Cfglen = sizeof ( xxcfg ) ;
struct APPLCONFIG * App ;
memset ( & xxcfg , 0 , sizeof ( xxcfg ) ) ;
memset ( & xxp , 0 , sizeof ( xxp ) ) ;
heading = 0 ;
portnum = 1 ;
NextAppl = 0 ;
LOCATOR [ 0 ] = 0 ;
MAPCOMMENT [ 0 ] = 0 ;
routeindex = 0 ;
portindex = 0 ;
2023-05-25 14:17:53 +01:00
for ( i = 0 ; i < 70 ; i + + )
2022-08-28 09:35:46 +01:00
{
if ( PortConfig [ i ] )
{
free ( PortConfig [ i ] ) ;
PortConfig [ i ] = NULL ;
}
PortDefined [ i ] = FALSE ;
if ( RadioConfigMsg [ i ] )
{
free ( RadioConfigMsg [ i ] ) ;
RadioConfigMsg [ i ] = NULL ;
}
}
nextRadioPort = 0 ;
TNCCONFIGTABLE = NULL ;
NUMBEROFTNCPORTS = 0 ;
AGWMask = 0 ;
UPNPConfig = NULL ;
Consoleprintf ( " Configuration file Preprocessor. " ) ;
2023-10-10 22:07:04 +01:00
if ( ConfigDirectory [ 0 ] = = 0 )
2022-08-28 09:35:46 +01:00
{
strcpy ( inputname , " bpq32.cfg " ) ;
}
else
{
2023-10-10 22:07:04 +01:00
strcpy ( inputname , ConfigDirectory ) ;
2022-08-28 09:35:46 +01:00
strcat ( inputname , " / " ) ;
strcat ( inputname , " bpq32.cfg " ) ;
}
if ( ( fp1 = fopen ( inputname , " r " ) ) = = NULL )
{
Consoleprintf ( " Could not open file %s Error code %d " , inputname , errno ) ;
return FALSE ;
}
Consoleprintf ( " Using Configuration file %s " , inputname ) ;
memset ( & xxcfg , 0 , sizeof ( xxcfg ) ) ;
App = ( struct APPLCONFIG * ) & xxcfg . C_APPL [ 0 ] ;
for ( i = 0 ; i < NumberofAppls ; i + + )
{
memset ( App - > Command , ' ' , 12 ) ;
memset ( App - > CommandAlias , ' ' , 48 ) ;
memset ( App - > ApplCall , ' ' , 10 ) ;
memset ( App - > ApplAlias , ' ' , 10 ) ;
App + + ;
}
// xxcfg.SaveMH = TRUE; // Default to save
GetNextLine ( rec ) ;
while ( rec [ 0 ] )
{
decode_rec ( rec ) ;
GetNextLine ( rec ) ;
}
2023-05-16 16:40:12 +01:00
if ( xxcfg . C_NODECALL [ 0 ] = = ' ' )
{
Consoleprintf ( " Missing NODECALL " ) ;
heading = 1 ;
}
2022-08-28 09:35:46 +01:00
paramok [ 6 ] = 1 ; /* dont need BUFFERS */
paramok [ 8 ] = 1 ; /* dont need TRANSDELAY */
paramok [ 13 ] = 1 ; // NodeAlias
paramok [ 17 ] = 1 ; /* dont need TNCPORTS */
paramok [ 20 ] = 1 ; // Or ROUTES
paramok [ 32 ] = 1 ; /* dont need UNPROTO */
paramok [ 35 ] = 1 ; /* dont need EMS */
paramok [ 37 ] = 1 ; /* dont need DESQVIEW */
paramok [ 38 ] = 1 ; /* dont need HOSTINTERRUPT */
paramok [ 40 ] = 1 ; /* or DEDHOST */
paramok [ 42 ] = 1 ; /* or SIMPLE */
paramok [ 43 ] = 1 ; /* or AUTOSAVE */
paramok [ 44 ] = 1 ; /* or L4APPL */
paramok [ 16 ] = 1 ; // BBSCALL
paramok [ 14 ] = 1 ; // BBSALIAS
paramok [ 33 ] = 1 ; // BBSQUAL
paramok [ 34 ] = 1 ; // APPLICATIONS
if ( paramok [ 45 ] = = 1 )
{
paramok [ 16 ] = 1 ; // APPL1CALL overrides BBSCALL
memcpy ( xxcfg . C_BBSCALL , xxcfg . C_APPL [ 0 ] . ApplCall , 10 ) ;
}
if ( paramok [ 53 ] = = 1 )
{
paramok [ 14 ] = 1 ; // APPL1ALIAS overrides BBSALIAS
memcpy ( xxcfg . C_BBSALIAS , xxcfg . C_APPL [ 0 ] . ApplAlias , 10 ) ;
}
if ( paramok [ 61 ] = = 1 )
{
paramok [ 33 ] = 1 ; // APPL1QUAL overrides BBSQUAL
xxcfg . C_BBSQUAL = xxcfg . C_APPL [ 0 ] . ApplQual ;
}
for ( i = 0 ; i < 24 ; i + + )
paramok [ 45 + i ] = 1 ; /* or APPLCALLS, APPLALIASS APPLQUAL */
paramok [ 69 ] = 1 ; // BText optional
paramok [ 70 ] = 1 ; // IPGateway optional
paramok [ 71 ] = 1 ; // C_IS_CHAT optional
paramok [ 72 ] = 1 ; // MAXRTT optional
paramok [ 73 ] = 1 ; // MAXHOPS optional
paramok [ 74 ] = 1 ; // LogL4Connects optional
paramok [ 75 ] = 1 ; // LogAllConnects optional
paramok [ 76 ] = 1 ; // SAVEMH optional
paramok [ 77 ] = 1 ; // ENABLEADIFLOG optional
2022-11-18 17:03:39 +00:00
paramok [ 78 ] = 1 ; // EnableEvents optional
paramok [ 79 ] = 1 ; // SaveAPRSMsgs optional
2023-10-10 22:07:04 +01:00
paramok [ 79 ] = 1 ; // SaveAPRSMsgs optional
paramok [ 80 ] = 1 ; // EnableM0LTEMap optional
2024-11-05 21:03:15 +00:00
paramok [ 81 ] = 1 ; // MQTT Params
paramok [ 82 ] = 1 ; // MQTT Params
paramok [ 83 ] = 1 ; // MQTT Params
paramok [ 84 ] = 1 ; // MQTT Params
paramok [ 85 ] = 1 ; // MQTT Params
2022-08-28 09:35:46 +01:00
for ( i = 0 ; i < PARAMLIM ; i + + )
{
if ( paramok [ i ] = = 0 )
{
if ( heading = = 0 )
{
Consoleprintf ( " " ) ;
Consoleprintf ( " The following parameters were not correctly specified " ) ;
heading = 1 ;
}
Consoleprintf ( keywords [ i ] ) ;
}
}
if ( portnum = = 1 )
{
Consoleprintf ( " No valid radio ports defined " ) ;
heading = 1 ;
}
if ( Comment )
{
Consoleprintf ( " Unterminated Comment (Missing */) at line %d " , CommentLine ) ;
heading = 1 ;
}
fclose ( fp1 ) ;
if ( LOCATOR [ 0 ] = = 0 & & LocSpecified = = 0 & & RFOnly = = 0 )
{
Consoleprintf ( " " ) ;
Consoleprintf ( " Please enter a LOCATOR statment in your BPQ32.cfg " ) ;
Consoleprintf ( " If you really don't want to be on the Node Map you can enter LOCATOR=NONE " ) ;
Consoleprintf ( " " ) ;
// _beginthread(WarnThread, 0, 0);
}
if ( heading = = 0 )
{
Consoleprintf ( " Conversion (probably) successful " ) ;
Consoleprintf ( " " ) ;
}
else
{
Consoleprintf ( " Conversion failed " ) ;
return FALSE ;
}
/*
// Dump to file for debugging
sprintf_s ( inputname , sizeof ( inputname ) , " CFG%d " , time ( NULL ) ) ;
fp1 = fopen ( inputname , " wb " ) ;
if ( fp1 )
{
fwrite ( ConfigBuffer , 1 , 100000 , fp1 ) ;
fclose ( fp1 ) ;
}
*/
return TRUE ;
}
/************************************************************************/
/* Decode PARAM= */
/************************************************************************/
int decode_rec ( char * rec )
{
int i ;
int cn = 1 ; /* RETURN CODE FROM ROUTINES */
char key_word [ 300 ] = " " ;
char value [ 300 ] = " " ;
if ( _memicmp ( rec , " NODEMAPSERVER= " , 14 ) = = 0 )
{
// Map reporting override
strcpy ( NodeMapServer , & rec [ 14 ] ) ;
strlop ( NodeMapServer , ' ' ) ;
return 1 ;
}
if ( _memicmp ( rec , " CloseOnError= " , 13 ) = = 0 )
{
// Close BPQ on trapped program error
CloseOnError = atoi ( & rec [ 13 ] ) ;
return 1 ;
}
if ( _memicmp ( rec , " CHATMAPSERVER= " , 14 ) = = 0 )
{
// Map reporting override
strcpy ( ChatMapServer , & rec [ 14 ] ) ;
strlop ( ChatMapServer , ' ' ) ;
return 1 ;
}
if ( _memicmp ( rec , " IPGATEWAY " , 9 ) = = 0 & & rec [ 9 ] ! = ' = ' ) // IPGATEWAY, not IPGATEWAY=
{
// Create Embedded IPGateway Config
// Copy all subsequent lines up to **** to a memory buffer
char * ptr ;
2023-05-25 14:17:53 +01:00
PortConfig [ IPConfigSlot ] = ptr = malloc ( 50000 ) ;
2022-08-28 09:35:46 +01:00
* ptr = 0 ;
GetNextLine ( rec ) ;
while ( ! feof ( fp1 ) )
{
if ( _memicmp ( rec , " **** " , 3 ) = = 0 )
{
2023-05-25 14:17:53 +01:00
PortConfig [ IPConfigSlot ] = realloc ( PortConfig [ IPConfigSlot ] , ( strlen ( ptr ) + 1 ) ) ;
2022-08-28 09:35:46 +01:00
xxcfg . C_IP = 1 ;
return 0 ;
}
strcat ( ptr , rec ) ;
strcat ( ptr , " \r \n " ) ;
GetNextLine ( rec ) ;
}
Consoleprintf ( " Missing **** for IPGateway Config " ) ;
heading = 1 ;
return 0 ;
}
if ( _memicmp ( rec , " PORTMAPPER " , 10 ) = = 0 )
{
// Create Embedded portmapper Config
// Copy all subsequent lines up to **** to a memory buffer
char * ptr ;
2023-05-25 14:17:53 +01:00
PortConfig [ PortMapConfigSlot ] = ptr = malloc ( 50000 ) ;
2022-08-28 09:35:46 +01:00
* ptr = 0 ;
GetNextLine ( rec ) ;
while ( ! feof ( fp1 ) )
{
if ( _memicmp ( rec , " **** " , 3 ) = = 0 )
{
2023-05-25 14:17:53 +01:00
PortConfig [ PortMapConfigSlot ] = realloc ( PortConfig [ PortMapConfigSlot ] , ( strlen ( ptr ) + 1 ) ) ;
2022-08-28 09:35:46 +01:00
xxcfg . C_PM = 1 ;
return 0 ;
}
strcat ( ptr , rec ) ;
strcat ( ptr , " \r \n " ) ;
GetNextLine ( rec ) ;
}
Consoleprintf ( " Missing **** for Portmapper Config " ) ;
heading = 1 ;
return 0 ;
}
if ( _memicmp ( rec , " APRSDIGI " , 8 ) = = 0 )
{
// Create Embedded APRS Config
// Copy all subsequent lines up to **** to a memory buffer
char * ptr ;
2023-05-25 14:17:53 +01:00
PortConfig [ APRSConfigSlot ] = ptr = malloc ( 50000 ) ;
2022-08-28 09:35:46 +01:00
* ptr = 0 ;
// Don't use GetNextLine - we need to keep ; in messages
fgets ( rec , MAXLINE , fp1 ) ;
LineNo + + ;
while ( ! feof ( fp1 ) )
{
if ( _memicmp ( rec , " **** " , 3 ) = = 0 )
{
2023-05-25 14:17:53 +01:00
PortConfig [ APRSConfigSlot ] = realloc ( PortConfig [ APRSConfigSlot ] , ( strlen ( ptr ) + 1 ) ) ;
2022-08-28 09:35:46 +01:00
return 0 ;
}
if ( strlen ( rec ) > 1 )
{
if ( memcmp ( rec , " /* " , 2 ) = = 0 )
{
Comment = TRUE ;
CommentLine = LineNo ;
goto NextAPRS ;
}
else if ( memcmp ( rec , " */ " , 2 ) = = 0 )
{
Comment = FALSE ;
goto NextAPRS ;
}
}
if ( Comment )
goto NextAPRS ;
strcat ( ptr , rec ) ;
strcat ( ptr , " \r \n " ) ;
NextAPRS :
fgets ( rec , MAXLINE , fp1 ) ;
LineNo + + ;
}
if ( _memicmp ( rec , " **** " , 3 ) = = 0 )
return 0 ; // No Newline after ***
Consoleprintf ( " Missing **** for APRS Config " ) ;
heading = 1 ;
return 0 ;
}
if ( _memicmp ( rec , " PASSWORD " , 8 ) = = 0 )
{
// SYSOP Password
if ( strlen ( rec ) > 88 ) rec [ 88 ] = 0 ;
_strupr ( rec ) ;
strcpy ( PWTEXT , & rec [ 9 ] ) ;
return 0 ;
}
# ifdef LINBPQ
if ( _memicmp ( rec , " LINMAIL " , 7 ) = = 0 )
{
// Enable Mail on Linux Verdion
IncludesMail = TRUE ;
return 0 ;
}
if ( _memicmp ( rec , " LINCHAT " , 7 ) = = 0 )
{
// Enable Chat on Linux Verdion
IncludesChat = TRUE ;
return 0 ;
}
# endif
if ( _memicmp ( rec , " ENABLEAIS " , 9 ) = = 0 )
{
needAIS = TRUE ;
return 0 ;
}
if ( _memicmp ( rec , " ENABLEADSB " , 9 ) = = 0 )
{
needADSB = TRUE ;
return 0 ;
}
if ( _memicmp ( rec , " HFCTEXT " , 7 ) = = 0 )
{
// HF only CTEXT (normlly short to reduce traffic)
if ( strlen ( rec ) > 87 ) rec [ 87 ] = 0 ;
strcpy ( HFCTEXT , & rec [ 8 ] ) ;
HFCTEXTLEN = ( int ) ( strlen ( HFCTEXT ) ) ;
HFCTEXT [ HFCTEXTLEN - 1 ] = ' \r ' ;
return 0 ;
}
if ( _memicmp ( rec , " LOCATOR " , 7 ) = = 0 )
{
// Station Maidenhead Locator or Lat/Long
char * Context ;
char * ptr1 = strtok_s ( & rec [ 7 ] , " ,= \t \n \r : " , & Context ) ;
char * ptr2 = strtok_s ( NULL , " ,= \t \n \r : " , & Context ) ;
LocSpecified = TRUE ;
if ( _memicmp ( & rec [ 8 ] , " NONE " , 4 ) = = 0 )
return 0 ;
if ( _memicmp ( & rec [ 8 ] , " XXnnXX " , 6 ) = = 0 )
return 0 ;
if ( ptr1 )
{
strcpy ( LOCATOR , ptr1 ) ;
if ( ptr2 )
{
strcat ( LOCATOR , " : " ) ;
strcat ( LOCATOR , ptr2 ) ;
ToLOC ( atof ( ptr1 ) , atof ( ptr2 ) , LOC ) ;
2024-11-28 22:33:53 +00:00
LatFromLOC = atof ( ptr1 ) ;
LonFromLOC = atof ( ptr2 ) ;
2022-08-28 09:35:46 +01:00
}
else
{
if ( strlen ( ptr1 ) = = 6 )
2024-11-28 22:33:53 +00:00
{
2022-08-28 09:35:46 +01:00
strcpy ( LOC , ptr1 ) ;
2024-11-28 22:33:53 +00:00
FromLOC ( LOC , & LatFromLOC , & LonFromLOC ) ;
// Randomise in square
LatFromLOC + = ( ( rand ( ) / 24.0 ) / RAND_MAX ) ;
LonFromLOC + = ( ( rand ( ) / 12.0 ) / RAND_MAX ) ;
}
2022-08-28 09:35:46 +01:00
}
}
return 0 ;
}
if ( _memicmp ( rec , " MAPCOMMENT " , 10 ) = = 0 )
{
// Additional Info for Node Map
char * ptr1 = & rec [ 11 ] ;
char * ptr2 = MAPCOMMENT ;
while ( * ptr1 )
{
if ( * ptr1 = = ' , ' )
{
* ptr2 + + = ' & ' ;
* ptr2 + + = ' # ' ;
* ptr2 + + = ' 4 ' ;
* ptr2 + + = ' 4 ' ;
* ptr2 + + = ' ; ' ;
}
else
* ( ptr2 + + ) = * ptr1 ;
ptr1 + + ;
if ( ( ptr2 - MAPCOMMENT ) > 248 )
break ;
}
* ptr2 = 0 ;
return 0 ;
}
// Process BRIDGE statement
if ( _memicmp ( rec , " BRIDGE " , 6 ) = = 0 )
{
int DigiTo ;
int Port ;
char * Context ;
char * p_value ;
char * ptr ;
p_value = strtok_s ( & rec [ 7 ] , " ,= \t \n \r " , & Context ) ;
Port = atoi ( p_value ) ;
2023-05-25 14:17:53 +01:00
if ( Port > MaxBPQPortNo )
2022-08-28 09:35:46 +01:00
return FALSE ;
if ( Context = = NULL )
return FALSE ;
ptr = strtok_s ( NULL , " , \t \n \r " , & Context ) ;
while ( ptr )
{
DigiTo = atoi ( ptr ) ;
2023-05-25 14:17:53 +01:00
if ( DigiTo > MaxBPQPortNo )
2022-08-28 09:35:46 +01:00
return 0 ;
if ( Port ! = DigiTo ) // Not to our port!
xxcfg . CfgBridgeMap [ Port ] [ DigiTo ] = TRUE ;
ptr = strtok_s ( NULL , " , \t \n \r " , & Context ) ;
}
return 0 ;
}
// AGW Emulator Params
if ( _memicmp ( rec , " AGWPORT " , 7 ) = = 0 )
{
AGWPort = atoi ( & rec [ 8 ] ) ;
return 0 ;
}
if ( _memicmp ( rec , " AGWSESSIONS " , 11 ) = = 0 )
{
AGWSessions = atoi ( & rec [ 12 ] ) ;
return 0 ;
}
if ( _memicmp ( rec , " AGWMASK " , 7 ) = = 0 )
{
AGWMask = strtol ( & rec [ 8 ] , 0 , 0 ) ;
return 0 ;
}
if ( _memicmp ( rec , " AGWAPPL " , 7 ) = = 0 )
{
AGWMask | = 1 < < ( strtol ( & rec [ 8 ] , 0 , 0 ) - 1 ) ;
return 0 ;
}
if ( _memicmp ( rec , " AGWLOOPMON " , 10 ) = = 0 )
{
LoopMonFlag = strtol ( & rec [ 11 ] , 0 , 0 ) ;
return 0 ;
}
if ( _memicmp ( rec , " AGWLOOPTX " , 9 ) = = 0 )
{
Loopflag = strtol ( & rec [ 10 ] , 0 , 0 ) ;
return 0 ;
}
if ( _memicmp ( rec , " APPLICATION " , 12 ) = = 0 | | _memicmp ( rec , " APPLICATION= " , 12 ) = = 0 )
{
// New Style APPLICATION Definition
char save [ 300 ] ;
strcpy ( save , rec ) ; // Save in case error
if ( ! ProcessAPPLDef ( & rec [ 12 ] ) )
{
Consoleprintf ( " Invalid Record %s " , save ) ;
heading = 1 ;
}
else
paramok [ 34 ] = 1 ; // Got APPLICATIONS
return 0 ;
}
if ( _memicmp ( rec , " EXCLUDE= " , 8 ) = = 0 )
{
char * ptr2 = & rec [ 8 ] ;
UCHAR * ptr3 = xxcfg . C_EXCLUDE ;
_strupr ( ptr2 ) ;
while ( * ( ptr2 ) > 32 )
{
ConvToAX25 ( ptr2 , ptr3 ) ;
ptr3 + = 7 ;
if ( strchr ( ptr2 , ' , ' ) )
{
ptr2 = strchr ( ptr2 , ' , ' ) ;
ptr2 + + ;
}
else
break ;
if ( ptr3 > & xxcfg . C_EXCLUDE [ 63 ] )
{
Consoleprintf ( " Too Many Excluded Calls " ) ;
heading = 1 ;
break ;
}
}
return 0 ;
}
if ( _memicmp ( rec , " RADIO " , 5 ) = = 0 )
{
if ( strlen ( rec ) > 11 )
{
RadioConfigMsg [ nextRadioPort + + ] = _strdup ( rec ) ;
return 0 ;
}
else
{
// Multiline config, ending in ****
char * rptr ;
RadioConfigMsg [ nextRadioPort ] = rptr = zalloc ( 50000 ) ;
strcpy ( rptr , rec ) ;
GetNextLine ( rec ) ;
while ( ! feof ( fp1 ) )
{
if ( memcmp ( rec , " *** " , 3 ) = = 0 )
{
RadioConfigMsg [ nextRadioPort ] = realloc ( RadioConfigMsg [ nextRadioPort ] , ( strlen ( rptr ) + 1 ) ) ;
nextRadioPort + + ;
return 0 ;
}
strcat ( rptr , rec ) ;
GetNextLine ( rec ) ;
}
}
}
if ( _memicmp ( rec , " UPNP " , 5 ) = = 0 )
{
struct UPNP * Entry = ( struct UPNP * ) zalloc ( sizeof ( struct UPNP ) ) ;
char * ptr , * context ;
char copy [ 256 ] ;
strcpy ( copy , rec ) ;
ptr = strtok_s ( & rec [ 5 ] , " , " , & context ) ;
if ( ptr )
Entry - > Protocol = _strdup ( ptr ) ;
ptr = strtok_s ( NULL , " , " , & context ) ;
if ( ptr )
Entry - > LANport = Entry - > WANPort = _strdup ( ptr ) ; ;
ptr = strtok_s ( NULL , " , " , & context ) ;
if ( ptr )
Entry - > WANPort = _strdup ( ptr ) ; ;
if ( Entry - > LANport )
{
Entry - > Next = UPNPConfig ;
UPNPConfig = Entry ;
return 1 ;
}
Consoleprintf ( " Bad UPNP Line %s " , copy ) ;
heading = 1 ;
return 0 ;
}
2024-11-05 21:03:15 +00:00
if ( _memicmp ( " MQTT_HOST= " , rec , 10 ) = = 0 )
{
strcpy ( xxcfg . C_MQTT_HOST , & rec [ 10 ] ) ;
xxcfg . C_MQTT_HOST [ strlen ( xxcfg . C_MQTT_HOST ) - 1 ] = ' \0 ' ;
return 0 ;
}
if ( _memicmp ( " MQTT_USER= " , rec , 10 ) = = 0 )
{
strcpy ( xxcfg . C_MQTT_USER , & rec [ 10 ] ) ;
xxcfg . C_MQTT_USER [ strlen ( xxcfg . C_MQTT_USER ) - 1 ] = ' \0 ' ;
return 0 ;
}
if ( _memicmp ( " MQTT_PASS= " , rec , 10 ) = = 0 )
{
strcpy ( xxcfg . C_MQTT_PASS , & rec [ 10 ] ) ;
xxcfg . C_MQTT_PASS [ strlen ( xxcfg . C_MQTT_PASS ) - 1 ] = ' \0 ' ;
return 0 ;
}
2022-08-28 09:35:46 +01:00
if ( xindex ( rec , " = " ) > = 0 )
sscanf ( rec , " %[^=]=%s " , key_word , value ) ;
else
sscanf ( rec , " %s " , key_word ) ;
/************************************************************************/
/* SEARCH FOR KEYWORD IN TABLE */
/************************************************************************/
for ( i = 0 ; i < PARAMLIM & & _stricmp ( keywords [ i ] , key_word ) ! = 0 ; i + + )
;
if ( i = = PARAMLIM )
Consoleprintf ( " bpq32.cfg line no %d not recognised - Ignored: %s " , LineNo , rec ) ;
else
{
switch ( routine [ i ] )
{
case 0 :
cn = callsign ( ( char * ) offset [ i ] , value , rec ) ; /* CALLSIGNS */
break ;
case 1 :
cn = int_value ( ( short * ) offset [ i ] , value , rec ) ; /* INTEGER VALUES */
break ;
case 2 :
cn = bin_switch ( ( char * ) offset [ i ] , value , rec ) ; /* 0/1 SWITCHES */
break ;
case 3 :
cn = tncports ( i ) ; /* VIRTUAL COMBIOS PORTS */
break ;
case 4 :
cn = dotext ( ( char * ) offset [ i ] , key_word , 510 ) ; /* TEXT PARMS */
break ;
case 20 :
cn = dotext ( ( char * ) offset [ i ] , key_word , 2000 ) ; /* INFO TEXT PARM */
break ;
case 5 :
cn = routes ( i ) ; /* ROUTES TO LOCK IN */
break ;
case 6 :
cn = ports ( i ) ; /* PORTS DEFINITION */
break ;
case 7 :
Consoleprintf ( " Obsolete Record %s ignored " , rec ) ;
Consoleprintf ( " UNPROTO address should now be specified in PORT definition " ) ;
break ;
case 8 :
cn = applstrings ( i , value , rec ) ; /* APPLICATIONS LIST */
break ;
case 9 :
cn = dec_switch ( ( char * ) offset [ i ] , value , rec ) ; /* 0/9 SWITCHES */
break ;
case 10 :
cn = dolinked ( i , value , rec ) ; /* SINGLE CHAR */
break ;
case 11 :
Consoleprintf ( " Obsolete Record %s ignored " , rec ) ;
break ;
case 12 :
cn = simple ( i ) ; /* Set up basic L2 system*/
break ;
case 13 :
cn = applcallsign ( i , value , rec ) ; /* CALLSIGNS */
break ;
case 14 :
cn = appl_qual ( i , value , rec ) ; /* INTEGER VALUES */
break ;
case 15 :
cn = dotext ( ( char * ) offset [ i ] , key_word , 120 ) ; /* BTEXT */
break ;
}
paramok [ i ] = cn ;
}
return 0 ;
}
/************************************************************************/
/* CALLSIGNS */
/************************************************************************/
int applcallsign ( int i , char * value , char * rec )
{
char * val = ( char * ) offset [ i ] ;
if ( call_check_internal ( value ) )
{
// Invalid
return 0 ;
}
memcpy ( val , value , 10 ) ;
if ( i = = 45 )
strcpy ( bbscall , value ) ;
if ( i = = 53 )
strcpy ( bbsalias , value ) ;
return 1 ;
}
int appl_qual ( int i , char * value , char * rec )
{
int j , k ;
int * val = ( int * ) offset [ i ] ;
k = sscanf ( value , " %d " , & j ) ;
if ( k ! = 1 )
{
Consoleprintf ( " Invalid numerical value " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
if ( i = = 61 ) bbsqual = j ;
* val = j ;
return ( 1 ) ;
}
int callsign ( char * ptr , char * value , char * rec )
{
if ( call_check ( value , ptr ) = = 1 )
{
Consoleprintf ( " %s " , rec ) ;
return ( 0 ) ;
}
return ( 1 ) ;
}
/************************************************************************/
/* VALIDATE INT VALUES */
/************************************************************************/
int int_value ( short * val , char value [ ] , char rec [ ] )
{
int j , k ;
k = sscanf ( value , " %d " , & j ) ;
if ( k ! = 1 )
{
Consoleprintf ( " Invalid numerical value " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
val [ 0 ] = j ;
return ( 1 ) ;
}
2024-04-06 02:10:08 +01:00
int64_t int64_value ( int64_t * val , char value [ ] , char rec [ ] )
{
* val = strtoll ( value , NULL , 10 ) ;
return ( 1 ) ;
}
2022-08-28 09:35:46 +01:00
/************************************************************************/
/* VALIDATE HEX INT VALUES */
/************************************************************************/
int hex_value ( int * val , char value [ ] , char rec [ ] )
{
int j = - 1 , k = 0 ;
k = sscanf ( value , " %xH " , & j ) ;
if ( j < 0 )
{
Consoleprintf ( " Bad Hex Value " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
val [ 0 ] = j ;
return ( 1 ) ;
}
;
/************************************************************************/
/* VALIDATE BINARY SWITCH DATA AND WRITE TO FILE */
/************************************************************************/
int bin_switch ( char * val , char * value , char * rec )
{
int value_int ;
value_int = atoi ( value ) ;
if ( value_int = = 0 | | value_int = = 1 )
{
val [ 0 ] = value_int ;
return 1 ;
}
else
{
Consoleprintf ( " Invalid switch value, must be either 0 or 1 " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
}
/*
; single byte decimal
*/
int dec_switch ( char * val , char * value , char * rec )
{
int value_int ;
value_int = atoi ( value ) ;
if ( value_int < 256 )
{
val [ 0 ] = value_int ;
return 1 ;
}
else
{
Consoleprintf ( " Invalid value, must be between 0 and 255 " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
}
int applstrings ( int i , char * value , char * rec )
{
char appl [ 250 ] ; // In case trailing spaces
char * ptr1 ;
char * ptr2 ;
struct APPLCONFIG * App ;
int j ;
// strcat(rec,commas); // Ensure 16 commas
ptr1 = & rec [ 13 ] ; // skip APPLICATIONS=
App = & xxcfg . C_APPL [ 0 ] ;
while ( NextAppl + + < NumberofAppls )
{
memset ( appl , ' ' , 249 ) ;
appl [ 249 ] = 0 ;
ptr2 = appl ;
j = * ptr1 + + ;
while ( j ! = ' , ' & & j )
{
* ( ptr2 + + ) = toupper ( j ) ;
j = * ptr1 + + ;
}
ptr2 = strchr ( appl , ' / ' ) ;
if ( ptr2 )
{
// Command has an Alias
* ptr2 + + = 0 ;
memcpy ( App - > CommandAlias , ptr2 , 48 ) ;
strcat ( appl , " " ) ;
}
memcpy ( App - > Command , appl , 12 ) ;
xxcfg . C_BBS = 1 ;
if ( * ( ptr1 - 1 ) = = 0 )
return 1 ;
App + + ;
}
return ( 1 ) ;
}
/************************************************************************/
/* USE FOR FREE FORM TEXT IN MESSAGES */
/************************************************************************/
int dotext ( char * val , char * key_word , int max )
{
int len = 0 ;
char * ptr ;
char rec [ MAXLINE ] ;
GetNextLine ( rec ) ;
if ( xindex ( rec , " *** " ) = = 0 )
* val = ' \r ' ;
while ( xindex ( rec , " *** " ) ! = 0 & & ! feof ( fp1 ) )
{
ptr = strchr ( rec , 10 ) ;
if ( ptr ) * ptr = 0 ;
ptr = strchr ( rec , 13 ) ;
if ( ptr ) * ptr = 0 ;
strcat ( rec , " \r " ) ;
len + = ( int ) strlen ( rec ) ;
if ( len < = max )
{
strcpy ( val , rec ) ;
val + = ( int ) strlen ( rec ) ;
}
fgets ( rec , MAXLINE , fp1 ) ;
LineNo + + ;
}
if ( len > max )
{
Consoleprintf ( " Text too long: %s \r \n " , key_word ) ;
return ( 0 ) ;
}
if ( feof ( fp1 ) )
return ( 0 ) ;
else
return ( 1 ) ;
}
/************************************************************************/
/* CONVERT PRE-SET ROUTES PARAMETERS TO BINARY */
/************************************************************************/
int routes ( int i )
{
struct ROUTECONFIG * Route ;
int err_flag = 0 ;
int main_err = 0 ;
char rec [ MAXLINE ] ;
GetNextLine ( rec ) ;
while ( xindex ( rec , " *** " ) ! = 0 & & ! feof ( fp1 ) )
{
char Param [ 8 ] [ 256 ] ;
char * ptr1 , * ptr2 ;
int n = 0 , inp3 = 0 ;
Route = & xxcfg . C_ROUTE [ routeindex + + ] ;
// strtok and sscanf can't handle successive commas, so split up usig strchr
memset ( Param , 0 , 2048 ) ;
strlop ( rec , 13 ) ;
strlop ( rec , ' ; ' ) ;
ptr1 = rec ;
while ( ptr1 & & * ptr1 & & n < 8 )
{
ptr2 = strchr ( ptr1 , ' , ' ) ;
if ( ptr2 ) * ptr2 + + = 0 ;
strcpy ( & Param [ n + + ] [ 0 ] , ptr1 ) ;
ptr1 = ptr2 ;
while ( ptr1 & & * ptr1 & & * ptr1 = = ' ' )
ptr1 + + ;
}
strcpy ( Route - > call , & Param [ 0 ] [ 0 ] ) ;
Route - > quality = atoi ( Param [ 1 ] ) ;
Route - > port = atoi ( Param [ 2 ] ) ;
Route - > pwind = atoi ( Param [ 3 ] ) ;
Route - > pfrack = atoi ( Param [ 4 ] ) ;
Route - > ppacl = atoi ( Param [ 5 ] ) ;
inp3 = atoi ( Param [ 6 ] ) ;
Route - > farQual = atoi ( Param [ 7 ] ) ;
if ( Route - > farQual < 0 | | Route - > farQual > 255 )
{
Consoleprintf ( " Remote Quality must be between 0 and 255 " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
err_flag = 1 ;
}
if ( Route - > quality < 0 | | Route - > quality > 255 )
{
Consoleprintf ( " Quality must be between 0 and 255 " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
err_flag = 1 ;
}
2023-05-25 14:17:53 +01:00
if ( Route - > port < 1 | | Route - > port > MaxBPQPortNo )
2022-08-28 09:35:46 +01:00
{
2023-05-25 14:17:53 +01:00
Consoleprintf ( " Port number must be between 1 and 64 " ) ;
2022-08-28 09:35:46 +01:00
Consoleprintf ( " %s \r \n " , rec ) ;
err_flag = 1 ;
}
// Use top bit of window as INP3 Flag, next as NoKeepAlive
if ( inp3 & 1 )
Route - > pwind | = 0x80 ;
if ( inp3 & 2 )
Route - > pwind | = 0x40 ;
if ( err_flag = = 1 )
{
Consoleprintf ( " %s \r \n " , rec ) ;
main_err = 1 ;
err_flag = 0 ;
}
GetNextLine ( rec ) ;
}
if ( routeindex > MaxLockedRoutes )
{
routeindex - - ;
Consoleprintf ( " Route information too long " ) ;
main_err = 1 ;
}
if ( feof ( fp1 ) )
{
Consoleprintf ( eof_message ) ;
return ( 0 ) ;
}
if ( main_err = = 1 )
return ( 0 ) ;
else
return ( 1 ) ;
}
/************************************************************************/
/* CONVERT PORT DEFINITIONS TO BINARY */
/************************************************************************/
int hw ; // Hardware type
int LogicalPortNum ; // As set by PORTNUM
int ports ( int i )
{
char rec [ MAXLINE ] ;
endport = 0 ;
porterror = 0 ;
kissflags = 0 ;
xxp . PORTNUM = portnum ;
LogicalPortNum = portnum ;
2023-05-25 14:17:53 +01:00
if ( LogicalPortNum > MaxBPQPortNo )
{
Consoleprintf ( " Port Number must be between 1 and %d " , MaxBPQPortNo ) ;
heading = 1 ;
}
2023-10-10 22:07:04 +01:00
xxp . SendtoM0LTEMap = 1 ; // Default to enabled
2022-08-28 09:35:46 +01:00
while ( endport = = 0 & & ! feof ( fp1 ) )
{
GetNextLine ( rec ) ;
decode_port_rec ( rec ) ;
}
if ( porterror ! = 0 )
{
Consoleprintf ( " Error in port definition " ) ;
return ( 0 ) ;
}
if ( PortDefined [ LogicalPortNum ] ) // Already defined?
{
Consoleprintf ( " Port %d already defined " , LogicalPortNum ) ;
heading = 1 ;
}
PortDefined [ LogicalPortNum ] = TRUE ;
xxp . KISSOPTIONS = kissflags ;
// copy Port Config to main config
memcpy ( & xxcfg . C_PORT [ portindex + + ] , & xxp , sizeof ( xxp ) ) ;
memset ( & xxp , 0 , sizeof ( xxp ) ) ;
portnum + + ;
return ( 1 ) ;
}
int tncports ( int i )
{
char rec [ MAXLINE ] ;
endport = 0 ;
tncporterror = 0 ;
TNC2ENTRY = zalloc ( sizeof ( struct TNCDATA ) ) ;
TNC2ENTRY - > APPLFLAGS = 6 ;
TNC2ENTRY - > PollDelay = 1 ;
while ( endport = = 0 & & ! feof ( fp1 ) )
{
GetNextLine ( rec ) ;
decode_tnc_rec ( rec ) ;
}
if ( tncporterror ! = 0 )
{
Consoleprintf ( " Error in TNC PORT definition " ) ;
free ( TNC2ENTRY ) ;
return ( 0 ) ;
}
C_Q_ADD_NP ( & TNCCONFIGTABLE , TNC2ENTRY ) ; // Add to chain
NUMBEROFTNCPORTS + + ;
return ( 1 ) ;
}
/************************************************************************/
/* MISC FUNCTIONS */
/************************************************************************/
/************************************************************************/
/* FIND OCCURENCE OF ONE STRING WITHIN ANOTHER */
/************************************************************************/
int xindex ( s , t )
char s [ ] , t [ ] ;
{
int i , j , k ;
for ( i = 0 ; s [ i ] ! = ' \0 ' ; i + + )
{
for ( j = i , k = 0 ; t [ k ] ! = ' \0 ' & & s [ i ] = = t [ k ] ; j + + , k + + )
;
if ( t [ k ] = = ' \0 ' )
return ( i ) ;
}
return ( - 1 ) ;
}
/************************************************************************/
/* FIND FIRST OCCURENCE OF A CHARACTER THAT IS NOT c */
/************************************************************************/
int verify ( s , c )
char s [ ] , c ;
{
int i ;
for ( i = 0 ; s [ i ] ! = ' \0 ' ; i + + )
if ( s [ i ] ! = c )
return ( i ) ;
return ( - 1 ) ;
}
/************************************************************************/
/* GET NEXT LINE THAT ISN'T BLANK OR IS A COMMENT LINE */
/************************************************************************/
// Returns an empty string to indicate end of config
// Modified Aril 2020 to allow #include of file fragments
FILE * savefp = NULL ;
int saveLineNo ;
char includefilename [ 250 ] ;
int GetNextLine ( char * rec )
{
int i , j ;
char * ret ;
char * ptr , * context ;
while ( TRUE )
{
ret = fgets ( rec , MAXLINE , fp1 ) ;
LineNo + + ;
if ( ret = = NULL )
{
if ( savefp )
{
// we have reached eof on an include file - switch back
fclose ( fp1 ) ;
fp1 = savefp ;
savefp = NULL ;
LineNo = saveLineNo ;
continue ;
}
rec [ 0 ] = 0 ;
return 0 ; // return end of config
}
for ( i = 0 ; rec [ i ] ! = ' \0 ' ; i + + )
if ( rec [ i ] = = ' \t ' | | rec [ i ] = = ' \n ' | | rec [ i ] = = ' \r ' )
rec [ i ] = ' ' ;
j = verify ( rec , ' ' ) ;
if ( j > 0 )
{
// Remove Leading Spaces
for ( i = 0 ; rec [ j ] ! = ' \0 ' ; i + + , j + + )
rec [ i ] = rec [ j ] ;
rec [ i ] = ' \0 ' ;
}
if ( stristr ( rec , " WebTermCSS " ) = = 0 & & stristr ( rec , " HybridCoLocatedRMS " ) = = 0 & & stristr ( rec , " HybridFrequencies " ) = = 0 ) // Needs ; in string
strlop ( rec , ' ; ' ) ;
else
j = j ;
if ( strlen ( rec ) > 1 )
if ( memcmp ( rec , " /* " , 2 ) = = 0 )
{
Comment = TRUE ;
CommentLine = LineNo ;
}
else
if ( memcmp ( rec , " */ " , 2 ) = = 0 )
{
rec [ 0 ] = 32 ;
rec [ 1 ] = 0 ;
Comment = FALSE ;
}
if ( Comment )
{
rec [ 0 ] = 32 ;
rec [ 1 ] = 0 ;
continue ;
}
// remove trailing spaces
while ( strlen ( rec ) & & rec [ strlen ( rec ) - 1 ] = = ' ' )
rec [ strlen ( rec ) - 1 ] = 0 ;
strcat ( rec , " " ) ;
ptr = strtok_s ( rec , " " , & context ) ;
// Put one back
if ( ptr )
{
if ( context )
{
ptr [ strlen ( ptr ) ] = ' ' ;
}
rec = ptr ;
// look for #include
if ( _memicmp ( rec , " #include " , 9 ) = = 0 )
{
savefp = fp1 ;
if ( BPQDirectory [ 0 ] = = 0 )
{
strcpy ( includefilename , & rec [ 9 ] ) ;
}
else
{
strcpy ( includefilename , BPQDirectory ) ;
strcat ( includefilename , " / " ) ;
strcat ( includefilename , & rec [ 9 ] ) ;
}
if ( ( fp1 = fopen ( includefilename , " r " ) ) = = NULL )
{
Consoleprintf ( " Could not open #include file %s Error code %d " , includefilename , errno ) ;
fp1 = savefp ;
savefp = NULL ;
}
else
{
saveLineNo = LineNo ;
LineNo = 0 ;
}
continue ; // get next line
}
return 0 ;
}
}
// Should never reach this
return 0 ;
}
/************************************************************************/
/* TEST VALIDITY OF CALLSIGN */
/************************************************************************/
int call_check_internal ( char * callsign )
{
char call [ 20 ] ;
int ssid ;
int err_flag = 0 ;
int i ;
if ( xindex ( callsign , " - " ) > 0 ) /* There is an SSID field */
{
sscanf ( callsign , " %[^-]-%d " , call , & ssid ) ;
if ( strlen ( call ) > 6 )
{
Consoleprintf ( " Callsign too long, 6 characters before SSID " ) ;
Consoleprintf ( " %s \r \n " , callsign ) ;
err_flag = 1 ;
}
if ( ssid < 0 | | ssid > 15 )
{
Consoleprintf ( " SSID out of range, must be between 0 and 15 " ) ;
Consoleprintf ( " %s \r \n " , callsign ) ;
err_flag = 1 ;
}
}
else /* No SSID field */
{
if ( strlen ( callsign ) > 6 )
{
Consoleprintf ( " Callsign too long, 6 characters maximum " ) ;
Consoleprintf ( " %s \r \n " , callsign ) ;
err_flag = 1 ;
}
}
strcat ( callsign , " " ) ;
callsign [ 10 ] = ' \0 ' ;
for ( i = 0 ; i < 10 ; i + + )
callsign [ i ] = toupper ( callsign [ i ] ) ;
return ( err_flag ) ;
}
int call_check ( char * callsign , char * loc )
{
int err = call_check_internal ( callsign ) ;
memcpy ( loc , callsign , 10 ) ;
return err ;
}
/* Process UNPROTO string allowing VIA */
char workstring [ 80 ] ;
int callstring ( int i , char * value , char * rec )
{
char * val = ( char * ) poffset [ i ] ;
size_t j = ( int ) strlen ( value ) ;
memcpy ( val , value , j ) ;
return 1 ;
}
/*
RADIO PORT PROCESSING
*/
int decode_port_rec ( char * rec )
{
int i ;
int cn = 1 ; /* RETURN CODE FROM ROUTINES */
uint32_t IPADDR ;
# ifdef WIN32
WSADATA WsaData ; // receives data from WSAStartupproblem
# endif
char key_word [ 30 ] = " " ;
char value [ 300 ] = " " ;
if ( _memicmp ( rec , " CONFIG " , 6 ) = = 0 )
{
// Create Embedded PORT Config
// Copy all subseuent lines up to ENDPORT to a memory buffer
char * ptr ;
int i ;
2023-05-25 14:17:53 +01:00
if ( LogicalPortNum > 64 )
2022-08-28 09:35:46 +01:00
{
Consoleprintf ( " Portnum %d is invalid " , LogicalPortNum ) ;
LogicalPortNum = 0 ;
}
PortConfig [ LogicalPortNum ] = ptr = malloc ( 50000 ) ;
* ptr = 0 ;
GetNextLine ( rec ) ;
while ( ! feof ( fp1 ) )
{
if ( _memicmp ( rec , " ENDPORT " , 7 ) = = 0 )
{
PortConfig [ LogicalPortNum ] = realloc ( PortConfig [ LogicalPortNum ] , ( strlen ( ptr ) + 1 ) ) ;
endport = 1 ;
return 0 ;
}
i = ( int ) strlen ( rec ) ;
i - - ;
while ( i > 1 )
{
if ( rec [ i ] = = ' ' )
rec [ i ] = 0 ; // Remove trailing spaces
else
break ;
i - - ;
}
// Pick out RIGCONFIG Records
if ( _memicmp ( rec , " RIGCONTROL " , 10 ) = = 0 )
{
// RIGCONTROL COM60 19200 ICOM IC706 5e 4 14.103/U1w 14.112/u1 18.1/U1n 10.12/l1
// Convert to new format (RADIO Interlockno);
int Interlock = xxp . INTERLOCK ;
char radio [ 16 ] ;
if ( Interlock = = 0 ) // Replace with dummy
{
Interlock = xxp . INTERLOCK = nextDummyInterlock ;
nextDummyInterlock + + ;
}
sprintf ( radio , " RADIO %d " , Interlock ) ;
memcpy ( rec , radio , 10 ) ;
if ( strlen ( rec ) > 15 )
{
RadioConfigMsg [ nextRadioPort + + ] = _strdup ( rec ) ;
}
else
{
// Multiline config, ending in ****
char * rptr ;
RadioConfigMsg [ nextRadioPort ] = rptr = zalloc ( 50000 ) ;
strcpy ( rptr , radio ) ;
GetNextLine ( rec ) ;
while ( ! feof ( fp1 ) )
{
if ( memcmp ( rec , " *** " , 3 ) = = 0 )
{
RadioConfigMsg [ nextRadioPort ] = realloc ( RadioConfigMsg [ nextRadioPort ] , ( strlen ( rptr ) + 1 ) ) ;
nextRadioPort + + ;
break ;
}
strcat ( rptr , rec ) ;
GetNextLine ( rec ) ;
}
}
}
else
{
strcat ( ptr , rec ) ;
strcat ( ptr , " \r \n " ) ;
}
GetNextLine ( rec ) ;
}
Consoleprintf ( " Missing ENDPORT for Port %d " , portnum ) ;
heading = 1 ;
return 0 ;
}
if ( xindex ( rec , " = " ) > = 0 )
sscanf ( rec , " %[^=]=%s " , key_word , value ) ;
else
sscanf ( rec , " %s " , key_word ) ;
if ( _stricmp ( key_word , " portnum " ) = = 0 )
{
// Save as LogicalPortNum
LogicalPortNum = atoi ( value ) ;
}
if ( _stricmp ( key_word , " XDIGI " ) = = 0 )
{
// Cross Port Digi definition
// XDIGI=CALL,PORT,UI
struct XDIGI * Digi = zalloc ( sizeof ( struct XDIGI ) ) ; // Chain
char * call , * pport , * Context ;
call = strtok_s ( value , " , " , & Context ) ;
pport = strtok_s ( NULL , " , " , & Context ) ;
if ( call & & pport & & ConvToAX25 ( call , Digi - > Call ) )
{
Digi - > Port = atoi ( pport ) ;
if ( Digi - > Port )
{
if ( Context )
{
_strupr ( Context ) ;
if ( strstr ( Context , " UI " ) )
Digi - > UIOnly = TRUE ;
}
// Add to chain
if ( xxp . XDIGIS )
Digi - > Next = xxp . XDIGIS ;
xxp . XDIGIS = Digi ;
return 0 ;
}
}
Consoleprintf ( " Invalid XDIGI Statement %s " , rec ) ;
porterror = 1 ;
return 0 ;
}
/************************************************************************/
/* SEARCH FOR KEYWORD IN TABLE */
/************************************************************************/
for ( i = 0 ; i < PPARAMLIM & & _stricmp ( pkeywords [ i ] , key_word ) ! = 0 ; i + + )
;
if ( i = = PPARAMLIM )
Consoleprintf ( " Source record not recognised - Ignored:%s \r \n " , rec ) ;
else
{
switch ( proutine [ i ] )
{
case 0 :
cn = callsign ( ( char * ) poffset [ i ] , value , rec ) ; /* CALLSIGNS */
break ;
case 1 :
cn = int_value ( ( short * ) poffset [ i ] , value , rec ) ; /* INTEGER VALUES */
break ;
case 2 :
cn = bin_switch ( ( char * ) poffset [ i ] , value , rec ) ; /* 0/1 SWITCHES */
break ;
case 3 :
cn = hex_value ( ( int * ) poffset [ i ] , value , rec ) ; /* HEX NUMBERS */
break ;
case 4 :
cn = doid ( i , value , rec ) ; /* ID PARMS */
break ;
case 5 :
cn = hwtypes ( i , value , rec ) ; /* HARDWARE TYPES */
break ;
case 6 :
cn = bbsflag ( i , value , rec ) ;
break ;
case 7 :
cn = channel ( i , value , rec ) ;
break ;
case 8 :
cn = protocols ( i , value , rec ) ;
break ;
case 10 :
cn = validcalls ( i , value , rec ) ;
break ;
case 11 :
cn = callstring ( i , value , rec ) ;
break ;
case 12 :
cn = kissoptions ( i , value , rec ) ;
break ;
case 13 :
cn = dec_switch ( ( char * ) poffset [ i ] , value , rec ) ; /* 0/9 SWITCHES */
break ;
case 14 :
cn = dodll ( i , value , rec ) ; /* DLL PARMS */
break ;
case 15 :
cn = doDriver ( i , value , rec ) ; /* DLL PARMS */
break ;
case 16 :
xxp . WL2K = DecodeWL2KReportLine ( rec ) ;
break ;
case 17 :
// IP Address for KISS over UDP
# ifdef WIN32
WSAStartup ( MAKEWORD ( 2 , 0 ) , & WsaData ) ;
# endif
IPADDR = inet_addr ( & rec [ 7 ] ) ;
memcpy ( & xxp . IPADDR , & IPADDR , 4 ) ;
# ifdef WIN32
WSACleanup ( ) ;
# endif
break ;
case 18 :
cn = doSerialPortName ( i , value , rec ) ; // COMPORT
break ;
case 19 :
2023-06-21 08:21:04 +01:00
cn = doPermittedAppls ( i , value , rec ) ; // Permitted Apps
break ;
case 20 :
cn = doKissCommand ( i , value , rec ) ; // Permitted Apps
2022-08-28 09:35:46 +01:00
break ;
2024-04-06 02:10:08 +01:00
case 21 :
cn = int64_value ( poffset [ i ] , value , rec ) ; /* INTEGER VALUES */
break ;
2024-10-11 15:37:11 +01:00
case 22 :
xxp . M0LTEMapInfo = _strdup ( value ) ;
cn = 1 ;
break ;
2022-08-28 09:35:46 +01:00
case 9 :
cn = 1 ;
endport = 1 ;
break ;
}
}
if ( cn = = 0 ) porterror = 1 ;
return 0 ;
}
int doid ( i , value , rec )
int i ;
char value [ ] ;
char rec [ ] ;
{
unsigned int j ;
for ( j = 3 ; ( j < ( unsigned int ) strlen ( rec ) + 1 ) ; j + + )
workstring [ j - 3 ] = rec [ j ] ;
// Remove trailing spaces before checking length
i = ( int ) strlen ( workstring ) ;
i - - ;
while ( i > 1 )
{
if ( workstring [ i ] = = ' ' )
workstring [ i ] = 0 ; // Remove trailing spaces
else
break ;
i - - ;
}
if ( i > 29 )
{
Consoleprintf ( " Port description too long - Truncated " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
}
strcat ( workstring , " " ) ;
workstring [ 30 ] = ' \0 ' ;
memcpy ( xxp . ID , workstring , 30 ) ;
return ( 1 ) ;
}
int dodll ( i , value , rec )
int i ;
char value [ ] ;
char rec [ ] ;
{
unsigned int j ;
strlop ( rec , ' ' ) ;
for ( j = 8 ; ( j < ( unsigned int ) strlen ( rec ) + 1 ) ; j + + )
workstring [ j - 8 ] = rec [ j ] ;
if ( j > 24 )
{
Consoleprintf ( " DLL name too long - Truncated " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
}
_strupr ( workstring ) ;
strcat ( workstring , " " ) ;
memcpy ( xxp . DLLNAME , workstring , 16 ) ;
xxp . TYPE = 16 ; // External
if ( strstr ( xxp . DLLNAME , " TELNET " ) | | strstr ( xxp . DLLNAME , " AXIP " ) )
RFOnly = FALSE ;
return ( 1 ) ;
}
int doDriver ( int i , char * value , char * rec )
{
unsigned int j ;
for ( j = 7 ; ( j < ( unsigned int ) strlen ( rec ) + 1 ) ; j + + )
workstring [ j - 7 ] = rec [ j ] ;
if ( j > 23 )
{
Consoleprintf ( " Driver name too long - Truncated " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
}
_strupr ( workstring ) ;
strcat ( workstring , " " ) ;
memcpy ( xxp . DLLNAME , workstring , 16 ) ;
xxp . TYPE = 16 ; // External
// Set some defaults in case HFKISS
xxp . CHANNEL = ' A ' ;
xxp . FRACK = 7000 ;
xxp . RESPTIME = 1000 ;
xxp . MAXFRAME = 4 ;
xxp . RETRIES = 6 ;
if ( strstr ( xxp . DLLNAME , " TELNET " ) | | strstr ( xxp . DLLNAME , " AXIP " ) )
RFOnly = FALSE ;
return 1 ;
}
int IsNumeric ( char * str )
{
while ( * str )
{
if ( ! isdigit ( * str ) )
return 0 ;
str + + ;
}
return 1 ;
}
int doSerialPortName ( int i , char * value , char * rec )
{
rec + = 8 ;
if ( strlen ( rec ) > 79 )
{
Consoleprintf ( " Serial Port Name too long - Truncated " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
rec [ 79 ] = 0 ;
}
strlop ( rec , ' ' ) ;
if ( IsNumeric ( rec ) )
xxp . IOADDR = atoi ( rec ) ;
else
strcpy ( xxp . SerialPortName , rec ) ;
return 1 ;
}
int doPermittedAppls ( int i , char * value , char * rec )
{
unsigned int Mask = 0 ;
char * Context ;
char * ptr1 = strtok_s ( value , " ,= \t \n \r " , & Context ) ;
2023-06-21 08:21:04 +01:00
// Param is a comma separated list of Appl Numbers allowed to connect on this port
2022-08-28 09:35:46 +01:00
while ( ptr1 & & ptr1 [ 0 ] )
{
Mask | = 1 < < ( atoi ( ptr1 ) - 1 ) ;
ptr1 = strtok_s ( NULL , " ,= \t \n \r " , & Context ) ;
}
xxp . HavePermittedAppls = 1 ; // indicate used
xxp . PERMITTEDAPPLS = Mask ;
return 1 ;
}
2023-06-21 08:21:04 +01:00
int doKissCommand ( int i , char * value , char * rec )
{
// Param is kiss command and any operands as decimal bytes
xxp . KissParams = _strdup ( strlop ( rec , ' = ' ) ) ;
return 1 ;
}
2022-08-28 09:35:46 +01:00
int hwtypes ( i , value , rec )
int i ;
char value [ ] ;
char rec [ ] ;
{
hw = 255 ;
if ( _stricmp ( value , " ASYNC " ) = = 0 )
{
// Set some defaults
xxp . CHANNEL = ' A ' ;
xxp . FRACK = 7000 ;
xxp . RESPTIME = 1000 ;
xxp . MAXFRAME = 4 ;
xxp . RETRIES = 6 ;
hw = 0 ;
}
if ( _stricmp ( value , " PC120 " ) = = 0 )
hw = 2 ;
if ( _stricmp ( value , " DRSI " ) = = 0 )
hw = 4 ;
if ( _stricmp ( value , " DE56 " ) = = 0 )
hw = 4 ;
if ( _stricmp ( value , " TOSH " ) = = 0 )
hw = 6 ;
if ( _stricmp ( value , " QUAD " ) = = 0 )
hw = 8 ;
if ( _stricmp ( value , " RLC100 " ) = = 0 )
hw = 10 ;
if ( _stricmp ( value , " RLC400 " ) = = 0 )
hw = 12 ;
if ( _stricmp ( value , " INTERNAL " ) = = 0 | | _stricmp ( value , " LOOPBACK " ) = = 0 )
{
// Set Sensible defaults
memset ( xxp . ID , ' ' , 30 ) ;
memcpy ( xxp . ID , " Loopback " , 8 ) ;
xxp . CHANNEL = ' A ' ;
xxp . FRACK = 5000 ;
xxp . RESPTIME = 1000 ;
xxp . MAXFRAME = 4 ;
xxp . RETRIES = 5 ;
xxp . DIGIFLAG = 1 ;
hw = 14 ;
}
if ( _stricmp ( value , " EXTERNAL " ) = = 0 )
{
hw = 16 ;
// Set some defaults in case KISSHF
xxp . CHANNEL = ' A ' ;
xxp . FRACK = 7000 ;
xxp . RESPTIME = 1000 ;
xxp . MAXFRAME = 4 ;
xxp . RETRIES = 6 ;
}
if ( _stricmp ( value , " BAYCOM " ) = = 0 )
hw = 18 ;
if ( _stricmp ( value , " PA0HZP " ) = = 0 )
hw = 20 ;
if ( _stricmp ( value , " I2C " ) = = 0 )
{
// Set some defaults
xxp . CHANNEL = ' A ' ;
xxp . FRACK = 7000 ;
xxp . RESPTIME = 1000 ;
xxp . MAXFRAME = 4 ;
xxp . RETRIES = 6 ;
hw = 22 ;
}
if ( hw = = 255 )
{
Consoleprintf ( " Invalid Hardware Type (not DRSI PC120 INTERNAL EXTERNAL BAYCOM PA0HZP ASYNC QUAD) " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
else
xxp . TYPE = hw ;
return ( 1 ) ;
}
int protocols ( i , value , rec )
int i ;
char value [ ] ;
char rec [ ] ;
{
int hw ;
hw = 255 ;
if ( _stricmp ( value , " KISS " ) = = 0 )
hw = 0 ;
if ( _stricmp ( value , " NETROM " ) = = 0 )
hw = 2 ;
if ( _stricmp ( value , " BPQKISS " ) = = 0 )
hw = 4 ;
if ( _stricmp ( value , " HDLC " ) = = 0 )
hw = 6 ;
if ( _stricmp ( value , " L2 " ) = = 0 )
hw = 8 ;
if ( _stricmp ( value , " PACTOR " ) = = 0 )
hw = 10 ;
if ( _stricmp ( value , " WINMOR " ) = = 0 )
hw = 10 ;
if ( _stricmp ( value , " ARQ " ) = = 0 )
hw = 12 ;
if ( hw = = 255 )
{
Consoleprintf ( " Invalid Protocol (not KISS NETROM PACTOR WINMOR ARQ HDLC ) " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
else
xxp . PROTOCOL = hw ;
return ( 1 ) ;
}
int bbsflag ( i , value , rec )
int i ;
char value [ ] ;
char rec [ ] ;
{
int hw = 255 ;
if ( _stricmp ( value , " NOBBS " ) = = 0 )
hw = 1 ;
if ( _stricmp ( value , " BBSOK " ) = = 0 )
hw = 0 ;
if ( _stricmp ( value , " " ) = = 0 )
hw = 0 ;
if ( hw = = 255 )
{
Consoleprintf ( " BBS Flag must be NOBBS, BBSOK, or null " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
xxp . BBSFLAG = hw ;
return ( 1 ) ;
}
int channel ( int i , char * value , char * rec )
{
char * val = ( char * ) poffset [ i ] ;
val [ 0 ] = value [ 0 ] ;
return 1 ;
}
int dolinked ( int i , char * value , char * rec )
{
char * val = ( char * ) offset [ i ] ;
val [ 0 ] = value [ 0 ] ;
return 1 ;
}
int validcalls ( int i , char * value , char * rec )
{
if ( ( strlen ( value ) + ( int ) strlen ( xxp . VALIDCALLS ) ) > 255 )
{
Consoleprintf ( " Too Many VALIDCALLS " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
return ( 0 ) ;
}
strcat ( xxp . VALIDCALLS , value ) ;
return ( 1 ) ;
}
int kissoptions ( i , value , rec )
int i ;
char value [ ] ;
char rec [ ] ;
{
int err = 255 ;
char opt1 [ 12 ] = " " ;
char opt2 [ 12 ] = " " ;
char opt3 [ 12 ] = " " ;
char opt4 [ 12 ] = " " ;
char opt5 [ 12 ] = " " ;
char opt6 [ 12 ] = " " ;
char opt7 [ 12 ] = " " ;
char opt8 [ 12 ] = " " ;
sscanf ( value , " %[^,+],%[^,+],%[^,+],%[^,+],%[^,+],%[^,+],%[^,+],%[^,+] " ,
opt1 , opt2 , opt3 , opt4 , opt5 , opt6 , opt6 , opt8 ) ;
if ( opt1 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt1 , rec ) ; }
if ( opt2 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt2 , rec ) ; }
if ( opt3 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt3 , rec ) ; }
if ( opt4 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt4 , rec ) ; }
if ( opt5 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt5 , rec ) ; }
if ( opt6 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt6 , rec ) ; }
if ( opt7 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt7 , rec ) ; }
if ( opt8 [ 0 ] ! = ' \0 ' ) { do_kiss ( opt8 , rec ) ; }
return ( 1 ) ;
}
/*
TNC PORT PROCESSING
*/
static char * tkeywords [ ] =
{
" COM " , " TYPE " , " APPLMASK " , " KISSMASK " , " APPLFLAGS " , " ENDPORT "
} ; /* parameter keywords */
static int toffset [ ] =
{
0 , 1 , 2 , 3 , 5 , 8
} ; /* offset for corresponding data in config file */
static int troutine [ ] =
{
1 , 5 , 1 , 3 , 1 , 9
} ; /* routine to process parameter */
# define TPARAMLIM 6
2023-06-21 08:21:04 +01:00
extern CMDX TNCCOMMANDLIST [ ] ;
2022-08-28 09:35:46 +01:00
extern int NUMBEROFTNCCOMMANDS ;
int decode_tnc_rec ( char * rec )
{
char key_word [ 20 ] ;
char value [ 300 ] ;
if ( xindex ( rec , " = " ) > = 0 )
sscanf ( rec , " %[^=]=%s " , key_word , value ) ;
else
sscanf ( rec , " %s " , key_word ) ;
if ( _stricmp ( key_word , " ENDPORT " ) = = 0 )
{
endport = 1 ;
return 0 ;
}
else if ( _stricmp ( key_word , " TYPE " ) = = 0 )
{
if ( _stricmp ( value , " TNC2 " ) = = 0 )
{
TNC2ENTRY - > Mode = TNC2 ;
// Set Defaults
TNC2ENTRY - > SENDPAC = 13 ;
TNC2ENTRY - > CRFLAG = 1 ;
TNC2ENTRY - > MTX = 1 ;
TNC2ENTRY - > MCOM = 1 ;
TNC2ENTRY - > MMASK = - 1 ; // MONITOR MASK FOR PORTS
TNC2ENTRY - > COMCHAR = 3 ;
TNC2ENTRY - > CMDTIME = 10 ; // SYSTEM TIMER = 100MS
TNC2ENTRY - > PASSCHAR = 0x16 ; // CTRL-V
TNC2ENTRY - > StreamSW = 0x7C ; // |
TNC2ENTRY - > LCStream = 1 ;
}
else if ( _stricmp ( value , " DED " ) = = 0 )
TNC2ENTRY - > Mode = DED ;
else if ( _stricmp ( value , " KANT " ) = = 0 )
TNC2ENTRY - > Mode = KANTRONICS ;
else if ( _stricmp ( value , " SCS " ) = = 0 )
TNC2ENTRY - > Mode = SCS ;
else
{
Consoleprintf ( " Invalid TNC Type " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
}
}
else if ( _stricmp ( key_word , " COMPORT " ) = = 0 )
strcpy ( TNC2ENTRY - > PORTNAME , value ) ;
else if ( _stricmp ( key_word , " APPLMASK " ) = = 0 )
TNC2ENTRY - > APPLICATION = strtol ( value , 0 , 0 ) ;
else if ( _stricmp ( key_word , " APPLNUM " ) = = 0 )
TNC2ENTRY - > APPLICATION = 1 < < ( strtol ( value , 0 , 0 ) - 1 ) ;
else if ( _stricmp ( key_word , " APPLFLAGS " ) = = 0 )
TNC2ENTRY - > APPLFLAGS = strtol ( value , 0 , 0 ) ;
else if ( _stricmp ( key_word , " CHANNELS " ) = = 0 )
TNC2ENTRY - > HOSTSTREAMS = strtol ( value , 0 , 0 ) ;
else if ( _stricmp ( key_word , " STREAMS " ) = = 0 )
TNC2ENTRY - > HOSTSTREAMS = strtol ( value , 0 , 0 ) ;
else if ( _stricmp ( key_word , " POLLDELAY " ) = = 0 )
TNC2ENTRY - > PollDelay = strtol ( value , 0 , 0 ) ;
else if ( _stricmp ( key_word , " CONOK " ) = = 0 )
TNC2ENTRY - > CONOK = strtol ( value , 0 , 0 ) ;
else if ( _stricmp ( key_word , " AUTOLF " ) = = 0 )
TNC2ENTRY - > AUTOLF = strtol ( value , 0 , 0 ) ;
else if ( _stricmp ( key_word , " ECHO " ) = = 0 )
TNC2ENTRY - > ECHOFLAG = ( char ) strtol ( value , 0 , 0 ) ;
else
{
if ( TNC2ENTRY - > Mode = = TNC2 )
{
// Try process as TNC2 Command
int n = 0 ;
2023-06-21 08:21:04 +01:00
CMDX * CMD = & TNCCOMMANDLIST [ 0 ] ;
2022-08-28 09:35:46 +01:00
char * ptr1 = key_word ;
UCHAR * valueptr ;
strcat ( key_word , " " ) ;
_strupr ( key_word ) ;
for ( n = 0 ; n < NUMBEROFTNCCOMMANDS ; n + + )
{
int CL = CMD - > CMDLEN ;
// ptr1 is input command
ptr1 = key_word ;
if ( memcmp ( CMD - > String , ptr1 , CL ) = = 0 )
{
// Found match so far - check rest
char * ptr2 = & CMD - > String [ CL ] ;
ptr1 + = CL ;
if ( * ( ptr1 ) ! = ' ' )
{
while ( * ( ptr1 ) = = * ptr2 & & * ( ptr1 ) ! = ' ' )
{
ptr1 + + ;
ptr2 + + ;
}
}
if ( * ( ptr1 ) = = ' ' )
{
valueptr = ( UCHAR * ) TNC2ENTRY + CMD - > CMDFLAG ;
* valueptr = ( UCHAR ) strtol ( value , 0 , 0 ) ;
return 0 ;
}
}
CMD + + ;
}
}
Consoleprintf ( " Source record not recognised - Ignored:%s \r \n " , rec ) ;
}
return 0 ;
}
int do_kiss ( char * value , char * rec )
{
int err = 255 ;
if ( _stricmp ( value , " POLLED " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | POLLINGKISS ;
}
else if ( _stricmp ( value , " CHECKSUM " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | CHECKSUM ;
}
else if ( _stricmp ( value , " D700 " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | D700 ;
}
else if ( _stricmp ( value , " TNCX " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | TNCX ;
}
else if ( _stricmp ( value , " PITNC " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | PITNC ;
}
else if ( _stricmp ( value , " TRACKER " ) = = 0 )
{
err = 0 ;
kissflags | = TRACKER ;
}
else if ( _stricmp ( value , " NOPARAMS " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | NOPARAMS ;
}
else if ( _stricmp ( value , " ACKMODE " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | ACKMODE ;
}
else if ( _stricmp ( value , " SLAVE " ) = = 0 )
{
err = 0 ;
kissflags = kissflags | POLLEDKISS ;
}
else if ( _stricmp ( value , " FLDIGI " ) = = 0 )
{
err = 0 ;
kissflags | = FLDIGI ;
}
else if ( _stricmp ( value , " FASTI2C " ) = = 0 )
{
err = 0 ;
kissflags | = FASTI2C ;
}
else if ( _stricmp ( value , " DRATS " ) = = 0 )
{
err = 0 ;
kissflags | = DRATS ;
}
if ( err = = 255 )
{
Consoleprintf ( " Invalid KISS Options (not POLLED ACKMODE CHECKSUM D700 SLAVE TNCX PITNC NOPARAMS FASTI2C DRATS) " ) ;
Consoleprintf ( " %s \r \n " , rec ) ;
}
return ( err ) ;
}
int simple ( int i )
{
// Set up the basic config header
xxcfg . C_AUTOSAVE = 1 ;
xxcfg . C_SaveMH = 1 ;
xxcfg . C_BBS = 1 ;
xxcfg . C_BTINTERVAL = 60 ;
xxcfg . C_BUFFERS = 999 ;
xxcfg . C_C = 1 ;
xxcfg . C_DESQVIEW = 0 ;
xxcfg . C_EMSFLAG = 0 ;
xxcfg . C_FULLCTEXT = 1 ;
xxcfg . C_HIDENODES = 0 ;
xxcfg . C_HOSTINTERRUPT = 127 ;
xxcfg . C_IDINTERVAL = 10 ;
xxcfg . C_IDLETIME = 900 ;
xxcfg . C_IP = 0 ;
xxcfg . C_PM = 0 ;
xxcfg . C_L3TIMETOLIVE = 25 ;
xxcfg . C_L4DELAY = 10 ;
xxcfg . C_L4RETRIES = 3 ;
xxcfg . C_L4TIMEOUT = 60 ;
xxcfg . C_L4WINDOW = 4 ;
xxcfg . C_LINKEDFLAG = ' A ' ;
xxcfg . C_MAXCIRCUITS = 128 ;
xxcfg . C_MAXDESTS = 250 ;
xxcfg . C_MAXHOPS = 4 ;
xxcfg . C_MAXLINKS = 64 ;
xxcfg . C_MAXNEIGHBOURS = 64 ;
xxcfg . C_MAXRTT = 90 ;
xxcfg . C_MINQUAL = 150 ;
xxcfg . C_NODE = 1 ;
xxcfg . C_NODESINTERVAL = 30 ;
xxcfg . C_OBSINIT = 6 ;
xxcfg . C_OBSMIN = 5 ;
xxcfg . C_PACLEN = 236 ;
xxcfg . C_T3 = 180 ;
xxcfg . C_TRANSDELAY = 1 ;
/* Set PARAMOK flags on all values that are defaulted */
for ( i = 0 ; i < PARAMLIM ; i + + )
paramok [ i ] = 1 ;
paramok [ 15 ] = 0 ; // Must have callsign
paramok [ 45 ] = 0 ; // Dont Have Appl1Call
paramok [ 53 ] = 0 ; // or APPL1ALIAS
return ( 1 ) ;
}
VOID FreeConfig ( )
{
}
BOOL ProcessAPPLDef ( char * buf )
{
// New Style APPL definition
// APPL n,COMMAND,CMDALIAS,APPLCALL,APPLALIAS,APPLQUAL,L2ALIAS
char * ptr1 , * ptr2 ;
int Appl , n = 0 ;
char Param [ 8 ] [ 256 ] ;
struct APPLCONFIG * App ;
memset ( Param , 0 , 2048 ) ;
ptr1 = buf ;
while ( ptr1 & & * ptr1 & & n < 8 )
{
ptr2 = strchr ( ptr1 , ' , ' ) ;
if ( ptr2 ) * ptr2 + + = 0 ;
strcpy ( & Param [ n + + ] [ 0 ] , ptr1 ) ;
ptr1 = ptr2 ;
}
if ( _stricmp ( Param [ 1 ] , Param [ 2 ] ) = = 0 )
{
// Alias = Application - will loop.
return FALSE ;
}
_strupr ( Param [ 0 ] ) ;
_strupr ( Param [ 1 ] ) ;
// Leave Alias in original case
_strupr ( Param [ 3 ] ) ;
_strupr ( Param [ 4 ] ) ;
_strupr ( Param [ 5 ] ) ;
_strupr ( Param [ 6 ] ) ;
_strupr ( Param [ 7 ] ) ;
Appl = atoi ( Param [ 0 ] ) ;
2023-10-10 22:07:04 +01:00
if ( Appl < 1 | | Appl > NumberofAppls ) return FALSE ;
2022-08-28 09:35:46 +01:00
App = & xxcfg . C_APPL [ Appl - 1 ] ; // Recs from zero
if ( Param [ 1 ] [ 0 ] = = 0 ) // No Application
return FALSE ;
if ( strlen ( Param [ 1 ] ) > 12 ) return FALSE ;
memcpy ( App - > Command , Param [ 1 ] , ( int ) strlen ( Param [ 1 ] ) ) ;
xxcfg . C_BBS = 1 ;
if ( strlen ( Param [ 2 ] ) > 48 ) return FALSE ;
memcpy ( App - > CommandAlias , Param [ 2 ] , ( int ) strlen ( Param [ 2 ] ) ) ;
if ( strlen ( Param [ 3 ] ) > 10 ) return FALSE ;
memcpy ( App - > ApplCall , Param [ 3 ] , ( int ) strlen ( Param [ 3 ] ) ) ;
if ( strlen ( Param [ 4 ] ) > 10 ) return FALSE ;
memcpy ( App - > ApplAlias , Param [ 4 ] , ( int ) strlen ( Param [ 4 ] ) ) ;
App - > ApplQual = atoi ( Param [ 5 ] ) ;
if ( strlen ( Param [ 6 ] ) > 10 ) return FALSE ;
memcpy ( App - > L2Alias , Param [ 6 ] , ( int ) strlen ( Param [ 6 ] ) ) ;
return TRUE ;
}
double xfmod ( double p1 , double p2 )
{
int temp ;
temp = ( int ) ( p1 / p2 ) ;
p1 = p1 - ( p2 * temp ) ;
return p1 ;
}
BOOL ToLOC ( double Lat , double Lon , char * Locator )
{
int i ;
double S1 , S2 ;
Lon = Lon + 180 ;
Lat = Lat + 90 ;
S1 = xfmod ( Lon , 20 ) ;
# pragma warning(push)
# pragma warning(disable : 4244)
i = Lon / 20 ;
Locator [ 0 ] = 65 + i ;
S2 = xfmod ( S1 , 2 ) ;
i = S1 / 2 ;
Locator [ 2 ] = 48 + i ;
i = S2 * 12 ;
Locator [ 4 ] = 65 + i ;
S1 = xfmod ( Lat , 10 ) ;
i = Lat / 10 ;
Locator [ 1 ] = 65 + i ;
S2 = xfmod ( S1 , 1 ) ;
i = S1 ;
Locator [ 3 ] = 48 + i ;
i = S2 * 24 ;
Locator [ 5 ] = 65 + i ;
# pragma warning(pop)
return TRUE ;
}
int FromLOC ( char * Locator , double * pLat , double * pLon )
{
double i ;
double Lat , Lon ;
_strupr ( Locator ) ;
* pLon = 0 ;
* pLat = 0 ; // in case invalid
// Basic validation for APRS positions
// The first pair (a field) encodes with base 18 and the letters "A" to "R".
// The second pair (square) encodes with base 10 and the digits "0" to "9".
// The third pair (subsquare) encodes with base 24 and the letters "a" to "x".
i = Locator [ 0 ] ;
if ( i < ' A ' | | i > ' R ' )
return 0 ;
Lon = ( i - 65 ) * 20 ;
i = Locator [ 2 ] ;
if ( i < ' 0 ' | | i > ' 9 ' )
return 0 ;
Lon = Lon + ( i - 48 ) * 2 ;
i = Locator [ 4 ] ;
if ( i < ' A ' | | i > ' X ' )
return 0 ;
Lon = Lon + ( i - 65 ) / 12 ;
i = Locator [ 1 ] ;
if ( i < ' A ' | | i > ' R ' )
return 0 ;
Lat = ( i - 65 ) * 10 ;
i = Locator [ 3 ] ;
if ( i < ' 0 ' | | i > ' 9 ' )
return 0 ;
Lat = Lat + ( i - 48 ) ;
i = Locator [ 5 ] ;
if ( i < ' A ' | | i > ' X ' )
return 0 ;
Lat = Lat + ( i - 65 ) / 24 ;
if ( Lon < 0 | | Lon > 360 )
Lon = 180 ;
if ( Lat < 0 | | Lat > 180 )
Lat = 90 ;
* pLon = Lon - 180 ;
* pLat = Lat - 90 ;
return 1 ;
}