New upstream version 6.0.24.45

This commit is contained in:
Hibby 2024-10-11 15:37:11 +01:00
parent 6dfe32758e
commit eb0d36d3f6
50 changed files with 1629 additions and 1387 deletions

View File

@ -348,7 +348,7 @@ APRSHEARDRECORD MHTABLE[MAXHEARD] = {0};
APRSHEARDRECORD * MHDATA = &MHTABLE[0];
static SOCKET sock = (SOCKET) NULL;
static SOCKET sock = (SOCKET)0;
//Duplicate suppression Code
@ -9154,7 +9154,7 @@ void GetSavedAPRSMessages()
FILE *file;
struct APRSMESSAGE * Message;
struct APRSMESSAGE * ptr;
char Line[256];
char Line[512];
char * Stamp = 0;
char * From = 0;
char * To = 0;

View File

@ -3225,6 +3225,170 @@ char * get_plane(int * Len)
return ptr;
}
char * get_portstats()
{
char Msg[] =
"<!DOCTYPE html>\n"
"<html>\n"
"\n"
"<head>\n"
"<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"> </script>\n"
"</head>\n"
"\n"
"\n"
"<body>\n"
"<H2 id=\"h1\"> Last hour's stats for Port </h2>\n"
"<p>\n"
"<canvas id=\"myCanvas\" width=\"600\" height=\"250\" style=\"border:1px solid #d3d3d3;\">\n"
"Your browser does not support the HTML canvas tag.</canvas>\n"
"<br>\n"
"<canvas id=\"myCanvas2\" width=\"600\" height=\"250\" style=\"border:1px solid #d3d3d3;\">\n"
"Your browser does not support the HTML canvas tag.</canvas>\n"
"\n"
"<script>\n"
"var c = document.getElementById(\"myCanvas\");\n"
"var ctx = c.getContext(\"2d\");\n"
"\n"
"var port = window.location.search.slice(1);\n"
"\n"
"document.getElementById(\"h1\").innerHTML = \"Last hour's stats for Port \" + port;;\n"
"\n"
"var oReq = new XMLHttpRequest();\n"
"oReq.open(\"GET\", \"/portstats.txt?\" + port, true);\n"
"oReq.responseType = \"arraybuffer\";\n"
"\n"
"oReq.onload = function(oEvent)\n"
" {\n"
" var arrayBuffer = oReq.response;\n"
"\n"
" var byteArray = new Uint8Array(arrayBuffer);\n"
" \n"
" \n"
" // Draw it. Do last hour for testing. Plot each value for 10 pixels\n"
" \n"
"\tctx.strokeStyle = \"green\";\n"
"\tctx.beginPath();\n"
"\t\n"
"\tctx.moveTo(0,200);\n"
"\tvar y = 2880 - 60;\n"
"\tvar val;\n"
"\t\n"
"\tfor (i = 0; i < 600; i+=10)\n"
"\t{\n"
"\t\tval = byteArray[y] * 2;\n"
"\t\t\n"
"\t\tctx.lineTo(i, 200 - val);\n"
"\t\tctx.lineTo(i+10, 200 - val);\n"
"\t\ty++;\n"
"\t}\n"
"\t\n"
"\tctx.stroke();\n"
"\t\n"
"\tctx.strokeStyle = \"gray\";\n"
"\tctx.setLineDash([5, 3]);\n"
"\t\n"
"\tctx.beginPath();\n"
" \tctx.moveTo(0,100);\n"
"\tctx.lineTo(600,100);\n"
" \tctx.moveTo(0,50);\n"
"\tctx.lineTo(600,50);\n"
" \tctx.moveTo(0,150);\n"
"\tctx.lineTo(600,150);\n"
"\tctx.stroke();\n"
"\n"
"\n"
"\t\n"
"\tctx.fillText(\"100%\",0,10);\n"
"\tctx.fillText(\"50%\",0,100);\n"
"\tctx.fillText(\"0%\",0,200);\t\n"
"\tctx.fillText(\"-60 mins\",0,220);\t\n"
"\tctx.fillText(\"-30 mins\",300,220);\t\n"
"\tctx.fillText(\"Now\",580,220);\t\n"
"\n"
"\t\n"
"\t// Do TX\n"
"\t\n"
"\t\n"
"\tc = document.getElementById(\"myCanvas2\");\n"
"\tctx = c.getContext(\"2d\");\n"
"\n"
"\tctx.fillText(\"100%\",0,10);\n"
"\tctx.fillText(\"50%\",0,100);\n"
"\tctx.fillText(\"0%\",0,200);\t\n"
"\tctx.fillText(\"-60 mins\",0,220);\t\n"
"\tctx.fillText(\"-30 mins\",300,220);\t\n"
"\tctx.fillText(\"Now\",580,220);\t\n"
"\n"
"\n"
"\tctx.strokeStyle = \"red\";\n"
"\tctx.beginPath();\n"
"\t\n"
"\tctx.moveTo(0,200);\n"
"\tvar y = 1440 - 60;\n"
"\tvar val;\n"
"\t\n"
"\tfor (i = 0; i < 600; i+=10)\n"
"\t\n"
"\t{\n"
"\t\tval = byteArray[y] * 2;\n"
"\t\t\n"
"\t\tctx.lineTo(i, 200 - val);\n"
"\t\tctx.lineTo(i+10, 200 - val);\n"
"\t\ty++;\n"
"\t}\n"
"\t\n"
"\tctx.stroke();\n"
"\n"
"\tctx.strokeStyle = \"gray\";\n"
"\tctx.setLineDash([5, 3]);\n"
"\t\n"
"\tctx.beginPath();\n"
" \tctx.moveTo(0,100);\n"
"\tctx.lineTo(600,100);\n"
" \tctx.moveTo(0,50);\n"
"\tctx.lineTo(600,50);\n"
" \tctx.moveTo(0,150);\n"
"\tctx.lineTo(600,150);\n"
"\tctx.stroke();\n"
"\n"
"\n"
"};\n"
"\n"
"oReq.send();\n"
"\n"
"\n"
"function draw(Data)\n"
"{\n"
"\n"
"\t// Data has 4 bytes of index to current position the 1440 bytes of load info\n"
"\t\n"
"\n"
"\tview = new Int8Array(Data);\n"
"\t\n"
"alert(view[3]);\n"
"\n"
"ctx.moveTo(0,200);\n"
"var y = 0;\n"
"for (i = 0; i < 720; i+=30)\n"
"{\n"
"\tctx.lineTo(i, 200 - y);\n"
"\tctx.lineTo(i+30, 200 - y);\n"
"\ty += 10;\n"
"}\n"
"\n"
"\n"
"ctx.stroke();\n"
"}\n"
"\n"
"</script>\n"
"\n"
"</body>\n"
"</html>\n"
"\n"
"";
return _strdup(Msg);;
}
char * get_aprs()
{
@ -3638,6 +3802,10 @@ char * GetStandardPage(char * FN, int * Len)
if (_stricmp(FN, "leaflet.rotatedMarker.js") == 0)
return get_rotatedMarker();
if (_stricmp(FN, "PortStats.html") == 0)
return get_portstats();
if (_stricmp(FN, "info_call.html") == 0)
return get_info_call();

42
ARDOP.c
View File

@ -958,7 +958,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
TNC->Streams[0].Connecting ||
TNC->Streams[0].Connected)
{
// discard if TNC not connected or sesison active
// discard if TNC not connected or session active
ReleaseBuffer(buffptr);
continue;
@ -1865,12 +1865,10 @@ VOID ARDOPReleaseTNC(struct TNCINFO * TNC)
ARDOPChangeMYC(TNC, TNC->NodeCall);
ARDOPSendCommand(TNC, "LISTEN TRUE", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
// Start Scanner
ARDOPSendCommand(TNC, "LISTEN TRUE", TRUE);
// Start Scanner
@ -1889,12 +1887,19 @@ VOID ARDOPReleaseTNC(struct TNCINFO * TNC)
VOID ARDOPSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{
TNC->PortRecord->PORTCONTROL.PortSuspended = TRUE;
ARDOPSendCommand(TNC, "LISTEN FALSE", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
}
VOID ARDOPReleasePort(struct TNCINFO * TNC)
{
TNC->PortRecord->PORTCONTROL.PortSuspended = FALSE;
ARDOPSendCommand(TNC, "LISTEN TRUE", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
}
extern char WebProcTemplate[];
@ -2953,6 +2958,15 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (TNC->PTTMode)
Rig_PTT(TNC, TRUE);
TNC->PTTonTime = GetTickCount();
// Cancel Busy timer (stats include ptt on time in port active
if (TNC->BusyonTime)
{
TNC->BusyActivemS += (GetTickCount() - TNC->BusyonTime);
TNC->BusyonTime = 0;
}
return;
}
if (_memicmp(Buffer, "PTT F", 5) == 0)
@ -2961,6 +2975,12 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (TNC->PTTMode)
Rig_PTT(TNC, FALSE);
if (TNC->PTTonTime)
{
TNC->PTTActivemS += (GetTickCount() - TNC->PTTonTime);
TNC->PTTonTime = 0;
}
return;
}
@ -2969,6 +2989,8 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
TNC->BusyFlags |= CDBusy;
TNC->Busy = TNC->BusyHold * 10; // BusyHold delay
TNC->BusyonTime = GetTickCount();
MySetWindowText(TNC->xIDC_CHANSTATE, "Busy");
strcpy(TNC->WEB_CHANSTATE, "Busy");
@ -2985,6 +3007,12 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
else
strcpy(TNC->WEB_CHANSTATE, "Clear");
if (TNC->BusyonTime)
{
TNC->BusyActivemS += (GetTickCount() - TNC->BusyonTime);
TNC->BusyonTime = 0;
}
MySetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE);
TNC->WinmorRestartCodecTimer = time(NULL);
return;
@ -3852,6 +3880,7 @@ VOID ARDOPProcessDataPacket(struct TNCINFO * TNC, UCHAR * Type, UCHAR * Data, in
char * ptr2;
char c;
int Len = Length;
char Call[10] = "";
Debugprintf(Data);
@ -3924,7 +3953,12 @@ VOID ARDOPProcessDataPacket(struct TNCINFO * TNC, UCHAR * Type, UCHAR * Data, in
buffptr->LENGTH = 16 + MSGHDDRLEN + APLen;
time(&buffptr->Timestamp);
memcpy(Call,ptr1, 9);
strlop(Call, '>');
UpdateMH(TNC, Call, '!', 'I');
BPQTRACE((MESSAGE *)buffptr, TRUE);
}
else
{

View File

@ -124,7 +124,7 @@ void decodeblock( unsigned char in[4], unsigned char out[3]);
int encode_quoted_printable(char *s, char * out, int Len);
int32_t Encode(char * in, char * out, int32_t inlen, BOOL B1Protocol, int Compress);
int APIENTRY ChangeSessionCallsign(int Stream, unsigned char * AXCall);
void SendMessageReadEvent(char * user, struct MsgInfo * Msg);
void SendMessageReadEvent(char * call, struct MsgInfo * Msg);
void SendNewMessageEvent(char * call, struct MsgInfo * Msg);
config_t cfg;
@ -10059,6 +10059,7 @@ BOOL GetConfig(char * ConfigName)
char Size[80];
config_setting_t *setting;
const char * ptr;
char * ptr1;
char FBBString[8192]= "";
FBBFilter f;
config_init(&cfg);
@ -10265,7 +10266,7 @@ BOOL GetConfig(char * ConfigName)
GetStringValue(group, "FBBFilters", FBBString);
ptr = FBBString;
ptr1 = FBBString;
// delete old list
@ -10279,31 +10280,31 @@ BOOL GetConfig(char * ConfigName)
free(Filters);
Filters = NULL;
while (ptr && ptr[0])
while (ptr1 && ptr1[0])
{
FBBFilter * PFilter;
f.Action = ptr[0];
f.Type = ptr[2];
ptr = &ptr[4];
f.Action = ptr1[0];
f.Type = ptr1[2];
ptr1 = &ptr1[4];
memcpy(f.From, ptr, 10);
memcpy(f.From, ptr1, 10);
strlop(f.From, '|');
ptr = strlop(ptr, '|');
ptr1 = strlop(ptr1, '|');
memcpy(f.TO, ptr, 10);
memcpy(f.TO, ptr1, 10);
strlop(f.TO, '|');
ptr = strlop(ptr, '|');
ptr1 = strlop(ptr1, '|');
memcpy(f.AT, ptr, 10);
memcpy(f.AT, ptr1, 10);
strlop(f.AT, '|');
ptr = strlop(ptr, '|');
ptr1 = strlop(ptr1, '|');
memcpy(f.BID, ptr, 10);
memcpy(f.BID, ptr1, 10);
strlop(f.BID, '|');
ptr = strlop(ptr, '|');
ptr1 = strlop(ptr1, '|');
f.MaxLen = atoi(ptr);
f.MaxLen = atoi(ptr1);
// add to list
@ -10325,7 +10326,7 @@ BOOL GetConfig(char * ConfigName)
p->Next = PFilter;
}
ptr = strlop(ptr, '|');
ptr1 = strlop(ptr1, '|');
}

Binary file not shown.

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

Binary file not shown.

View File

@ -1138,6 +1138,8 @@
// Allow selection of 2 or 4 character country codes for forward processing (39)
// Fix Send P to multiple BBS's when routing on HR (40)
// Rewrite PG server code on Lunux (41)
// Fix SendPToMultiple not stopping at Implied AT match (45)
// Log Our HA when checking for flood bulls (45)
#include "bpqmail.h"
#include "winstdint.h"

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BPQMail", "BPQMail.vcproj", "{3766AA10-C777-4ED8-A83D-F1452DE9B665}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3766AA10-C777-4ED8-A83D-F1452DE9B665}.Debug|Win32.ActiveCfg = Debug|Win32
{3766AA10-C777-4ED8-A83D-F1452DE9B665}.Debug|Win32.Build.0 = Debug|Win32
{3766AA10-C777-4ED8-A83D-F1452DE9B665}.Release|Win32.ActiveCfg = Release|Win32
{3766AA10-C777-4ED8-A83D-F1452DE9B665}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="SKIGACER"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="SKIGACER"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1212,7 +1212,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Add NodeAPI call sendLinks and remove get from other calls (32)
// Improve validation of Web Beacon Config (33)
// Support SNMP via host ip stack as well as IPGateway (34)
// Switch APRS Map to OSM tile servers (36)
// Fix potential buffer overflow in Telnet login (36)
// Allow longer serial device names (37)
@ -1222,6 +1221,12 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Change default of SECURETELNET to 1 (41)
// Add optional ATTACH time limit for ARDOP (42)
// Fix buffer overflow risk in HTTP Terminal(42)
// Fix KISSHF Interlock (43)
// Support other than channel A on HFKISS (43)
// Support additional port info reporting for M0LTE Map (44)
// Allow interlocking of KISS and Session mode ports (eg ARDOP and VARA) (45)
// Add ARDOP UI Packets to MH (45)
// Add support for Qtsm Mgmt Interface (45)

Binary file not shown.

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="C:\Devprogs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="C:\Devprogs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="C:\Devprogs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="C:\DevProgs\BPQ32\bpq32.exe"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="SKIGACER"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command=""
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="SKIGACER"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

136
Cmd.c
View File

@ -10,7 +10,7 @@ the Free Software Foundation, either version 3 of the License, or
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
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. S"paclenee the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
@ -66,6 +66,10 @@ VOID SaveMH();
BOOL RestartTNC(struct TNCINFO * TNC);
void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD);
VOID WriteMiniDump();
int CheckKissInterlock(struct PORTCONTROL * PORT, int Exclusive);
int seeifInterlockneeded(struct PORTCONTROL * PORT);
extern VOID KISSTX();
char COMMANDBUFFER[81] = ""; // Command Hander input buffer
char OrigCmdBuffer[81] = ""; // Command Hander input buffer before toupper
@ -171,7 +175,8 @@ VOID APRSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX *
VOID RECONFIGTELNET (TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD);
VOID HELPCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD);
VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD);
VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * UserCMD);
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
@ -1196,11 +1201,12 @@ VOID CMDSTATS(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX *
Bufferptr = Cmdprintf(Session, Bufferptr, "\r");
PORT = STARTPORT;
Bufferptr = Cmdprintf(Session, Bufferptr, "Link Active %% ");
// Bufferptr = Cmdprintf(Session, Bufferptr, "Link Active %% ");
Bufferptr = Cmdprintf(Session, Bufferptr, "Active(TX/Busy) %%");
for (i = 0; i < cols; i++)
{
Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %3d", PORT->AVSENDING, PORT->AVACTIVE);
Bufferptr = Cmdprintf(Session, Bufferptr, " %2d %3d ", PORT->AVSENDING, PORT->AVACTIVE);
PORT = PORT->PORTPOINTER;
}
Bufferptr = Cmdprintf(Session, Bufferptr, "\r");
@ -2295,8 +2301,8 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * C
int TextCallLen;
char PortString[10];
char cmdCopy[256];
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;;
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;
char toCall[12], fromCall[12];
#ifdef EXCLUDEBITS
@ -2738,6 +2744,16 @@ noFlip:
return;
}
ret = CheckKissInterlock(PORT, TRUE);
if (ret)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry, Interlocked port %d is in use\r", ret);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
if (Session->L4USER[6] == 0x42 || Session->L4USER[6] == 0x44)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Sorry - Can't make ax.25 calls with SSID of T or R\r");
@ -2822,6 +2838,12 @@ noFlip3:
RESET2(LINK); // RESET ALL FLAGS
toCall[ConvFromAX25(LINK->LINKCALL, toCall)] = 0;
fromCall[ConvFromAX25(LINK->OURCALL, fromCall)] = 0;
hookL2SessionAttempt(CONNECTPORT, fromCall, toCall, LINK);
if (CMD->String[0] == 'N' && SUPPORT2point2)
LINK->L2STATE = 1; // New (2.2) send XID
else
@ -2836,6 +2858,8 @@ noFlip3:
if (CQFLAG == 0) // if a CQ CALL DONT SEND SABM
{
seeifInterlockneeded(PORT);
if (LINK->L2STATE == 1)
L2SENDXID(LINK);
else
@ -4166,7 +4190,7 @@ VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX
if (EXTPORT->ATTACHEDSESSIONS[sess])
if (EXTPORT->ATTACHEDSESSIONS[sess] || PORT->PortSuspended)
{
// In use
@ -4434,6 +4458,7 @@ CMDX COMMANDS[] =
"NAT ",3,SHOWNAT,0,
"IPROUTE ",3,SHOWIPROUTE,0,
"UZ7HO ",5,UZ7HOCMD,0,
"QTSM ",4,QTSMCMD,0,
"..FLMSG ",7,FLMSG,0
};
@ -4897,15 +4922,65 @@ VOID DoTheCommand(TRANSPORTENTRY * Session)
VOID StatsTimer()
{
struct PORTCONTROL * PORT = PORTTABLE;
int sum;
uint64_t sum, sum2;
// Interval is 60 secs
while(PORT)
{
sum = PORT->SENDING / 11;
PORT->AVSENDING = sum;
int index = PORT->StatsPointer++;
sum = (PORT->SENDING + PORT->ACTIVE) /11;
PORT->AVACTIVE = sum;
if (index == 1439)
PORT->StatsPointer = 0; // Cyclic through 24 hours (1440 Mins)
if (PORT->TNC)
{
struct TNCINFO * TNC = PORT->TNC;
if (TNC->Hardware == H_ARDOP || TNC->Hardware == H_VARA)
{
sum = TNC->PTTActivemS / 600; // ms but want %
PORT->AVSENDING = (UCHAR)sum;
TNC->PTTActivemS = 0;
sum2 = TNC->BusyActivemS / 600; // ms but want %
PORT->AVACTIVE = (UCHAR)(sum + sum2);
TNC->BusyActivemS = 0;
}
}
else
{
// if KISS port using QtSM Average is already updated
struct KISSINFO * KISS = (struct KISSINFO *)PORT;
if (PORT->PORTNUMBER == 17)
{
int x = 17;
}
if (PORT->PORTTXROUTINE == KISSTX && (KISS->QtSMStats || KISS->FIRSTPORT->PORT.QtSMPort)) // KISS Port QtSM Stats
{
}
else
{
sum = PORT->SENDING / 11;
PORT->AVSENDING = (UCHAR)sum;
sum = (PORT->SENDING + PORT->ACTIVE) /11;
PORT->AVACTIVE = (UCHAR)sum;
}
}
if (PORT->TX == NULL && PORT->AVACTIVE)
{
PORT->TX = zalloc(1440); // Keep 1 day history
PORT->BUSY = zalloc(1440);
}
if (PORT->TX)
{
PORT->TX[index] = PORT->AVSENDING;
PORT->BUSY[index] = PORT->AVACTIVE;
}
PORT->SENDING = 0;
PORT->ACTIVE = 0;
@ -5865,6 +5940,43 @@ VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX *
return;
}
VOID QTSMCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD)
{
int port;
struct PORTCONTROL * PORT;
struct KISSINFO * KISS;
CmdTail = CmdTail + (OrigCmdBuffer - COMMANDBUFFER); // Replace with original case version
port = atoi(CmdTail);
PORT = GetPortTableEntryFromPortNum(port);
if (PORT == NULL || PORT->PORTTXROUTINE != KISSTX) // Must be a kiss like port
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port %d is not a KISS port\r", port);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
KISS = (struct KISSINFO *)PORT;
if (KISS->QtSMModem == 0)
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port %d has no QtSM information\r", port);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
Bufferptr = Cmdprintf(Session, Bufferptr, "Modem %s Centre frequency %d\r",
(KISS->QtSMModem) ? KISS->QtSMModem : "Not Available", KISS->QtSMFreq);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}

View File

@ -73,6 +73,7 @@ void SendDataToPktMap(char *Msg);
extern BOOL LogAllConnects;
extern BOOL M0LTEMap;
char * stristr (char *ch1, char *ch2);
extern VOID * ENDBUFFERPOOL;
@ -547,6 +548,7 @@ VOID * _GetBuff(char * File, int Line)
Msg->Process = (short)GetCurrentProcessId();
Msg->Linkptr = NULL;
Msg->Padding[0] = 0; // Used for modem status info
}
else
Debugprintf("Warning - Getbuff returned NULL");
@ -1669,7 +1671,7 @@ DllExport time_t APIENTRY GetRaw(int stream, char * msg, int * len, int * count)
Stamp = MSG->Timestamp;
memcpy(msg, MSG, Msglen);
memcpy(msg, MSG, BUFFLEN - sizeof(void *)); // To c
*len = Msglen;
@ -2454,8 +2456,8 @@ HANDLE OpenCOMPort(VOID * pPort, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet
struct termios term;
struct speed_struct *s;
if ((UINT)pPort < 256)
sprintf(Port, "%s/com%d", BPQDirectory, (int)pPort);
if ((uintptr_t)pPort < 256)
sprintf(Port, "%s/com%d", BPQDirectory, (int)(uintptr_t)pPort);
else
strcpy(Port, pPort);
@ -3688,7 +3690,7 @@ VOID OpenReportingSockets()
{
// Enable Node Map Reports
ReportTimer = 60;
ReportTimer = 1200; // 2 mins - Give Rigcontrol time to start
ReportSocket = socket(AF_INET,SOCK_DGRAM,0);
@ -5160,6 +5162,7 @@ void SendDataToPktMap(char *Msg)
char * Use;
char * Type;
char * Modulation;
char * Usage;
char locked[] = " ! ";
int Percent = 0;
@ -5264,6 +5267,10 @@ void SendDataToPktMap(char *Msg)
Type = "RF";
Bitrate = 0;
Modulation = "FSK";
Usage = "Access";
if (PORT->PortFreq)
Freq = PORT->PortFreq;
if (PORT->PORTTYPE == 0)
{
@ -5321,7 +5328,7 @@ void SendDataToPktMap(char *Msg)
continue;
}
if (TNC->RIG)
if (Freq == 0 && TNC->RIG)
Freq = TNC->RIG->RigFreq * 1000000;
switch (TNC->Hardware) // Hardware Type
@ -5387,6 +5394,15 @@ void SendDataToPktMap(char *Msg)
break;
case H_KISSHF:
// Try to get mode from ID then drop through
if (stristr(PORT->PORTDESCRIPTION, "BPSK"))
{
Modulation = "BPSK";
}
case H_WINMOR:
case H_V4:
@ -5395,7 +5411,7 @@ void SendDataToPktMap(char *Msg)
case H_UIARQ:
case H_ARDOP:
case H_VARA:
case H_KISSHF:
case H_FREEDATA:
// TCP
@ -5431,12 +5447,58 @@ void SendDataToPktMap(char *Msg)
while (*(ptr2) == ' ' && ptr2 != ID)
*(ptr2--) = 0;
if (PORT->M0LTEMapInfo)
{
// Override with user configured values - RF,7.045,BPSK,300,300,Access
char param[256];
char *p1, *p2, *p3, *p4, *p5;
strcpy(param, PORT->M0LTEMapInfo);
p1 = strlop(param, ',');
p2 = strlop(p1, ',');
p3 = strlop(p2, ',');
p4 = strlop(p3, ',');
p5 = strlop(p4, ',');
// int n = sscanf(PORT->M0LTEMapInfo, "%s,%s,%s,%s,%s,%s", &p1, &p2, &p3, &p4, &p5, &p6);
if (p5)
{
if (param[0]) Type = param;
if (p1[0])
{
// if set to DIAL+=n and frequency set from config or rigcontrol modify it
uint64_t offset = 0;
if (_memicmp(p1, "DIAL+", 5) == 0)
offset = atoi(&p1[5]);
else if (_memicmp(p1, "DIAL-", 5) == 0)
offset = -atoi(&p1[5]);
else
Freq = atof(p1) * 1000000;
if (Freq != 0)
Freq += offset;
}
if (p2[0]) Modulation = p2;
if (p3[0]) Baud = atoi(p3);
if (p4[0]) Bitrate = atoi(p4);
if (p5[0]) Usage = p5;
}
}
ptr += sprintf(ptr, "{\"id\": \"%d\",\"linkType\": \"%s\","
"\"freq\": \"%lld\",\"mode\": \"%s\",\"modulation\": \"%s\","
"\"baud\": \"%d\",\"bitrate\": \"%d\",\"usage\": \"%s\",\"comment\": \"%s\"},\r\n",
PortNo, Type,
Freq, Mode, Modulation,
Baud, Bitrate, "Access", ID);
Baud, Bitrate, Usage, ID);
// G7TAJ //
// make MH list to be added later

View File

@ -107,3 +107,16 @@ DllExport void APIENTRY RunEventProgram(char * Program, char * Param)
return;
}
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK)
{
}
void hookL2SessionDeleted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK)
{
}
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK)
{
}

