Merge branch 'debian/latest' into hibbian/latest

This commit is contained in:
Hibby 2024-10-11 15:42:00 +01:00
commit f527c60884
Signed by: hibby
SSH Key Fingerprint: SHA256:Y6XbnzN0FEB1R/exPF5hUbHUgE/Nn7M1uT566fxo6pE
51 changed files with 1630 additions and 1388 deletions

View File

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

View File

@ -3225,6 +3225,170 @@ char * get_plane(int * Len)
return ptr; 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() char * get_aprs()
{ {
@ -3638,6 +3802,10 @@ char * GetStandardPage(char * FN, int * Len)
if (_stricmp(FN, "leaflet.rotatedMarker.js") == 0) if (_stricmp(FN, "leaflet.rotatedMarker.js") == 0)
return get_rotatedMarker(); return get_rotatedMarker();
if (_stricmp(FN, "PortStats.html") == 0)
return get_portstats();
if (_stricmp(FN, "info_call.html") == 0) if (_stricmp(FN, "info_call.html") == 0)
return get_info_call(); return get_info_call();

44
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].Connecting ||
TNC->Streams[0].Connected) TNC->Streams[0].Connected)
{ {
// discard if TNC not connected or sesison active // discard if TNC not connected or session active
ReleaseBuffer(buffptr); ReleaseBuffer(buffptr);
continue; continue;
@ -1865,13 +1865,11 @@ VOID ARDOPReleaseTNC(struct TNCINFO * TNC)
ARDOPChangeMYC(TNC, TNC->NodeCall); ARDOPChangeMYC(TNC, TNC->NodeCall);
ARDOPSendCommand(TNC, "LISTEN TRUE", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Free"); strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
// Start Scanner ARDOPSendCommand(TNC, "LISTEN TRUE", TRUE);
// Start Scanner // Start Scanner
if (TNC->DefaultRadioCmd) if (TNC->DefaultRadioCmd)
@ -1889,12 +1887,19 @@ VOID ARDOPReleaseTNC(struct TNCINFO * TNC)
VOID ARDOPSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC) VOID ARDOPSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{ {
TNC->PortRecord->PORTCONTROL.PortSuspended = TRUE;
ARDOPSendCommand(TNC, "LISTEN FALSE", TRUE); ARDOPSendCommand(TNC, "LISTEN FALSE", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
} }
VOID ARDOPReleasePort(struct TNCINFO * TNC) VOID ARDOPReleasePort(struct TNCINFO * TNC)
{ {
TNC->PortRecord->PORTCONTROL.PortSuspended = FALSE;
ARDOPSendCommand(TNC, "LISTEN TRUE", TRUE); ARDOPSendCommand(TNC, "LISTEN TRUE", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
} }
extern char WebProcTemplate[]; extern char WebProcTemplate[];
@ -2953,6 +2958,15 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (TNC->PTTMode) if (TNC->PTTMode)
Rig_PTT(TNC, TRUE); 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; return;
} }
if (_memicmp(Buffer, "PTT F", 5) == 0) if (_memicmp(Buffer, "PTT F", 5) == 0)
@ -2961,6 +2975,12 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (TNC->PTTMode) if (TNC->PTTMode)
Rig_PTT(TNC, FALSE); Rig_PTT(TNC, FALSE);
if (TNC->PTTonTime)
{
TNC->PTTActivemS += (GetTickCount() - TNC->PTTonTime);
TNC->PTTonTime = 0;
}
return; return;
} }
@ -2969,6 +2989,8 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
TNC->BusyFlags |= CDBusy; TNC->BusyFlags |= CDBusy;
TNC->Busy = TNC->BusyHold * 10; // BusyHold delay TNC->Busy = TNC->BusyHold * 10; // BusyHold delay
TNC->BusyonTime = GetTickCount();
MySetWindowText(TNC->xIDC_CHANSTATE, "Busy"); MySetWindowText(TNC->xIDC_CHANSTATE, "Busy");
strcpy(TNC->WEB_CHANSTATE, "Busy"); strcpy(TNC->WEB_CHANSTATE, "Busy");
@ -2985,6 +3007,12 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
else else
strcpy(TNC->WEB_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear");
if (TNC->BusyonTime)
{
TNC->BusyActivemS += (GetTickCount() - TNC->BusyonTime);
TNC->BusyonTime = 0;
}
MySetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE); MySetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE);
TNC->WinmorRestartCodecTimer = time(NULL); TNC->WinmorRestartCodecTimer = time(NULL);
return; return;
@ -3852,6 +3880,7 @@ VOID ARDOPProcessDataPacket(struct TNCINFO * TNC, UCHAR * Type, UCHAR * Data, in
char * ptr2; char * ptr2;
char c; char c;
int Len = Length; int Len = Length;
char Call[10] = "";
Debugprintf(Data); Debugprintf(Data);
@ -3924,7 +3953,12 @@ VOID ARDOPProcessDataPacket(struct TNCINFO * TNC, UCHAR * Type, UCHAR * Data, in
buffptr->LENGTH = 16 + MSGHDDRLEN + APLen; buffptr->LENGTH = 16 + MSGHDDRLEN + APLen;
time(&buffptr->Timestamp); time(&buffptr->Timestamp);
memcpy(Call,ptr1, 9);
strlop(Call, '>');
UpdateMH(TNC, Call, '!', 'I');
BPQTRACE((MESSAGE *)buffptr, TRUE); BPQTRACE((MESSAGE *)buffptr, TRUE);
} }
else 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); int encode_quoted_printable(char *s, char * out, int Len);
int32_t Encode(char * in, char * out, int32_t inlen, BOOL B1Protocol, int Compress); int32_t Encode(char * in, char * out, int32_t inlen, BOOL B1Protocol, int Compress);
int APIENTRY ChangeSessionCallsign(int Stream, unsigned char * AXCall); 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); void SendNewMessageEvent(char * call, struct MsgInfo * Msg);
config_t cfg; config_t cfg;
@ -10059,6 +10059,7 @@ BOOL GetConfig(char * ConfigName)
char Size[80]; char Size[80];
config_setting_t *setting; config_setting_t *setting;
const char * ptr; const char * ptr;
char * ptr1;
char FBBString[8192]= ""; char FBBString[8192]= "";
FBBFilter f; FBBFilter f;
config_init(&cfg); config_init(&cfg);
@ -10265,7 +10266,7 @@ BOOL GetConfig(char * ConfigName)
GetStringValue(group, "FBBFilters", FBBString); GetStringValue(group, "FBBFilters", FBBString);
ptr = FBBString; ptr1 = FBBString;
// delete old list // delete old list
@ -10279,31 +10280,31 @@ BOOL GetConfig(char * ConfigName)
free(Filters); free(Filters);
Filters = NULL; Filters = NULL;
while (ptr && ptr[0]) while (ptr1 && ptr1[0])
{ {
FBBFilter * PFilter; FBBFilter * PFilter;
f.Action = ptr[0]; f.Action = ptr1[0];
f.Type = ptr[2]; f.Type = ptr1[2];
ptr = &ptr[4]; ptr1 = &ptr1[4];
memcpy(f.From, ptr, 10); memcpy(f.From, ptr1, 10);
strlop(f.From, '|'); strlop(f.From, '|');
ptr = strlop(ptr, '|'); ptr1 = strlop(ptr1, '|');
memcpy(f.TO, ptr, 10); memcpy(f.TO, ptr1, 10);
strlop(f.TO, '|'); strlop(f.TO, '|');
ptr = strlop(ptr, '|'); ptr1 = strlop(ptr1, '|');
memcpy(f.AT, ptr, 10); memcpy(f.AT, ptr1, 10);
strlop(f.AT, '|'); strlop(f.AT, '|');
ptr = strlop(ptr, '|'); ptr1 = strlop(ptr1, '|');
memcpy(f.BID, ptr, 10); memcpy(f.BID, ptr1, 10);
strlop(f.BID, '|'); strlop(f.BID, '|');
ptr = strlop(ptr, '|'); ptr1 = strlop(ptr1, '|');
f.MaxLen = atoi(ptr); f.MaxLen = atoi(ptr1);
// add to list // add to list
@ -10325,7 +10326,7 @@ BOOL GetConfig(char * ConfigName)
p->Next = PFilter; 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) // 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) // Fix Send P to multiple BBS's when routing on HR (40)
// Rewrite PG server code on Lunux (41) // 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 "bpqmail.h"
#include "winstdint.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) // Add NodeAPI call sendLinks and remove get from other calls (32)
// Improve validation of Web Beacon Config (33) // Improve validation of Web Beacon Config (33)
// Support SNMP via host ip stack as well as IPGateway (34) // Support SNMP via host ip stack as well as IPGateway (34)
// Switch APRS Map to OSM tile servers (36) // Switch APRS Map to OSM tile servers (36)
// Fix potential buffer overflow in Telnet login (36) // Fix potential buffer overflow in Telnet login (36)
// Allow longer serial device names (37) // 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) // Change default of SECURETELNET to 1 (41)
// Add optional ATTACH time limit for ARDOP (42) // Add optional ATTACH time limit for ARDOP (42)
// Fix buffer overflow risk in HTTP Terminal(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>

140
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, LinBPQ/BPQ32 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of 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. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
@ -66,6 +66,10 @@ VOID SaveMH();
BOOL RestartTNC(struct TNCINFO * TNC); BOOL RestartTNC(struct TNCINFO * TNC);
void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD); void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD);
VOID WriteMiniDump(); 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 COMMANDBUFFER[81] = ""; // Command Hander input buffer
char OrigCmdBuffer[81] = ""; // Command Hander input buffer before toupper 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 RECONFIGTELNET (TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD);
VOID HELPCMD(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 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"); Bufferptr = Cmdprintf(Session, Bufferptr, "\r");
PORT = STARTPORT; 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++) 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; PORT = PORT->PORTPOINTER;
} }
Bufferptr = Cmdprintf(Session, Bufferptr, "\r"); Bufferptr = Cmdprintf(Session, Bufferptr, "\r");
@ -2295,8 +2301,8 @@ VOID CMDC00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * C
int TextCallLen; int TextCallLen;
char PortString[10]; char PortString[10];
char cmdCopy[256]; char cmdCopy[256];
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;; struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;
char toCall[12], fromCall[12];
#ifdef EXCLUDEBITS #ifdef EXCLUDEBITS
@ -2737,6 +2743,16 @@ noFlip:
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return; 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) if (Session->L4USER[6] == 0x42 || Session->L4USER[6] == 0x44)
{ {
@ -2822,6 +2838,12 @@ noFlip3:
RESET2(LINK); // RESET ALL FLAGS 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) if (CMD->String[0] == 'N' && SUPPORT2point2)
LINK->L2STATE = 1; // New (2.2) send XID LINK->L2STATE = 1; // New (2.2) send XID
else else
@ -2836,6 +2858,8 @@ noFlip3:
if (CQFLAG == 0) // if a CQ CALL DONT SEND SABM if (CQFLAG == 0) // if a CQ CALL DONT SEND SABM
{ {
seeifInterlockneeded(PORT);
if (LINK->L2STATE == 1) if (LINK->L2STATE == 1)
L2SENDXID(LINK); L2SENDXID(LINK);
else 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 // In use
@ -4434,6 +4458,7 @@ CMDX COMMANDS[] =
"NAT ",3,SHOWNAT,0, "NAT ",3,SHOWNAT,0,
"IPROUTE ",3,SHOWIPROUTE,0, "IPROUTE ",3,SHOWIPROUTE,0,
"UZ7HO ",5,UZ7HOCMD,0, "UZ7HO ",5,UZ7HOCMD,0,
"QTSM ",4,QTSMCMD,0,
"..FLMSG ",7,FLMSG,0 "..FLMSG ",7,FLMSG,0
}; };
@ -4897,19 +4922,69 @@ VOID DoTheCommand(TRANSPORTENTRY * Session)
VOID StatsTimer() VOID StatsTimer()
{ {
struct PORTCONTROL * PORT = PORTTABLE; struct PORTCONTROL * PORT = PORTTABLE;
int sum; uint64_t sum, sum2;
// Interval is 60 secs
while(PORT) while(PORT)
{ {
sum = PORT->SENDING / 11; int index = PORT->StatsPointer++;
PORT->AVSENDING = sum;
sum = (PORT->SENDING + PORT->ACTIVE) /11; if (index == 1439)
PORT->AVACTIVE = sum; 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->SENDING = 0;
PORT->ACTIVE = 0; PORT->ACTIVE = 0;
PORT = PORT->PORTPOINTER; PORT = PORT->PORTPOINTER;
} }
} }
@ -5819,7 +5894,7 @@ VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX *
AGW = TNC->AGWInfo; AGW = TNC->AGWInfo;
if (TNC == 0 || AGW == 0) if (TNC == 0 || AGW == 0)
{ {
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - %d is not UZ7HO port\r", port); Bufferptr = Cmdprintf(Session, Bufferptr, "Error - %d is not UZ7HO port\r", port);
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return; return;
@ -5865,6 +5940,43 @@ VOID UZ7HOCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX *
return; 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 LogAllConnects;
extern BOOL M0LTEMap; extern BOOL M0LTEMap;
char * stristr (char *ch1, char *ch2);
extern VOID * ENDBUFFERPOOL; extern VOID * ENDBUFFERPOOL;
@ -547,6 +548,7 @@ VOID * _GetBuff(char * File, int Line)
Msg->Process = (short)GetCurrentProcessId(); Msg->Process = (short)GetCurrentProcessId();
Msg->Linkptr = NULL; Msg->Linkptr = NULL;
Msg->Padding[0] = 0; // Used for modem status info
} }
else else
Debugprintf("Warning - Getbuff returned NULL"); 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; Stamp = MSG->Timestamp;
memcpy(msg, MSG, Msglen); memcpy(msg, MSG, BUFFLEN - sizeof(void *)); // To c
*len = Msglen; *len = Msglen;
@ -2454,8 +2456,8 @@ HANDLE OpenCOMPort(VOID * pPort, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet
struct termios term; struct termios term;
struct speed_struct *s; struct speed_struct *s;
if ((UINT)pPort < 256) if ((uintptr_t)pPort < 256)
sprintf(Port, "%s/com%d", BPQDirectory, (int)pPort); sprintf(Port, "%s/com%d", BPQDirectory, (int)(uintptr_t)pPort);
else else
strcpy(Port, pPort); strcpy(Port, pPort);
@ -3688,7 +3690,7 @@ VOID OpenReportingSockets()
{ {
// Enable Node Map Reports // Enable Node Map Reports
ReportTimer = 60; ReportTimer = 1200; // 2 mins - Give Rigcontrol time to start
ReportSocket = socket(AF_INET,SOCK_DGRAM,0); ReportSocket = socket(AF_INET,SOCK_DGRAM,0);
@ -5160,6 +5162,7 @@ void SendDataToPktMap(char *Msg)
char * Use; char * Use;
char * Type; char * Type;
char * Modulation; char * Modulation;
char * Usage;
char locked[] = " ! "; char locked[] = " ! ";
int Percent = 0; int Percent = 0;
@ -5264,6 +5267,10 @@ void SendDataToPktMap(char *Msg)
Type = "RF"; Type = "RF";
Bitrate = 0; Bitrate = 0;
Modulation = "FSK"; Modulation = "FSK";
Usage = "Access";
if (PORT->PortFreq)
Freq = PORT->PortFreq;
if (PORT->PORTTYPE == 0) if (PORT->PORTTYPE == 0)
{ {
@ -5321,7 +5328,7 @@ void SendDataToPktMap(char *Msg)
continue; continue;
} }
if (TNC->RIG) if (Freq == 0 && TNC->RIG)
Freq = TNC->RIG->RigFreq * 1000000; Freq = TNC->RIG->RigFreq * 1000000;
switch (TNC->Hardware) // Hardware Type switch (TNC->Hardware) // Hardware Type
@ -5387,6 +5394,15 @@ void SendDataToPktMap(char *Msg)
break; 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_WINMOR:
case H_V4: case H_V4:
@ -5395,7 +5411,7 @@ void SendDataToPktMap(char *Msg)
case H_UIARQ: case H_UIARQ:
case H_ARDOP: case H_ARDOP:
case H_VARA: case H_VARA:
case H_KISSHF:
case H_FREEDATA: case H_FREEDATA:
// TCP // TCP
@ -5431,12 +5447,58 @@ void SendDataToPktMap(char *Msg)
while (*(ptr2) == ' ' && ptr2 != ID) while (*(ptr2) == ' ' && ptr2 != ID)
*(ptr2--) = 0; *(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\"," ptr += sprintf(ptr, "{\"id\": \"%d\",\"linkType\": \"%s\","
"\"freq\": \"%lld\",\"mode\": \"%s\",\"modulation\": \"%s\"," "\"freq\": \"%lld\",\"mode\": \"%s\",\"modulation\": \"%s\","
"\"baud\": \"%d\",\"bitrate\": \"%d\",\"usage\": \"%s\",\"comment\": \"%s\"},\r\n", "\"baud\": \"%d\",\"bitrate\": \"%d\",\"usage\": \"%s\",\"comment\": \"%s\"},\r\n",
PortNo, Type, PortNo, Type,
Freq, Mode, Modulation, Freq, Mode, Modulation,
Baud, Bitrate, "Access", ID); Baud, Bitrate, Usage, ID);
// G7TAJ // // G7TAJ //
// make MH list to be added later // make MH list to be added later

View File

@ -107,3 +107,16 @@ DllExport void APIENTRY RunEventProgram(char * Program, char * Param)
return; 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 if (buffptr == 0) return (0); // No buffers, so ignore
buffptr->Len = 36; buffptr->Len = sprintf(&buffptr->Data[0], "No Connection to TNC\r");
memcpy(&buffptr->Data[0], "No Connection to TNC\r", 36);
C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); 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) if (TNC->FreeDataInfo->arqstate != 4)
{ {

View File

@ -1623,23 +1623,23 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
char * WebSock = 0; char * WebSock = 0;
char PortsHddr[] = "<h2 align=center>Ports</h2><table align=center border=2 bgcolor=white>" 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>" 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>" 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>" 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>" char PortLineWithBeaconAndDriver[] = "<tr><td>%d</td><td>%s</td><td>%s</td>"
"<td><a href=PortBeacons?%d>&nbsp;Beacons</a></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>" 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"; "<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; 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) else if (_memicmp(NodeURL, "/Icon", 5) == 0 && _memicmp(&NodeURL[10], ".png", 4) == 0)
{ {
// APRS internal Icon // APRS internal Icon
@ -2880,7 +2927,7 @@ doHeader:
" {" " {"
" // The browser doesn't support WebSocket\r\n" " // The browser doesn't support WebSocket\r\n"
" const div = document.getElementById('div');\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)" "function PTT(p)"
@ -3235,6 +3282,7 @@ doHeader:
int count; int count;
char DLL[20]; char DLL[20];
char StatsURL[64];
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", PortsHddr); ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], "%s", PortsHddr);
@ -3243,6 +3291,13 @@ doHeader:
Port = GetPortTableEntryFromSlot(count); Port = GetPortTableEntryFromSlot(count);
ExtPort = (struct _EXTPORTDATA *)Port; 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) if (Port->PORTTYPE == 0x10)
{ {
strcpy(DLL, ExtPort->PORT_DLL_NAME); strcpy(DLL, ExtPort->PORT_DLL_NAME);
@ -3265,20 +3320,20 @@ doHeader:
{ {
if (Port->UICAPABLE) if (Port->UICAPABLE)
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithBeaconAndDriver, Port->PORTNUMBER, DLL, 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 else
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithDriver, Port->PORTNUMBER, DLL, 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; continue;
} }
if (Port->PORTTYPE == 16 && Port->PROTOCOL == 10 && Port->UICAPABLE == 0) // EXTERNAL, Pactor/WINMO if (Port->PORTTYPE == 16 && Port->PROTOCOL == 10 && Port->UICAPABLE == 0) // EXTERNAL, Pactor/WINMO
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], SessionPortLine, Port->PORTNUMBER, DLL, ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], SessionPortLine, Port->PORTNUMBER, DLL,
Port->PORTDESCRIPTION, Port->PORTNUMBER); Port->PORTDESCRIPTION, Port->PORTNUMBER, StatsURL);
else else
ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithBeacon, Port->PORTNUMBER, Port->PORTNUMBER, ReplyLen += sprintf(&_REPLYBUFFER[ReplyLen], PortLineWithBeacon, Port->PORTNUMBER, Port->PORTNUMBER,
DLL, DLL, Port->PORTDESCRIPTION, Port->PORTNUMBER); DLL, DLL, Port->PORTDESCRIPTION, Port->PORTNUMBER, StatsURL);
} }
if (RigActive) if (RigActive)