View File

@ -686,8 +686,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (buffptr == 0) return (0); // No buffers, so ignore
buffptr->Len = 36;
memcpy(&buffptr->Data[0], "No Connection to TNC\r", 36);
buffptr->Len = sprintf(&buffptr->Data[0], "No Connection to TNC\r");
C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr);
@ -3215,7 +3214,7 @@ void ProcessTNCJSON(struct TNCINFO * TNC, char * Msg, int Len)
}
}
else if (memcmp(ptr, "close", 12) == 0)
else if (memcmp(ptr, "close", 5) == 0)
{
if (TNC->FreeDataInfo->arqstate != 4)
{

View File

@ -1623,23 +1623,23 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
char * WebSock = 0;
char PortsHddr[] = "<h2 align=center>Ports</h2><table align=center border=2 bgcolor=white>"
"<tr><th>Port</th><th>Driver</th><th>ID</th><th>Beacons</th><th>Driver Window</th></tr>";
"<tr><th>Port</th><th>Driver</th><th>ID</th><th>Beacons</th><th>Driver Window</th><th>Stats Graph</th></tr>";
char PortLine[] = "<tr><td>%d</td><td><a href=PortStats?%d&%s>&nbsp;%s</a></td><td>%s</td></tr>";
// char PortLine[] = "<tr><td>%d</td><td><a href=PortStats?%d&%s>&nbsp;%s</a></td><td>%s</td></tr>";
char PortLineWithBeacon[] = "<tr><td>%d</td><td><a href=PortStats?%d&%s>&nbsp;%s</a></td><td>%s</td>"
"<td><a href=PortBeacons?%d>&nbsp;Beacons</a><td> </td></td></tr>\r\n";
"<td><a href=PortBeacons?%d>&nbsp;Beacons</a><td> </td></td><td>%s</td></tr>\r\n";
char SessionPortLine[] = "<tr><td>%d</td><td>%s</td><td>%s</td><td> </td>"
"<td> </td></tr>\r\n";
"<td> </td><td>%s</td></tr>\r\n";
char PortLineWithDriver[] = "<tr><td>%d</td><td>%s</td><td>%s</td><td> </td>"
"<td><a href=\"javascript:dev_win('/Node/Port?%d',%d,%d,%d,%d);\">Driver Window</a></td></tr>\r\n";
"<td><a href=\"javascript:dev_win('/Node/Port?%d',%d,%d,%d,%d);\">Driver Window</a></td><td>%s</td></tr>\r\n";
char PortLineWithBeaconAndDriver[] = "<tr><td>%d</td><td>%s</td><td>%s</td>"
"<td><a href=PortBeacons?%d>&nbsp;Beacons</a></td>"
"<td><a href=\"javascript:dev_win('/Node/Port?%d',%d,%d,%d,%d);\">Driver Window</a></td></tr>\r\n";
"<td><a href=\"javascript:dev_win('/Node/Port?%d',%d,%d,%d,%d);\">Driver Window</a></td><td>%s</td></tr>\r\n";
char RigControlLine[] = "<tr><td>%d</td><td>%s</td><td>%s</td><td> </td>"
"<td><a href=\"javascript:dev_win('/Node/RigControl.html',%d,%d,%d,%d);\">Rig Control</a></td></tr>\r\n";
@ -2707,6 +2707,53 @@ doHeader:
return 0;
}
else if (_memicmp(NodeURL, "/portstats.txt", 15) == 0)
{
char * Compressed;
char * ptr;
int port;
struct PORTCONTROL * PORT;
ptr = &NodeURL[15];
port = atoi(ptr);
PORT = GetPortTableEntryFromPortNum(port);
ReplyLen = 0;
if (PORT && PORT->TX)
{
// We send the last 24 hours worth of data. Buffer is cyclic so oldest byte is at StatsPointer
int first = PORT->StatsPointer;
int firstlen = 1440 - first;
memcpy(&_REPLYBUFFER[0], &PORT->TX[first], firstlen);
memcpy(&_REPLYBUFFER[firstlen], PORT->TX, first);
memcpy(&_REPLYBUFFER[1440], &PORT->BUSY[first], firstlen);
memcpy(&_REPLYBUFFER[1440 + firstlen], PORT->BUSY, first);
ReplyLen = 2880;
}
if (allowDeflate)
Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen);
else
Compressed = _REPLYBUFFER;
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nContent-Length: %d\r\nContent-Type: Text\r\n%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, Compressed, ReplyLen);
if (allowDeflate)
free (Compressed);
return 0;
}
else if (_memicmp(NodeURL, "/Icon", 5) == 0 && _memicmp(&NodeURL[10], ".png", 4) == 0)
{
// APRS internal Icon
@ -2880,7 +2927,7 @@ doHeader:
" {"
" // The browser doesn't support WebSocket\r\n"
" const div = document.getElementById('div');\r\n"
" div.innerHTML = 'WebSocket not supported by your Browser - RigControl Page not availble'\r\n"
" div.innerHTML = 'WebSocket not supported by your Browser - RigControl Page not availible'\r\n"
" }"
"}"
"function PTT(p)"
@ -3235,6 +3282,7 @@ doHeader:
int count;
char DLL[20];
char StatsURL[64];
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", PortsHddr);
@ -3243,6 +3291,13 @@ doHeader:
Port = GetPortTableEntryFromSlot(count);
ExtPort = (struct _EXTPORTDATA *)Port;
// see if has a stats page
if (Port->AVACTIVE)
sprintf(StatsURL, "<a href=/PortStats.html?%d>&nbsp;Stats Graph</a>", Port->PORTNUMBER);
else
StatsURL[0] = 0;
if (Port->PORTTYPE == 0x10)
{
strcpy(DLL, ExtPort->PORT_DLL_NAME);
@ -3265,20 +3320,20 @@ doHeader:
{
if (Port->UICAPABLE)
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithBeaconAndDriver, Port->PORTNUMBER, DLL,
Port->PORTDESCRIPTION, Port->PORTNUMBER, Port->PORTNUMBER, Port->TNC->WebWinX, Port->TNC->WebWinY, 200, 200);
Port->PORTDESCRIPTION, Port->PORTNUMBER, Port->PORTNUMBER, Port->TNC->WebWinX, Port->TNC->WebWinY, 200, 200, StatsURL);
else
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithDriver, Port->PORTNUMBER, DLL,
Port->PORTDESCRIPTION, Port->PORTNUMBER, Port->TNC->WebWinX, Port->TNC->WebWinY, 200, 200);
Port->PORTDESCRIPTION, Port->PORTNUMBER, Port->TNC->WebWinX, Port->TNC->WebWinY, 200, 200, StatsURL);
continue;
}
if (Port->PORTTYPE == 16 && Port->PROTOCOL == 10 && Port->UICAPABLE == 0) // EXTERNAL, Pactor/WINMO
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], SessionPortLine, Port->PORTNUMBER, DLL,
Port->PORTDESCRIPTION, Port->PORTNUMBER);
Port->PORTDESCRIPTION, Port->PORTNUMBER, StatsURL);
else
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithBeacon, Port->PORTNUMBER, Port->PORTNUMBER,
DLL, DLL, Port->PORTDESCRIPTION, Port->PORTNUMBER);
DLL, DLL, Port->PORTDESCRIPTION, Port->PORTNUMBER, StatsURL);
}
if (RigActive)

View File

@ -343,12 +343,12 @@ VOID ExpireMessages()
Killed = 0;
PRLimit = now - PR*86400;
PURLimit = now - PUR*86400;
PFLimit = now - PF*86400;
PNFLimit = now - PNF*86400;
BFLimit = now - BF*86400;
BNFLimit = now - BNF*86400;
PRLimit = now - (time_t)PR*86400;
PURLimit = now -(time_t)PUR*86400;
PFLimit = now - (time_t)PF*86400;
PNFLimit = now - (time_t)PNF*86400;
BFLimit = now - (time_t)BF*86400;
BNFLimit = now -(time_t) BNF*86400;
if (NTSU == 0)
{
@ -391,7 +391,7 @@ VOID ExpireMessages()
if (Msg->datecreated < PURLimit)
{
if (SendNonDeliveryMsgs)
SendNonDeliveryMessage(Msg, TRUE, PUR);
SendNonDeliveryMessage(Msg, TRUE, (int)PUR);
KillMsg(Msg);
}
@ -401,7 +401,7 @@ VOID ExpireMessages()
if (Msg->datecreated < PNFLimit)
{
if (SendNonDeliveryMsgs)
SendNonDeliveryMessage(Msg, FALSE, PNF);
SendNonDeliveryMessage(Msg, FALSE, (int)PNF);
KillMsg(Msg);
}

115
KISSHF.c
View File

@ -50,8 +50,8 @@ int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len);
VOID SendInitScript(struct TNCINFO * TNC);
int KISSHFGetLine(char * buf);
int ProcessEscape(UCHAR * TXMsg);
VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC);
static int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC, int Channel);
static int KissEncode(struct TNCINFO * TNC, UCHAR * inbuff, UCHAR * outbuff, int len, int Channel);
int ConnecttoKISS(int port);
TRANSPORTENTRY * SetupNewSession(TRANSPORTENTRY * Session, char * Bufferptr);
BOOL DecodeCallString(char * Calls, BOOL * Stay, BOOL * Spy, UCHAR * AXCalls);
@ -265,6 +265,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
struct TNCINFO * TNC = TNCInfo[port];
struct STREAMINFO * STREAM = &TNC->Streams[0];
struct ScanEntry * Scan;
int Channel = ((TNC->PortRecord->PORTCONTROL.CHANNELNUM - 1) & 15) << 4;
if (TNC == NULL)
return 0; // Port not defined
@ -417,7 +418,10 @@ ok:
if (buff->PID != 240) // ax.25 address
{
txlen = KissEncode(&buff->PID, txbuff, txlen);
txlen = KissEncode(TNC, &buff->PID, txbuff, txlen, Channel);
// We need to che check for ackmode
txlen = send(TNC->TCPSock, txbuff, txlen, 0);
return 1;
}
@ -504,7 +508,8 @@ ok:
}
}
if (toupper(buff->L2DATA[0]) == 'C' && buff->L2DATA[1] == ' ' && txlen > 2) // Connect
if ((toupper(buff->L2DATA[0]) == 'C' && buff->L2DATA[1] == ' ' && txlen > 2) // Connect
|| (toupper(buff->L2DATA[0]) == 'N' && buff->L2DATA[1] == ' ' && txlen > 2)) // Connect
{
// Connect Command. Pass to L2 code to start session
@ -616,9 +621,9 @@ noFlip3:
RESET2(LINK); // RESET ALL FLAGS
// if (CMD->String[0] == 'N' && SUPPORT2point2)
// LINK->L2STATE = 1; // New (2.2) send XID
// else
if (toupper(buff->L2DATA[0]) == 'N' && SUPPORT2point2)
LINK->L2STATE = 1; // New (2.2) send XID
else
LINK->L2STATE = 2; // Send SABM
LINK->CIRCUITPOINTER = NewSess;
@ -722,10 +727,16 @@ VOID KISSHFReleaseTNC(struct TNCINFO * TNC)
VOID KISSHFSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{
TNC->PortRecord->PORTCONTROL.PortSuspended = 1;
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
}
VOID KISSHFReleasePort(struct TNCINFO * TNC)
{
TNC->PortRecord->PORTCONTROL.PortSuspended = 0;
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
}
static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL)
@ -735,9 +746,9 @@ static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL)
"function ScrollOutput()\r\n"
"{var textarea = document.getElementById('textarea');"
"textarea.scrollTop = textarea.scrollHeight;}</script>"
"</head><title>VARA Status</title></head><body id=Text onload=\"ScrollOutput()\">"
"</head><title>KISSHF Status</title></head><body id=Text onload=\"ScrollOutput()\">"
"<h2><form method=post target=\"POPUPW\" onsubmit=\"POPUPW = window.open('about:blank','POPUPW',"
"'width=440,height=150');\" action=ARDOPAbort?%d>KISSHF Status"
"'width=440,height=50');\" action=ARDOPAbort?%d>KISSHF Status"
"<input name=Save value=\"Abort Session\" type=submit style=\"position: absolute; right: 20;\"></form></h2>",
TNC->Port);
@ -746,14 +757,14 @@ static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL)
Len += sprintf(&Buff[Len], "<tr><td width=110px>Comms State</td><td>%s</td></tr>", TNC->WEB_COMMSSTATE);
Len += sprintf(&Buff[Len], "<tr><td>TNC State</td><td>%s</td></tr>", TNC->WEB_TNCSTATE);
Len += sprintf(&Buff[Len], "<tr><td>Mode</td><td>%s</td></tr>", TNC->WEB_MODE);
Len += sprintf(&Buff[Len], "<tr><td>Channel State</td><td>%s</td></tr>", TNC->WEB_CHANSTATE);
Len += sprintf(&Buff[Len], "<tr><td>Proto State</td><td>%s</td></tr>", TNC->WEB_PROTOSTATE);
Len += sprintf(&Buff[Len], "<tr><td>Traffic</td><td>%s</td></tr>", TNC->WEB_TRAFFIC);
// Len += sprintf(&Buff[Len], "<tr><td>Mode</td><td>%s</td></tr>", TNC->WEB_MODE);
// Len += sprintf(&Buff[Len], "<tr><td>Channel State</td><td>%s</td></tr>", TNC->WEB_CHANSTATE);
// Len += sprintf(&Buff[Len], "<tr><td>Proto State</td><td>%s</td></tr>", TNC->WEB_PROTOSTATE);
// Len += sprintf(&Buff[Len], "<tr><td>Traffic</td><td>%s</td></tr>", TNC->WEB_TRAFFIC);
// Len += sprintf(&Buff[Len], "<tr><td>TNC Restarts</td><td></td></tr>", TNC->WEB_RESTARTS);
Len += sprintf(&Buff[Len], "</table>");
Len += sprintf(&Buff[Len], "<textarea rows=10 style=\"width:500px; height:250px;\" id=textarea >%s</textarea>", TNC->WebBuffer);
Len += sprintf(&Buff[Len], "<textarea rows=2 style=\"width:500px; height:50px;\" id=textarea >%s</textarea>", TNC->WebBuffer);
Len = DoScanLine(TNC, Buff, Len);
return Len;
@ -976,6 +987,7 @@ VOID KISSThread(void * portptr)
char * ptr1;
char * ptr2;
UINT * buffptr;
int Channel = ((TNC->PortRecord->PORTCONTROL.CHANNELNUM - 1) & 15) << 4;
if (TNC->HostName == NULL)
return;
@ -1184,7 +1196,7 @@ VOID KISSThread(void * portptr)
if (FD_ISSET(TNC->TCPSock, &readfs))
{
GetSemaphore(&Semaphore, 52);
KISSHFProcessReceivedPacket(TNC);
KISSHFProcessReceivedPacket(TNC, Channel);
FreeSemaphore(&Semaphore);
}
@ -1243,16 +1255,43 @@ static int KissDecode(UCHAR * inbuff, UCHAR * outbuff, int len)
}
#define ACKMODE 4 // CAN USE ACK REQURED FRAMES
#define MSGHDDRLEN (USHORT)(sizeof(VOID *) + sizeof(UCHAR) + sizeof(USHORT))
#define ONEMINUTE 60*3
static int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len)
static int KissEncode(struct TNCINFO * TNC, UCHAR * inbuff, UCHAR * outbuff, int len, int Channel)
{
int i,txptr=0;
UCHAR c;
outbuff[0]=FEND;
outbuff[1]=0;
outbuff[0] = FEND;
outbuff[1] = Channel;
txptr=2;
// See if we need ackmode
if (TNC->PortRecord->PORTCONTROL.KISSFLAGS & ACKMODE)
{
UCHAR * ptr = inbuff - MSGHDDRLEN;
PMESSAGE Buffer = (PMESSAGE)ptr;
if (Buffer->Linkptr) // Frame Needs ACK
{
UINT ACKWORD = (UINT)(Buffer->Linkptr - LINKS);
outbuff[1] |= 0x0c; // ACK OPCODE
outbuff[2] = ACKWORD & 0xff;
outbuff[3] = (ACKWORD >> 8) &0xff;
Buffer->Linkptr->L2TIMER = ONEMINUTE; // Extend timeout
txptr = 4;
// have to reset flag so trace doesnt clear it
Buffer->Linkptr = 0;
}
}
for (i=0;i<len;i++)
{
c=inbuff[i];
@ -1283,7 +1322,7 @@ static int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len)
}
VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC)
VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC, int Channel)
{
int InputLen, MsgLen;
unsigned char * ptr;
@ -1335,10 +1374,42 @@ VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC)
if (MsgLen > 1)
{
PMESSAGE Buff = GetBuff();
PMESSAGE Buff;
if ((TNC->ARDOPBuffer[1] & 0xf0) != Channel)
goto ignoreit;
Buff = GetBuff();
MsgLen = KissDecode(TNC->ARDOPBuffer, Buffer, MsgLen);
// See if ACKMODE ACK
if ((Buffer[1] & 0xf) == 12)
{
//Ackmode
struct _LINKTABLE * LINK;
int ACKWORD = Buffer[2] | Buffer[3] << 8;
if (ACKWORD < MAXLINKS)
{
LINK = LINKS + ACKWORD;
if (LINK->L2TIMER)
LINK->L2TIMER = LINK->L2TIME;
}
ReleaseBuffer(Buff);
goto ignoreit;
}
if ((Buffer[1] & 0xf) != 0)
{
ReleaseBuffer(Buff);
goto ignoreit; // Not data
}
// we dont need the FENDS or control byte
MsgLen -= 3;
@ -1354,6 +1425,8 @@ VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC)
}
}
ignoreit:
if (TNC->InputLen == 0)
return;
@ -1463,7 +1536,7 @@ void DetachKISSHF(struct PORTCONTROL * PORT)
struct STREAMINFO * STREAM = &TNC->Streams[0];
if (STREAM->Attached)
STREAM->ReportDISC = TRUE; // Tell Node
STREAM->ReportDISC = 10; // Tell Node but give time for error message to display
STREAM->Connecting = FALSE;
STREAM->Connected = FALSE;