View File

@ -343,12 +343,12 @@ VOID ExpireMessages()
Killed = 0; Killed = 0;
PRLimit = now - PR*86400; PRLimit = now - (time_t)PR*86400;
PURLimit = now - PUR*86400; PURLimit = now -(time_t)PUR*86400;
PFLimit = now - PF*86400; PFLimit = now - (time_t)PF*86400;
PNFLimit = now - PNF*86400; PNFLimit = now - (time_t)PNF*86400;
BFLimit = now - BF*86400; BFLimit = now - (time_t)BF*86400;
BNFLimit = now - BNF*86400; BNFLimit = now -(time_t) BNF*86400;
if (NTSU == 0) if (NTSU == 0)
{ {
@ -391,7 +391,7 @@ VOID ExpireMessages()
if (Msg->datecreated < PURLimit) if (Msg->datecreated < PURLimit)
{ {
if (SendNonDeliveryMsgs) if (SendNonDeliveryMsgs)
SendNonDeliveryMessage(Msg, TRUE, PUR); SendNonDeliveryMessage(Msg, TRUE, (int)PUR);
KillMsg(Msg); KillMsg(Msg);
} }
@ -401,7 +401,7 @@ VOID ExpireMessages()
if (Msg->datecreated < PNFLimit) if (Msg->datecreated < PNFLimit)
{ {
if (SendNonDeliveryMsgs) if (SendNonDeliveryMsgs)
SendNonDeliveryMessage(Msg, FALSE, PNF); SendNonDeliveryMessage(Msg, FALSE, (int)PNF);
KillMsg(Msg); 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); VOID SendInitScript(struct TNCINFO * TNC);
int KISSHFGetLine(char * buf); int KISSHFGetLine(char * buf);
int ProcessEscape(UCHAR * TXMsg); int ProcessEscape(UCHAR * TXMsg);
VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC); VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC, int Channel);
static int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len); static int KissEncode(struct TNCINFO * TNC, UCHAR * inbuff, UCHAR * outbuff, int len, int Channel);
int ConnecttoKISS(int port); int ConnecttoKISS(int port);
TRANSPORTENTRY * SetupNewSession(TRANSPORTENTRY * Session, char * Bufferptr); TRANSPORTENTRY * SetupNewSession(TRANSPORTENTRY * Session, char * Bufferptr);
BOOL DecodeCallString(char * Calls, BOOL * Stay, BOOL * Spy, UCHAR * AXCalls); 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 TNCINFO * TNC = TNCInfo[port];
struct STREAMINFO * STREAM = &TNC->Streams[0]; struct STREAMINFO * STREAM = &TNC->Streams[0];
struct ScanEntry * Scan; struct ScanEntry * Scan;
int Channel = ((TNC->PortRecord->PORTCONTROL.CHANNELNUM - 1) & 15) << 4;
if (TNC == NULL) if (TNC == NULL)
return 0; // Port not defined return 0; // Port not defined
@ -417,7 +418,10 @@ ok:
if (buff->PID != 240) // ax.25 address 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); txlen = send(TNC->TCPSock, txbuff, txlen, 0);
return 1; 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 // Connect Command. Pass to L2 code to start session
@ -616,9 +621,9 @@ noFlip3:
RESET2(LINK); // RESET ALL FLAGS RESET2(LINK); // RESET ALL FLAGS
// if (CMD->String[0] == 'N' && SUPPORT2point2) if (toupper(buff->L2DATA[0]) == 'N' && SUPPORT2point2)
// LINK->L2STATE = 1; // New (2.2) send XID LINK->L2STATE = 1; // New (2.2) send XID
// else else
LINK->L2STATE = 2; // Send SABM LINK->L2STATE = 2; // Send SABM
LINK->CIRCUITPOINTER = NewSess; LINK->CIRCUITPOINTER = NewSess;
@ -722,10 +727,16 @@ VOID KISSHFReleaseTNC(struct TNCINFO * TNC)
VOID KISSHFSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC) 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) 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) 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" "function ScrollOutput()\r\n"
"{var textarea = document.getElementById('textarea');" "{var textarea = document.getElementById('textarea');"
"textarea.scrollTop = textarea.scrollHeight;}</script>" "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'," "<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>", "<input name=Save value=\"Abort Session\" type=submit style=\"position: absolute; right: 20;\"></form></h2>",
TNC->Port); 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 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>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>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>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>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>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], "<tr><td>TNC Restarts</td><td></td></tr>", TNC->WEB_RESTARTS);
Len += sprintf(&Buff[Len], "</table>"); 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); Len = DoScanLine(TNC, Buff, Len);
return Len; return Len;
@ -976,6 +987,7 @@ VOID KISSThread(void * portptr)
char * ptr1; char * ptr1;
char * ptr2; char * ptr2;
UINT * buffptr; UINT * buffptr;
int Channel = ((TNC->PortRecord->PORTCONTROL.CHANNELNUM - 1) & 15) << 4;
if (TNC->HostName == NULL) if (TNC->HostName == NULL)
return; return;
@ -1184,7 +1196,7 @@ VOID KISSThread(void * portptr)
if (FD_ISSET(TNC->TCPSock, &readfs)) if (FD_ISSET(TNC->TCPSock, &readfs))
{ {
GetSemaphore(&Semaphore, 52); GetSemaphore(&Semaphore, 52);
KISSHFProcessReceivedPacket(TNC); KISSHFProcessReceivedPacket(TNC, Channel);
FreeSemaphore(&Semaphore); 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; int i,txptr=0;
UCHAR c; UCHAR c;
outbuff[0]=FEND; outbuff[0] = FEND;
outbuff[1]=0; outbuff[1] = Channel;
txptr=2; 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++) for (i=0;i<len;i++)
{ {
c=inbuff[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; int InputLen, MsgLen;
unsigned char * ptr; unsigned char * ptr;
@ -1335,10 +1374,42 @@ VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC)
if (MsgLen > 1) if (MsgLen > 1)
{ {
PMESSAGE Buff = GetBuff(); PMESSAGE Buff;
if ((TNC->ARDOPBuffer[1] & 0xf0) != Channel)
goto ignoreit;
Buff = GetBuff();
MsgLen = KissDecode(TNC->ARDOPBuffer, Buffer, MsgLen); 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 // we dont need the FENDS or control byte
MsgLen -= 3; MsgLen -= 3;
@ -1354,6 +1425,8 @@ VOID KISSHFProcessReceivedPacket(struct TNCINFO * TNC)
} }
} }
ignoreit:
if (TNC->InputLen == 0) if (TNC->InputLen == 0)
return; return;
@ -1463,7 +1536,7 @@ void DetachKISSHF(struct PORTCONTROL * PORT)
struct STREAMINFO * STREAM = &TNC->Streams[0]; struct STREAMINFO * STREAM = &TNC->Streams[0];
if (STREAM->Attached) 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->Connecting = FALSE;
STREAM->Connected = FALSE; STREAM->Connected = FALSE;

485
L2Code.c
View File

@ -106,6 +106,13 @@ void AttachKISSHF(struct PORTCONTROL * PORT, MESSAGE * Buffer);
void DetachKISSHF(struct PORTCONTROL * PORT); void DetachKISSHF(struct PORTCONTROL * PORT);
void KISSHFConnected(struct PORTCONTROL * PORT, struct _LINKTABLE * LINK); void KISSHFConnected(struct PORTCONTROL * PORT, struct _LINKTABLE * LINK);
void WriteConnectLog(char * fromcall, char * tocall, UCHAR * Mode); 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; 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) 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 // 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 // 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 // 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! // SABM with XID, but others don't seem to agree!
// Run through XID fields, changing any we don't like, // Run through XID fields, changing any we don't like,
// then return an XID response // then return an XID response
// Decode and process XID // Decode and process XID
UCHAR * ptr = &ADJBUFFER->PID; UCHAR * ptr = &ADJBUFFER->PID;
UCHAR * ptr1, * ptr2; UCHAR * ptr1, * ptr2;
UCHAR TEMPDIGI[57]; UCHAR TEMPDIGI[57];
int n; int n;
if (*ptr++ == 0x82 && *ptr++ == 0x80) // Check Interlock - should we also check exclude etc?. No, checked in L2FORUS
{
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) if (CheckKissInterlock(PORT, TRUE)) // Interlock with ARDOP/VARA etc
{ {
Type = *ptr++; L2SENDDM(PORT, Buffer, ADJBUFFER);
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; 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;
} }
@ -1100,13 +1115,22 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
TRANSPORTENTRY * Session; TRANSPORTENTRY * Session;
int CONERROR; int CONERROR;
char toCall[12], fromCall[12];
if (LINK == 0) // NO LINK ENTRIES - SEND DM RESPONSE if (LINK == 0) // NO LINK ENTRIES - SEND DM RESPONSE
{ {
L2SENDDM(PORT, Buffer, ADJBUFFER); L2SENDDM(PORT, Buffer, ADJBUFFER);
return; return;
} }
if (CheckKissInterlock(PORT, TRUE)) // Interlock with ARDOP/VARA etc
{
L2SENDDM(PORT, Buffer, ADJBUFFER);
return;
}
SETUPNEWL2SESSION(LINK, PORT, Buffer, MSGFLAG); SETUPNEWL2SESSION(LINK, PORT, Buffer, MSGFLAG);
if (LINK->L2STATE != 5) // Setup OK? if (LINK->L2STATE != 5) // Setup OK?
@ -1115,6 +1139,14 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
return; 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 CONNECT TO APPL ADDRESS, SET UP APPL SESSION
if (APPLMASK == 0) if (APPLMASK == 0)
@ -1136,6 +1168,8 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
fromCall[ConvFromAX25(ADJBUFFER->ORIGIN, fromCall)] = 0; fromCall[ConvFromAX25(ADJBUFFER->ORIGIN, fromCall)] = 0;
WriteConnectLog(fromCall, toCall, "AX.25"); WriteConnectLog(fromCall, toCall, "AX.25");
} }
hookL2SessionAccepted(PORT->PORTNUMBER, fromCall, toCall, LINK);
L2SENDUA(PORT, Buffer, ADJBUFFER); L2SENDUA(PORT, Buffer, ADJBUFFER);
@ -3226,6 +3260,15 @@ VOID SENDFRMR(struct _LINKTABLE * LINK)
VOID CLEAROUTLINK(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 CLEARL2QUEUES(LINK); // TO RELEASE ANY BUFFERS
memset(LINK, 0, sizeof(struct _LINKTABLE)); memset(LINK, 0, sizeof(struct _LINKTABLE));
@ -3593,7 +3636,7 @@ VOID ConnectFailedOrRefused(struct _LINKTABLE * LINK, char * Msg)
Buffer->LENGTH = (int)(ptr1 - (UCHAR *)Buffer); Buffer->LENGTH = (int)(ptr1 - (UCHAR *)Buffer);
Session = LINK->CIRCUITPOINTER; // GET CIRCUIT TABLE ENTRY Session = LINK->CIRCUITPOINTER; // GET CIRCUIT TABLE ENTRY
InSession = Session->L4CROSSLINK; // TO INCOMMONG SESSION InSession = Session->L4CROSSLINK; // TO INCOMMING SESSION
CLEARSESSIONENTRY(Session); CLEARSESSIONENTRY(Session);
@ -3960,3 +4003,141 @@ BOOL CheckForListeningSession(struct PORTCONTROL * PORT, MESSAGE * Msg)
} }
return FALSE; 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" #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) 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; 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 // All elements of Helements must match Myelements
while (MyElements[i] && HElements[i]) // Until one set runs out 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 // 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. // 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') if (SendPtoMultiple && Msg->type == 'P')
{ {
struct UserInfo * bestbbs = NULL; struct UserInfo * bestbbs = NULL;
@ -1425,6 +1432,16 @@ NOHA:
{ {
ForwardingInfo = bbs->ForwardingInfo; 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]); depth = CheckBBSHElements(Msg, bbs, ForwardingInfo, ATBBS, &HElements[0]);
if (depth) if (depth)

View File

@ -210,7 +210,12 @@ KC6OAR*>ID:
Port &= 0x7F; Port &= 0x7F;
if ((((uint64_t)1 << (Port - 1)) & Mask) == 0) // Check MMASK if ((((uint64_t)1 << (Port - 1)) & Mask) == 0) // Check MMASK
{
if (msg->Padding[0] == '[')
msg->Padding[0] = 0;
return 0; return 0;
}
// We now pass Text format monitoring from non-ax25 drivers through this code // 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) if (Info)
{ {
// We have an info frame // 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, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
setsockopt(PORT->remoteSock, IPPROTO_TCP, TCP_NODELAY, (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 // Connected successful

View File

@ -4297,16 +4297,22 @@ VOID PTCSuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{ {
struct STREAMINFO * STREAM = &TNC->Streams[0]; struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100); STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
sprintf(STREAM->CmdSet, "I%s\r", "SCSPTC"); // Should prevent connects 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) VOID PTCReleasePort(struct TNCINFO * TNC)
{ {
struct STREAMINFO * STREAM = &TNC->Streams[0]; struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100); STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
if (TNC->UseAPPLCallsforPactor && TNC->RIG && TNC->RIG != &TNC->DummyRig if (TNC->UseAPPLCallsforPactor && TNC->RIG && TNC->RIG != &TNC->DummyRig
@ -4315,7 +4321,7 @@ VOID PTCReleasePort(struct TNCINFO * TNC)
else else
sprintf(STREAM->CmdSet, "I%s\r", TNC->NodeCall); 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]; struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100); STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
sprintf(STREAM->CmdSet, "\1\1\1IDSPTNC"); sprintf(STREAM->CmdSet, "\1\1\1IDSPTNC");
} }
@ -117,6 +120,9 @@ VOID TRKReleasePort(struct TNCINFO * TNC)
{ {
struct STREAMINFO * STREAM = &TNC->Streams[0]; struct STREAMINFO * STREAM = &TNC->Streams[0];
strcpy(TNC->WEB_TNCSTATE, "Free");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->CmdSet = STREAM->CmdSave = zalloc(100); STREAM->CmdSet = STREAM->CmdSave = zalloc(100);
sprintf(STREAM->CmdSet, "\1\1\1I%s", TNC->NodeCall); sprintf(STREAM->CmdSet, "\1\1\1I%s", TNC->NodeCall);
} }

View File

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

224
VARA.c
View File

@ -258,6 +258,9 @@ static int ProcessLine(char * buf, int Port)
*ptr = 0; *ptr = 0;
} }
else if (_memicmp(buf, "VARAAC", 6) == 0)
TNC->VaraACAllowed = atoi(&buf[7]);
else if (_memicmp(buf, "BW2300", 6) == 0) else if (_memicmp(buf, "BW2300", 6) == 0)
{ {
TNC->ARDOPCurrentMode[0] = 'W'; // Save current state for scanning TNC->ARDOPCurrentMode[0] = 'W'; // Save current state for scanning
@ -281,7 +284,8 @@ static int ProcessLine(char * buf, int Port)
else if (_memicmp(buf, "FM9600", 5) == 0) else if (_memicmp(buf, "FM9600", 5) == 0)
TNC->DefaultMode = TNC->WL2KMode = 52; TNC->DefaultMode = TNC->WL2KMode = 52;
else if (standardParams(TNC, buf) == FALSE) else if (standardParams(TNC, buf) == FALSE)
strcat(TNC->InitScript, buf); strcat(TNC->InitScript, buf);
} }
return (TRUE); return (TRUE);
@ -304,12 +308,31 @@ static SOCKADDR_IN rxaddr;
static int addrlen=sizeof(sinx); 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) static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{ {
size_t datalen; size_t datalen;
PMSGWITHLEN buffptr; PMSGWITHLEN buffptr;
char txbuff[500]; char txbuff[500];
unsigned int bytes,txlen=0; unsigned int bytes;
size_t txlen=0;
size_t Param; size_t Param;
HKEY hKey=0; HKEY hKey=0;
struct TNCINFO * TNC = TNCInfo[port]; 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 // 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 // G7TAJ's code to record activity for stats display
if ( TNC->BusyFlags && CDBusy ) 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); PMSGWITHLEN buffptr = Q_REM(&TNC->Streams[0].BPQtoPACTOR_Q);
txlen = (int)buffptr->Len; 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); bytes = VARASendData(TNC, &txbuff[0], txlen);
STREAM->BytesTXed += bytes; STREAM->BytesTXed += bytes;
ReleaseBuffer(buffptr); 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 if (buffptr == 0) return (0); // No buffers, so ignore
buffptr->Len=36; buffptr->Len = sprintf(buffptr->Data,"No Connection to VARA TNC\r");
memcpy(buffptr->Data,"No Connection to VARA TNC\r", 36);
C_Q_ADD(&TNC->WINMORtoBPQ_Q, buffptr); 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) if (TNC->Streams[0].Connected)
{ {
unsigned char txbuff[512];
STREAM->PacketsSent++; STREAM->PacketsSent++;
bytes=send(TNC->TCPDataSock, buff->L2DATA, txlen, 0); if(TNC->VaraACMode == 0 && TNC->VaraModeSet == 1)
STREAM->BytesTXed += bytes; {
// 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); 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 else
{ {
@ -608,7 +721,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
TNC->Streams[0].ReportDISC = TRUE; // Tell Node TNC->Streams[0].ReportDISC = TRUE; // Tell Node
return 0; return 0;
} }
// See if Local command (eg RADIO) // See if Local command (eg RADIO)
if (_memicmp(buff->L2DATA, "RADIO ", 6) == 0) if (_memicmp(buff->L2DATA, "RADIO ", 6) == 0)
@ -651,13 +764,13 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (buff->L2DATA[16] != 13) if (buff->L2DATA[16] != 13)
{ {
PMSGWITHLEN buffptr = (PMSGWITHLEN)GetBuff(); PMSGWITHLEN buffptr = (PMSGWITHLEN)GetBuff();
TNC->SessionTimeLimit = atoi(&buff->L2DATA[16]) * 60; TNC->SessionTimeLimit = atoi(&buff->L2DATA[16]) * 60;
if (buffptr) if (buffptr)
{ {
buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "VARA} OK\r"); 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; return 0;
} }
@ -704,7 +817,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
TNC->Streams[0].Connecting = TRUE; TNC->Streams[0].Connecting = TRUE;
// See if Busy // See if Busy
if (InterlockedCheckBusy(TNC)) if (InterlockedCheckBusy(TNC))
{ {
// Channel Busy. Unless override set, wait // Channel Busy. Unless override set, wait
@ -712,7 +825,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (TNC->OverrideBusy == 0) if (TNC->OverrideBusy == 0)
{ {
// Save Command, and wait up to 10 secs // Save Command, and wait up to 10 secs
sprintf(TNC->WEB_TNCSTATE, "Waiting for clear channel"); sprintf(TNC->WEB_TNCSTATE, "Waiting for clear channel");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
@ -979,12 +1092,19 @@ static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL)
VOID VARASuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC) VOID VARASuspendPort(struct TNCINFO * TNC, struct TNCINFO * ThisTNC)
{ {
TNC->PortRecord->PORTCONTROL.PortSuspended = TRUE;
VARASendCommand(TNC, "LISTEN OFF\r", TRUE); VARASendCommand(TNC, "LISTEN OFF\r", TRUE);
strcpy(TNC->WEB_TNCSTATE, "Interlocked");
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
} }
VOID VARAReleasePort(struct TNCINFO * TNC) VOID VARAReleasePort(struct TNCINFO * TNC)
{ {
TNC->PortRecord->PORTCONTROL.PortSuspended = FALSE;
VARASendCommand(TNC, "LISTEN ON\r", TRUE); 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->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) if (TNC->PTTMode)
Rig_PTT(TNC, TRUE); Rig_PTT(TNC, TRUE);
@ -1740,6 +1869,12 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
{ {
// Debugprintf("PTT Off"); // Debugprintf("PTT Off");
if (TNC->PTTonTime)
{
TNC->PTTActivemS += (GetTickCount() - TNC->PTTonTime);
TNC->PTTonTime = 0;
}
if (TNC->PTTMode) if (TNC->PTTMode)
Rig_PTT(TNC, FALSE); Rig_PTT(TNC, FALSE);
@ -1760,6 +1895,8 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
TNC->BusyFlags |= CDBusy; TNC->BusyFlags |= CDBusy;
TNC->Busy = TNC->BusyHold * 10; // BusyHold delay TNC->Busy = TNC->BusyHold * 10; // BusyHold delay
TNC->BusyonTime = GetTickCount();
MySetWindowText(TNC->xIDC_CHANSTATE, "Busy"); MySetWindowText(TNC->xIDC_CHANSTATE, "Busy");
strcpy(TNC->WEB_CHANSTATE, "Busy"); strcpy(TNC->WEB_CHANSTATE, "Busy");
@ -1775,6 +1912,13 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
else else
strcpy(TNC->WEB_CHANSTATE, "Clear"); strcpy(TNC->WEB_CHANSTATE, "Clear");
if (TNC->BusyonTime)
{
TNC->BusyActivemS += (GetTickCount() - TNC->BusyonTime);
TNC->BusyonTime = 0;
}
MySetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE); MySetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE);
TNC->WinmorRestartCodecTimer = time(NULL); TNC->WinmorRestartCodecTimer = time(NULL);
return; return;
@ -1879,6 +2023,17 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->ConnectTime = time(NULL); STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0; 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, ""); strcpy(TNC->WEB_MODE, "");
if (strstr(Buffer, "2300")) if (strstr(Buffer, "2300"))
@ -1937,6 +2092,8 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
TNC->SessionTimeLimit = TNC->DefaultSessionTimeLimit; // Reset Limit TNC->SessionTimeLimit = TNC->DefaultSessionTimeLimit; // Reset Limit
// Only allow VarAC mode for incomming sessions
ProcessIncommingConnectEx(TNC, Call, 0, (TNC->NetRomMode == 0), TRUE); ProcessIncommingConnectEx(TNC, Call, 0, (TNC->NetRomMode == 0), TRUE);
SESS = TNC->PortRecord->ATTACHEDSESSIONS[0]; SESS = TNC->PortRecord->ATTACHEDSESSIONS[0];
@ -2125,7 +2282,6 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (TNC->NetRomTxLen) if (TNC->NetRomTxLen)
{ {
STREAM->PacketsSent++; STREAM->PacketsSent++;
bytes = send(TNC->TCPDataSock, TNC->NetRomTxBuffer, TNC->NetRomTxLen, 0); bytes = send(TNC->TCPDataSock, TNC->NetRomTxBuffer, TNC->NetRomTxLen, 0);
@ -2137,6 +2293,9 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
} }
else else
{ {
TNC->VaraACMode = 0;
TNC->VaraModeSet = 1; // Don't allow connect to VaraAC
buffptr = GetBuff(); buffptr = GetBuff();
if (buffptr == 0) if (buffptr == 0)
@ -2592,6 +2751,45 @@ VOID VARAProcessDataPacket(struct TNCINFO * TNC, UCHAR * Data, int Length)
STREAM->BytesTXed, STREAM->BytesRXed,STREAM->BytesOutstanding); STREAM->BytesTXed, STREAM->BytesRXed,STREAM->BytesOutstanding);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC); 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 // May need to fragment
while (Length) while (Length)

View File

@ -10,14 +10,14 @@
#endif #endif
#define KVers 6,0,24,42 #define KVers 6,0,24,45
#define KVerstring "6.0.24.42\0" #define KVerstring "6.0.24.45\0"
#ifdef CKernel #ifdef CKernel
#define Vers KVers #define Vers KVers
#define Verstring KVerstring #define Verstring KVerstring
#define Datestring "August 2024" #define Datestring "October 2024"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring #define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2024 John Wiseman G8BPQ\0" #define VerCopyright "Copyright © 2001-2024 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\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 AVSENDING; // LAST MINUTE
UCHAR AVACTIVE; UCHAR AVACTIVE;
char PktFlags[64]; // Decode stts rom QtSM
char PORTTYPE; // H/W TYPE char PORTTYPE; // H/W TYPE
// 0 = ASYNC, 2 = PC120, 4 = DRSI // 0 = ASYNC, 2 = PC120, 4 = DRSI
// 6 = TOSH, 8 = QUAD, 10 = RLC100 // 6 = TOSH, 8 = QUAD, 10 = RLC100
@ -691,6 +693,13 @@ typedef struct PORTCONTROL
time_t SmartIDInterval; // Smart ID Interval (Secs) time_t SmartIDInterval; // Smart ID Interval (Secs)
int SendtoM0LTEMap; int SendtoM0LTEMap;
uint64_t PortFreq; // Configured freq 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; } PORTCONTROLX, *PPORTCONTROL;
@ -704,7 +713,7 @@ typedef struct FULLPORTDATA
typedef struct KISSINFO typedef struct KISSINFO
{ {
struct PORTCONTROL PORT; struct PORTCONTROL PORT;
int LINKSTS; // CURRENT STATE int LINKSTS; // CURRENT STATE
UINT * CURALP; // CURRENT BUFFER UINT * CURALP; // CURRENT BUFFER
@ -735,6 +744,19 @@ typedef struct KISSINFO
UCHAR * KISSCMD; // Commands to be sent when port opened UCHAR * KISSCMD; // Commands to be sent when port opened
int KISSCMDLEN; 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 // UCHAR WIN32INFO[16]; // FOR WINDOWS DRIVER
} *PKISSINFO; } *PKISSINFO;

View File

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

View File

@ -365,7 +365,7 @@ static char *pkeywords[] =
"BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY", "BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY",
"UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE", "UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE",
"IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE", "IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE",
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq"}; /* parameter keywords */ "SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort"}; /* parameter keywords */
static void * poffset[] = 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.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.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.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[] = static int proutine[] =
{ {
@ -393,7 +393,7 @@ static int proutine[] =
0, 1, 2, 18, 15, 16, 2, 0, 1, 2, 18, 15, 16, 2,
1, 17, 1, 1, 1, 1, 2, 1, 17, 1, 1, 1, 1, 2,
2, 2, 1, 1, 19, 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); 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 */ cn = int64_value(poffset[i], value, rec); /* INTEGER VALUES */
break; break;
case 22:
xxp.M0LTEMapInfo = _strdup(value);
cn = 1;
break;
case 9: 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; unsigned char * KissParams;
int SendtoM0LTEMap; int SendtoM0LTEMap;
uint64_t PortFreq; uint64_t PortFreq;
char * M0LTEMapInfo;
int QtSMPort;
}; };
struct ROUTECONFIG struct ROUTECONFIG

2
debian/control vendored
View File

@ -11,7 +11,7 @@ Rules-Requires-Root: no
Package: linbpq Package: linbpq
Architecture: linux-any Architecture: linux-any
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, hibbian-archive-keyring
Description: Packet node and ax25 stack Description: Packet node and ax25 stack
LINBPQ is a Linux version of the BPQ32 Node, BBS and Chat Server components. LINBPQ is a Linux version of the BPQ32 Node, BBS and Chat Server components.
It is actively developed by John G8BPQ and contains a complete, independent It is actively developed by John G8BPQ and contains a complete, independent

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/ttyutils.h>
//#include <netax25/daemon.h> //#include <netax25/daemon.h>
#include <netinet/tcp.h>
#ifdef MACBPQ #ifdef MACBPQ
#define NOI2C #define NOI2C
#endif #endif
@ -84,6 +86,7 @@ int i2cPoll(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO);
#define FESC 0xDB #define FESC 0xDB
#define TFEND 0xDC #define TFEND 0xDC
#define TFESC 0xDD #define TFESC 0xDD
#define QTSMKISSCMD 7
#define STX 2 // NETROM CONTROL CODES #define STX 2 // NETROM CONTROL CODES
#define ETX 3 #define ETX 3
@ -112,7 +115,8 @@ int ConnecttoTCP(NPASYINFO ASY);
int KISSGetTCPMessage(NPASYINFO ASY); int KISSGetTCPMessage(NPASYINFO ASY);
VOID CloseKISSPort(struct PORTCONTROL * PortVector); VOID CloseKISSPort(struct PORTCONTROL * PortVector);
int ReadCOMBlockEx(HANDLE fd, char * Block, int MaxLength, BOOL * Error); 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 struct PORTCONTROL * PORTTABLE;
extern int NUMBEROFPORTS; extern int NUMBEROFPORTS;
@ -801,11 +805,14 @@ VOID KISSINIT(struct KISSINFO * KISS)
PORTCONTROLX * PORT = (struct PORTCONTROL *)KISS; PORTCONTROLX * PORT = (struct PORTCONTROL *)KISS;
struct KISSINFO * FIRSTCHAN = NULL; struct KISSINFO * FIRSTCHAN = NULL;
PORT->PORTINTERLOCK = 0; // CANT USE INTERLOCK ON KISS
if (PORT->CHANNELNUM == 0) if (PORT->CHANNELNUM == 0)
PORT->CHANNELNUM = 'A'; 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 FIRSTCHAN = (struct KISSINFO *)CHECKIOADDR(PORT); // IF ANOTHER ENTRY FOR THIS ADDR
// MAY BE CHANGED IN ANOTHER CHANNEL USED // 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 // ACK FRAME. WE DONT SUPPORT ACK REQUIRED FRAMES AS A SLAVE - THEY ARE ONLY ACCEPTED BY TNCS
struct _LINKTABLE * LINK; struct _LINKTABLE * LINK;
UINT ACKWORD = Port->RXMSG[1] | Port->RXMSG[2] << 8; int ACKWORD = Port->RXMSG[1] | Port->RXMSG[2] << 8;
if (ACKWORD < MAXLINKS) if (ACKWORD < MAXLINKS)
{ {
@ -1524,6 +1531,66 @@ SeeifMore:
if (Port->RXMSG[0] & 0x0f) // Not Data 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) // If a reply to a manual KISS command(Session set and time not too long ago)
// send reponse to terminal // send reponse to terminal
@ -1618,6 +1685,8 @@ SeeifMore:
PORT->RXERRORS++; PORT->RXERRORS++;
Debugprintf("KISS Checksum Error"); Debugprintf("KISS Checksum Error");
PORT->PktFlags[0] = 0;
goto SeeifMore; // SEE IF ANYTHING ELSE goto SeeifMore; // SEE IF ANYTHING ELSE
} }
len--; // Remove Checksum len--; // Remove Checksum
@ -1630,7 +1699,12 @@ SeeifMore:
KISS = KISS->SUBCHAIN; KISS = KISS->SUBCHAIN;
if (KISS == NULL) 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 // ok, KISS now points to our port
@ -1648,6 +1722,13 @@ SeeifMore:
PutLengthinBuffer((PDATAMESSAGE)Buffer, len); // Needed for arm5 portability 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 // Randomly drop packets
@ -1893,6 +1974,10 @@ VOID ConnecttoTCPThread(NPASYINFO ASY)
if (KISS && KISS->KISSCMD && KISS->KISSCMDLEN) if (KISS && KISS->KISSCMD && KISS->KISSCMDLEN)
send(sock, KISS->KISSCMD, KISS->KISSCMDLEN, 0); send(sock, KISS->KISSCMD, KISS->KISSCMDLEN, 0);
// Try to open Mgmt Port
ConnecttoQtSM(&KISS->PORT);
continue; continue;
} }
else else
@ -2030,3 +2115,264 @@ int KISSGetTCPMessage(NPASYINFO ASY)
} }
return 0; 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); static int ProcessLine(char * buf,int Port, BOOL CheckPort);
int WritetoConsoleLocal(char * buff); 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; int len,txlen=0,res;
char txbuff[500]; char txbuff[500];
@ -110,9 +110,8 @@ int ExtProc(int fn, int port,unsigned char * buff)
len-=3; len-=3;
memcpy(&buff[7],&rxbuff[19],len); memcpy(&buff->DEST, &rxbuff[19], len);
len += (1 + sizeof(void *));
len+=5;
} }
else 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 if ((len < 16) || (len > 320)) return 0; // Probably RLI Mode Frame
len-=3; len-=3;
memcpy(&buff->DEST, &rxbuff[16], len);
memcpy(&buff[7],&rxbuff[16],len); len += (1 + sizeof(void *));
len+=5;
} }
buff[5]=(len & 0xff); PutLengthinBuffer((PDATAMESSAGE)buff, len);
buff[6]=(len >> 8);
return 1; 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 // 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 = GetLengthfromBuffer((PDATAMESSAGE)buff); // 2 for CRC
txlen -= (sizeof(void *) - 2);
txlen-=2;
txbuff[16]=0x41; txbuff[16]=0x41;
txbuff[17]=(txlen & 0xff); txbuff[17]=(txlen & 0xff);
txbuff[18]=(txlen >> 8); txbuff[18]=(txlen >> 8);
@ -150,14 +145,14 @@ int ExtProc(int fn, int port,unsigned char * buff)
if (txlen < 1 || txlen > 400) if (txlen < 1 || txlen > 400)
return 0; return 0;
memcpy(&txbuff[19],&buff[7],txlen); memcpy(&txbuff[19], &buff->DEST[0], txlen);
} }
else else
{ {
txlen=(buff[6]<<8) + buff[5]; // BPQEther is DOS-based - chain word is 2 bytes txlen = GetLengthfromBuffer((PDATAMESSAGE)buff); // 2 for CRC
txlen -= (sizeof(void *) - 2);
txlen-=2;
txbuff[14]=(txlen & 0xff); txbuff[14]=(txlen & 0xff);
txbuff[15]=(txlen >> 8); txbuff[15]=(txlen >> 8);
@ -166,7 +161,7 @@ int ExtProc(int fn, int port,unsigned char * buff)
return 0; return 0;
memcpy(&txbuff[16],&buff[7],txlen); memcpy(&txbuff[16], &buff->DEST[0], txlen);
} }
memcpy(&txbuff[0], &IF->EthDest[0],6); 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 // 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); // n=sprintf(buf,"Using %s Adapter = Interface %d\r", ifr.ifr_ifindex);
// WritetoConsole(buf); // 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) int request_token(char * response)
{ {
Token * token = generate_token(); Token * token = generate_token();
int expires_in = 3600;
char scope[] = "create"; char scope[] = "create";
printf("Token generated: %s\n", token->token); printf("Token generated: %s\n", token->token);
sprintf(response, "{\"access_token\":\"%s\", \"expires_in\":%d, \"scope\":\"create\"}\r\n", sprintf(response, "{\"access_token\":\"%s\", \"expires_at\":%ld,\"scope\":\"create\"}\r\n",
token->token, expires_in); token->token, token->expiration_time);
return strlen(response); return strlen(response);
} }