483
L2Code.c
View File

@ -106,6 +106,13 @@ void AttachKISSHF(struct PORTCONTROL * PORT, MESSAGE * Buffer);
void DetachKISSHF(struct PORTCONTROL * PORT);
void KISSHFConnected(struct PORTCONTROL * PORT, struct _LINKTABLE * LINK);
void WriteConnectLog(char * fromcall, char * tocall, UCHAR * Mode);
int seeifInterlockneeded(struct PORTCONTROL * PORT);
int seeifUnlockneeded(struct _LINKTABLE * LINK);
int CheckKissInterlock(struct PORTCONTROL * MYPORT, int Exclusive);
void hookL2SessionAccepted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
extern int REALTIMETICKS;
@ -773,163 +780,171 @@ VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buff
VOID ProcessXIDCommand(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffer, MESSAGE * ADJBUFFER, UCHAR CTL, UCHAR MSGFLAG)
{
// I think it is fairly safe to accept XID as soon as we
// can process SREJ, but only accept Mod 8 and 256 Byte frames
// I think it is fairly safe to accept XID as soon as we
// can process SREJ, but only accept Mod 8 and 256 Byte frames
// I think the only way to run 2.2 Mod 8 is to preceed a
// SABM with XID, but others don't seem to agree!
// I think the only way to run 2.2 Mod 8 is to preceed a
// SABM with XID, but others don't seem to agree!
// Run through XID fields, changing any we don't like,
// then return an XID response
// Run through XID fields, changing any we don't like,
// then return an XID response
// Decode and process XID
// Decode and process XID
UCHAR * ptr = &ADJBUFFER->PID;
UCHAR * ptr1, * ptr2;
UCHAR TEMPDIGI[57];
int n;
UCHAR * ptr = &ADJBUFFER->PID;
UCHAR * ptr1, * ptr2;
UCHAR TEMPDIGI[57];
int n;
if (*ptr++ == 0x82 && *ptr++ == 0x80)
{
int Type;
int Len;
unsigned int value;
int xidlen = *(ptr++) << 8;
xidlen += *ptr++;
// Check Interlock - should we also check exclude etc?. No, checked in L2FORUS
// XID is set of Type, Len, Value n-tuples
while (xidlen > 0)
{
Type = *ptr++;
Len = *ptr++;
value = 0;
xidlen -= (Len + 2);
while (Len--)
{
value <<=8;
value += *ptr++;
}
switch(Type)
{
case 2: //Bin fields
break;
case 3:
if ((value & OPMustHave) != OPMustHave)
goto BadXID;
if ((value & OPMod8) == 0)
goto BadXID;
if ((value & OPSREJMult) == 0)
goto BadXID;
// Reply Mod 8 SREJMULTI
value = OPMustHave | OPSREJMult | OPMod8;
ptr -=3;
*ptr++ = value >> 16;
*ptr++ = value >> 8;
*ptr++ = value;
break;
case 6: //RX Size
break;
case 8: //RX Window
break;
}
}
// Send back as XID response
LINK->L2STATE = 1; // XID received
LINK->Ver2point2 = TRUE; // Must support 2.2 if sent XID
LINK->L2TIME = PORT->PORTT1;
LINK->LINKPORT = PORT;
// save calls so we can match up SABM when it comes
memcpy(LINK->LINKCALL, Buffer->ORIGIN, 7);
LINK->LINKCALL[6] &= 0x1e; // Mask SSID
memcpy(LINK->OURCALL, Buffer->DEST, 7);
LINK->OURCALL[6] &= 0x1e; // Mask SSID
memset(LINK->DIGIS, 0, 56); // CLEAR DIGI FIELD IN CASE RECONNECT
if ((Buffer->ORIGIN[6] & 1) == 0) // End of Address
{
// THERE ARE DIGIS TO PROCESS - COPY TO WORK AREA reversed, THEN COPY BACK
memset(TEMPDIGI, 0, 57); // CLEAR DIGI FIELD IN CASE RECONNECT
ptr1 = &Buffer->ORIGIN[6]; // End of add
ptr2 = &TEMPDIGI[7 * 7]; // Last Temp Digi
while((*ptr1 & 1) == 0) // End of address bit
{
ptr1++;
memcpy(ptr2, ptr1, 7);
ptr2[6] &= 0x1e; // Mask Repeated and Last bits
ptr2 -= 7;
ptr1 += 6;
}
// LIST OF DIGI CALLS COMPLETE - COPY TO LINK CONTROL ENTRY
n = PORT->PORTMAXDIGIS;
ptr1 = ptr2 + 7; // First in TEMPDIGIS
ptr2 = &LINK->DIGIS[0];
while (*ptr1)
{
if (n == 0)
{
// Too many for us
CLEAROUTLINK(LINK);
ReleaseBuffer(Buffer);
return;
}
memcpy(ptr2, ptr1, 7);
ptr1 += 7;
ptr2 += 7;
n--;
}
}
ADJBUFFER->CTL = CTL | PFBIT;
// Buffer->LENGTH = (UCHAR *)ADJBUFFER - (UCHAR *)Buffer + MSGHDDRLEN + 15; // SET UP BYTE COUNT
L2SWAPADDRESSES(Buffer); // SWAP ADDRESSES AND SET RESP BITS
// We need to save APPLMASK and ALIASPTR so following SABM connects to application
LINK->APPLMASK = APPLMASK;
LINK->ALIASPTR = ALIASPTR;
PUT_ON_PORT_Q(PORT, Buffer);
return;
}
BadXID:
L2SENDINVALIDCTRL(PORT, Buffer, ADJBUFFER, CTL);
if (CheckKissInterlock(PORT, TRUE)) // Interlock with ARDOP/VARA etc
{
L2SENDDM(PORT, Buffer, ADJBUFFER);
return;
}
if (*ptr++ == 0x82 && *ptr++ == 0x80)
{
int Type;
int Len;
unsigned int value;
int xidlen = *(ptr++) << 8;
xidlen += *ptr++;
// XID is set of Type, Len, Value n-tuples
while (xidlen > 0)
{
Type = *ptr++;
Len = *ptr++;
value = 0;
xidlen -= (Len + 2);
while (Len--)
{
value <<=8;
value += *ptr++;
}
switch(Type)
{
case 2: //Bin fields
break;
case 3:
if ((value & OPMustHave) != OPMustHave)
goto BadXID;
if ((value & OPMod8) == 0)
goto BadXID;
if ((value & OPSREJMult) == 0)
goto BadXID;
// Reply Mod 8 SREJMULTI
value = OPMustHave | OPSREJMult | OPMod8;
ptr -=3;
*ptr++ = value >> 16;
*ptr++ = value >> 8;
*ptr++ = value;
break;
case 6: //RX Size
break;
case 8: //RX Window
break;
}
}
// Send back as XID response
LINK->L2STATE = 1; // XID received
LINK->Ver2point2 = TRUE; // Must support 2.2 if sent XID
LINK->L2TIME = PORT->PORTT1;
LINK->LINKPORT = PORT;
// save calls so we can match up SABM when it comes
memcpy(LINK->LINKCALL, Buffer->ORIGIN, 7);
LINK->LINKCALL[6] &= 0x1e; // Mask SSID
memcpy(LINK->OURCALL, Buffer->DEST, 7);
LINK->OURCALL[6] &= 0x1e; // Mask SSID
memset(LINK->DIGIS, 0, 56); // CLEAR DIGI FIELD IN CASE RECONNECT
if ((Buffer->ORIGIN[6] & 1) == 0) // End of Address
{
// THERE ARE DIGIS TO PROCESS - COPY TO WORK AREA reversed, THEN COPY BACK
memset(TEMPDIGI, 0, 57); // CLEAR DIGI FIELD IN CASE RECONNECT
ptr1 = &Buffer->ORIGIN[6]; // End of add
ptr2 = &TEMPDIGI[7 * 7]; // Last Temp Digi
while((*ptr1 & 1) == 0) // End of address bit
{
ptr1++;
memcpy(ptr2, ptr1, 7);
ptr2[6] &= 0x1e; // Mask Repeated and Last bits
ptr2 -= 7;
ptr1 += 6;
}
// LIST OF DIGI CALLS COMPLETE - COPY TO LINK CONTROL ENTRY
n = PORT->PORTMAXDIGIS;
ptr1 = ptr2 + 7; // First in TEMPDIGIS
ptr2 = &LINK->DIGIS[0];
while (*ptr1)
{
if (n == 0)
{
// Too many for us
CLEAROUTLINK(LINK);
ReleaseBuffer(Buffer);
return;
}
memcpy(ptr2, ptr1, 7);
ptr1 += 7;
ptr2 += 7;
n--;
}
}
ADJBUFFER->CTL = CTL | PFBIT;
// Buffer->LENGTH = (UCHAR *)ADJBUFFER - (UCHAR *)Buffer + MSGHDDRLEN + 15; // SET UP BYTE COUNT
L2SWAPADDRESSES(Buffer); // SWAP ADDRESSES AND SET RESP BITS
// We need to save APPLMASK and ALIASPTR so following SABM connects to application
LINK->APPLMASK = APPLMASK;
LINK->ALIASPTR = ALIASPTR;
PUT_ON_PORT_Q(PORT, Buffer);
return;
}
BadXID:
L2SENDINVALIDCTRL(PORT, Buffer, ADJBUFFER, CTL);
return;
}
@ -1101,12 +1116,21 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
TRANSPORTENTRY * Session;
int CONERROR;
char toCall[12], fromCall[12];
if (LINK == 0) // NO LINK ENTRIES - SEND DM RESPONSE
{
L2SENDDM(PORT, Buffer, ADJBUFFER);
return;
}
if (CheckKissInterlock(PORT, TRUE)) // Interlock with ARDOP/VARA etc
{
L2SENDDM(PORT, Buffer, ADJBUFFER);
return;
}
SETUPNEWL2SESSION(LINK, PORT, Buffer, MSGFLAG);
if (LINK->L2STATE != 5) // Setup OK?
@ -1115,6 +1139,14 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
return;
}
// See if need to Interlock non-sharable modes, eg ARDOP and VARA
seeifInterlockneeded(PORT);
toCall[ConvFromAX25(ADJBUFFER->DEST, toCall)] = 0;
fromCall[ConvFromAX25(ADJBUFFER->ORIGIN, fromCall)] = 0;
// IF CONNECT TO APPL ADDRESS, SET UP APPL SESSION
if (APPLMASK == 0)
@ -1137,6 +1169,8 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
WriteConnectLog(fromCall, toCall, "AX.25");
}
hookL2SessionAccepted(PORT->PORTNUMBER, fromCall, toCall, LINK);
L2SENDUA(PORT, Buffer, ADJBUFFER);
if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF)
@ -3226,6 +3260,15 @@ VOID SENDFRMR(struct _LINKTABLE * LINK)
VOID CLEAROUTLINK(struct _LINKTABLE * LINK)
{
char toCall[12], fromCall[12];
toCall[ConvFromAX25(LINK->LINKCALL, toCall)] = 0;
fromCall[ConvFromAX25(LINK->OURCALL, fromCall)] = 0;
hookL2SessionDeleted(LINK->LINKPORT->PORTNUMBER, fromCall, toCall, LINK);
seeifUnlockneeded(LINK);
CLEARL2QUEUES(LINK); // TO RELEASE ANY BUFFERS
memset(LINK, 0, sizeof(struct _LINKTABLE));
@ -3593,7 +3636,7 @@ VOID ConnectFailedOrRefused(struct _LINKTABLE * LINK, char * Msg)
Buffer->LENGTH = (int)(ptr1 - (UCHAR *)Buffer);
Session = LINK->CIRCUITPOINTER; // GET CIRCUIT TABLE ENTRY
InSession = Session->L4CROSSLINK; // TO INCOMMONG SESSION
InSession = Session->L4CROSSLINK; // TO INCOMMING SESSION
CLEARSESSIONENTRY(Session);
@ -3960,3 +4003,141 @@ BOOL CheckForListeningSession(struct PORTCONTROL * PORT, MESSAGE * Msg)
}
return FALSE;
}
int COUNTLINKS(int Port);
VOID SuspendOtherPorts(struct TNCINFO * ThisTNC);
VOID ReleaseOtherPorts(struct TNCINFO * ThisTNC);
int CheckKissInterlock(struct PORTCONTROL * PORT, int Exclusive)
{
// This checks for interlocked kiss and other ports. Returns 1 if attach/connect not allowed
// If Exclusive is not set allow connects on specified port up to l2limit,
// If Exclusive is set also don't allow any connects on specified port.
// Generally use Exclusive if locking a port that doesn't allow shared access, eg ARDOP, VARAus
// Maybe only Exclusive is needed, and just check session mode ports. Sharing of KISS ports is controlled by USERS
int Interlock = PORT->PORTINTERLOCK;
if (Interlock == 0)
return 0; // No locking
PORT = PORTTABLE;
if (Exclusive)
{
while(PORT)
{
if (PORT->TNC)
{
struct TNCINFO * TNC = PORT->TNC;
if (Interlock == TNC->RXRadio || Interlock == TNC->TXRadio) // Same Group
{
// See if port in use
int n;
for (n = 0; n <= 26; n++)
{
if (TNC->PortRecord->ATTACHEDSESSIONS[n])
{
return TNC->Port; ; // Refuse Connect
}
}
}
}
PORT = PORT->PORTPOINTER;
}
}
return 0; // ok to connect
}
int seeifInterlockneeded(struct PORTCONTROL * PORT)
{
// Can we just call SuspendOtherPorts - it won't do any harm if already suspended
// No, at that needs a TNC Record, so duplicate code here
int i;
int Interlock = PORT->PORTINTERLOCK;
struct TNCINFO * TNC;
if (Interlock == 0)
return 0; // No locking
for (i = 1; i <= MAXBPQPORTS; i++)
{
TNC = TNCInfo[i];
if (TNC)
if (Interlock == TNC->RXRadio || Interlock == TNC->TXRadio) // Same Group
if (TNC->SuspendPortProc && TNC->PortRecord->PORTCONTROL.PortSuspended == FALSE)
TNC->SuspendPortProc(TNC, TNC);
}
return 0;
}
int seeifUnlockneeded(struct _LINKTABLE * LINK)
{
// We need to see if any other links are active on any interlocked KISS ports. If not, release the lock
int i;
int links = 0;
int Interlock;
struct TNCINFO * TNC;
struct PORTCONTROL * PORT = LINK->LINKPORT;
if (PORT == NULL)
return 0;
// Should only be called for KISS links, but just in case
if (PORT->PORTTYPE > 12) // INTERNAL or EXTERNAL?
return 0; // Not KISS Port
Interlock = PORT->PORTINTERLOCK;
if (Interlock == 0)
return 0; // No locking
// Count all L2 links on interlocked KISS ports
PORT = PORTTABLE;
while(PORT)
{
if (PORT->PORTTYPE <= 12) // INTERNAL or EXTERNAL?
if (Interlock == PORT->PORTINTERLOCK)
links += COUNTLINKS(PORT->PORTNUMBER);
PORT = PORT->PORTPOINTER;
}
if (links > 1) // must be the one we are closing
return 0; // Keep lock
for (i = 1; i <= MAXBPQPORTS; i++)
{
TNC = TNCInfo[i];
if (TNC)
if (Interlock == TNC->RXRadio || Interlock == TNC->TXRadio) // Same Group
if (TNC->ReleasePortProc && TNC->PortRecord->PORTCONTROL.PortSuspended == TRUE)
TNC->ReleasePortProc(TNC, TNC);
}
return 0;
}

View File

@ -23,7 +23,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "bpqmail.h"
void SendMessageReadEvent(struct UserInfo * user, struct MsgInfo * Msg);
void SendMessageReadEvent(char * call, struct MsgInfo * Msg);
VOID ProcessMBLLine(CIRCUIT * conn, struct UserInfo * user, UCHAR* Buffer, int len)

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory="c:\linbpq"
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor="0"
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="SKIGACER"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="SKIGACER"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1317,6 +1317,10 @@ FULLHA:
{
int i = 0;
// Log My HA for debugging
Logprintf(LOG_BBS, conn, '?', "Routing Trace. Check if reached correct area My HA is %s", HRoute);
// All elements of Helements must match Myelements
while (MyElements[i] && HElements[i]) // Until one set runs out
@ -1409,6 +1413,9 @@ NOHA:
// So if SendPtoMultiple is set I think I need to find the best depth then send to all with the same depth
// If none are found on HA match drop through.
// But this means a message at the @BBS call will be forwarded without checking the Implied AT. So do that first
if (SendPtoMultiple && Msg->type == 'P')
{
struct UserInfo * bestbbs = NULL;
@ -1425,6 +1432,16 @@ NOHA:
{
ForwardingInfo = bbs->ForwardingInfo;
// Check Implied AT
if ((strcmp(ATBBS, bbs->Call) == 0)) // @BBS = BBS
{
Logprintf(LOG_BBS, conn, '?', "Routing Trace %s Matches implied AT %s", ATBBS, bbs->Call);
CheckAndSend(Msg, conn, bbs);
return 1;
}
depth = CheckBBSHElements(Msg, bbs, ForwardingInfo, ATBBS, &HElements[0]);
if (depth)

View File

@ -210,7 +210,12 @@ KC6OAR*>ID:
Port &= 0x7F;
if ((((uint64_t)1 << (Port - 1)) & Mask) == 0) // Check MMASK
{
if (msg->Padding[0] == '[')
msg->Padding[0] = 0;
return 0;
}
// We now pass Text format monitoring from non-ax25 drivers through this code
@ -535,6 +540,12 @@ KC6OAR*>ID:
}
}
}
if (msg->Padding[0] == '[')
Output += sprintf((char *)Output, " %s", msg->Padding);
msg->Padding[0] = 0;
if (Info)
{
// We have an info frame

View File

@ -8941,7 +8941,7 @@ VOID FLRIGThread(struct RIGPORTINFO * PORT)
setsockopt(PORT->remoteSock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
setsockopt(PORT->remoteSock, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&bcopt, 4);
if (connect(PORT->remoteSock,(LPSOCKADDR) &PORT->remoteDest,sizeof(PORT->remoteDest)) == 0)
if (connect(PORT->remoteSock,(LPSOCKADDR) &PORT->remoteDest, sizeof(PORT->remoteDest)) == 0)
{
//
// Connected successful

View File

@ -4297,16 +4297,22 @@ VOID PTCSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{
struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
sprintf(STREAM->CmdSet, "I%s\r", "SCSPTC"); // Should prevent connects
Debugprintf("SCS Pactor CMDSet = %s", STREAM->CmdSet);
// Debugprintf("SCS Pactor CMDSet = %s", STREAM->CmdSet);
}
VOID PTCReleasePort(struct TNCINFO * TNC)
{
struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
if (TNC->UseAPPLCallsforPactor && TNC->RIG && TNC->RIG != &TNC->DummyRig
@ -4315,7 +4321,7 @@ VOID PTCReleasePort(struct TNCINFO * TNC)
else
sprintf(STREAM->CmdSet, "I%s\r", TNC->NodeCall);
Debugprintf("SCS Pactor CMDSet = %s", STREAM->CmdSet);
// Debugprintf("SCS Pactor CMDSet = %s", STREAM->CmdSet);
}

View File

@ -109,6 +109,9 @@ VOID TRKSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{
struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
sprintf(STREAM->CmdSet, "\1\1\1IDSPTNC");
}
@ -117,6 +120,9 @@ VOID TRKReleasePort(struct TNCINFO * TNC)
{
struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
sprintf(STREAM->CmdSet, "\1\1\1I%s", TNC->NodeCall);
}

View File

@ -350,12 +350,17 @@ VOID UZ7HOSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
return;
TNC->PortRecord->PORTCONTROL.PortSuspended = TRUE;
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
RegisterAPPLCalls(TNC, TRUE);
}
VOID UZ7HOReleasePort(struct TNCINFO * TNC)
{
TNC->PortRecord->PORTCONTROL.PortSuspended = FALSE;
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
RegisterAPPLCalls(TNC, FALSE);
}

214
VARA.c
View File

@ -258,6 +258,9 @@ static int ProcessLine(char * buf, int Port)
*ptr = 0;
}
else if (_memicmp(buf, "VARAAC", 6) == 0)
TNC->VaraACAllowed = atoi(&buf[7]);
else if (_memicmp(buf, "BW2300", 6) == 0)
{
TNC->ARDOPCurrentMode[0] = 'W'; // Save current state for scanning
@ -282,6 +285,7 @@ static int ProcessLine(char * buf, int Port)
TNC->DefaultMode = TNC->WL2KMode = 52;
else if (standardParams(TNC, buf) == FALSE)
strcat(TNC->InitScript, buf);
}
return (TRUE);
@ -304,12 +308,31 @@ static SOCKADDR_IN rxaddr;
static int addrlen=sizeof(sinx);
void doVarACSend(struct TNCINFO * TNC)
{
int hdrlen;
int txlen = strlen(TNC->VARACMsg);
char txbuff[64];
txlen--; // remove cr
hdrlen = sprintf(txbuff, "%d ", txlen);
send(TNC->TCPDataSock, txbuff, hdrlen, 0); // send length
send(TNC->TCPDataSock, TNC->VARACMsg, txlen, 0);
free (TNC->VARACMsg);
TNC->VARACMsg = 0;
TNC->VARACSize = 0;
TNC->VarACTimer = 0;
return ;
}
static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
size_t datalen;
PMSGWITHLEN buffptr;
char txbuff[500];
unsigned int bytes,txlen=0;
unsigned int bytes;
size_t txlen=0;
size_t Param;
HKEY hKey=0;
struct TNCINFO * TNC = TNCInfo[port];
@ -342,6 +365,14 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
// approx 100 mS Timer. May now be needed, as Poll can be called more frequently in some circumstances
if (TNC->VarACTimer)
{
TNC->VarACTimer--;
if (TNC->VarACTimer == 0)
doVarACSend(TNC);
}
// G7TAJ's code to record activity for stats display
if ( TNC->BusyFlags && CDBusy )
@ -528,7 +559,45 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
PMSGWITHLEN buffptr = Q_REM(&TNC->Streams[0].BPQtoPACTOR_Q);
txlen = (int)buffptr->Len;
memcpy(txbuff, buffptr->Data, txlen);
if(TNC->VaraACMode || TNC->VaraModeSet == 0)
{
// Send in varac format -
// 5 Hello, 15 de G8 BPQ
buffptr->Data[txlen] = 0; // Null terminate
STREAM->BytesTXed += txlen;
WritetoTrace(TNC, buffptr->Data, txlen);
// Always add to stored data and set timer. If it expires send message
if (TNC->VARACMsg == 0)
{
TNC->VARACMsg = zalloc(4096);
TNC->VARACSize = 4096;
}
else
{
if (strlen(TNC->VARACMsg) + txlen >= (TNC->VARACSize - 10))
{
TNC->VARACSize += 4096;
TNC->VARACMsg = realloc(TNC->VARACMsg, TNC->VARACSize);
}
}
strcat(TNC->VARACMsg, buffptr->Data);
TNC->VarACTimer = 10; // One second
return 0;
}
else
memcpy(txbuff, buffptr->Data, txlen);
bytes = VARASendData(TNC, &txbuff[0], txlen);
STREAM->BytesTXed += bytes;
ReleaseBuffer(buffptr);
@ -565,8 +634,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (buffptr == 0) return (0); // No buffers, so ignore
buffptr->Len=36;
memcpy(buffptr->Data,"No Connection to VARA TNC\r", 36);
buffptr->Len = sprintf(buffptr->Data,"No Connection to VARA TNC\r");
C_Q_ADD(&TNC->WINMORtoBPQ_Q, buffptr);
@ -595,11 +663,56 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (TNC->Streams[0].Connected)
{
unsigned char txbuff[512];
STREAM->PacketsSent++;
bytes=send(TNC->TCPDataSock, buff->L2DATA, txlen, 0);
STREAM->BytesTXed += bytes;
if(TNC->VaraACMode == 0 && TNC->VaraModeSet == 1)
{
// Normal Send
memcpy(txbuff, buff->L2DATA, txlen);
bytes=send(TNC->TCPDataSock, txbuff, txlen, 0);
STREAM->BytesTXed += bytes;
WritetoTrace(TNC, buff->L2DATA, txlen);
return 0;
}
// Send in varac format - len space data. No cr on end, but is implied
// 5 Hello
// I think we have to send a whole message (something terminated with a new line)
// may need to combine packets. Also I think we need to combine seqential sends
// (eg CTEXT and SID)
buff->L2DATA[txlen] = 0; // Null terminate
STREAM->BytesTXed += txlen;
WritetoTrace(TNC, buff->L2DATA, txlen);
// Always add to stored data and set timer. If it expires send message
if (TNC->VARACMsg == 0)
{
TNC->VARACMsg = zalloc(4096);
TNC->VARACSize = 4096;
}
else
{
if (strlen(TNC->VARACMsg) + txlen >= (TNC->VARACSize - 10))
{
TNC->VARACSize += 4096;
TNC->VARACMsg = realloc(TNC->VARACMsg, TNC->VARACSize);
}
}
strcat(TNC->VARACMsg, buff->L2DATA);
TNC->VarACTimer = 10; // One second
return 0;
}
else
{
@ -657,7 +770,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (buffptr)
{
buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "VARA} OK\r");
C_Q_ADD(&TNC->WINMORtoBPQ_Q, buffptr);
C_Q_ADD(&TNC->WINMORtoBPQ_Q, buffptr);
}
return 0;
}
@ -979,12 +1092,19 @@ static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL)
VOID VARASuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{
TNC->PortRecord->PORTCONTROL.PortSuspended = TRUE;
VARASendCommand(TNC, "LISTEN OFF\r", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
}
VOID VARAReleasePort(struct TNCINFO * TNC)
{
TNC->PortRecord->PORTCONTROL.PortSuspended = FALSE;
VARASendCommand(TNC, "LISTEN ON\r", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
}
@ -1730,6 +1850,15 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
TNC->Busy = TNC->BusyHold * 10; // BusyHold delay
TNC->PTTonTime = GetTickCount();
// Cancel Busy timer (stats include ptt on time in port active)
if (TNC->BusyonTime)
{
TNC->BusyActivemS += (GetTickCount() - TNC->BusyonTime);
TNC->BusyonTime = 0;
}
if (TNC->PTTMode)
Rig_PTT(TNC, TRUE);
@ -1740,6 +1869,12 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
{
// Debugprintf("PTT Off");
if (TNC->PTTonTime)
{
TNC->PTTActivemS += (GetTickCount() - TNC->PTTonTime);
TNC->PTTonTime = 0;
}
if (TNC->PTTMode)
Rig_PTT(TNC, FALSE);
@ -1760,6 +1895,8 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
TNC->BusyFlags |= CDBusy;
TNC->Busy = TNC->BusyHold * 10; // BusyHold delay
TNC->BusyonTime = GetTickCount();
MySetWindowText(TNC->xIDC_CHANSTATE, "Busy");
strcpy(TNC->WEB_CHANSTATE, "Busy");
@ -1775,6 +1912,13 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
else
strcpy(TNC->WEB_CHANSTATE, "Clear");
if (TNC->BusyonTime)
{
TNC->BusyActivemS += (GetTickCount() - TNC->BusyonTime);
TNC->BusyonTime = 0;
}
MySetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE);
TNC->WinmorRestartCodecTimer = time(NULL);
return;
@ -1879,6 +2023,17 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
if (TNC->VARACMsg)
free(TNC->VARACMsg);
TNC->VaraACMode = 0;
TNC->VARACMsg = 0;
TNC->VARACSize = 0;
if (TNC->VaraACAllowed == 0)
TNC->VaraModeSet = 1; // definitly not varaac
else
TNC->VaraModeSet = 0; // Don't know yet
strcpy(TNC->WEB_MODE, "");
if (strstr(Buffer, "2300"))
@ -1937,6 +2092,8 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
TNC->SessionTimeLimit = TNC->DefaultSessionTimeLimit; // Reset Limit
// Only allow VarAC mode for incomming sessions
ProcessIncommingConnectEx(TNC, Call, 0, (TNC->NetRomMode == 0), TRUE);
SESS = TNC->PortRecord->ATTACHEDSESSIONS[0];
@ -2125,7 +2282,6 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (TNC->NetRomTxLen)
{
STREAM->PacketsSent++;
bytes = send(TNC->TCPDataSock, TNC->NetRomTxBuffer, TNC->NetRomTxLen, 0);
@ -2137,6 +2293,9 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
}
else
{
TNC->VaraACMode = 0;
TNC->VaraModeSet = 1; // Don't allow connect to VaraAC
buffptr = GetBuff();
if (buffptr == 0)
@ -2592,6 +2751,45 @@ VOID VARAProcessDataPacket(struct TNCINFO * TNC, UCHAR * Data, int Length)
STREAM->BytesTXed, STREAM->BytesRXed,STREAM->BytesOutstanding);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
// if VARAAC Mode, remove byte count from front and add cr
// could possibly be longer than buffer size
if (TNC->VaraModeSet == 0) // Could be normal or VaraAC
{
unsigned char *ptr = memchr(Data, ' ', Length); // contains a space
if (ptr)
{
int ACLen = atoi(Data);
int lenLen = (ptr - Data) + 1;
if (ACLen == (Length - lenLen))
TNC->VaraACMode = 1; // AC Mode
}
TNC->VaraModeSet = 1; // Know which mode
}
if (TNC->VaraACMode)
{
char * lenp;
char * msg;
int len;
lenp = Data;
msg = strlop(lenp, ' ');
len = atoi(lenp);
if (len != strlen(msg))
return;
msg[len++] = 13;
msg[len] = 0;
Length = len;
memmove(Data, msg, len + 1);
}
// May need to fragment
while (Length)

View File

@ -10,14 +10,14 @@
#endif
#define KVers 6,0,24,42
#define KVerstring "6.0.24.42\0"
#define KVers 6,0,24,45
#define KVerstring "6.0.24.45\0"
#ifdef CKernel
#define Vers KVers
#define Verstring KVerstring
#define Datestring "August 2024"
#define Datestring "October 2024"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2024 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0"

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="LAPTOP-Q6S4RP5Q"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="8.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
>
<DebugSettings
Command="$(TargetPath)"
WorkingDirectory=""
CommandArguments=""
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="NOTTSDESKTOP"
RemoteCommand=""
HttpUrl=""
PDBPath=""
SQLDebugging=""
Environment=""
EnvironmentMerge="true"
DebuggerFlavor=""
MPIRunCommand=""
MPIRunArguments=""
MPIRunWorkingDirectory=""
ApplicationCommand=""
ApplicationArguments=""
ShimCommand=""
MPIAcceptMode=""
MPIAcceptFilter=""
/>
</Configuration>
</Configurations>
</VisualStudioUserFile>

View File

@ -600,6 +600,8 @@ typedef struct PORTCONTROL
UCHAR AVSENDING; // LAST MINUTE
UCHAR AVACTIVE;
char PktFlags[64]; // Decode stts rom QtSM
char PORTTYPE; // H/W TYPE
// 0 = ASYNC, 2 = PC120, 4 = DRSI
// 6 = TOSH, 8 = QUAD, 10 = RLC100
@ -691,6 +693,13 @@ typedef struct PORTCONTROL
time_t SmartIDInterval; // Smart ID Interval (Secs)
int SendtoM0LTEMap;
uint64_t PortFreq; // Configured freq
char * M0LTEMapInfo;
int QtSMPort;
BOOL QtSMConnected;
int StatsPointer;
UCHAR * TX; // % Sending
UCHAR * BUSY; // % Active (Normally DCD active or TX)
} PORTCONTROLX, *PPORTCONTROL;
@ -704,7 +713,7 @@ typedef struct FULLPORTDATA
typedef struct KISSINFO
{
struct PORTCONTROL PORT;
struct PORTCONTROL PORT;
int LINKSTS; // CURRENT STATE
UINT * CURALP; // CURRENT BUFFER
@ -735,6 +744,19 @@ typedef struct KISSINFO
UCHAR * KISSCMD; // Commands to be sent when port opened
int KISSCMDLEN;
int PTTMode; // PTT Mode Flags
int PTTState; // Current State
uint64_t PTTActivemS; // For Stats
uint64_t PTTonTime; //
uint64_t BusyActivemS; // For channel busy stats
uint64_t BusyonTime;
char * QtSMModem;
int QtSMFreq;
int QtSMStats; // Set if stats received as KISS Command
// UCHAR WIN32INFO[16]; // FOR WINDOWS DRIVER
} *PKISSINFO;

View File

@ -46,6 +46,8 @@ int upnpInit();
void AISTimer();
void ADSBTimer();
VOID SendSmartID(struct PORTCONTROL * PORT);
int CanPortDigi(int Port);
int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
#include "configstructs.h"
@ -368,7 +370,8 @@ VOID EXTTX(PEXTPORTDATA PORTVEC, MESSAGE * Buffer)
if (LINK->L2TIMER)
LINK->L2TIMER = LINK->L2TIME;
Buffer->Linkptr = 0; // CLEAR FLAG FROM BUFFER
if (PORT->TNC == 0 || PORT->TNC->Hardware != H_KISSHF)
Buffer->Linkptr = 0; // CLEAR FLAG FROM BUFFER
}
PORTVEC->PORT_EXT_ADDR(2, PORT->PORTNUMBER, Buffer);
@ -1081,6 +1084,10 @@ BOOL Start()
PORT->SendtoM0LTEMap = PortRec->SendtoM0LTEMap;
PORT->PortFreq = PortRec->PortFreq;
PORT->M0LTEMapInfo = PortRec->M0LTEMapInfo;
PORT->QtSMPort = PortRec->QtSMPort;
if (PortRec->BBSFLAG) // Appl 1 not permitted - BBSFLAG=NOBBS
PORT->PERMITTEDAPPLS &= 0xfffffffe; // Clear bottom bit