View File

@ -532,6 +532,8 @@ typedef struct TNCINFO
BOOL TNCCONNECTING; // For FreeData BOOL TNCCONNECTING; // For FreeData
BOOL TNCCONNECTED; BOOL TNCCONNECTED;
BOOL QtSMConnected;
char NodeCall[10]; // Call we listen for (PORTCALL or NODECALL char NodeCall[10]; // Call we listen for (PORTCALL or NODECALL
char CurrentMYC[10]; // Save current call so we don't change it unnecessarily char CurrentMYC[10]; // Save current call so we don't change it unnecessarily
char * LISTENCALLS; // Calls TNC will respond to (currently only for VARA) char * LISTENCALLS; // Calls TNC will respond to (currently only for VARA)
@ -543,6 +545,11 @@ typedef struct TNCINFO
int PTTMode; // PTT Mode Flags int PTTMode; // PTT Mode Flags
int PTTState; // Current State 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 PTTOn[60]; // Port override of RIGCONTROL config
char PTTOff[60]; char PTTOff[60];
@ -847,7 +854,12 @@ typedef struct TNCINFO
int NRCloseTimer; int NRCloseTimer;
struct _LINKTABLE * DummyLink; // Simulated link to simplify interface to ax,25 netrom code struct _LINKTABLE * DummyLink; // Simulated link to simplify interface to ax,25 netrom code
struct sixPackPortInfo * sixPack; 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; } *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;
}