View File

@ -365,7 +365,7 @@ static char *pkeywords[] =
"BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY",
"UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE",
"IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE",
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq"}; /* parameter keywords */
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort"}; /* parameter keywords */
static void * poffset[] =
{
@ -379,7 +379,7 @@ static void * poffset[] =
&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,
&xxp.IGNOREUNLOCKED, &xxp.INP3ONLY, &xxp.TCPPORT, &xxp.RIGPORT, &xxp.PERMITTEDAPPLS, &xxp.Hide,
&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq}; /* offset for corresponding data in config file */
&xxp.SmartID, &xxp.KissParams, &xxp.SendtoM0LTEMap, &xxp.PortFreq, &xxp.M0LTEMapInfo, &xxp.QtSMPort}; /* offset for corresponding data in config file */
static int proutine[] =
{
@ -393,7 +393,7 @@ static int proutine[] =
0, 1, 2, 18, 15, 16, 2,
1, 17, 1, 1, 1, 1, 2,
2, 2, 1, 1, 19, 2,
1, 20, 1, 21}; /* routine to process parameter */
1, 20, 1, 21, 22, 1}; /* routine to process parameter */
int PPARAMLIM = sizeof(proutine)/sizeof(int);
@ -2237,7 +2237,10 @@ int decode_port_rec(char * rec)
cn = int64_value(poffset[i], value, rec); /* INTEGER VALUES */
break;
case 22:
xxp.M0LTEMapInfo = _strdup(value);
cn = 1;
break;
case 9:

View File

@ -1,40 +0,0 @@
[NETWORK]
#network settings
tncport = 3004
[STATION]
#station settings
mycall = GM8BPQ-2
mygrid = IO68VL
[AUDIO]
#audio settings
rx = 8
tx = 16
txaudiolevel = 125
[RADIO]
#radio settings
radiocontrol = disabled
devicename = RIG_MODEL_NETRIGCTL
deviceport = COM99
serialspeed = 19200
pttprotocol = USB
pttport = COM99
data_bits = 8
stop_bits = 1
handshake = None
rigctld_ip = 127.0.0.1
rigctld_port = 0
[TNC]
#tnc settings
scatter = False
fft = False
narrowband = True
fmin = -50.0
fmax = 50.0
qrv = True
rxbuffersize = 16
explorer = False

View File

@ -79,6 +79,8 @@ struct PORTCONFIG
unsigned char * KissParams;
int SendtoM0LTEMap;
uint64_t PortFreq;
char * M0LTEMapInfo;
int QtSMPort;
};
struct ROUTECONFIG

356
kiss.c
View File

@ -44,6 +44,8 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
//#include <netax25/ttyutils.h>
//#include <netax25/daemon.h>
#include <netinet/tcp.h>
#ifdef MACBPQ
#define NOI2C
#endif
@ -84,6 +86,7 @@ int i2cPoll(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO);
#define FESC 0xDB
#define TFEND 0xDC
#define TFESC 0xDD
#define QTSMKISSCMD 7
#define STX 2 // NETROM CONTROL CODES
#define ETX 3
@ -112,7 +115,8 @@ int ConnecttoTCP(NPASYINFO ASY);
int KISSGetTCPMessage(NPASYINFO ASY);
VOID CloseKISSPort(struct PORTCONTROL * PortVector);
int ReadCOMBlockEx(HANDLE fd, char * Block, int MaxLength, BOOL * Error);
void processDRATSFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr);
void processDRATSFrame(unsigned char * Message, int Len, void * sockptr);
VOID ConnecttoQtSM(struct PORTCONTROL * PORT);
extern struct PORTCONTROL * PORTTABLE;
extern int NUMBEROFPORTS;
@ -801,11 +805,14 @@ VOID KISSINIT(struct KISSINFO * KISS)
PORTCONTROLX * PORT = (struct PORTCONTROL *)KISS;
struct KISSINFO * FIRSTCHAN = NULL;
PORT->PORTINTERLOCK = 0; // CANT USE INTERLOCK ON KISS
if (PORT->CHANNELNUM == 0)
PORT->CHANNELNUM = 'A';
// As transition aid warn if Interlock is used on kiss port
if (PORT->PORTINTERLOCK)
WritetoConsoleLocal("Interlock defined on KISS port - is this intended? ");
FIRSTCHAN = (struct KISSINFO *)CHECKIOADDR(PORT); // IF ANOTHER ENTRY FOR THIS ADDR
// MAY BE CHANGED IN ANOTHER CHANNEL USED
@ -1510,7 +1517,7 @@ SeeifMore:
// ACK FRAME. WE DONT SUPPORT ACK REQUIRED FRAMES AS A SLAVE - THEY ARE ONLY ACCEPTED BY TNCS
struct _LINKTABLE * LINK;
UINT ACKWORD = Port->RXMSG[1] | Port->RXMSG[2] << 8;
int ACKWORD = Port->RXMSG[1] | Port->RXMSG[2] << 8;
if (ACKWORD < MAXLINKS)
{
@ -1524,6 +1531,66 @@ SeeifMore:
if (Port->RXMSG[0] & 0x0f) // Not Data
{
// See if QTSM Status Packet
if ((Port->RXMSG[0] & 0x0f) == QTSMKISSCMD)
{
unsigned char * Msg = &Port->RXMSG[1];
int Chan = Port->RXMSG[0] & 0xf0;
len--;
Msg[len] = 0;
while (KISS->OURCTRL != Chan)
{
KISS = KISS->SUBCHAIN;
if (KISS == NULL)
goto SeeifMore; // SEE IF ANYTHING ELSE
}
// ok, KISS now points to our port
// Debugprintf("%d %x %s", PORT->PORTNUMBER, Port->RXMSG[0], Msg);
if (memcmp(Msg, "STATS ", 6) == 0)
{
// Save busy
int TX, DCD;
char * Msg1 = strlop(&Msg[6], ' ');
TX = atoi(&Msg[6]);
if (Msg1)
{
DCD = atoi(Msg1);
KISS->PORT.AVSENDING = TX;
KISS->PORT.AVACTIVE = DCD + TX;
KISS->QtSMStats = 1;
}
}
else if (memcmp(Msg, "PKTINFO ", 8) == 0)
{
// Save State
char * Msg1 = &Msg[8];
if (strlen(Msg) > 63)
Msg[63] = 0;
strcpy(PORT->PktFlags, Msg1);
}
else
Debugprintf("Unknown Command %d %x %s", PORT->PORTNUMBER, Port->RXMSG[0], Msg);
// Note status applies to NEXT data packet received
goto SeeifMore;
}
// If a reply to a manual KISS command(Session set and time not too long ago)
// send reponse to terminal
@ -1618,6 +1685,8 @@ SeeifMore:
PORT->RXERRORS++;
Debugprintf("KISS Checksum Error");
PORT->PktFlags[0] = 0;
goto SeeifMore; // SEE IF ANYTHING ELSE
}
len--; // Remove Checksum
@ -1630,7 +1699,12 @@ SeeifMore:
KISS = KISS->SUBCHAIN;
if (KISS == NULL)
goto SeeifMore; // SEE IF ANYTHING ELSE
{
// Unknown channel - clear any status info
PORT->PktFlags[0] = 0;
goto SeeifMore; // SEE IF ANYTHING ELSE
}
}
// ok, KISS now points to our port
@ -1648,6 +1722,13 @@ SeeifMore:
PutLengthinBuffer((PDATAMESSAGE)Buffer, len); // Needed for arm5 portability
if (PORT->PktFlags[0])
strcpy(Buffer->Padding, PORT->PktFlags);
else
Buffer->Padding[0] = 0;
PORT->PktFlags[0] = 0;
/*
// Randomly drop packets
@ -1893,6 +1974,10 @@ VOID ConnecttoTCPThread(NPASYINFO ASY)
if (KISS && KISS->KISSCMD && KISS->KISSCMDLEN)
send(sock, KISS->KISSCMD, KISS->KISSCMDLEN, 0);
// Try to open Mgmt Port
ConnecttoQtSM(&KISS->PORT);
continue;
}
else
@ -2030,3 +2115,264 @@ int KISSGetTCPMessage(NPASYINFO ASY)
}
return 0;
}
// Interface to QtSM Managmemt Interface
VOID QtSMThread(struct PORTCONTROL * PORT);
VOID ConnecttoQtSM(struct PORTCONTROL * PORT)
{
if (PORT && PORT->QtSMPort)
_beginthread(QtSMThread, 0, (void *)PORT);
return ;
}
VOID QtSMThread(struct PORTCONTROL * PORT)
{
// This is the Managemt Interface in QtSM. It receives PTT ON/OFF msgs from QtSM and allows changing modem mode and freq.
// Also will collect link usage stats
char Msg[255];
int err, i, ret;
u_long param = 1;
BOOL bcopt = TRUE;
fd_set readfs;
fd_set errorfs;
struct timeval timeout;
SOCKET qtsmsock;
struct sockaddr_in qtsmaddr; // For QtSM Management Session
qtsmaddr.sin_family = AF_INET;
memcpy(&qtsmaddr.sin_addr.s_addr, &PORT->PORTIPADDR, 4); // Same as for KISS connection
qtsmaddr.sin_port = htons(PORT->QtSMPort);
qtsmsock = 0;
qtsmsock = socket(AF_INET,SOCK_STREAM,0);
if (qtsmsock == INVALID_SOCKET)
{
i=sprintf(Msg, "Socket Failed for QtSM Mgmt socket - error code = %d\r\n", WSAGetLastError());
WritetoConsoleLocal(Msg);
return;
}
setsockopt(qtsmsock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
setsockopt(qtsmsock, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&bcopt, 4);
if (connect(qtsmsock,(LPSOCKADDR) &qtsmaddr,sizeof(qtsmaddr)) == 0)
{
//
// Connected successful
//
ioctl(qtsmsock, FIONBIO, &param);
PORT->QtSMConnected = TRUE;
}
else
{
err = WSAGetLastError();
sprintf(Msg, "Connect Failed for QtSM Mgmt - error code = %d Port %d\r\n",
err, PORT->QtSMPort);
WritetoConsoleLocal(Msg);
closesocket(qtsmsock);
qtsmsock = 0;
PORT->QtSMConnected = FALSE;
return;
}
PORT->QtSMConnected = TRUE;
while (PORT->QtSMConnected)
{
FD_ZERO(&readfs);
FD_ZERO(&errorfs);
FD_SET(qtsmsock,&readfs);
FD_SET(qtsmsock,&errorfs);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
ret = select((int)qtsmsock + 1, &readfs, NULL, &errorfs, &timeout);
if (ret == SOCKET_ERROR)
{
Debugprintf("QTSM Mgmt Select failed %d ", WSAGetLastError());
goto Lost;
}
if (ret > 0)
{
// See what happened
if (FD_ISSET(qtsmsock, &readfs))
{
char Buffer[512];
char * Line = Buffer;
char * Rest;
int InputLen = recv(qtsmsock, Buffer, 500, 0);
if (InputLen == 0 || InputLen == SOCKET_ERROR)
{
goto Lost;
}
Buffer[InputLen] = 0;
while(Line && Line[0])
{
Rest = strlop(Line, '\r');
// Need to extract lines from data
if (strcmp(Line, "Ok") == 0)
{
}
else if (memcmp(Line, "PTT ", 4) == 0)
{
// PTT 43 OFF
int Port = atoi(&Line[4]);
char * State = strlop(&Line[4], ' ');
struct KISSINFO * KISS = (struct KISSINFO *)GetPortTableEntryFromPortNum(Port);
if (strcmp(State, "ON") == 0)
{
KISS->PTTonTime = GetTickCount();
// Cancel Busy timer (stats include ptt on time in port active)
if (KISS->BusyonTime)
{
KISS->BusyActivemS += (GetTickCount() - KISS->BusyonTime);
KISS->BusyonTime = 0;
}
// if (KISS->PTTMode)
// Rig_PTT(TNC, TRUE);
}
else if (strcmp(State, "OFF") == 0)
{
if (KISS->PTTonTime)
{
KISS->PTTActivemS += (GetTickCount() - KISS->PTTonTime);
KISS->PTTonTime = 0;
}
// if (KISS->PTTMode)
// Rig_PTT(TNC, FALSE);
}
}
else if (strcmp(Line, "Connected to QtSM") == 0)
{
char Msg[64];
int Len;
// We need tp send a QtSMPort message for each Channel sharing thia connection
// Note struct KISSINFO and struct PORTCONTROL are different mappings of the same data
struct KISSINFO * KISS = (struct KISSINFO *)PORT;
while (KISS)
{
Len = sprintf(Msg, "QtSMPort %d %d\r", KISS->PORT.CHANNELNUM - '@', KISS->PORT.PORTNUMBER);
send(qtsmsock, Msg, Len, 0);
Len = sprintf(Msg, "Modem %d\r", KISS->PORT.CHANNELNUM - '@');
send(qtsmsock, Msg, Len, 0);
KISS = KISS->SUBCHAIN;
}
}
else if (memcmp(Line, "Port ", 5) == 0)
{
// Port 1 Freq 1500 Modem BPSK AX.25 300bd
int Port, chan, Freq;
char * Modem;
struct KISSINFO * KISS;
Port = atoi(&Line[5]);
Line = strlop(&Line[9], ' ');
chan = atoi(Line);
Freq = atoi(&Line[6]);
Modem = strlop(&Line[13], ' ');
KISS = (struct KISSINFO *)GetPortTableEntryFromPortNum(Port);
if (KISS->QtSMModem)
free(KISS->QtSMModem);
KISS->QtSMModem = _strdup(Modem);
KISS->QtSMFreq = Freq;
}
else if (memcmp(Line, "XXSTATS ", 6) == 0)
{
// STATS PORT PTT BUSY
int Port, PTT, Busy;
struct PORTCONTROL * MPORT;
Port = atoi(&Line[6]);
Line = strlop(&Line[6], ' ');
PTT = atoi(Line);
Line = strlop(Line, ' ');
Busy = atoi(Line);
MPORT = GetPortTableEntryFromPortNum(Port);
if (MPORT)
{
MPORT->AVACTIVE = Busy + PTT;
MPORT->AVSENDING = PTT;
}
}
else
Debugprintf("Unexpected QtSM Message %s", Line);
Line = Rest;
}
}
if (FD_ISSET(qtsmsock, &errorfs))
{
Lost:
sprintf(Msg, "QtSM Mgmt Connection lost for TCP Port %d Port %d\r\n", PORT->QtSMPort, PORT->PORTNUMBER);
WritetoConsoleLocal(Msg);
PORT->QtSMConnected = FALSE;
closesocket(qtsmsock);
qtsmsock = 0;
return;
}
continue;
}
else
{
}
}
sprintf(Msg, "QtSM Mgmt Thread Terminated TCP Port %d Port %d\r\n", PORT->QtSMPort, PORT->PORTNUMBER);
WritetoConsoleLocal(Msg);
}

View File

@ -67,7 +67,7 @@ static BOOL ReadConfigFile(int Port);
static int ProcessLine(char * buf,int Port, BOOL CheckPort);
int WritetoConsoleLocal(char * buff);
int ExtProc(int fn, int port,unsigned char * buff)
static size_t ExtProc(int fn, int port, PMESSAGE buff)
{
int len,txlen=0,res;
char txbuff[500];
@ -110,9 +110,8 @@ int ExtProc(int fn, int port,unsigned char * buff)
len-=3;
memcpy(&buff[7],&rxbuff[19],len);
len+=5;
memcpy(&buff->DEST, &rxbuff[19], len);
len += (1 + sizeof(void *));
}
else
{
@ -121,14 +120,11 @@ int ExtProc(int fn, int port,unsigned char * buff)
if ((len < 16) || (len > 320)) return 0; // Probably RLI Mode Frame
len-=3;
memcpy(&buff[7],&rxbuff[16],len);
len+=5;
memcpy(&buff->DEST, &rxbuff[16], len);
len += (1 + sizeof(void *));
}
buff[5]=(len & 0xff);
buff[6]=(len >> 8);
PutLengthinBuffer((PDATAMESSAGE)buff, len);
return 1;
@ -140,9 +136,8 @@ int ExtProc(int fn, int port,unsigned char * buff)
// RLI MODE - An extra 3 bytes before len, seem to be 00 00 41
{
txlen=(buff[6]<<8) + buff[5]; // BPQEther is DOS-based - chain word is 2 bytes
txlen-=2;
txlen = GetLengthfromBuffer((PDATAMESSAGE)buff); // 2 for CRC
txlen -= (sizeof(void *) - 2);
txbuff[16]=0x41;
txbuff[17]=(txlen & 0xff);
txbuff[18]=(txlen >> 8);
@ -150,14 +145,14 @@ int ExtProc(int fn, int port,unsigned char * buff)
if (txlen < 1 || txlen > 400)
return 0;
memcpy(&txbuff[19],&buff[7],txlen);
memcpy(&txbuff[19], &buff->DEST[0], txlen);
}
else
{
txlen=(buff[6]<<8) + buff[5]; // BPQEther is DOS-based - chain word is 2 bytes
txlen-=2;
txlen = GetLengthfromBuffer((PDATAMESSAGE)buff); // 2 for CRC
txlen -= (sizeof(void *) - 2);
txbuff[14]=(txlen & 0xff);
txbuff[15]=(txlen >> 8);
@ -166,7 +161,7 @@ int ExtProc(int fn, int port,unsigned char * buff)
return 0;
memcpy(&txbuff[16],&buff[7],txlen);
memcpy(&txbuff[16], &buff->DEST[0], txlen);
}
memcpy(&txbuff[0], &IF->EthDest[0],6);
@ -210,7 +205,7 @@ int ExtProc(int fn, int port,unsigned char * buff)
}
UINT ETHERExtInit(struct PORTCONTROL * PortEntry)
void * ETHERExtInit(struct PORTCONTROL * PortEntry)
{
// Can have multiple ports, each mapping to a different Ethernet Adapter
@ -299,7 +294,7 @@ UINT ETHERExtInit(struct PORTCONTROL * PortEntry)
// n=sprintf(buf,"Using %s Adapter = Interface %d\r", ifr.ifr_ifindex);
// WritetoConsole(buf);
return ((int) ExtProc);
return (ExtProc);
}

View File

@ -158,13 +158,12 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
int request_token(char * response)
{
Token * token = generate_token();
int expires_in = 3600;
char scope[] = "create";
printf("Token generated: %s\n", token->token);
sprintf(response, "{\"access_token\":\"%s\", \"expires_in\":%d, \"scope\":\"create\"}\r\n",
token->token, expires_in);
sprintf(response, "{\"access_token\":\"%s\", \"expires_at\":%ld,\"scope\":\"create\"}\r\n",
token->token, token->expiration_time);
return strlen(response);
}

View File

@ -532,6 +532,8 @@ typedef struct TNCINFO
BOOL TNCCONNECTING; // For FreeData
BOOL TNCCONNECTED;
BOOL QtSMConnected;
char NodeCall[10]; // Call we listen for (PORTCALL or NODECALL
char CurrentMYC[10]; // Save current call so we don't change it unnecessarily
char * LISTENCALLS; // Calls TNC will respond to (currently only for VARA)
@ -543,6 +545,11 @@ typedef struct TNCINFO
int PTTMode; // PTT Mode Flags
int PTTState; // Current State
uint64_t PTTActivemS; // For Stats
uint64_t PTTonTime; //
uint64_t BusyActivemS; // For channel busy stats
uint64_t BusyonTime;
char PTTOn[60]; // Port override of RIGCONTROL config
char PTTOff[60];
@ -847,7 +854,12 @@ typedef struct TNCINFO
int NRCloseTimer;
struct _LINKTABLE * DummyLink; // Simulated link to simplify interface to ax,25 netrom code
struct sixPackPortInfo * sixPack;
int VaraACMode;
int VaraACAllowed; // Set by config
int VaraACMode; // Set by first message received
int VaraModeSet; // Have decicded if VarAC mode or not
char * VARACMsg; // to build message from packets
int VarACTimer; // delayed send timer
size_t VARACSize; // malloc'ed size
} *PTNCINFO;

View File

@ -1,187 +0,0 @@
// Includes code from MiniUPnPc, used subject to the following conditions:
/*
MiniUPnPc
Copyright (c) 2005-2020, Thomas BERNARD
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#define MINIUPNP_STATICLIB
#include <stdio.h>
#ifdef _WIN32
#include "upnpcommands.h"
#include "miniupnpc.h"
#include "upnperrors.h"
#include <winsock2.h>
#else
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/miniupnpc.h>
#include <miniupnpc/upnperrors.h>
#include <stdio.h>
#endif
int AddMap(char * controlURL, char * eport, char * iport, char * proto);
int DeleteMap(char * controlURL, char * eport, char * iport, char * proto);
void Consoleprintf(const char * format, ...);
struct UPNP
{
struct UPNP * Next;
char * Protocol;
char * LANport;
char * WANPort;
};
extern struct UPNP * UPNPConfig;
char * controlURL = 0;
char * servicetype = 0;
char iaddr[] = "IP";
char * inClient = NULL;
#ifdef LINBPQ
char desc[] = "LinBPQ ";
#else
char desc[] = "BPQ32 ";
#endif
char * remoteHost = NULL;
char * leaseDuration = NULL;
struct UPNPDev * devlist = 0;
char lanaddr[64] = "unset"; /* my ip address on the LAN */
struct UPNPUrls urls;
struct IGDdatas data;
int i;
const char * rootdescurl = 0;
const char * multicastif = 0;
const char * minissdpdpath = 0;
int localport = UPNP_LOCAL_PORT_ANY;
int retcode = 0;
int error = 0;
int ipv6 = 0;
int ignore = 0;
unsigned char ttl = 2;
int upnpInit()
{
struct UPNP * Config = UPNPConfig;
int i;
#ifdef WIN32
WSADATA wsaData;
int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(nResult != NO_ERROR)
{
fprintf(stderr, "WSAStartup() failed.\n");
return -1;
}
#endif
while (Config)
{
if (devlist == NULL)
{
devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error);
if (devlist == NULL)
{
Consoleprintf("Failed to find a UPNP device");
return 0;
}
i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
}
AddMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol);
Config = Config->Next;
}
return 0;
}
int upnpClose()
{
struct UPNP * Config = UPNPConfig;
int i;
while (Config)
{
if (devlist == NULL)
{
devlist = upnpDiscover(2000, multicastif, minissdpdpath, localport, ipv6, ttl, &error);
if (devlist == NULL)
{
Consoleprintf("Failed to find a UPNP device");
return 0;
}
i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
}
DeleteMap(devlist->descURL, Config->LANport, Config->WANPort, Config->Protocol);
Config = Config->Next;
}
return 0;
}
int AddMap(char * controlURL, char * eport, char * iport, char * proto)
{
int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
eport, iport, lanaddr, desc,
proto, remoteHost, leaseDuration);
if (r != UPNPCOMMAND_SUCCESS)
{
Consoleprintf("UPNP AddPortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r));
return -2;
}
Consoleprintf("UPNP AddPortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r);
return 0;
}
int DeleteMap(char * controlURL, char * eport, char * iport, char * proto)
{
int r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, eport, proto, remoteHost);
if(r != UPNPCOMMAND_SUCCESS)
{
Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) failed with code %d (%s)", eport, iport, lanaddr, r, strupnperror(r));
return -2;
}
Consoleprintf("UPNP DeletePortMapping(%s, %s, %s) Succeeded", eport, iport, lanaddr, r);
return 0;
}