New upstream version 6.0.24.65+repack

This commit is contained in:
Hibby 2025-02-25 09:32:57 +00:00
parent 64d58d0c5a
commit c858986248
56 changed files with 2003 additions and 42389 deletions

139
.rej
View File

@ -1,139 +0,0 @@
--- APRSCode.c
+++ APRSCode.c
@@ -3674,7 +3674,7 @@
if (ptr1)
*ptr1 = 0;
-// Debugprintf("Duplicate Message supressed %s", Msg);
+// Debugprintf("Duplicate Message suppressed %s", Msg);
return TRUE; // Duplicate
}
}
--- BPQChat.rc
+++ BPQChat.rc
@@ -162,7 +162,7 @@
WS_VSCROLL
DEFPUSHBUTTON "Save Welcome Message",SAVEWELCOME,140,296,91,14,
BS_CENTER | BS_VCENTER
- LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
+ LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
IDC_STATIC,9,52,355,24
END
--- BPQMail.rc
+++ BPQMail.rc
@@ -1045,7 +1045,7 @@
CONTROL "Delete Log and Message Files to Recycle Bin",
IDC_DELETETORECYCLE,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | BS_MULTILINE | WS_TABSTOP,5,142,115,20
- CONTROL "Supress Mailing of Housekeeping Results",
+ CONTROL "Suppress Mailing of Housekeeping Results",
IDC_MAINTNOMAIL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
BS_MULTILINE | WS_TABSTOP,5,182,115,20
CONTROL "Generate Traffic Report",IDC_MAINTTRAFFIC,"Button",
--- HanksRT.c
+++ HanksRT.c
@@ -1186,7 +1186,7 @@
// Duplicate, so discard, but save time
DupInfo[i].DupTime = Now;
- Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s supressed", Call, Msg);
+ Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s suppressed", Call, Msg);
return TRUE; // Duplicate
}
--- RigControl.c
+++ RigControl.c
@@ -8385,7 +8385,7 @@
switch (Msg[0])
{
- case 'f': // Get Freqency
+ case 'f': // Get Frequency
HLGetFreq(Sock, RIG, sep);
return 0;
--- UZ7HODrv.c
+++ UZ7HODrv.c
@@ -374,7 +374,7 @@
{
// Read Freq
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Freqency %d\r", AGW->CenterFreq);
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Frequency %d\r", AGW->CenterFreq);
return 1;
}
@@ -382,7 +382,7 @@
if (AGW->CenterFreq == 0)
{
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Freqency\r");
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Frequency\r");
return 1;
}
--- WinRPRHelper.c
+++ WinRPRHelper.c
@@ -111,7 +111,7 @@
if (argc < 3)
{
- printf ("Missing paramters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
+ printf ("Missing parameters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
" WinRPRHelper com10 192.168.1.64:4532\r\n\r\n"
"Press any key to exit\r\n");
--- config.c
+++ config.c
@@ -649,7 +649,7 @@
if (LOCATOR[0] == 0 && LocSpecified == 0 && RFOnly == 0)
{
Consoleprintf("");
- Consoleprintf("Please enter a LOCATOR statment in your BPQ32.cfg");
+ Consoleprintf("Please enter a LOCATOR statement in your BPQ32.cfg");
Consoleprintf("If you really don't want to be on the Node Map you can enter LOCATOR=NONE");
Consoleprintf("");
--- kiss.c
+++ kiss.c
@@ -1485,7 +1485,7 @@
}
}
else
- Debugprintf("Polled KISS - response from wrong address - Polled %d Reponse %d",
+ Debugprintf("Polled KISS - response from wrong address - Polled %d Response %d",
KISS->POLLPOINTER->OURCTRL, (Port->RXMSG[0] & 0xf0));
goto SeeifMore; // SEE IF ANYTHING ELSE
--- templatedefs.c
+++ templatedefs.c
@@ -1165,7 +1165,7 @@
"Send Non-delivery Notifications<br>\r\n"
"for P and T messages <input %sname=\"SendND\" value=\"SendND\" type=\"checkbox\" /><br>\r\n"
" <br />\r\n"
- "Supress Mailing of<br>\r\n"
+ "Suppress Mailing of<br>\r\n"
"Housekeeping Result <input %sname=\"NoMail\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"Generate Traffic Report<input %sname=\"GenTraffic\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"<div style=\"text-align: center;\"><input class='btn' name=RunNow value=\"Run Housekeeping\" type=submit class='btn'></div>\r\n"
@@ -1454,7 +1454,7 @@
"<div style=\"text-align: left; width: 680px; margin: auto;\">The Nodes to link to box defines which other Chat Nodes should be connected to, or from which "
"connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4. If the node is not directly "
"connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands "
- "seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
+ "separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
"<br><br>The Callsign of the Chat Node is not defined here - it is obtained from the bpq32.cfg APPLICATION line corresponding to the Chat Appl Number.<br>\r\n"
"<br></div>\n"
--- WebMail.c
+++ WebMail.c
@@ -2020,7 +2020,7 @@
"document.getElementById('myform').action = '/WebMail/QuoteOriginal' + '?%s';"
" document.getElementById('myform').submit();}</script>"
"<input type=button class='btn' onclick='myfunc()' "
- "value='Include Orignal Msg'>";
+ "value='Include Original Msg'>";
char Temp[1024];
char ReplyAddr[128];

View File

@ -1412,10 +1412,11 @@ VOID * SIXPACKExtInit(EXTPORTDATA * PortEntry)
TNC->sixPack = zalloc(sizeof(struct sixPackTNCInfo)); TNC->sixPack = zalloc(sizeof(struct sixPackTNCInfo));
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_SIXPACK; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_SIXPACK;
TNC->ARDOPBuffer = malloc(8192); TNC->ARDOPBuffer = malloc(8192);
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

View File

@ -382,7 +382,8 @@ VOID * AEAExtInit(EXTPORTDATA * PortEntry)
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_AEA; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_AEA;
TNC->TEXTMODE = FALSE; TNC->TEXTMODE = FALSE;
@ -390,8 +391,6 @@ VOID * AEAExtInit(EXTPORTDATA * PortEntry)
TNC->InitScript = _strupr(TNC->InitScript); TNC->InitScript = _strupr(TNC->InitScript);
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
{ {
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

File diff suppressed because it is too large Load Diff

View File

@ -1,139 +0,0 @@
--- APRSCode.c
+++ APRSCode.c
@@ -3674,7 +3674,7 @@
if (ptr1)
*ptr1 = 0;
-// Debugprintf("Duplicate Message supressed %s", Msg);
+// Debugprintf("Duplicate Message suppressed %s", Msg);
return TRUE; // Duplicate
}
}
--- BPQChat.rc
+++ BPQChat.rc
@@ -162,7 +162,7 @@
WS_VSCROLL
DEFPUSHBUTTON "Save Welcome Message",SAVEWELCOME,140,296,91,14,
BS_CENTER | BS_VCENTER
- LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
+ LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
IDC_STATIC,9,52,355,24
END
--- BPQMail.rc
+++ BPQMail.rc
@@ -1045,7 +1045,7 @@
CONTROL "Delete Log and Message Files to Recycle Bin",
IDC_DELETETORECYCLE,"Button",BS_AUTOCHECKBOX |
BS_LEFTTEXT | BS_MULTILINE | WS_TABSTOP,5,142,115,20
- CONTROL "Supress Mailing of Housekeeping Results",
+ CONTROL "Suppress Mailing of Housekeeping Results",
IDC_MAINTNOMAIL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
BS_MULTILINE | WS_TABSTOP,5,182,115,20
CONTROL "Generate Traffic Report",IDC_MAINTTRAFFIC,"Button",
--- HanksRT.c
+++ HanksRT.c
@@ -1186,7 +1186,7 @@
// Duplicate, so discard, but save time
DupInfo[i].DupTime = Now;
- Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s supressed", Call, Msg);
+ Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s suppressed", Call, Msg);
return TRUE; // Duplicate
}
--- RigControl.c
+++ RigControl.c
@@ -8385,7 +8385,7 @@
switch (Msg[0])
{
- case 'f': // Get Freqency
+ case 'f': // Get Frequency
HLGetFreq(Sock, RIG, sep);
return 0;
--- UZ7HODrv.c
+++ UZ7HODrv.c
@@ -374,7 +374,7 @@
{
// Read Freq
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Freqency %d\r", AGW->CenterFreq);
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Frequency %d\r", AGW->CenterFreq);
return 1;
}
@@ -382,7 +382,7 @@
if (AGW->CenterFreq == 0)
{
- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Freqency\r");
+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Frequency\r");
return 1;
}
--- WinRPRHelper.c
+++ WinRPRHelper.c
@@ -111,7 +111,7 @@
if (argc < 3)
{
- printf ("Missing paramters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
+ printf ("Missing parameters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
" WinRPRHelper com10 192.168.1.64:4532\r\n\r\n"
"Press any key to exit\r\n");
--- config.c
+++ config.c
@@ -649,7 +649,7 @@
if (LOCATOR[0] == 0 && LocSpecified == 0 && RFOnly == 0)
{
Consoleprintf("");
- Consoleprintf("Please enter a LOCATOR statment in your BPQ32.cfg");
+ Consoleprintf("Please enter a LOCATOR statement in your BPQ32.cfg");
Consoleprintf("If you really don't want to be on the Node Map you can enter LOCATOR=NONE");
Consoleprintf("");
--- kiss.c
+++ kiss.c
@@ -1485,7 +1485,7 @@
}
}
else
- Debugprintf("Polled KISS - response from wrong address - Polled %d Reponse %d",
+ Debugprintf("Polled KISS - response from wrong address - Polled %d Response %d",
KISS->POLLPOINTER->OURCTRL, (Port->RXMSG[0] & 0xf0));
goto SeeifMore; // SEE IF ANYTHING ELSE
--- templatedefs.c
+++ templatedefs.c
@@ -1165,7 +1165,7 @@
"Send Non-delivery Notifications<br>\r\n"
"for P and T messages <input %sname=\"SendND\" value=\"SendND\" type=\"checkbox\" /><br>\r\n"
" <br />\r\n"
- "Supress Mailing of<br>\r\n"
+ "Suppress Mailing of<br>\r\n"
"Housekeeping Result <input %sname=\"NoMail\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"Generate Traffic Report<input %sname=\"GenTraffic\" value=\"Yes\" type=\"checkbox\"><br><br>\r\n"
"<div style=\"text-align: center;\"><input class='btn' name=RunNow value=\"Run Housekeeping\" type=submit class='btn'></div>\r\n"
@@ -1454,7 +1454,7 @@
"<div style=\"text-align: left; width: 680px; margin: auto;\">The Nodes to link to box defines which other Chat Nodes should be connected to, or from which "
"connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4. If the node is not directly "
"connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands "
- "seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
+ "separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
"<br><br>The Callsign of the Chat Node is not defined here - it is obtained from the bpq32.cfg APPLICATION line corresponding to the Chat Appl Number.<br>\r\n"
"<br></div>\n"
--- WebMail.c
+++ WebMail.c
@@ -2020,7 +2020,7 @@
"document.getElementById('myform').action = '/WebMail/QuoteOriginal' + '?%s';"
" document.getElementById('myform').submit();}</script>"
"<input type=button class='btn' onclick='myfunc()' "
- "value='Include Orignal Msg'>";
+ "value='Include Original Msg'>";
char Temp[1024];
char ReplyAddr[128];

18
ARDOP.c
View File

@ -136,6 +136,7 @@ BOOL ARDOPStopPort(struct PORTCONTROL * PORT)
if (TNC->Streams[0].Attached) if (TNC->Streams[0].Attached)
TNC->Streams[0].ReportDISC = TRUE; TNC->Streams[0].ReportDISC = TRUE;
TNC->Streams[0].Connecting = 0;
TNC->Streams[0].Connected = 0; TNC->Streams[0].Connected = 0;
TNC->Streams[0].Attached = 0; TNC->Streams[0].Attached = 0;
@ -888,7 +889,8 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (TNC->SessionTimeLimit && STREAM->ConnectTime && time(NULL) > (TNC->SessionTimeLimit + STREAM->ConnectTime)) if (TNC->SessionTimeLimit && STREAM->ConnectTime && time(NULL) > (TNC->SessionTimeLimit + STREAM->ConnectTime))
{ {
ARDOPSendCommand(TNC, "DISCONNECT", TRUE); ARDOPSendCommand(TNC, "DISCONNECT", TRUE);
STREAM->Disconnecting = TRUE; STREAM->ReportDISC = 1;
STREAM->AttachTime = 0;
} }
} }
@ -1979,6 +1981,7 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry;
if (TNC->LogPath) if (TNC->LogPath)
ARDOPOpenLogFiles(TNC); ARDOPOpenLogFiles(TNC);
@ -1991,7 +1994,7 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry)
if (TNC->ProgramPath) if (TNC->ProgramPath)
TNC->WeStartedTNC = RestartTNC(TNC); TNC->WeStartedTNC = RestartTNC(TNC);
TNC->Hardware = H_ARDOP; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_ARDOP;
if (TNC->BusyWait == 0) if (TNC->BusyWait == 0)
TNC->BusyWait = 10; TNC->BusyWait = 10;
@ -1999,7 +2002,6 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry)
if (TNC->BusyHold == 0) if (TNC->BusyHold == 0)
TNC->BusyHold = 1; TNC->BusyHold = 1;
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);
@ -2282,11 +2284,11 @@ VOID TNCLost(struct TNCINFO * TNC)
} }
if (STREAM->Attached) if (STREAM->Attached)
{
STREAM->Connected = FALSE;
STREAM->Connecting = FALSE;
STREAM->ReportDISC = TRUE; STREAM->ReportDISC = TRUE;
}
STREAM->Connected = FALSE;
STREAM->Connecting = FALSE;
} }
} }
@ -3318,9 +3320,9 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
} }
} }
if (_memicmp(Buffer, "DISCONNECTED", 12) == 0 if (_memicmp(Buffer, "DISCONNECTED", 12) == 0
|| _memicmp(Buffer, "STATUS CONNECT TO", 17) == 0 || _memicmp(Buffer, "STATUS CONNECT TO", 17) == 0
|| _memicmp(Buffer, "STATUS END ARQ CALL", 19) == 0
|| _memicmp(Buffer, "STATUS ARQ TIMEOUT FROM PROTOCOL STATE", 24) == 0 || _memicmp(Buffer, "STATUS ARQ TIMEOUT FROM PROTOCOL STATE", 24) == 0
// || _memicmp(Buffer, "NEWSTATE DISC", 13) == 0 // || _memicmp(Buffer, "NEWSTATE DISC", 13) == 0
|| _memicmp(Buffer, "ABORT", 5) == 0) || _memicmp(Buffer, "ABORT", 5) == 0)

View File

@ -932,7 +932,7 @@ int SendRIPTimer()
// Delay more if Locked - they could be retrying for a long time // Delay more if Locked - they could be retrying for a long time
if ((Route->NEIGHBOUR_FLAG & 1)) // LOCKED ROUTE if ((Route->NEIGHBOUR_FLAG)) // LOCKED ROUTE
INP3Delay = 1200; INP3Delay = 1200;
else else
INP3Delay = 600; INP3Delay = 600;

View File

@ -1147,6 +1147,7 @@
// Send forwarding info to packetnodes.spots.radio database (51) // Send forwarding info to packetnodes.spots.radio database (51)
// Fix bug in WP Message processing (56) // Fix bug in WP Message processing (56)
// Fix treating addresses ending in WW as Internet (57) // Fix treating addresses ending in WW as Internet (57)
// Run sending to packetnodes.spots.radio in a separate thread (61)
#include "bpqmail.h" #include "bpqmail.h"
#include "winstdint.h" #include "winstdint.h"

File diff suppressed because it is too large Load Diff

15
Bpq32.c
View File

@ -1243,11 +1243,16 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix MailAPI msgs endpoint // Fix MailAPI msgs endpoint
// Attempt to fix NC going to wrong application. (57) // Attempt to fix NC going to wrong application. (57)
// Improve ARDOP end of session code (58) // Improve ARDOP end of session code (58)
// Run M0LTE Map repoorting in a separate thread (59) // Run M0LTE Map reporting in a separate thread (59/60)
// Add support fro WhatsPac (59) // Add RHP support for WhatsPac (59)
// Add timestamps to LIS monitor // Add timestamps to LIS monitor (60)
// Fix problem with L4 frames being delivered out of sequence (60)
// Add Compression of Netrom connections (62)
// Improve handling of Locked Routes (62)
// Add L4 RESET (Paula G8PZT's extension to NETROM)
// Fix problem using SENDRAW from BPQMail (63)
// Fix compatibility with latest ardopcf (64)
// Fix bug in RHP socket timeout code (65)
#define CKernel #define CKernel

191
Cmd.c
View File

@ -1516,7 +1516,7 @@ VOID CMDP00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE * Routes, char Verbose) char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE * Routes, char Verbose)
{ {
char Normcall[10]; char Normcall[10];
char locked[] = " ! "; char locked[4] = " ";
int NodeCount; int NodeCount;
int Percent = 0; int Percent = 0;
char PercentString[20]; char PercentString[20];
@ -1530,11 +1530,16 @@ char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE *
Normcall[9]=0; Normcall[9]=0;
if ((Routes->NEIGHBOUR_FLAG & 1) == 1) if (Routes->NEIGHBOUR_FLAG == LOCKEDBYCONFIG)
strcpy(locked, "!"); strcpy(locked, "!");
else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP)
strcpy(locked, "!!");
else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP + LOCKEDBYCONFIG)
strcpy(locked, "!!!");
else else
strcpy(locked, " "); strcpy(locked, " ");
NodeCount = COUNTNODES(Routes); NodeCount = COUNTNODES(Routes);
if (Routes->NEIGHBOUR_LINK && Routes->NEIGHBOUR_LINK->L2STATE >= 5) if (Routes->NEIGHBOUR_LINK && Routes->NEIGHBOUR_LINK->L2STATE >= 5)
@ -1678,7 +1683,7 @@ ROUTEUPDATE:
{ {
// Toggle Lock // Toggle Lock
Routes->NEIGHBOUR_FLAG ^= 1; // FLIP LOCKED BIT Routes->NEIGHBOUR_FLAG ^= LOCKEDBYSYSOP; // FLIP LOCKED BIT
goto Displayit; goto Displayit;
} }
@ -1697,7 +1702,7 @@ ROUTEUPDATE:
{ {
// Toggle Lock // Toggle Lock
Routes->NEIGHBOUR_FLAG ^= 1; // FLIP LOCKED BIT Routes->NEIGHBOUR_FLAG ^= LOCKEDBYSYSOP; // FLIP LOCKED BIT
goto Displayit; goto Displayit;
} }
} }
@ -1711,167 +1716,6 @@ Displayit:
else else
Bufferptr = Cmdprintf(Session, Bufferptr, "Not Found\r"); Bufferptr = Cmdprintf(Session, Bufferptr, "Not Found\r");
/* MOV ROUTEDISP,1
CMP BYTE PTR [ESI],20H
JE SHORT JUSTDISPLAY
MOV ZAPFLAG,0
CMP BYTE PTR [ESI],'Z'
JNE SHORT NOTZAP
MOV ZAPFLAG,1
JMP SHORT JUSTDISPLAY
PUBLIC NOTZAP
NOTZAP:
MOV ROUTEDISP,2 ; LOCK UPDATE
CMP BYTE PTR [ESI],'!'
JE SHORT JUSTDISPLAY
;
; LOOK FOR V FOR ADDING A DIGI
;
CMP WORD PTR [ESI],' V' ; V [SPACE]
JE ADDDIGI
CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH
JC SHORT BADROUTECMD ; INVALID DIGITS
MOV NEWROUTEVAL,AL
MOV ROUTEDISP,0
CALL SCAN ; SEE IF !
MOV AH,[ESI]
PUBLIC JUSTDISPLAY
JUSTDISPLAY:
MOV ESI,OFFSET32 AX25CALL
CALL _FINDNEIGHBOUR
JZ SHORT FOUNDROUTE ; IN LIST - OK
CMP EBX,0
JE SHORT BADROUTECMD ; TABLE FULL??
MOV ECX,7
MOV EDI,EBX
REP MOVSB ; PUT IN CALL
MOV AL,SAVEPORT
MOV NEIGHBOUR_PORT[EBX],AL
JMP SHORT FOUNDROUTE
PUBLIC BADROUTECMD
BADROUTECMD:
POP EDI
JMP PBADVALUE
PUBLIC FOUNDROUTE
FOUNDROUTE:
CMP ZAPFLAG,1
JNE SHORT NOTCLEARCOUNTS
XOR AX,AX
MOV ES:WORD PTR NBOUR_IFRAMES[EDI],AX
MOV ES:WORD PTR NBOUR_IFRAMES+2[EDI],AX
MOV ES:WORD PTR NBOUR_RETRIES[EDI],AX
MOV ES:WORD PTR NBOUR_RETRIES+2[EDI],AX
JMP SHORT NOUPDATE
PUBLIC NOTCLEARCOUNTS
NOTCLEARCOUNTS:
CMP ROUTEDISP,1
JE SHORT NOUPDATE
CMP ROUTEDISP,2
JE SHORT LOCKUPDATE
MOV AL,NEWROUTEVAL
MOV NEIGHBOUR_QUAL[EBX],AL
CMP AH,'!'
JNE SHORT NOUPDATE
PUBLIC LOCKUPDATE
LOCKUPDATE:
XOR NEIGHBOUR_FLAG[EBX],1 ; FLIP LOCKED BIT
PUBLIC NOUPDATE
NOUPDATE:
MOV ESI,EBX
POP EDI
POP EBX
CALL DISPLAYROUTE
JMP SENDCOMMANDREPLY
PUBLIC ADDDIGI
ADDDIGI:
ADD ESI,2
PUSH ESI ; SAVE INPUT BUFFER
MOV ESI,OFFSET32 AX25CALL
CALL _FINDNEIGHBOUR
POP ESI
JZ SHORT ADD_FOUND ; IN LIST - OK
JMP BADROUTECMD
PUBLIC ADD_FOUND
ADD_FOUND:
CALL CONVTOAX25 ; GET DIGI CALLSIGN
PUSH ESI
MOV ESI,OFFSET32 AX25CALL
LEA EDI,NEIGHBOUR_DIGI[EBX]
MOV ECX,7
REP MOVSB
POP ESI ; MSG BUFFER
;
; SEE IF ANOTHER DIGI
;
CMP BYTE PTR [ESI],20H
JE SHORT NOMORE
CALL CONVTOAX25 ; GET DIGI CALLSIGN
MOV ESI,OFFSET32 AX25CALL
LEA EDI,NEIGHBOUR_DIGI+7[EBX]
MOV ECX,7
REP MOVSB
PUBLIC NOMORE
NOMORE:
JMP NOUPDATE
*/
SendReply: SendReply:
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
@ -4144,7 +3988,7 @@ VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc
if (ret & 0x8000) // Disconnecting if (ret & 0x8000) // Disconnecting
{ {
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use\r"); Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use (Disconnecting)\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return; return;
} }
@ -4195,14 +4039,25 @@ VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc
if (EXTPORT->ATTACHEDSESSIONS[sess] || PORT->PortSuspended) if (EXTPORT->ATTACHEDSESSIONS[sess])
{ {
// In use // In use
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use\r"); Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use (Session Attached\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER)); SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return; return;
} }
if (PORT->PortSuspended)
{
// In use
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port Suspended\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
// GET CIRCUIT TABLE ENTRY FOR OTHER END OF LINK // GET CIRCUIT TABLE ENTRY FOR OTHER END OF LINK
NewSess = SetupNewSession(Session, Bufferptr); NewSess = SetupNewSession(Session, Bufferptr);

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/ */
// General C Routines common to bpq32 and linbpq. Mainly moved from BPQ32.c // General C Routines common to bpq32 and linbpq. Mainly moved from BPQ32.c
#pragma data_seg("_BPQDATA") #pragma data_seg("_BPQDATA")
@ -914,7 +913,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
sprintf(Msg, "%d SCANSTOP", TNC->Port); sprintf(Msg, "%d SCANSTOP", TNC->Port);
Rig_Command( (TRANSPORTENTRY *) -1, Msg); Rig_Command((TRANSPORTENTRY *) -1, Msg);
UpdateMH(TNC, Call, '+', 'I'); UpdateMH(TNC, Call, '+', 'I');
} }
@ -1493,8 +1492,8 @@ int SendMsgEx(int stream, char * msg, int len, int GetSem)
if (QCOUNT < 50) if (QCOUNT < 50)
return 0; // Dont want to run out return 0; // Dont want to run out
if (GetSem) if (GetSem)
GetSemaphore(&Semaphore, 10); GetSemaphore(&Semaphore, 10);
if ((MSG = GetBuff()) == 0) if ((MSG = GetBuff()) == 0)
{ {
@ -1623,7 +1622,7 @@ DllExport int APIENTRY SendRaw(int port, char * msg, int len)
MSG->LENGTH = len + MSGHDDRLEN; MSG->LENGTH = len + MSGHDDRLEN;
if (PORT->PROTOCOL == 10 && PORT->TNC && PORT->TNC->Hardware != H_KISSHF) // PACTOR/WINMOR Style if (PORT->PROTOCOL == 10 && PORT->HWType != H_KISSHF) // PACTOR/WINMOR Style
{ {
// Pactor Style. Probably will only be used for Tracker unless we do APRS over V4 or WINMOR // Pactor Style. Probably will only be used for Tracker unless we do APRS over V4 or WINMOR
@ -2687,6 +2686,14 @@ int DoRoutes()
{ {
if (Routes->NEIGHBOUR_CALL[0] != 0) if (Routes->NEIGHBOUR_CALL[0] != 0)
{ {
// Dont save routes from config file here or they are difficult to get rid of
if (Routes->NEIGHBOUR_FLAG & LOCKEDBYCONFIG)
{
Routes++;
continue;
}
len=ConvFromAX25(Routes->NEIGHBOUR_CALL,Normcall); len=ConvFromAX25(Routes->NEIGHBOUR_CALL,Normcall);
Normcall[len]=0; Normcall[len]=0;
@ -2710,7 +2717,7 @@ int DoRoutes()
digis[0] = 0; digis[0] = 0;
len=sprintf(line, len=sprintf(line,
"ROUTE ADD %s %d %d %s %d %d %d %d %d\n", "ROUTE ADD %s %d %d %s %d %d %d %d %d %c\n",
Normcall, Normcall,
Routes->NEIGHBOUR_PORT, Routes->NEIGHBOUR_PORT,
Routes->NEIGHBOUR_QUAL, digis, Routes->NEIGHBOUR_QUAL, digis,
@ -2718,7 +2725,8 @@ int DoRoutes()
Routes->NBOUR_FRACK, Routes->NBOUR_FRACK,
Routes->NBOUR_PACLEN, Routes->NBOUR_PACLEN,
Routes->INP3Node | (Routes->NoKeepAlive << 2), Routes->INP3Node | (Routes->NoKeepAlive << 2),
Routes->OtherendsRouteQual); Routes->OtherendsRouteQual,
(Routes->NEIGHBOUR_FLAG & LOCKEDBYSYSOP)?'!':' ');
fputs(line, file); fputs(line, file);
} }

View File

@ -1180,7 +1180,6 @@ VOID * FLDigiExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry; TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
@ -1211,7 +1210,7 @@ VOID * FLDigiExtInit(EXTPORTDATA * PortEntry)
ptr=strchr(TNC->NodeCall, ' '); ptr=strchr(TNC->NodeCall, ' ');
if (ptr) *(ptr) = 0; // Null Terminate if (ptr) *(ptr) = 0; // Null Terminate
TNC->Hardware = H_FLDIGI; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_FLDIGI;
if (TNC->BusyWait == 0) if (TNC->BusyWait == 0)
TNC->BusyWait = 10; TNC->BusyWait = 10;

View File

@ -1393,14 +1393,14 @@ VOID * FreeDataExtInit(EXTPORTDATA * PortEntry)
Consoleprintf("FreeData Host %s %d", TNC->HostName, TNC->TCPPort); Consoleprintf("FreeData Host %s %d", TNC->HostName, TNC->TCPPort);
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_FREEDATA; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_FREEDATA;
TNC->WeStartedTNC = 1; TNC->WeStartedTNC = 1;
TNC->ARDOPDataBuffer = malloc(MAXRXSIZE); TNC->ARDOPDataBuffer = malloc(MAXRXSIZE);
TNC->ARDOPBuffer = malloc(FREEDATABUFLEN); TNC->ARDOPBuffer = malloc(FREEDATABUFLEN);
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

View File

@ -499,15 +499,15 @@ VOID * HALExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry;
TNC->Hardware = H_HAL; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_HAL;
if (PortEntry->PORTCONTROL.PORTINTERLOCK && TNC->RXRadio == 0 && TNC->TXRadio == 0) if (PortEntry->PORTCONTROL.PORTINTERLOCK && TNC->RXRadio == 0 && TNC->TXRadio == 0)
TNC->RXRadio = TNC->TXRadio = PortEntry->PORTCONTROL.PORTINTERLOCK; TNC->RXRadio = TNC->TXRadio = PortEntry->PORTCONTROL.PORTINTERLOCK;
PortEntry->MAXHOSTMODESESSIONS = 1; // Default PortEntry->MAXHOSTMODESESSIONS = 1; // Default
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
{ {

View File

@ -336,7 +336,8 @@ LRESULT CALLBACK PacWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
} }
#endif #endif
BOOL CreatePactorWindow(struct TNCINFO * TNC, char * ClassName, char * WindowTitle, int RigControlRow, WNDPROC WndProc, int Width, int Height, VOID ForcedCloseProc()) BOOL CreatePactorWindow(struct TNCINFO * TNC, char * ClassName, char * WindowTitle, int RigControlRow, WNDPROC WndProc, int Width, int Height,
VOID ForcedCloseProc(struct TNCINFO * TNC, int Stream))
{ {
#ifdef LINBPQ #ifdef LINBPQ
return FALSE; return FALSE;

View File

@ -1177,10 +1177,10 @@ VOID * HSMODEMExtInit(EXTPORTDATA * PortEntry)
Consoleprintf("HSMODEM Host %s %d", TNC->HostName, TNC->TCPPort); Consoleprintf("HSMODEM Host %s %d", TNC->HostName, TNC->TCPPort);
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_HSMODEM;
TNC->PortRecord = PortEntry; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_HSMODEM;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);
else else

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/ */
//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE
@ -71,6 +70,8 @@ BOOL SHA1PasswordHash(char * String, char * Hash);
char * byte_base64_encode(char *str, int len); char * byte_base64_encode(char *str, int len);
int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE); int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE);
int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE); int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE);
unsigned char * Compressit(unsigned char * In, int Len, int * OutLen);
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen);
extern struct ROUTE * NEIGHBOURS; extern struct ROUTE * NEIGHBOURS;
extern int ROUTE_LEN; extern int ROUTE_LEN;
@ -143,7 +144,7 @@ char Tail[] = "</body></html>";
char RouteHddr[] = "<h2 align=center>Routes</h2><table align=center border=2 style=font-family:monospace bgcolor=white>" char RouteHddr[] = "<h2 align=center>Routes</h2><table align=center border=2 style=font-family:monospace bgcolor=white>"
"<tr><th>Port</th><th>Call</th><th>Quality</th><th>Node Count</th><th>Frame Count</th><th>Retries</th><th>Percent</th><th>Maxframe</th><th>Frack</th><th>Last Heard</th><th>Queued</th><th>Rem Qual</th></tr>"; "<tr><th>Port</th><th>Call</th><th>Quality</th><th>Node Count</th><th>Frame Count</th><th>Retries</th><th>Percent</th><th>Maxframe</th><th>Frack</th><th>Last Heard</th><th>Queued</th><th>Rem Qual</th></tr>";
char RouteLine[] = "<tr><td>%s%d</td><td>%s%c</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d%</td><td>%d</td><td>%d</td><td>%02d:%02d</td><td>%d</td><td>%d</td></tr>"; char RouteLine[] = "<tr><td>%s%d</td><td>%s%s</td><td>%d</td><td>%d</td><td>%d</td><td>%d</td><td>%d%</td><td>%d</td><td>%d</td><td>%02d:%02d</td><td>%d</td><td>%d</td></tr>";
char xNodeHddr[] = "<align=center><form align=center method=get action=/Node/Nodes.html>" char xNodeHddr[] = "<align=center><form align=center method=get action=/Node/Nodes.html>"
"<table align=center bgcolor=white>" "<table align=center bgcolor=white>"
"<tr><td><input type=submit class='btn' name=a value=\"Nodes Sorted by Alias\"></td><td>" "<tr><td><input type=submit class='btn' name=a value=\"Nodes Sorted by Alias\"></td><td>"
@ -2412,7 +2413,10 @@ doHeader:
if (Session == 0) if (Session == 0)
Session = &Dummy; Session = &Dummy;
Session->TNC = LOCAL; // TNC is only used on Web Terminal Sessions so can reuse as LOCAL flag if (LOCAL)
Session->TNC = (struct TNCINFO *)(uintptr_t)1; // TNC is only used on Web Terminal Sessions so can reuse as LOCAL flag
else
Session->TNC = 0;
WriteFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL); WriteFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL);
WriteFile(hPipe, MsgPtr, MsgLen, &InputLen, NULL); WriteFile(hPipe, MsgPtr, MsgLen, &InputLen, NULL);
@ -3796,7 +3800,7 @@ doHeader:
int MaxRoutes = MAXNEIGHBOURS; int MaxRoutes = MAXNEIGHBOURS;
int count; int count;
char Normcall[10]; char Normcall[10];
char locked; char locked[4] = " ";
int NodeCount; int NodeCount;
int Percent = 0; int Percent = 0;
int Iframes, Retries; int Iframes, Retries;
@ -3812,10 +3816,14 @@ doHeader:
int len = ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall); int len = ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall);
Normcall[len]=0; Normcall[len]=0;
if ((Routes->NEIGHBOUR_FLAG & 1) == 1) if (Routes->NEIGHBOUR_FLAG == LOCKEDBYCONFIG)
locked = '!'; strcpy(locked, "!");
else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP)
strcpy(locked, "!!");
else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP + LOCKEDBYCONFIG)
strcpy(locked, "!!!");
else else
locked = ' '; strcpy(locked, " ");
NodeCount = COUNTNODES(Routes); NodeCount = COUNTNODES(Routes);
@ -4322,7 +4330,7 @@ int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char
{ {
int ReplyLen = 0; int ReplyLen = 0;
char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers
char * user, * password, * Key; char * user, * password;
struct HTTPConnectionInfo * NewSession; struct HTTPConnectionInfo * NewSession;
int i; int i;
struct UserRec * USER; struct UserRec * USER;

View File

@ -5413,11 +5413,8 @@ VOID ProcessSNMPMessage(PIPMSG IPptr)
int Len; int Len;
PUDPMSG UDPptr = (PUDPMSG)&IPptr->Data; PUDPMSG UDPptr = (PUDPMSG)&IPptr->Data;
UCHAR * Msg; UCHAR * Msg;
int Type;
int Length, ComLen;
int IntVal;
UCHAR Reply[256]; UCHAR Reply[256];
int PDULen, SendLen; int SendLen;
int Offset = 0; int Offset = 0;
Len = ntohs(IPptr->IPLENGTH); Len = ntohs(IPptr->IPLENGTH);

View File

@ -567,15 +567,15 @@ void * KAMExtInit(EXTPORTDATA * PortEntry)
return ExtProc; return ExtProc;
} }
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry;
TNC->Hardware = H_KAM; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_KAM;
if (TNC->BusyWait == 0) if (TNC->BusyWait == 0)
TNC->BusyWait = 10; TNC->BusyWait = 10;
PortEntry->MAXHOSTMODESESSIONS = 11; // Default PortEntry->MAXHOSTMODESESSIONS = 11; // Default
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

View File

@ -809,10 +809,10 @@ VOID * KISSHFExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_KISSHF; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_KISSHF;
TNC->ARDOPBuffer = malloc(8192); TNC->ARDOPBuffer = malloc(8192);
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

View File

@ -759,7 +759,7 @@ VOID L2FORUS(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buff
NO_CTEXT = 1; NO_CTEXT = 1;
if (ROUTE->NEIGHBOUR_FLAG == 1 && ROUTE->NEIGHBOUR_QUAL == 0) // Locked, qual 0 if (ROUTE->NEIGHBOUR_FLAG && ROUTE->NEIGHBOUR_QUAL == 0) // Locked, qual 0
{ {
ReleaseBuffer(Buffer); ReleaseBuffer(Buffer);
return; return;

View File

@ -319,13 +319,13 @@ VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
// if locked route with quality zero ignore // if locked route with quality zero ignore
if ((ROUTE->NEIGHBOUR_FLAG & 1)) // LOCKED ROUTE if ((ROUTE->NEIGHBOUR_FLAG)) // LOCKED ROUTE
if (ROUTE->NEIGHBOUR_QUAL == 0) if (ROUTE->NEIGHBOUR_QUAL == 0)
return; return;
// If Ignoreunlocked set, ignore it not locked // If Ignoreunlocked set, ignore it not locked
if ((ROUTE->NEIGHBOUR_FLAG & 1) == 0) // LOCKED ROUTE if ((ROUTE->NEIGHBOUR_FLAG) == 0) // LOCKED ROUTE
if (PORT->IgnoreUnlocked) if (PORT->IgnoreUnlocked)
return; return;
@ -333,7 +333,7 @@ VOID PROCESSNODEMESSAGE(MESSAGE * Msg, struct PORTCONTROL * PORT)
// if not locked, update route quality from port quality (may have changed config and not cleared SAVENODES // if not locked, update route quality from port quality (may have changed config and not cleared SAVENODES
if ((ROUTE->NEIGHBOUR_FLAG & 1) == 0) // Not LOCKED ROUTE if (ROUTE->NEIGHBOUR_FLAG == 0) // Not LOCKED ROUTE
ROUTE->NEIGHBOUR_QUAL = PORT->PORTQUALITY; ROUTE->NEIGHBOUR_QUAL = PORT->PORTQUALITY;
// GET TIME FROM BIOS DATA AREA OR RTC // GET TIME FROM BIOS DATA AREA OR RTC
@ -1038,7 +1038,7 @@ VOID L3TimerProc()
{ {
ROUTE++; ROUTE++;
if (ROUTE->NEIGHBOUR_FLAG & 1) // Locked? if (ROUTE->NEIGHBOUR_FLAG) // Locked?
continue; continue;
if (ROUTE->NEIGHBOUR_LINK) // Has an active Session if (ROUTE->NEIGHBOUR_LINK) // Has an active Session

517
L4Code.c
View File

@ -67,12 +67,18 @@ VOID ProcessRTTMsg(struct ROUTE * Route, struct _L3MESSAGEBUFFER * Buff, int Len
VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask, UCHAR * ApplCall); VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask, UCHAR * ApplCall);
void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode); void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode);
void SendVARANetromMsg(struct TNCINFO * TNC, PL3MESSAGEBUFFER MSG); void SendVARANetromMsg(struct TNCINFO * TNC, PL3MESSAGEBUFFER MSG);
unsigned char * Compressit(unsigned char * In, int Len, int * OutLen);
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen);
static UINT APPLMASK; static UINT APPLMASK;
extern BOOL LogL4Connects; extern BOOL LogL4Connects;
extern BOOL LogAllConnects; extern BOOL LogAllConnects;
extern int L4Compress;
extern int L4CompMaxframe;
extern int L4CompPaclen;
// L4 Flags Values // L4 Flags Values
#define DISCPENDING 8 // SEND DISC WHEN ALL DATA ACK'ED #define DISCPENDING 8 // SEND DISC WHEN ALL DATA ACK'ED
@ -341,6 +347,17 @@ VOID SENDL4MESSAGE(TRANSPORTENTRY * L4, struct DATAMESSAGE * Msg)
L3MSG->L4FLAGS = L4INFO | L4->NAKBITS; L3MSG->L4FLAGS = L4INFO | L4->NAKBITS;
if (Msg->PID == 0xF1) // Compressed Message
{
L3MSG->L4FLAGS |= L4COMP;
Msg->PID = 0xF0;
}
else if (Msg->PID == 0xF2) // Compressed Message - More to come
{
L3MSG->L4FLAGS |= (L4COMP | L4MORE);
Msg->PID = 0xF0;
}
L4->L4TIMER = L4->SESSIONT1; // SET TIMER L4->L4TIMER = L4->SESSIONT1; // SET TIMER
L4->L4ACKREQ = 0; // CANCEL ACK NEEDED L4->L4ACKREQ = 0; // CANCEL ACK NEEDED
@ -470,6 +487,9 @@ VOID SENDL4CONNECT(TRANSPORTENTRY * Session)
MSG->LENGTH = (int)(&MSG->L4DATA[17] - (UCHAR *)MSG); MSG->LENGTH = (int)(&MSG->L4DATA[17] - (UCHAR *)MSG);
if (L4Compress)
MSG->L4DATA[16] |= 0x40; // Set Compression Supported
if (Session->SPYFLAG) if (Session->SPYFLAG)
{ {
MSG->L4DATA[17] = 'Z'; // ADD SPY ON BBS FLAG MSG->L4DATA[17] = 'Z'; // ADD SPY ON BBS FLAG
@ -500,6 +520,53 @@ void RETURNEDTONODE(TRANSPORTENTRY * Session)
extern void * BUFFER; extern void * BUFFER;
void sendChunk(TRANSPORTENTRY * L4, unsigned char * Compressed, int complen, int savePort)
{
unsigned char * compdata;
struct DATAMESSAGE * Msg;
int sendLen = complen;
int fragments;
L4->SentAfterCompression += complen;
if (complen > L4CompPaclen)
{
fragments = (complen / L4CompPaclen); // Split to roughly equal sized fraagments
if (fragments * L4CompPaclen != complen)
fragments++;
sendLen = (complen / fragments) + 1;
}
compdata = Compressed;
while (complen > 0)
{
int PID = 0xF1;
if (complen > sendLen)
PID = 0xF2; // More to come
Msg = GetBuff();
if (!Msg)
return;
Msg->PORT = savePort;
memcpy(Msg->L2DATA, compdata, sendLen);
Msg->LENGTH = sendLen + MSGHDDRLEN + 1; // 1 for pid field
Msg->PID = PID; // Not sent so use as a flag for compressed msg
compdata += sendLen;
complen -= sendLen;
SENDL4MESSAGE(L4, Msg);
ReleaseBuffer(Msg);
}
}
VOID L4BG() VOID L4BG()
{ {
// PROCESS DATA QUEUED ON SESSIONS // PROCESS DATA QUEUED ON SESSIONS
@ -593,8 +660,151 @@ VOID L4BG()
if (L4->L4CIRCUITTYPE & SESSION) if (L4->L4CIRCUITTYPE & SESSION)
{ {
SENDL4MESSAGE(L4, Msg); // Now support compressing NetRom Sessions.
ReleaseBuffer(Msg); // We collect as much data as possible before compressing and re-packetizing
if (L4->AllowCompress)
{
int complen = 0;
unsigned char * Compressed;
int dataLen;
int savePort = Msg->PORT;
int maxCompSendLen;
// Save first packet, then see if more on TX_Q
L4->toCompress = malloc(8192);
L4->toCompressLen = 0;
dataLen = Msg->LENGTH - MSGHDDRLEN - 1; // No header or pid
L4->Sent += dataLen;
memcpy(&L4->toCompress[L4->toCompressLen], Msg->L2DATA, dataLen);
L4->toCompressLen += dataLen;
// See if first will compress. If not assume too short or already compressed data and just send
Compressed = Compressit(L4->toCompress, L4->toCompressLen, &complen);
if (complen >= dataLen)
{
free(Compressed);
L4->SentAfterCompression += dataLen;
SENDL4MESSAGE(L4, Msg);
ReleaseBuffer(Msg);
free(L4->toCompress);
L4->toCompress = 0;
L4->toCompressLen = 0;
continue;
}
// Worth compressing. Try to collect several packets
if (L4->L4TX_Q == 0)
{
// no more, so just send the stuff we've just compressed. Compressed data will fit in input packet
// Debugprintf("%d %d %d%%", L4->toCompressLen, complen, ((L4->toCompressLen - complen) * 100) / L4->toCompressLen);
memcpy(Msg->L2DATA, Compressed, complen);
Msg->PID = 0xF1; // Compressed
Msg->LENGTH = complen + MSGHDDRLEN + 1; // 1 for pid field
L4->SentAfterCompression += complen;
SENDL4MESSAGE(L4, Msg);
ReleaseBuffer(Msg);
free(L4->toCompress);
L4->toCompressLen = 0;
L4->toCompress = 0;
free(Compressed);
continue;
}
free(Compressed);
ReleaseBuffer(Msg); // Not going to use it
while (L4->L4TX_Q && L4->toCompressLen < (8192 - 256)) // Make sure can't overrin buffer
{
// Collect the data from L4TX_Q
Msg = Q_REM((void *)&L4->L4TX_Q);
dataLen = Msg->LENGTH - MSGHDDRLEN - 1; // No header or pid
L4->Sent += dataLen;
memcpy(&L4->toCompress[L4->toCompressLen], Msg->L2DATA, dataLen);
L4->toCompressLen += dataLen;
ReleaseBuffer(Msg);
}
L4->toCompress[L4->toCompressLen] = 0;
Compressed = Compressit(L4->toCompress, L4->toCompressLen, &complen);
// Debugprintf("%d %d %d%%", L4->toCompressLen, complen, ((L4->toCompressLen - complen) * 100) / L4->toCompressLen);
// Send compressed
// Fragment if more than L4CompPaclen
// Entered with original first fragment in saveMsg;
// Check for too big a compressed frame size. Bigger compresses better but adds latency to link
maxCompSendLen = L4CompPaclen * L4CompMaxframe;
if (complen > maxCompSendLen)
{
// Too Much Data. Needs to recompress less. To avoid too many recompresses be a bit conservative in calulating max size
// to allow for a bit less compression of part of data. Getting it wrong isn't fatal as sending more than optimum isn't fatal
int Fragments;
int ChunkSize;
unsigned char * CompressPtr = L4->toCompress;
int bytesleft = L4->toCompressLen;
// Assume 10% worse compression on smaller input
int j = (complen * 11) / 10; // New Comp size
Fragments = j / maxCompSendLen;
Fragments++;
ChunkSize = (L4->toCompressLen / Fragments) + 1; // 1 for rounding
while (bytesleft > 0)
{
int Len = bytesleft;
if (Len > ChunkSize)
Len = ChunkSize;
free (Compressed);
Compressed = Compressit(CompressPtr, Len, &complen);
// Debugprintf("Chunked %d %d %d%%", Len, complen, ((Len - complen) * 100) / Len);
sendChunk(L4, Compressed, complen, savePort);
CompressPtr += Len;
bytesleft -= Len;
}
}
else
sendChunk(L4, Compressed, complen,savePort);
free(L4->toCompress);
L4->toCompressLen = 0;
L4->toCompress = 0;
free(Compressed);
}
else
{
// Compression Disabled
SENDL4MESSAGE(L4, Msg);
ReleaseBuffer(Msg);
}
continue; continue;
} }
@ -703,12 +913,35 @@ VOID CLEARSESSIONENTRY(TRANSPORTENTRY * Session)
Session->L4RESEQ_Q = 0; Session->L4RESEQ_Q = 0;
} }
// if compressed session display stats
if (Session->Sent && Session->Received)
{
char SRCE[10];
char TO[10];
struct DEST_LIST * DEST = Session->L4TARGET.DEST;
SRCE[ConvFromAX25(Session->L4MYCALL, SRCE)] = 0;
TO[ConvFromAX25(DEST->DEST_CALL, TO)] = 0;
Debugprintf("L4 Compression Stats %s %s TX %d %d %d%% RX %d %d %d%%", SRCE, TO,
Session->Sent, Session->SentAfterCompression, ((Session->Sent - Session->SentAfterCompression) * 100) / Session->Sent,
Session->Received, Session->ReceivedAfterExpansion, ((Session->ReceivedAfterExpansion - Session->Received) * 100) / Session->Received);
}
while (Session->L4RESEQ_Q) while (Session->L4RESEQ_Q)
ReleaseBuffer(Q_REM((void *)&Session->L4RESEQ_Q)); ReleaseBuffer(Q_REM((void *)&Session->L4RESEQ_Q));
if (Session->PARTCMDBUFFER) if (Session->PARTCMDBUFFER)
ReleaseBuffer(Session->PARTCMDBUFFER); ReleaseBuffer(Session->PARTCMDBUFFER);
if (Session->toCompress)
free(Session->toCompress);
if (Session->unCompress)
free(Session->unCompress);
memset(Session, 0, sizeof(TRANSPORTENTRY)); memset(Session, 0, sizeof(TRANSPORTENTRY));
} }
@ -900,10 +1133,14 @@ VOID L4TimerProc()
L4->STAYFLAG = 0; L4->STAYFLAG = 0;
Partner = L4->L4CROSSLINK; Partner = L4->L4CROSSLINK;
CLOSECURRENTSESSION(L4); CLOSECURRENTSESSION(L4);
if (Partner) if (Partner)
{ {
// if compressed session display stats
Partner->L4KILLTIMER = 0; //ITS TIMES IS ALSO ABOUT TO EXPIRE Partner->L4KILLTIMER = 0; //ITS TIMES IS ALSO ABOUT TO EXPIRE
CLOSECURRENTSESSION(Partner); // CLOSE THIS ONE CLOSECURRENTSESSION(Partner); // CLOSE THIS ONE
} }
@ -978,6 +1215,8 @@ VOID L4TIMEOUT(TRANSPORTENTRY * L4)
{ {
// RETRIED N2 TIMES - FAIL LINK // RETRIED N2 TIMES - FAIL LINK
// if compressed session display stats
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT) CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return; return;
} }
@ -1250,6 +1489,7 @@ VOID SENDL4DISC(TRANSPORTENTRY * Session)
MSG->LENGTH = (int)(&MSG->L4DATA[0] - (UCHAR *)MSG); MSG->LENGTH = (int)(&MSG->L4DATA[0] - (UCHAR *)MSG);
C_Q_ADD(&DEST->DEST_Q, (UINT *)MSG); C_Q_ADD(&DEST->DEST_Q, (UINT *)MSG);
} }
@ -1458,6 +1698,9 @@ VOID SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER *
if (BPQNODE) if (BPQNODE)
{ {
L3MSG->L4DATA[1] = L3LIVES; // Our TTL L3MSG->L4DATA[1] = L3LIVES; // Our TTL
if (L4->AllowCompress)
L3MSG->L4DATA[1] |= 0x80;
L3MSG->LENGTH++; L3MSG->LENGTH++;
} }
@ -1559,6 +1802,25 @@ VOID SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
C_Q_ADD(&LINK->TX_Q, L3MSG); C_Q_ADD(&LINK->TX_Q, L3MSG);
} }
VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
{
// Paula's extension
L3MSG->L4FLAGS = L4RESET;
L3SWAPADDRESSES(L3MSG);
L3MSG->L3TTL = L3LIVES;
L3MSG->LENGTH = (int)(&L3MSG->L4DATA[0] - (UCHAR *)L3MSG);
C_Q_ADD(&LINK->TX_Q, L3MSG);
}
VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE) TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE)
{ {
@ -1573,8 +1835,9 @@ VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
L4->CIRCUITID = NEXTID; L4->CIRCUITID = NEXTID;
NEXTID++; NEXTID++;
if (NEXTID == 0)
NEXTID++; // kEEP nON-ZERO if (NEXTID == 0)
NEXTID++; // kEEP nON-ZERO
L4->SESSIONT1 = L4T1; L4->SESSIONT1 = L4T1;
@ -1597,10 +1860,18 @@ VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
// GET BPQ EXTENDED CONNECT PARAMS IF PRESENT // GET BPQ EXTENDED CONNECT PARAMS IF PRESENT
if (L3MSG->LENGTH == MSGHDDRLEN + 38 || L3MSG->LENGTH == MSGHDDRLEN + 39) if (L3MSG->LENGTH == MSGHDDRLEN + 38 || L3MSG->LENGTH == MSGHDDRLEN + 39)
{ {
*BPQNODE = 1; *BPQNODE = 1;
memcpy(BPQPARAMS, &L3MSG->L4DATA[15],L3MSG->LENGTH - (MSGHDDRLEN + 36)); memcpy(BPQPARAMS, &L3MSG->L4DATA[15],L3MSG->LENGTH - (MSGHDDRLEN + 36));
// 40 bit of 2nd byte is Compress Flag
if (BPQPARAMS[1] & 0x40 && L4Compress)
L4->AllowCompress = 1;
BPQPARAMS[1] &= 0xf; // Only bottom bit is significant in Timeeout field
} }
L4->L4CIRCUITTYPE = SESSION | UPLINK; L4->L4CIRCUITTYPE = SESSION | UPLINK;
@ -1658,7 +1929,7 @@ TryAgain:
{ {
SHORT T1; SHORT T1;
DEST->DEST_STATE |= 0x40; // SET BPQ _NODE BIT DEST->DEST_STATE |= 0x40; // SET BPQ NODE BIT
memcpy((char *)&T1, BPQPARAMS, 2); memcpy((char *)&T1, BPQPARAMS, 2);
if (T1 > 300) if (T1 > 300)
@ -1694,7 +1965,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
{ {
// INTERNODE LINK // INTERNODE LINK
TRANSPORTENTRY * L4; TRANSPORTENTRY * L4 = 0;
struct DEST_LIST * DEST; struct DEST_LIST * DEST;
int Opcode; int Opcode;
char Nodename[20]; char Nodename[20];
@ -1744,19 +2015,45 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
// OTHERS NEED A SESSION // OTHERS NEED A SESSION
L4 = &L4TABLE[L3MSG->L4INDEX]; if (Opcode == L4RESET)
if (L4->CIRCUITID!= L3MSG->L4ID)
{ {
// Paula's extension - other end dosn't know about session so disconnect
// A reset has our far index and id, not our index and id so have to search table for L4 entry
int n = MAXCIRCUITS;
L4 = L4TABLE;
while (n--)
{
if (L4->L4USER[0] && L4->FARID == L3MSG->L4ID && L4->FARINDEX == L3MSG->L4INDEX)
{
// Check L3 source call to be sure (should that be L4 source call??
L3MSG->L3SRCE[6] &= 0xfe; // mask end of call
if (memcmp(L3MSG->L3SRCE, L4->L4TARGET.DEST->DEST_CALL, 7) == 0)
{
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
}
ReleaseBuffer(L3MSG);
return;
}
L4++;
}
ReleaseBuffer(L3MSG); ReleaseBuffer(L3MSG);
return; return;
} }
if ((L4->L4CIRCUITTYPE & SESSION) == 0) if (L3MSG->L4INDEX < MAXCIRCUITS)
{ L4 = &L4TABLE[L3MSG->L4INDEX];
// Not an L4 Session - must be an old connection
ReleaseBuffer(L3MSG); // If wrong ID or not an L4 session we must have restarted or cleared session
if (L4 == 0 || L4->CIRCUITID != L3MSG->L4ID || (L4->L4CIRCUITTYPE & SESSION) == 0)
{
SendL4RESET(LINK, L3MSG); // Paula's extension
return; return;
} }
@ -1774,6 +2071,12 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
if (L3MSG->LENGTH > MSGHDDRLEN + 22) // Standard Msg if (L3MSG->LENGTH > MSGHDDRLEN + 22) // Standard Msg
{ {
if (L3MSG->L4DATA[1] & 0x80) // Compress Flag
{
L4->AllowCompress = 1;
L3MSG->L4DATA[1] &= 0x7f;
}
DEST->DEST_STATE &= 0x80; DEST->DEST_STATE &= 0x80;
DEST->DEST_STATE |= (L3MSG->L4DATA[1] - L3MSG->L3TTL) + 0x41; // Hops to dest + x40 DEST->DEST_STATE |= (L3MSG->L4DATA[1] - L3MSG->L3TTL) + 0x41; // Hops to dest + x40
} }
@ -1840,13 +2143,13 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
// DISCONNECT REQUEST // DISCONNECT REQUEST
L3MSG->L4INDEX = L4->FARINDEX; L3MSG->L4INDEX = L4->FARINDEX;
L3MSG->L4ID = L4->FARID; L3MSG->L4ID = L4->FARID;
L3MSG->L4FLAGS = L4DACK; L3MSG->L4FLAGS = L4DACK;
L3SWAPADDRESSES(L3MSG); // EXCHANGE SOURCE AND DEST L3SWAPADDRESSES(L3MSG); // EXCHANGE SOURCE AND DEST
L3MSG->L3TTL = L3LIVES; L3MSG->L3TTL = L3LIVES;
TNC = LINK->LINKPORT->TNC; TNC = LINK->LINKPORT->TNC;
@ -1855,8 +2158,8 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
else else
C_Q_ADD(&LINK->TX_Q, L3MSG); C_Q_ADD(&LINK->TX_Q, L3MSG);
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT) CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return; return;
case L4DACK: case L4DACK:
@ -1874,6 +2177,19 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
return; return;
} }
// Randomly drop packets
/*
Debugprintf("L4 Test Received packet %d ", L3MSG->L4TXNO);
if ((rand() % 7) > 5)
{
Debugprintf("L4 Test Drop packet %d ", L3MSG->L4TXNO);
ReleaseBuffer(L3MSG);
return;
}
*/
ACKFRAMES(L3MSG, L4, L3MSG->L4RXNO); ACKFRAMES(L3MSG, L4, L3MSG->L4RXNO);
// If DISCPENDING or STATE IS 4, THEN SESSION IS CLOSING - IGNORE ANY I FRAMES // If DISCPENDING or STATE IS 4, THEN SESSION IS CLOSING - IGNORE ANY I FRAMES
@ -1898,7 +2214,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
// FRAME IS A REPEAT // FRAME IS A REPEAT
Call[ConvFromAX25(L3MSG->L3SRCE, Call)] = 0; Call[ConvFromAX25(L3MSG->L3SRCE, Call)] = 0;
Debugprintf("Discarding repeated frame seq %d from %s", L3MSG->L4TXNO, Call); Debugprintf("L4 Discarding repeated frame seq %d from %s", L3MSG->L4TXNO, Call);
L4->L4ACKREQ = 1; L4->L4ACKREQ = 1;
ReleaseBuffer(L3MSG); ReleaseBuffer(L3MSG);
@ -1911,15 +2227,14 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
// AND KEEP THIS FRAME UNTIL MISSING ONE ARRIVES // AND KEEP THIS FRAME UNTIL MISSING ONE ARRIVES
L4->NAKBITS |= L4NAK; // SET NAK REQUIRED L4->NAKBITS |= L4NAK; // SET NAK REQUIRED
SENDL4IACK(L4); // SEND DATA ACK COMMAND TO ACK OUTSTANDING FRAMES SENDL4IACK(L4); // SEND DATA ACK COMMAND TO ACK OUTSTANDING FRAMES
// SEE IF WE ALREADY HAVE A COPY OF THIS ONE // SEE IF WE ALREADY HAVE A COPY OF THIS ONE
/*
Saved = L4->L4RESEQ_Q; Saved = L4->L4RESEQ_Q;
Call[ConvFromAX25(L3MSG->L3SRCE, Call)] = 0; Call[ConvFromAX25(L3MSG->L3SRCE, Call)] = 0;
Debugprintf("saving seq %d from %s", L3MSG->L4TXNO, Call); Debugprintf("L4 Out Of Seq saving seq %d from %s", L3MSG->L4TXNO, Call);
while (Saved) while (Saved)
{ {
@ -1927,7 +2242,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
{ {
// ALREADY HAVE A COPY - DISCARD IT // ALREADY HAVE A COPY - DISCARD IT
Debugprintf("Already have seq %d - discarding", L3MSG->L4TXNO); Debugprintf("L4 Already have seq %d - discarding", L3MSG->L4TXNO);
ReleaseBuffer(L3MSG); ReleaseBuffer(L3MSG);
return; return;
} }
@ -1937,7 +2252,6 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
C_Q_ADD(&L4->L4RESEQ_Q, L3MSG); // ADD TO CHAIN C_Q_ADD(&L4->L4RESEQ_Q, L3MSG); // ADD TO CHAIN
return; return;
*/
} }
// Frame is OK // Frame is OK
@ -1966,15 +2280,122 @@ L4INFO_OK:
L3MSG->L3PID = 0xF0; // Normal Data PID L3MSG->L3PID = 0xF0; // Normal Data PID
memmove(L3MSG->L3SRCE, L3MSG->L4DATA, L3MSG->LENGTH - (4 + sizeof(void *))); // if compressed, expand
REFRESHROUTE(L4); if ((L3MSG->L4FLAGS & L4COMP) == 0)
{
// Not Compressed
L4->Received += L3MSG->LENGTH - MSGHDDRLEN - 1;
L4->ReceivedAfterExpansion += L3MSG->LENGTH - MSGHDDRLEN - 1;
memmove(L3MSG->L3SRCE, L3MSG->L4DATA, L3MSG->LENGTH - (4 + sizeof(void *)));
IFRM150(L4, (PDATAMESSAGE)L3MSG); // CHECK IF SETTING UP AND PASS ON
}
else
{
char Buffer[8192];
int Len;
int outLen;
int sendLen;
char * sendptr;
int savePort = L3MSG->Port;
// May be more thsn one packet
Len = L3MSG->LENGTH - MSGHDDRLEN - 1;
L4->Received += Len;
if (L3MSG->L4FLAGS & L4MORE)
{
if (L4->unCompressLen == 0)
{
// New packet
L4->unCompress = malloc(8192);
}
// Save data
memcpy(&L4->unCompress[L4->unCompressLen], L3MSG->L4DATA, Len);
L4->unCompressLen += Len;
ReleaseBuffer(L3MSG);
goto checkReseq;
}
if (L4->unCompressLen)
{
// Already have some data - add this to it
memcpy(&L4->unCompress[L4->unCompressLen], L3MSG->L4DATA, Len);
L4->unCompressLen += Len;
Len = doinflate(L4->unCompress, Buffer, L4->unCompressLen, 8192, &outLen);
}
else
{
// Just inflate this bit
Len = doinflate(L3MSG->L4DATA, Buffer, L3MSG->LENGTH - MSGHDDRLEN - 1, 8192, &outLen);
}
free(L4->unCompress);
L4->unCompress = 0;
L4->unCompressLen = 0;
sendLen = outLen;
sendptr = Buffer;
L4->ReceivedAfterExpansion += outLen;
// Send first bit in input buffer. If still some left get new buffers for it
if (sendLen > 236)
sendLen = 236;
memcpy(L3MSG->L3SRCE, sendptr, sendLen); // Converting to DATAMESSAGE format
L3MSG->LENGTH = sendLen + MSGHDDRLEN + 1;
IFRM150(L4, (PDATAMESSAGE)L3MSG); // CHECK IF SETTING UP AND PASS ON
outLen -= sendLen;
sendptr += sendLen;
while (outLen > 0)
{
sendLen = outLen;
if (sendLen > 236)
sendLen = 236;
Msg = GetBuff();
if (Msg)
{
// Just ignore if no buffers - shouldn't happen
Msg->PID = 240;
Msg->PORT = savePort;
memcpy(Msg->L2DATA, sendptr, sendLen);
Msg->LENGTH = sendLen + MSGHDDRLEN + 1;
IFRM150(L4, Msg); // CHECK IF SETTING UP AND PASS ON
}
outLen -= sendLen;
sendptr += sendLen;
}
}
L4->L4ACKREQ = L4DELAY; // SEND INFO ACK AFTER L4DELAY (UNLESS I FRAME SENT) L4->L4ACKREQ = L4DELAY; // SEND INFO ACK AFTER L4DELAY (UNLESS I FRAME SENT)
REFRESHROUTE(L4);
IFRM150(L4, (PDATAMESSAGE)L3MSG); // CHECK IF SETTING UP AND PASS ON
// See if anything on reseq Q to process // See if anything on reseq Q to process
checkReseq:
if (L4->L4RESEQ_Q == 0) if (L4->L4RESEQ_Q == 0)
return; return;
@ -1993,11 +2414,11 @@ L4INFO_OK:
OLDFRAMES++; // COUNT FOR STATS OLDFRAMES++; // COUNT FOR STATS
L3MSG = Saved; L3MSG = Saved;
Debugprintf("Processing Saved Message %d Address %x", L4->RXSEQNO, L3MSG); Debugprintf("L4 Processing Saved Message %d Address %x", L4->RXSEQNO, L3MSG);
goto L4INFO_OK; goto L4INFO_OK;
} }
Debugprintf("Message %d %x still on Reseq Queue", Saved->L4TXNO, Saved); Debugprintf("L4 Message %d %x still on Reseq Queue", Saved->L4TXNO, Saved);
Prev = &Saved; Prev = &Saved;
Saved = Saved->Next; Saved = Saved->Next;
@ -2010,7 +2431,9 @@ L4INFO_OK:
ACKFRAMES(L3MSG, L4, L3MSG->L4RXNO); ACKFRAMES(L3MSG, L4, L3MSG->L4RXNO);
REFRESHROUTE(L4); REFRESHROUTE(L4);
// Drop Through ReleaseBuffer(L3MSG);
return;
} }
// Unrecognised - Ignore // Unrecognised - Ignore
@ -2066,10 +2489,13 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR)
RTT = GetTickCount() - L4->RTT_TIMER; RTT = GetTickCount() - L4->RTT_TIMER;
if (DEST->DEST_RTT == 0) if (RTT < 180) // Sanity Check
DEST->DEST_RTT = RTT; {
else if (DEST->DEST_RTT == 0)
DEST->DEST_RTT = ((DEST->DEST_RTT * 9) + RTT) /10; // 90% Old + New DEST->DEST_RTT = RTT;
else
DEST->DEST_RTT = ((DEST->DEST_RTT * 9) + RTT) /10; // 90% Old + New
}
} }
} }
@ -2106,7 +2532,7 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR)
L4->FLAGS |= L3MSG->L4FLAGS & L4BUSY; // Get Busy flag from message L4->FLAGS |= L3MSG->L4FLAGS & L4BUSY; // Get Busy flag from message
if ((L3MSG->L4FLAGS & L4NAK) == 0) if ((L3MSG->L4FLAGS & L4NAK) == 0)
return; // Dont send while biust unless NAC received return; // Dont send while busy unless NAK received
} }
if (L3MSG->L4FLAGS & L4NAK) if (L3MSG->L4FLAGS & L4NAK)
@ -2134,17 +2560,6 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR)
VOID SENDL4IACK(TRANSPORTENTRY * Session) VOID SENDL4IACK(TRANSPORTENTRY * Session)
{ {
// SEND INFO ACK // SEND INFO ACK
@ -2168,6 +2583,7 @@ VOID SENDL4IACK(TRANSPORTENTRY * Session)
MSG->L4TXNO = 0; MSG->L4TXNO = 0;
MSG->L4RXNO = Session->RXSEQNO; MSG->L4RXNO = Session->RXSEQNO;
Session->L4LASTACKED = Session->RXSEQNO; // SAVE LAST NUMBER ACKED Session->L4LASTACKED = Session->RXSEQNO; // SAVE LAST NUMBER ACKED
@ -2175,7 +2591,10 @@ VOID SENDL4IACK(TRANSPORTENTRY * Session)
MSG->LENGTH = MSGHDDRLEN + 22; MSG->LENGTH = MSGHDDRLEN + 22;
// Debugprintf("Sending L4 IACK %d %x", MSG->L4RXNO, MSG->L4FLAGS);
C_Q_ADD(&DEST->DEST_Q, (UINT *)MSG); C_Q_ADD(&DEST->DEST_Q, (UINT *)MSG);
} }

File diff suppressed because it is too large Load Diff

View File

@ -710,7 +710,7 @@ void * MPSKExtInit(EXTPORTDATA * PortEntry)
ptr=strchr(TNC->NodeCall, ' '); ptr=strchr(TNC->NodeCall, ' ');
if (ptr) *(ptr) = 0; // Null Terminate if (ptr) *(ptr) = 0; // Null Terminate
TNC->Hardware = H_MPSK; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_MPSK;
MPSKChannel[port] = PortEntry->PORTCONTROL.CHANNELNUM-65; MPSKChannel[port] = PortEntry->PORTCONTROL.CHANNELNUM-65;

View File

@ -728,6 +728,10 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
return Output + sprintf((char *)Output, " <DISC ACK>"); return Output + sprintf((char *)Output, " <DISC ACK>");
case L4RESET:
return Output + sprintf((char *)Output, " <RESET>");
case L4INFO: case L4INFO:
{ {
char Infofield[257]; char Infofield[257];
@ -746,6 +750,9 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
if (Flags & L4MORE) if (Flags & L4MORE)
*(Output++) = 'M'; *(Output++) = 'M';
if (Flags & L4COMP)
*(Output++) = 'C';
MsgLen = MsgLen - (19 + sizeof(void *)); MsgLen = MsgLen - (19 + sizeof(void *));
if (MsgLen < 0 || MsgLen > 257) if (MsgLen < 0 || MsgLen > 257)

View File

@ -1,641 +0,0 @@
/*
Copyright 2001-2022 John Wiseman G8BPQ
This file is part of LinBPQ/BPQ32.
LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LinBPQ/BPQ32 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/
/*
Paula (G8PZT)'s Remote Host Protocol interface.
For now only sufficient support for WhatsPac
*/
#define _CRT_SECURE_NO_DEPRECATE
#include "cheaders.h"
#include "bpq32.h"
int FindFreeStreamNoSem();
DllExport int APIENTRY DeallocateStream(int stream);
int SendMsgNoSem(int stream, char * msg, int len);
static void GetJSONValue(char * _REPLYBUFFER, char * Name, char * Value, int Len);
static int GetJSONInt(char * _REPLYBUFFER, char * Name);
// Generally Can have multiple RHP connections and each can have multiple RHF Sessions
struct RHPSessionInfo
{
SOCKET Socket; // Websocks Socket
int BPQStream;
int Handle; // RHP session ID
int Seq;
char Local[12];
char Remote[12];
BOOL Connecting; // Set while waiting for connection to complete
BOOL Listening;
BOOL Connected;
};
struct RHPConnectionInfo
{
SOCKET socket;
struct RHPSessionInfo ** RHPSessions;
int NumberofRHPSessions;
};
struct RHPConnectionInfo ** RHPSockets = NULL;
int NumberofRHPConnections = 0;
struct RHPSessionInfo ** RHPSessions;
int NumberofRHPSessions;
char ErrCodes[18][24] =
{"Ok", "Unspecified", "Bad or missing type", "Invalid handle", "No memory", "Bad or missing mode",
"Invalid local address",
"Invalid remote address" ,
"Bad or missing family" ,
"Duplicate socket" ,
"No such port" ,
"Invalid protocol" ,
"Bad parameter" ,
"No buffers" ,
"Unauthorised" ,
"No Route" ,
"Operation not supported"};
extern char pgm[256];
SOCKET agwsock;
extern int SemHeldByAPI;
char szBuff[80];
int WhatsPacConfigured = 1;
int RHPPaclen = 236;
int processRHCPOpen(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer);
int processRHCPSend(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer);
int processRHCPClose(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer);
void SendWebSockMessage(SOCKET socket, char * Msg, int Len)
{
int Loops = 0;
int Sent;
int TxLen;
char * OutBuffer = Msg;
// WebSock Encode. Buffer has 10 bytes on front for header but header len depends on Msg len
if (Len < 126)
{
// Two Byte Header
OutBuffer[8] = 0x81; // Fin, Data
OutBuffer[9] = Len;
TxLen = Len + 2;
OutBuffer = &Msg[8];
}
else if (Len < 65536)
{
OutBuffer[6] = 0x81; // Fin, Data
OutBuffer[7] = 126; // Unmasked, Extended Len 16
OutBuffer[8] = Len >> 8;
OutBuffer[9] = Len & 0xff;
TxLen = Len + 4;
OutBuffer = &Msg[6];
}
else
{
OutBuffer[0] = 0x81; // Fin, Data
OutBuffer[1] = 127; // Unmasked, Extended Len 64 bits
// Len is 32 bits, so pad with zeros
OutBuffer[2] = 0;
OutBuffer[3] = 0;
OutBuffer[4] = 0;
OutBuffer[5] = 0;
OutBuffer[6] = (Len >> 24) & 0xff;
OutBuffer[7] = (Len >> 16) & 0xff;
OutBuffer[8] = (Len >> 8) & 0xff;
OutBuffer[9] = Len & 0xff;
TxLen = Len + + 10;
OutBuffer = &Msg[0];
}
// Send may block
Sent = send(socket, OutBuffer, TxLen, 0);
while (Sent != TxLen && Loops++ < 3000) // 100 secs max
{
if (Sent > 0) // something sent
{
TxLen -= Sent;
memmove(OutBuffer, &OutBuffer[Sent], TxLen);
}
Sleep(30);
Sent = send(socket, OutBuffer, TxLen, 0);
if (Sent == -1)
break;
}
free(Msg);
return;
}
int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE)
{
// RHP messages can be sent over Websocks or normal http but I think WhatsPac only uses WebSocks
return 0;
}
void ProcessRHPWebSock(SOCKET socket, char * Msg, int MsgLen)
{
int Loops = 0;
int InputLen = 0;
int Len;
char Value[16];
char * OutBuffer = malloc(250000);
struct RHPConnectionInfo * RHPSocket = NULL;
int n;
Msg[MsgLen] = 0;
// Find Connection Record. If none, create one
for (n = 0; n < NumberofRHPConnections; n++)
{
if (RHPSockets[n]->socket == socket)
{
RHPSocket = RHPSockets[n];
break;
}
}
if (RHPSocket == 0)
{
NumberofRHPConnections;
RHPSockets = realloc(RHPSockets, sizeof(void *) * (NumberofRHPConnections + 1));
RHPSocket = RHPSockets[NumberofRHPConnections] = zalloc(sizeof (struct RHPConnectionInfo));
NumberofRHPConnections++;
RHPSocket->socket = socket;
}
// {"type":"open","id":5,"pfam":"ax25","mode":"stream","port":"1","local":"G8BPQ","remote":"G8BPQ-2","flags":128}
// {"type": "openReply", "id": 82, "handle": 1, "errCode": 0, "errText": "Ok"}
// {"seqno": 0, "type": "status", "handle": 1, "flags": 0}
// ("seqno": 1, "type": "close", "handle": 1}
// {"id":40,"type":"close","handle":1}
// {"seqno": 0, "type": "status", "handle": 1, "flags": 2}.~.
// {"seqno": 1, "type": "recv", "handle": 1, "data": "Welcome to G8BPQ's Test Switch in Nottingham \rType ? for list of available commands.\r"}.
GetJSONValue(Msg, "\"type\":", Value, 15);
if (_stricmp(Value, "open") == 0)
{
Len = processRHCPOpen(RHPSocket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
if (Len)
SendWebSockMessage(RHPSocket->socket, OutBuffer, Len);
return;
}
if (_stricmp(Value, "send") == 0)
{
Len = processRHCPSend(RHPSocket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
SendWebSockMessage(RHPSocket->socket, OutBuffer, Len);
return;
}
if (_stricmp(Value, "close") == 0)
{
Len = processRHCPClose(RHPSocket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
SendWebSockMessage(RHPSocket->socket, OutBuffer, Len);
return;
}
Debugprintf(Msg);
}
void ProcessRHPWebSockClosed(SOCKET socket)
{
// Close any connections on this scoket and delete socket entry
struct RHPConnectionInfo * RHPSocket = NULL;
int n;
// Find Connection Record. CLear any Sessions
for (n = 0; n < NumberofRHPConnections; n++)
{
if (RHPSockets[n]->socket == socket)
{
RHPSocket = RHPSockets[n];
break;
}
}
}
int processRHCPOpen(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer)
{
//{"type":"open","id":5,"pfam":"ax25","mode":"stream","port":"1","local":"G8BPQ","remote":"G8BPQ-2","flags":128}
struct RHPSessionInfo * RHPSession = 0;
char * Value = malloc(strlen(Msg)); // Will always be long enough
int ID;
char pfam[16];
char Mode[16];
int Port;
char Local[16];
char Remote[16];
int flags;
int Handle = 1;
int Stream;
unsigned char AXCall[10];
int Len;
int n;
// ID seems to be used for control commands like open. SeqNo for data within a session (i Think!
ID = GetJSONInt(Msg, "\"id\":");
GetJSONValue(Msg, "\"pfam\":", pfam, 15);
GetJSONValue(Msg, "\"mode\":", Mode, 15);
Port = GetJSONInt(Msg, "\"port\":");
GetJSONValue(Msg, "\"local\":", Local, 15);
GetJSONValue(Msg, "\"remote\":", Remote, 15);
flags = GetJSONInt(Msg, "\"flags\":");
if (_stricmp(pfam, "ax25") != 0)
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0);
if (_stricmp(Mode, "stream") == 0)
{
{
// Allocate a RHP Session
// See if there is an old one we can reuse
for (n = 0; n < NumberofRHPSessions; n++)
{
if (RHPSessions[n]->BPQStream == 0)
{
RHPSession = RHPSessions[n];
Handle = n + 1;
Stream = RHPSessions[n]->BPQStream;
break;
}
}
if (RHPSession == 0)
{
RHPSessions = realloc(RHPSessions, sizeof(void *) * (NumberofRHPSessions + 1));
RHPSession = RHPSessions[NumberofRHPSessions] = zalloc(sizeof (struct RHPSessionInfo));
NumberofRHPSessions++;
Handle = NumberofRHPSessions;
}
strcpy(pgm, "RHP");
Stream = FindFreeStreamNoSem();
strcpy(pgm, "bpq32.exe");
if (Stream == 255)
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0);
RHPSession->BPQStream = Stream;
RHPSession->Handle = Handle;
RHPSession->Connecting = TRUE;
RHPSession->Socket = RHPSocket->socket;
strcpy(RHPSession->Local, Local);
strcpy(RHPSession->Remote, Remote);
Connect(Stream);
ConvToAX25(Local, AXCall);
ChangeSessionCallsign(Stream, AXCall);
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 0, \"errText\": \"Ok\"}", ID, Handle);
}
}
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0);
}
int processRHCPSend(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer)
{
// {"type":"send","handle":1,"data":";;;;;;\r","id":70}
struct RHPSessionInfo * RHPSession;
int ID;
char * Data;
char * ptr;
int c;
int Len;
int Handle = 1;
Data = malloc(strlen(Msg));
ID = GetJSONInt(Msg, "\"id\":");
Handle = GetJSONInt(Msg, "\"handle\":");
GetJSONValue(Msg, "\"data\":", Data, strlen(Msg) - 1);
if (Handle < 1 || Handle > NumberofRHPSessions)
{
free(Data);
return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errtext\": \"Invalid handle\"}", ID, Handle);
}
RHPSession = RHPSessions[Handle - 1];
// Look for \ escapes
ptr = Data;
while (ptr = strchr(ptr, '\\'))
{
c = ptr[1];
switch (c)
{
case 'r':
*ptr = 13;
break;
case '\\':
*ptr = '\\';
break;
case '"':
*ptr = '"';
break;
}
memmove(ptr + 1, ptr + 2, strlen(ptr + 1));
ptr++;
}
Debugprintf(Data);
Len = strlen(Data);
ptr = Data;
while (Len > RHPPaclen)
{
SendMsgNoSem(RHPSession->BPQStream, ptr, RHPPaclen);
Len -= RHPPaclen;
ptr += RHPPaclen;
}
SendMsgNoSem(RHPSession->BPQStream, ptr, Len);
free(Data);
return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 0, \"errText\": \"Ok\", \"status\": %d}", ID, Handle, 2);
}
int processRHCPClose(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer)
{
// {"id":70,"type":"close","handle":1}
struct RHPSessionInfo * RHPSession;
int ID;
int Handle = 1;
char * OutBuffer = malloc(256);
ID = GetJSONInt(Msg, "\"id\":");
Handle = GetJSONInt(Msg, "\"handle\":");
if (Handle < 1 || Handle > NumberofRHPSessions)
return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 12, \"errtext\": \"Invalid handle\"}", ID, Handle);
RHPSession = RHPSessions[Handle - 1];
Disconnect(RHPSession->BPQStream);
RHPSession->Connected = 0;
RHPSession->Connecting = 0;
DeallocateStream(RHPSession->BPQStream);
RHPSession->BPQStream = 0;
return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 0, \"errtext\": \"Ok\"}", ID, Handle);
}
void RHPPoll()
{
int Stream;
int n;
int state, change;
int Len;
char * RHPMsg;
unsigned char Buffer[1024]; // Space to escape control chars
int pktlen, count;
struct RHPSessionInfo * RHPSession;
for (n = 0; n < NumberofRHPSessions; n++)
{
RHPSession = RHPSessions[n];
Stream = RHPSession->BPQStream;
// See if connected state has changed
SessionState(Stream, &state, &change);
if (change == 1)
{
if (state == 1)
{
// Connected
RHPSession->Seq = 0;
RHPSession->Connecting = FALSE;
RHPSession->Connected = TRUE;
RHPMsg = malloc(256);
Len = sprintf(&RHPMsg[10], "{\"seqno\": %d, \"type\": \"status\", \"handle\": %d, \"flags\": 2}", RHPSession->Seq++, RHPSession->Handle);
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
// Send RHP CTEXT
RHPMsg = malloc(256);
Len = sprintf(&RHPMsg[10], "{\"seqno\": %d, \"type\": \"recv\", \"handle\": %d, \"data\": \"Connected to RHP Server\\r\"}", RHPSession->Seq++, RHPSession->Handle);
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
}
else
{
// Disconnected. Send Close to client
RHPMsg = malloc(256);
Len = sprintf(&RHPMsg[10], "{\"type\": \"close\", \"seqno\": %d, \"handle\": %d}", RHPSession->Seq++, RHPSession->Handle);
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
RHPSession->Connected = 0;
RHPSession->Connecting = 0;
DeallocateStream(RHPSession->BPQStream);
RHPSession->BPQStream = 0;
}
}
do
{
GetMsg(Stream, Buffer, &pktlen, &count);
if (pktlen > 0)
{
char * ptr = Buffer;
char c;
Buffer[pktlen] = 0;
// Message is JSON so Convert CR to \r, \ to \\ " to \"
while (c = *(ptr))
{
switch (c)
{
case 13:
memmove(ptr + 2, ptr + 1, strlen(ptr));
*(ptr++) = '\\';
*(ptr++) = 'r';
break;
case '"':
memmove(ptr + 2, ptr + 1, strlen(ptr));
*(ptr++) = '\\';
*(ptr++) = '"';
break;
case '\\':
memmove(ptr + 2, ptr + 1, strlen(ptr));
*(ptr++) = '\\';
*(ptr++) = '\\';
break;
}
ptr++;
}
RHPMsg = malloc(1024);
Len = sprintf(&RHPMsg[10], "{\"seqno\": %d, \"type\": \"recv\", \"handle\": %d, \"data\": \"%s\"}", RHPSession->Seq++, RHPSession->Handle, Buffer);
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
}
}
while (count > 0);
}
}
static void GetJSONValue(char * _REPLYBUFFER, char * Name, char * Value, int Len)
{
char * ptr1, * ptr2;
Value[0] = 0;
ptr1 = strstr(_REPLYBUFFER, Name);
if (ptr1 == 0)
return;
ptr1 += (strlen(Name) + 1);
// "data":"{\"t\":\"c\",\"n\":\"John\",\"c\":\"G8BPQ\",\"lm\":1737912636,\"le\":1737883907,\"led\":1737758451,\"v\":0.33,\"cc\":[{\"cid\":1,\"lp\":1737917257201,\"le\":1737913735726,\"led\":1737905249785},{\"cid\":0,\"lp\":1737324074107,\"le\":1737323831510,\"led\":1737322973662},{\"cid\":5,\"lp\":1737992107419,\"le\":1737931466510,\"led\":1737770056244}]}\r","id":28}
// There may be escaped " in data stream
ptr2 = strchr(ptr1, '"');
while (*(ptr2 - 1) == '\\')
{
ptr2 = strchr(ptr2 + 2, '"');
}
if (ptr2)
{
size_t ValLen = ptr2 - ptr1;
if (ValLen > Len)
ValLen = Len;
memcpy(Value, ptr1, ValLen);
Value[ValLen] = 0;
}
return;
}
static int GetJSONInt(char * _REPLYBUFFER, char * Name)
{
char * ptr1;
ptr1 = strstr(_REPLYBUFFER, Name);
if (ptr1 == 0)
return 0;
ptr1 += (strlen(Name));
return atoi(ptr1);
}

107
RHP.c
View File

@ -28,6 +28,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "cheaders.h" #include "cheaders.h"
#include "bpq32.h" #include "bpq32.h"
#include "telnetserver.h"
int FindFreeStreamNoSem(); int FindFreeStreamNoSem();
DllExport int APIENTRY DeallocateStream(int stream); DllExport int APIENTRY DeallocateStream(int stream);
@ -40,6 +41,7 @@ static int GetJSONInt(char * _REPLYBUFFER, char * Name);
struct RHPSessionInfo struct RHPSessionInfo
{ {
struct ConnectionInfo * sockptr;
SOCKET Socket; // Websocks Socket SOCKET Socket; // Websocks Socket
int BPQStream; int BPQStream;
int Handle; // RHP session ID int Handle; // RHP session ID
@ -49,6 +51,7 @@ struct RHPSessionInfo
BOOL Connecting; // Set while waiting for connection to complete BOOL Connecting; // Set while waiting for connection to complete
BOOL Listening; BOOL Listening;
BOOL Connected; BOOL Connected;
int Busy;
}; };
struct RHPConnectionInfo struct RHPConnectionInfo
@ -65,6 +68,7 @@ struct RHPParamBlock
unsigned char * Msg; unsigned char * Msg;
int Len; int Len;
SOCKET Socket; SOCKET Socket;
struct ConnectionInfo * sockptr;
}; };
@ -76,19 +80,24 @@ struct RHPSessionInfo ** RHPSessions;
int NumberofRHPSessions; int NumberofRHPSessions;
char ErrCodes[18][24] = char ErrCodes[18][24] =
{"Ok", "Unspecified", "Bad or missing type", "Invalid handle", "No memory", "Bad or missing mode", {
"Ok",
"Invalid local address", "Unspecified",
"Invalid remote address" , "Bad or missing type",
"Bad or missing family" , "Invalid handle",
"Duplicate socket" , "No memory",
"No such port" , "Bad or missing mode",
"Invalid protocol" , "Invalid local address",
"Bad parameter" , "Invalid remote address" ,
"No buffers" , "Bad or missing family" ,
"Unauthorised" , "Duplicate socket" ,
"No Route" , "No such port" ,
"Operation not supported"}; "Invalid protocol" ,
"Bad parameter" ,
"No buffers" ,
"Unauthorised" ,
"No Route" ,
"Operation not supported"};
@ -107,9 +116,10 @@ int WhatsPacConfigured = 1;
int RHPPaclen = 236; int RHPPaclen = 236;
int processRHCPOpen(SOCKET Socket, char * Msg, char * ReplyBuffer); int processRHCPOpen(struct ConnectionInfo * sockptr, SOCKET Socket, char * Msg, char * ReplyBuffer);
int processRHCPSend(SOCKET Socket, char * Msg, char * ReplyBuffer); int processRHCPSend(SOCKET Socket, char * Msg, char * ReplyBuffer);
int processRHCPClose(SOCKET Socket, char * Msg, char * ReplyBuffer); int processRHCPClose(SOCKET Socket, char * Msg, char * ReplyBuffer);
int processRHCPStatus(SOCKET Socket, char * Msg, char * ReplyBuffer);
@ -122,7 +132,6 @@ void SendWebSockMessage(SOCKET socket, char * Msg, int Len)
// WebSock Encode. Buffer has 10 bytes on front for header but header len depends on Msg len // WebSock Encode. Buffer has 10 bytes on front for header but header len depends on Msg len
if (Len < 126) if (Len < 126)
{ {
// Two Byte Header // Two Byte Header
@ -182,7 +191,7 @@ void SendWebSockMessage(SOCKET socket, char * Msg, int Len)
return; return;
} }
void ProcessRHPWebSock(SOCKET Socket, char * Msg, int MsgLen); void ProcessRHPWebSock(struct ConnectionInfo * sockptr, SOCKET Socket, char * Msg, int MsgLen);
void RHPThread(void * Params) void RHPThread(void * Params)
{ {
@ -190,7 +199,7 @@ void RHPThread(void * Params)
struct RHPParamBlock * Block = (struct RHPParamBlock *)Params; struct RHPParamBlock * Block = (struct RHPParamBlock *)Params;
ProcessRHPWebSock(Block->Socket, Block->Msg, Block->Len); ProcessRHPWebSock(Block->sockptr, Block->Socket, Block->Msg, Block->Len);
free(Block->Msg); free(Block->Msg);
free(Params); free(Params);
@ -202,7 +211,7 @@ int RHPProcessHTTPMessage(void * conn, char * response, char * Method, char * UR
return 0; return 0;
} }
void ProcessRHPWebSock(SOCKET Socket, char * Msg, int MsgLen) void ProcessRHPWebSock(struct ConnectionInfo * sockptr, SOCKET Socket, char * Msg, int MsgLen)
{ {
int Loops = 0; int Loops = 0;
int InputLen = 0; int InputLen = 0;
@ -264,11 +273,14 @@ void ProcessRHPWebSock(SOCKET Socket, char * Msg, int MsgLen)
// {"seqno": 0, "type": "status", "handle": 1, "flags": 2}.~. // {"seqno": 0, "type": "status", "handle": 1, "flags": 2}.~.
// {"seqno": 1, "type": "recv", "handle": 1, "data": "Welcome to G8BPQ's Test Switch in Nottingham \rType ? for list of available commands.\r"}. // {"seqno": 1, "type": "recv", "handle": 1, "data": "Welcome to G8BPQ's Test Switch in Nottingham \rType ? for list of available commands.\r"}.
// {"type": "status", "handle": 0}. XRouter will reply with {"type": "statusReply", "handle": 0, "errcode": 12, "errtext": "invalid handle"}. It
// {type: 'keepalive'} if there has been no other activity for nearly 3 minutes. Replies with {"type": "keepaliveReply"}
GetJSONValue(Msg, "\"type\":", Value, 15); GetJSONValue(Msg, "\"type\":", Value, 15);
if (_stricmp(Value, "open") == 0) if (_stricmp(Value, "open") == 0)
{ {
Len = processRHCPOpen(Socket, Msg, &OutBuffer[10]); // Space at front for WebSock Header Len = processRHCPOpen(sockptr, Socket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
if (Len) if (Len)
SendWebSockMessage(Socket, OutBuffer, Len); SendWebSockMessage(Socket, OutBuffer, Len);
return; return;
@ -287,7 +299,22 @@ void ProcessRHPWebSock(SOCKET Socket, char * Msg, int MsgLen)
SendWebSockMessage(Socket, OutBuffer, Len); SendWebSockMessage(Socket, OutBuffer, Len);
return; return;
} }
Debugprintf(Msg);
if (_stricmp(Value, "status") == 0)
{
Len = processRHCPStatus(Socket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
SendWebSockMessage(Socket, OutBuffer, Len);
return;
}
if (_stricmp(Value, "keepalive") == 0)
{
Len = sprintf(&OutBuffer[10], "{\"type\": \"keepaliveReply\"}"); // Space at front for WebSock Header
SendWebSockMessage(Socket, OutBuffer, Len);
return;
}
Debugprintf("Unrecognised RHP Message - %s", Msg);
} }
void ProcessRHPWebSockClosed(SOCKET socket) void ProcessRHPWebSockClosed(SOCKET socket)
@ -326,7 +353,7 @@ void ProcessRHPWebSockClosed(SOCKET socket)
int processRHCPOpen(SOCKET Socket, char * Msg, char * ReplyBuffer) int processRHCPOpen(struct ConnectionInfo * sockptr, SOCKET Socket, char * Msg, char * ReplyBuffer)
{ {
//{"type":"open","id":5,"pfam":"ax25","mode":"stream","port":"1","local":"G8BPQ","remote":"G8BPQ-2","flags":128} //{"type":"open","id":5,"pfam":"ax25","mode":"stream","port":"1","local":"G8BPQ","remote":"G8BPQ-2","flags":128}
@ -344,7 +371,7 @@ int processRHCPOpen(SOCKET Socket, char * Msg, char * ReplyBuffer)
int Handle = 1; int Handle = 1;
int Stream; int Stream;
unsigned char AXCall[10]; unsigned char AXCall[10];
int Len;
int n; int n;
// ID seems to be used for control commands like open. SeqNo for data within a session (i Think! // ID seems to be used for control commands like open. SeqNo for data within a session (i Think!
@ -389,7 +416,7 @@ int processRHCPOpen(SOCKET Socket, char * Msg, char * ReplyBuffer)
} }
strcpy(pgm, "RHP"); strcpy(pgm, "RHP");
Stream = FindFreeStreamNoSem(); Stream = FindFreeStream();
strcpy(pgm, "bpq32.exe"); strcpy(pgm, "bpq32.exe");
if (Stream == 255) if (Stream == 255)
@ -399,6 +426,7 @@ int processRHCPOpen(SOCKET Socket, char * Msg, char * ReplyBuffer)
RHPSession->Handle = Handle; RHPSession->Handle = Handle;
RHPSession->Connecting = TRUE; RHPSession->Connecting = TRUE;
RHPSession->Socket = Socket; RHPSession->Socket = Socket;
RHPSession->sockptr = sockptr;
strcpy(RHPSession->Local, Local); strcpy(RHPSession->Local, Local);
strcpy(RHPSession->Remote, Remote); strcpy(RHPSession->Remote, Remote);
@ -437,7 +465,7 @@ int processRHCPSend(SOCKET Socket, char * Msg, char * ReplyBuffer)
if (Handle < 1 || Handle > NumberofRHPSessions) if (Handle < 1 || Handle > NumberofRHPSessions)
{ {
free(Data); free(Data);
return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errtext\": \"Invalid handle\"}", ID, Handle); return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 3, \"errtext\": \"Invalid handle\"}", ID, Handle);
} }
RHPSession = RHPSessions[Handle - 1]; RHPSession = RHPSessions[Handle - 1];
@ -471,20 +499,17 @@ int processRHCPSend(SOCKET Socket, char * Msg, char * ReplyBuffer)
ptr++; ptr++;
} }
Debugprintf(Data);
Len = strlen(Data); Len = strlen(Data);
ptr = Data; ptr = Data;
while (Len > RHPPaclen) while (Len > RHPPaclen)
{ {
SendMsgNoSem(RHPSession->BPQStream, ptr, RHPPaclen); SendMsg(RHPSession->BPQStream, ptr, RHPPaclen);
Len -= RHPPaclen; Len -= RHPPaclen;
ptr += RHPPaclen; ptr += RHPPaclen;
} }
SendMsgNoSem(RHPSession->BPQStream, ptr, Len); SendMsg(RHPSession->BPQStream, ptr, Len);
free(Data); free(Data);
return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 0, \"errText\": \"Ok\", \"status\": %d}", ID, Handle, 2); return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 0, \"errText\": \"Ok\", \"status\": %d}", ID, Handle, 2);
@ -508,7 +533,7 @@ int processRHCPClose(SOCKET Socket, char * Msg, char * ReplyBuffer)
Handle = GetJSONInt(Msg, "\"handle\":"); Handle = GetJSONInt(Msg, "\"handle\":");
if (Handle < 1 || Handle > NumberofRHPSessions) if (Handle < 1 || Handle > NumberofRHPSessions)
return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 12, \"errtext\": \"Invalid handle\"}", ID, Handle); return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 3, \"errtext\": \"Invalid handle\"}", ID, Handle);
RHPSession = RHPSessions[Handle - 1]; RHPSession = RHPSessions[Handle - 1];
@ -522,6 +547,24 @@ int processRHCPClose(SOCKET Socket, char * Msg, char * ReplyBuffer)
return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 0, \"errtext\": \"Ok\"}", ID, Handle); return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 0, \"errtext\": \"Ok\"}", ID, Handle);
} }
int processRHCPStatus(SOCKET Socket, char * Msg, char * ReplyBuffer)
{
// {"type": "status", "handle": 0}. XRouter will reply with {"type": "statusReply", "handle": 0, "errcode": 3, "errtext": "invalid handle"}. It
struct RHPSessionInfo * RHPSession;
int Handle = 0;
Handle = GetJSONInt(Msg, "\"handle\":");
if (Handle < 1 || Handle > NumberofRHPSessions)
return sprintf(ReplyBuffer, "{\"type\": \"statusReply\", \"handle\": %d, \"errcode\": 3, \"errtext\": \"Invalid handle\"}", Handle);
RHPSession = RHPSessions[Handle - 1];
return sprintf(ReplyBuffer, "{\"type\": \"status\", \"handle\": %d, \"flags\": 2}", RHPSession->Handle);
}
char toHex[] = "0123456789abcdef"; char toHex[] = "0123456789abcdef";
void RHPPoll() void RHPPoll()
@ -592,6 +635,9 @@ void RHPPoll()
Buffer[pktlen] = 0; Buffer[pktlen] = 0;
RHPSession->sockptr->LastSendTime = time(NULL);
// Message is JSON so Convert CR to \r, \ to \\ " to \" // Message is JSON so Convert CR to \r, \ to \\ " to \"
// Looks like I need to escape everything not between 0x20 and 0x7f eg \U00c3 // Looks like I need to escape everything not between 0x20 and 0x7f eg \U00c3
@ -649,7 +695,6 @@ void RHPPoll()
} }
while (count > 0); while (count > 0);
} }
} }

View File

@ -854,7 +854,8 @@ void * SCSExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_SCS; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_SCS;
OpenLogFile(TNC->Port); OpenLogFile(TNC->Port);
CloseLogFile(TNC->Port); CloseLogFile(TNC->Port);
@ -885,8 +886,6 @@ void * SCSExtInit(EXTPORTDATA * PortEntry)
PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream
PortEntry->SCANCAPABILITIES = CONLOCK; // Scan Control 3 stage/conlock PortEntry->SCANCAPABILITIES = CONLOCK; // Scan Control 3 stage/conlock
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTINTERLOCK && TNC->RXRadio == 0 && TNC->TXRadio == 0) if (PortEntry->PORTCONTROL.PORTINTERLOCK && TNC->RXRadio == 0 && TNC->TXRadio == 0)
TNC->RXRadio = TNC->TXRadio = PortEntry->PORTCONTROL.PORTINTERLOCK; TNC->RXRadio = TNC->TXRadio = PortEntry->PORTCONTROL.PORTINTERLOCK;

View File

@ -376,7 +376,8 @@ void * TrackerMExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_TRKM; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TRKM;
// Set up DED addresses for streams // Set up DED addresses for streams
@ -392,8 +393,6 @@ void * TrackerMExtInit(EXTPORTDATA * PortEntry)
PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream
PortEntry->SCANCAPABILITIES = NONE; // Scan Control 3 stage/conlock PortEntry->SCANCAPABILITIES = NONE; // Scan Control 3 stage/conlock
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);
else else

View File

@ -666,7 +666,8 @@ void * TrackerExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_TRK; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TRK;
// Set up DED addresses for streams // Set up DED addresses for streams
@ -682,8 +683,6 @@ void * TrackerExtInit(EXTPORTDATA * PortEntry)
PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream
PortEntry->SCANCAPABILITIES = NONE; // Scan Control 3 stage/conlock PortEntry->SCANCAPABILITIES = NONE; // Scan Control 3 stage/conlock
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);
else else

View File

@ -770,9 +770,9 @@ VOID * SerialExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_SERIAL;
TNC->PortRecord = PortEntry; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_SERIAL;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/ */
// //
// Telnet Driver for BPQ Switch // Telnet Driver for BPQ Switch
// //
@ -113,7 +114,7 @@ extern int REALTIMETICKS;
#define MaxSockets 26 #define MaxSockets 26
struct UserRec RelayUser; struct UserRec RelayUser;
struct UserRec SyncUser = {"","Sync"};; struct UserRec SyncUser = {"","Sync"};
struct UserRec CMSUser; struct UserRec CMSUser;
struct UserRec HostUser = {"","Host"}; struct UserRec HostUser = {"","Host"};
struct UserRec TriModeUser; struct UserRec TriModeUser;
@ -953,13 +954,27 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{ {
if (sockptr->WebSocks == 0) if (sockptr->WebSocks == 0)
{ {
if (sockptr->LastSendTime && (REALTIMETICKS - sockptr->LastSendTime) > 1500) // ~ 2.5 mins if (sockptr->LastSendTime && (time(NULL) - sockptr->LastSendTime) > 150) // ~ 2.5 mins
{ {
closesocket(sockptr->socket); closesocket(sockptr->socket);
sockptr->SocketActive = FALSE; sockptr->SocketActive = FALSE;
ShowConnections(TNC); ShowConnections(TNC);
} }
} }
else if (memcmp(sockptr->WebURL, "rhp", 3) == 0)
{
// RHP Sockets (Used for WhatsPack) Need a timeout
// Normally keepalives are sent each way around every 9 mins
// Keepalives aren't sent when connecting so may need a bit longer
if (sockptr->LastSendTime && (time(NULL) - sockptr->LastSendTime) > 20 * 60) // 20mins
{
ProcessRHPWebSockClosed(sockptr->socket);
closesocket(sockptr->socket);
sockptr->SocketActive = FALSE;
ShowConnections(TNC);
}
}
} }
else else
{ {
@ -1174,7 +1189,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
TNC = TNCInfo[n]; TNC = TNCInfo[n];
TNC->Port = n; TNC->Port = n;
TNC->Hardware = H_TELNET; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TELNET;
TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy
// Get Menu Handles // Get Menu Handles
@ -1449,13 +1464,12 @@ void * TelnetExtInit(EXTPORTDATA * PortEntry)
TCP = TNC->TCPInfo; TCP = TNC->TCPInfo;
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry;
TNC->Hardware = H_TELNET; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TELNET;
PortEntry->MAXHOSTMODESESSIONS = TNC->TCPInfo->MaxSessions + 1; // Default PortEntry->MAXHOSTMODESESSIONS = TNC->TCPInfo->MaxSessions + 1; // Default
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] != 0) if (PortEntry->PORTCONTROL.PORTCALL[0] != 0)
ConvFromAX25(&PortEntry->PORTCONTROL.PORTCALL[0], TNC->NodeCall); ConvFromAX25(&PortEntry->PORTCONTROL.PORTCALL[0], TNC->NodeCall);
@ -2473,15 +2487,11 @@ nosocks:
if (sockptr->SocketActive && sockptr->Keepalive && L4LIMIT) if (sockptr->SocketActive && sockptr->Keepalive && L4LIMIT)
{ {
#ifdef WIN32 if ((time(NULL) - sockptr->LastSendTime) > (L4LIMIT - 60)) // PC Ticks are about 10% slow
if ((REALTIMETICKS - sockptr->LastSendTime) > (L4LIMIT - 60) * 9) // PC Ticks are about 10% slow
#else
if ((REALTIMETICKS - sockptr->LastSendTime) > (L4LIMIT - 60) * 10)
#endif
{ {
// Send Keepalive // Send Keepalive
sockptr->LastSendTime = REALTIMETICKS; sockptr->LastSendTime = time(NULL);
BuffertoNode(sockptr, "Keepalive\r", 10); BuffertoNode(sockptr, "Keepalive\r", 10);
} }
} }
@ -2611,7 +2621,7 @@ nosocks:
if (P3[0] == 'K' || P4[0] == 'K' || P5[0] == 'K' || P6[0] == 'K') if (P3[0] == 'K' || P4[0] == 'K' || P5[0] == 'K' || P6[0] == 'K')
{ {
sockptr->Keepalive = TRUE; sockptr->Keepalive = TRUE;
sockptr->LastSendTime = REALTIMETICKS; sockptr->LastSendTime = time(NULL);
} }
if (P3[0] == 'S' || P4[0] == 'S' || P5[0] == 'S' || P6[0] == 'S') if (P3[0] == 'S' || P4[0] == 'S' || P5[0] == 'S' || P6[0] == 'S')
@ -2843,7 +2853,7 @@ nosocks:
SendtoNode(TNC, Stream, &sockptr->FromHostBuffer[sockptr->FromHostBuffGetptr], Msglen); SendtoNode(TNC, Stream, &sockptr->FromHostBuffer[sockptr->FromHostBuffGetptr], Msglen);
sockptr->FromHostBuffGetptr += Msglen; sockptr->FromHostBuffGetptr += Msglen;
sockptr->LastSendTime = REALTIMETICKS; sockptr->LastSendTime = time(NULL);
} }
} }
} }
@ -3100,7 +3110,10 @@ LRESULT CALLBACK TelWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
TNC = TNCInfo[n]; TNC = TNCInfo[n];
TNC->Port = n; TNC->Port = n;
TNC->Hardware = H_TELNET; TNC->PortRecord = PortRecord;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_TELNET;
TNC->hDlg = SavehDlg; TNC->hDlg = SavehDlg;
TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy
@ -3131,8 +3144,6 @@ LRESULT CALLBACK TelWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPara
ModifyMenu(TCP->hDisMenu,i - 1 ,MF_BYPOSITION | MF_STRING,IDM_DISCONNECT + 1, "."); ModifyMenu(TCP->hDisMenu,i - 1 ,MF_BYPOSITION | MF_STRING,IDM_DISCONNECT + 1, ".");
} }
TNC->PortRecord = PortRecord;
Sleep(500); Sleep(500);
OpenSockets(TNC); OpenSockets(TNC);
OpenSockets6(TNC); OpenSockets6(TNC);
@ -3755,7 +3766,7 @@ MsgLoop:
BuffertoNode(sockptr, NodeLine, len); BuffertoNode(sockptr, NodeLine, len);
sockptr->InputLen = 0; sockptr->InputLen = 0;
ShowConnections(TNC);; ShowConnections(TNC);
return 0; return 0;
} }
@ -3929,7 +3940,7 @@ MsgLoop:
#ifndef LINBPQ #ifndef LINBPQ
ModifyMenu(TCP->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, MsgPtr); ModifyMenu(TCP->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, MsgPtr);
#endif #endif
ShowConnections(TNC);; ShowConnections(TNC);
return 0; return 0;
} }
@ -4185,7 +4196,7 @@ int DataSocket_ReadRelay(struct TNCINFO * TNC, struct ConnectionInfo * sockptr,
#ifndef LINBPQ #ifndef LINBPQ
ModifyMenu(TCP->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, MsgPtr); ModifyMenu(TCP->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, MsgPtr);
#endif #endif
ShowConnections(TNC);; ShowConnections(TNC);
return 0; return 0;
@ -4305,7 +4316,7 @@ int DataSocket_ReadRelay(struct TNCINFO * TNC, struct ConnectionInfo * sockptr,
SendtoNode(TNC, sockptr->Number, TCP->RelayAPPL, (int)strlen(TCP->RelayAPPL)); SendtoNode(TNC, sockptr->Number, TCP->RelayAPPL, (int)strlen(TCP->RelayAPPL));
ShowConnections(TNC);; ShowConnections(TNC);
return 0; return 0;
@ -4490,7 +4501,7 @@ MsgLoop:
WritetoTrace(Stream, MsgPtr, InputLen, sockptr->ADIF, 'R'); WritetoTrace(Stream, MsgPtr, InputLen, sockptr->ADIF, 'R');
} }
if (InputLen == 8 && memcmp(MsgPtr, ";;;;;;\r\n", 8) == 0) if (InputLen == 8 && memcmp(MsgPtr, ";;;\r\n", 8) == 0)
{ {
// CMS Keepalive // CMS Keepalive
@ -4804,7 +4815,7 @@ MsgLoop:
ModifyMenu(TCP->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, MsgPtr); ModifyMenu(TCP->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, MsgPtr);
#endif #endif
ShowConnections(TNC);; ShowConnections(TNC);
InputLen=InputLen-(MsgLen+1); InputLen=InputLen-(MsgLen+1);
@ -4880,7 +4891,7 @@ MsgLoop:
WriteLog (logmsg); WriteLog (logmsg);
} }
ShowConnections(TNC);; ShowConnections(TNC);
InputLen=InputLen-(MsgLen+1); InputLen=InputLen-(MsgLen+1);
sockptr->InputLen=InputLen; sockptr->InputLen=InputLen;
@ -4978,6 +4989,7 @@ struct RHPParamBlock
unsigned char * Msg; unsigned char * Msg;
int Len; int Len;
SOCKET Socket; SOCKET Socket;
struct ConnectionInfo * sockptr;
}; };
@ -5107,7 +5119,7 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
{ {
sockcopy = malloc(sizeof(struct ConnectionInfo)); sockcopy = malloc(sizeof(struct ConnectionInfo));
sockptr->TNC = TNC; sockptr->TNC = TNC;
sockptr->LastSendTime = REALTIMETICKS; sockptr->LastSendTime = time(NULL);
memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo)); memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo));
@ -5120,10 +5132,13 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
struct RHPParamBlock * ParamBlock = malloc(sizeof(struct RHPParamBlock)); struct RHPParamBlock * ParamBlock = malloc(sizeof(struct RHPParamBlock));
ParamBlock->sockptr = sockptr;
ParamBlock->Socket = sockptr->socket; ParamBlock->Socket = sockptr->socket;
ParamBlock->Len = Len; ParamBlock->Len = Len;
ParamBlock->Msg = malloc(Len + 10); ParamBlock->Msg = malloc(Len + 10);
memcpy(ParamBlock->Msg, Payload, Len); memcpy(ParamBlock->Msg, Payload, Len);
sockptr->LastSendTime = time(NULL);
_beginthread(RHPThread, 0, (VOID *)ParamBlock); _beginthread(RHPThread, 0, (VOID *)ParamBlock);
sockptr->InputLen = 0; sockptr->InputLen = 0;
@ -5158,7 +5173,7 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
sockcopy = malloc(sizeof(struct ConnectionInfo)); sockcopy = malloc(sizeof(struct ConnectionInfo));
sockptr->TNC = TNC; sockptr->TNC = TNC;
sockptr->LastSendTime = REALTIMETICKS; sockptr->LastSendTime = time(NULL);
memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo)); memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo));
@ -5265,7 +5280,7 @@ int DataSocket_Disconnect(struct TNCINFO * TNC, struct ConnectionInfo * sockptr
ModifyMenu(TNC->TCPInfo->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, "."); ModifyMenu(TNC->TCPInfo->hDisMenu, n - 1, MF_BYPOSITION | MF_STRING, IDM_DISCONNECT + n, ".");
#endif #endif
sockptr->SocketActive = FALSE; sockptr->SocketActive = FALSE;
ShowConnections(TNC);; ShowConnections(TNC);
} }
return 0; return 0;
} }
@ -7154,7 +7169,7 @@ int DoRefreshWebMailIndex()
{ {
sockcopy = malloc(sizeof(struct ConnectionInfo)); sockcopy = malloc(sizeof(struct ConnectionInfo));
sockptr->TNC = TNC; sockptr->TNC = TNC;
sockptr->LastSendTime = REALTIMETICKS; sockptr->LastSendTime = time(NULL);
memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo)); memcpy(sockcopy, sockptr, sizeof(struct ConnectionInfo));

View File

@ -464,7 +464,7 @@ UINT UIARQExtInit(EXTPORTDATA * PortEntry)
ptr=strchr(TNC->NodeCall, ' '); ptr=strchr(TNC->NodeCall, ' ');
if (ptr) *(ptr) = 0; // Null Terminate if (ptr) *(ptr) = 0; // Null Terminate
TNC->Hardware = H_UIARQ; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_UIARQ;
if (TNC->BusyWait == 0) if (TNC->BusyWait == 0)
TNC->BusyWait = 10; TNC->BusyWait = 10;

View File

@ -1400,7 +1400,7 @@ void * UZ7HOExtInit(EXTPORTDATA * PortEntry)
ptr=strchr(TNC->NodeCall, ' '); ptr=strchr(TNC->NodeCall, ' ');
if (ptr) *(ptr) = 0; // Null Terminate if (ptr) *(ptr) = 0; // Null Terminate
TNC->Hardware = H_UZ7HO; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_UZ7HO;
UZ7HOChannel[port] = PortEntry->PORTCONTROL.CHANNELNUM-65; UZ7HOChannel[port] = PortEntry->PORTCONTROL.CHANNELNUM-65;

4
V4.c
View File

@ -971,13 +971,13 @@ void * V4ExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry;
if (TNC->ProgramPath) if (TNC->ProgramPath)
TNC->WeStartedTNC = RestartTNC(TNC); TNC->WeStartedTNC = RestartTNC(TNC);
TNC->Hardware = H_V4; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_V4;
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

41
VARA.c
View File

@ -1163,6 +1163,7 @@ void * VARAExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry;
TNC->ARDOPBuffer = malloc(8192); TNC->ARDOPBuffer = malloc(8192);
TNC->ARDOPDataBuffer = malloc(8192); TNC->ARDOPDataBuffer = malloc(8192);
@ -1170,7 +1171,7 @@ void * VARAExtInit(EXTPORTDATA * PortEntry)
if (TNC->ProgramPath) if (TNC->ProgramPath)
TNC->WeStartedTNC = 1; TNC->WeStartedTNC = 1;
TNC->Hardware = H_VARA; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_VARA;
if (TNC->BusyWait == 0) if (TNC->BusyWait == 0)
TNC->BusyWait = 10; TNC->BusyWait = 10;
@ -1178,8 +1179,6 @@ void * VARAExtInit(EXTPORTDATA * PortEntry)
if (TNC->BusyHold == 0) if (TNC->BusyHold == 0)
TNC->BusyHold = 1; TNC->BusyHold = 1;
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);
else else
@ -1446,9 +1445,6 @@ VOID VARAThread(void * portptr)
return; return;
} }
// printf("Starting VARA Thread\n");
// if on Windows and Localhost see if TNC is running // if on Windows and Localhost see if TNC is running
#ifdef WIN32 #ifdef WIN32
@ -1564,14 +1560,11 @@ TNCRunning:
sinx.sin_addr.s_addr = INADDR_ANY; sinx.sin_addr.s_addr = INADDR_ANY;
sinx.sin_port = 0; sinx.sin_port = 0;
// printf("Trying to connect to VARA TNC\n");
if (connect(TNC->TCPSock,(LPSOCKADDR) &TNC->destaddr,sizeof(TNC->destaddr)) == 0) if (connect(TNC->TCPSock,(LPSOCKADDR) &TNC->destaddr,sizeof(TNC->destaddr)) == 0)
{ {
// Connected successful // Connected successful
goto VConnected; goto VConnected;
} }
if (TNC->Alerted == FALSE) if (TNC->Alerted == FALSE)
@ -1727,6 +1720,7 @@ VConnected:
GetSemaphore(&Semaphore, 52); GetSemaphore(&Semaphore, 52);
VARAProcessReceivedControl(TNC); VARAProcessReceivedControl(TNC);
FreeSemaphore(&Semaphore); FreeSemaphore(&Semaphore);
Debugprintf("VARA Returned from processing control packet");
} }
if (FD_ISSET(TNC->TCPDataSock, &readfs)) if (FD_ISSET(TNC->TCPDataSock, &readfs))
@ -2230,6 +2224,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (App < 32) if (App < 32)
{ {
char AppName[13]; char AppName[13];
char AppBuffer[64];
memcpy(AppName, &ApplPtr[App * sizeof(struct CMDX)], 12); memcpy(AppName, &ApplPtr[App * sizeof(struct CMDX)], 12);
AppName[12] = 0; AppName[12] = 0;
@ -2244,7 +2239,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (CheckAppl(TNC, AppName)) if (CheckAppl(TNC, AppName))
{ {
MsgLen = sprintf(Buffer, "%s\r", AppName); MsgLen = sprintf(AppBuffer, "%s\r", AppName);
buffptr = GetBuff(); buffptr = GetBuff();
@ -2254,7 +2249,9 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
} }
buffptr->Len = MsgLen; buffptr->Len = MsgLen;
memcpy(buffptr->Data, Buffer, MsgLen); memcpy(buffptr->Data, AppBuffer, MsgLen);
Debugprintf("Calling Application %s", AppBuffer);
C_Q_ADD(&TNC->WINMORtoBPQ_Q, buffptr); C_Q_ADD(&TNC->WINMORtoBPQ_Q, buffptr);
@ -2429,7 +2426,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
// return; // return;
} }
if (_memicmp(Buffer, "REGISTERED", 9) == 0) if (_memicmp(Buffer, "LINK REGISTERED", 9) == 0)
{ {
strcat(Buffer, "\r"); strcat(Buffer, "\r");
WritetoTrace(TNC, Buffer, (int)strlen(Buffer)); WritetoTrace(TNC, Buffer, (int)strlen(Buffer));
@ -2443,6 +2440,13 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
return; return;
} }
if (_memicmp(Buffer, "UNENCRYPTED LINK ", 11) == 0)
{
strcat(Buffer, "\r");
WritetoTrace(TNC, Buffer, (int)strlen(Buffer));
return;
}
if (_memicmp(Buffer, "MISSING SOUNDCARD", 17) == 0) if (_memicmp(Buffer, "MISSING SOUNDCARD", 17) == 0)
{ {
strcat(Buffer, "\r"); strcat(Buffer, "\r");
@ -2668,7 +2672,7 @@ VOID VARAProcessReceivedControl(struct TNCINFO * TNC)
{ {
int InputLen, MsgLen; int InputLen, MsgLen;
char * ptr, * ptr2; char * ptr, * ptr2;
char Buffer[4096]; char Buffer[8192];
// shouldn't get several messages per packet, as each should need an ack // shouldn't get several messages per packet, as each should need an ack
// May get message split over packets // May get message split over packets
@ -2676,7 +2680,7 @@ VOID VARAProcessReceivedControl(struct TNCINFO * TNC)
if (TNC->InputLen > 8000) // Shouldnt have packets longer than this if (TNC->InputLen > 8000) // Shouldnt have packets longer than this
TNC->InputLen=0; TNC->InputLen=0;
InputLen=recv(TNC->TCPSock, &TNC->ARDOPBuffer[TNC->InputLen], 8192 - TNC->InputLen, 0); InputLen=recv(TNC->TCPSock, &TNC->ARDOPBuffer[TNC->InputLen], 8191 - TNC->InputLen, 0);
if (InputLen == 0 || InputLen == SOCKET_ERROR) if (InputLen == 0 || InputLen == SOCKET_ERROR)
{ {
@ -2699,12 +2703,18 @@ VOID VARAProcessReceivedControl(struct TNCINFO * TNC)
TNC->InputLen += InputLen; TNC->InputLen += InputLen;
TNC->ARDOPBuffer[TNC->InputLen] = 0;
Debugprintf("VARA Processing buffer - %s", TNC->ARDOPBuffer);
loop: loop:
ptr = memchr(TNC->ARDOPBuffer, '\r', TNC->InputLen); ptr = memchr(TNC->ARDOPBuffer, '\r', TNC->InputLen);
if (ptr == 0) // CR in buffer if (ptr == 0) // CR in buffer
{
Debugprintf("VARA Part Packet Received - Waiting for rest");
return; // Wait for it return; // Wait for it
}
ptr2 = &TNC->ARDOPBuffer[TNC->InputLen]; ptr2 = &TNC->ARDOPBuffer[TNC->InputLen];
@ -2727,9 +2737,10 @@ loop:
if (TNC->InputLen < MsgLen) if (TNC->InputLen < MsgLen)
{ {
TNC->InputLen = 0; TNC->InputLen = 0;
Debugprintf("VARA Corrupt multi command input");
return; return;
} }
memmove(TNC->ARDOPBuffer, ptr + 1, TNC->InputLen-MsgLen); memmove(TNC->ARDOPBuffer, ptr + 1, TNC->InputLen - MsgLen);
TNC->InputLen -= MsgLen; TNC->InputLen -= MsgLen;
goto loop; goto loop;

View File

@ -1,125 +0,0 @@
#ifdef Kernel
#define Vers 5,2,9,2
#define Verstring "5.2.9.2\0"
#define Datestring "September 2012"
#define VerComments "G8BPQ Packet Switch V5.2.9.2\0"
#define VerCopyright "Copyright © 2001-2012 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0"
#endif
#define KVers 6,0,24,59
#define KVerstring "6.0.24.59\0"
#ifdef CKernel
#define Vers KVers
#define Verstring KVerstring
#define Datestring "January 2025"
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
#define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0"
#define VerDesc "BPQ32 Switch\0"
#define VerProduct "BPQ32"
#endif
#ifdef TermTCP
#define Vers 1,0,16,2
#define Verstring "1.0.16.2\0"
#define VerComments "Internet Terminal for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 2011-2025 John Wiseman G8BPQ\0"
#define VerDesc "Simple TCP Terminal Program for G8BPQ Switch\0"
#define VerProduct "BPQTermTCP"
#endif
#ifdef BPQTerm
#define Vers 2,2,5,2
#define Verstring "2.2.5.2\0"
#define VerComments "Simple Terminal for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 1999-2025 John Wiseman G8BPQ\0"
#define VerDesc "Simple Terminal Program for G8BPQ Switch\0"
#define VerProduct "BPQTerminal"
#endif
#ifdef BPQTermMDI
#define Vers 2,2,0,3
#define Verstring "2.2.0.3\0"
#define VerComments "MDI Terminal for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 1999-2025 John Wiseman G8BPQ\0"
#define VerDesc "MDI Terminal Program for G8BPQ Switch\0"
#endif
#ifdef MAIL
#define Vers KVers
#define Verstring KVerstring
#define VerComments "Mail server for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 2009-2025 John Wiseman G8BPQ\0"
#define VerDesc "Mail server for G8BPQ's 32 Bit Switch\0"
#define VerProduct "BPQMail"
#endif
#ifdef HOSTMODES
#define Vers 1,1,8,1
#define Verstring "1.1.8.1\0"
//#define SPECIALVERSION "Test 3"
#define VerComments "Host Modes Emulator for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 2009-2019 John Wiseman G8BPQ\0"
#define VerDesc "Host Modes Emulator for G8BPQ's 32 Bit Switch\0"
#define VerProduct "BPQHostModes"
#endif
#ifdef UIUTIL
#define Vers 0,1,3,1
#define Verstring "0.1.3.1\0"
#define VerComments "Beacon Utility for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 2011-2019 John Wiseman G8BPQ\0"
#define VerDesc "Beacon Utility for G8BPQ Switch\0"
#define VerProduct "BPQUIUtil"
#endif
#ifdef AUTH
#define Vers 0,1,0,0
#define Verstring "0.1.0.0\0"
#define VerComments "Password Generation Utility for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 2011-2025 John Wiseman G8BPQ\0"
#define VerDesc "Password Generation Utility for G8BPQ Switch\0"
#endif
#ifdef APRS
#define Vers KVers
#define Verstring KVerstring
#define VerComments "APRS Client for G8BPQ Switch\0"
#define VerCopyright "Copyright © 2012-2025 John Wiseman G8BPQ\0"
#define VerDesc "APRS Client for G8BPQ Switch\0"
#define VerProduct "BPQAPRS"
#endif
#ifdef CHAT
#define Vers KVers
#define Verstring KVerstring
#define VerComments "Chat server for G8BPQ Packet Switch\0"
#define VerCopyright "Copyright © 2009-2025 John Wiseman G8BPQ\0"
#define VerDesc "Chat server for G8BPQ's 32 Bit Switch\0"
#define VerProduct "BPQChat"
#endif

View File

@ -10,8 +10,8 @@
#endif #endif
#define KVers 6,0,24,59 #define KVers 6,0,24,65
#define KVerstring "6.0.24.59\0" #define KVerstring "6.0.24.65\0"
#ifdef CKernel #ifdef CKernel

View File

@ -1462,11 +1462,12 @@ void * WinmorExtInit(EXTPORTDATA * PortEntry)
} }
TNC->Port = port; TNC->Port = port;
TNC->PortRecord = PortEntry;
if (TNC->ProgramPath) if (TNC->ProgramPath)
TNC->WeStartedTNC = RestartTNC(TNC); TNC->WeStartedTNC = RestartTNC(TNC);
TNC->Hardware = H_WINMOR; TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_WINMOR;
if (TNC->BusyWait == 0) if (TNC->BusyWait == 0)
TNC->BusyWait = 10; TNC->BusyWait = 10;
@ -1474,7 +1475,6 @@ void * WinmorExtInit(EXTPORTDATA * PortEntry)
if (TNC->BusyHold == 0) if (TNC->BusyHold == 0)
TNC->BusyHold = 1; TNC->BusyHold = 1;
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);

View File

@ -795,7 +795,8 @@ void * WinRPRExtInit(EXTPORTDATA * PortEntry)
WritetoConsoleLocal(msg); WritetoConsoleLocal(msg);
TNC->Port = port; TNC->Port = port;
TNC->Hardware = H_WINRPR; TNC->PortRecord = PortEntry;
TNC->PortRecord->PORTCONTROL.HWType = TNC->Hardware = H_WINRPR;
// Set up DED addresses for streams // Set up DED addresses for streams
@ -811,8 +812,6 @@ void * WinRPRExtInit(EXTPORTDATA * PortEntry)
PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream
PortEntry->SCANCAPABILITIES = NONE; // Scan Control 3 stage/conlock PortEntry->SCANCAPABILITIES = NONE; // Scan Control 3 stage/conlock
TNC->PortRecord = PortEntry;
if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) if (PortEntry->PORTCONTROL.PORTCALL[0] == 0)
memcpy(TNC->NodeCall, MYNODECALL, 10); memcpy(TNC->NodeCall, MYNODECALL, 10);
else else

View File

@ -33,6 +33,7 @@ typedef int (FAR *FARPROCY)();
#define L4BUSY 0x80 // BNA - DONT SEND ANY MORE #define L4BUSY 0x80 // BNA - DONT SEND ANY MORE
#define L4NAK 0x40 // NEGATIVE RESPONSE FLAG #define L4NAK 0x40 // NEGATIVE RESPONSE FLAG
#define L4MORE 0x20 // MORE DATA FOLLOWS - FRAGMENTATION FLAG #define L4MORE 0x20 // MORE DATA FOLLOWS - FRAGMENTATION FLAG
#define L4COMP 0x10 // BPQ Specific use of spare it - data is compressed
#define L4CREQ 1 // CONNECT REQUEST #define L4CREQ 1 // CONNECT REQUEST
#define L4CACK 2 // CONNECT ACK #define L4CACK 2 // CONNECT ACK
@ -40,6 +41,7 @@ typedef int (FAR *FARPROCY)();
#define L4DACK 4 // DISCONNECT ACK #define L4DACK 4 // DISCONNECT ACK
#define L4INFO 5 // INFORMATION #define L4INFO 5 // INFORMATION
#define L4IACK 6 // INFORMATION ACK #define L4IACK 6 // INFORMATION ACK
#define L4RESET 7 // Paula's extension
extern char MYCALL[]; // 7 chars, ax.25 format extern char MYCALL[]; // 7 chars, ax.25 format
@ -170,6 +172,23 @@ typedef struct _TRANSPORTENTRY
char APPL[16]; // Set if session initiated by an APPL char APPL[16]; // Set if session initiated by an APPL
int L4LIMIT; // Idle time for this Session int L4LIMIT; // Idle time for this Session
// Now support compressing NetRom Sessions.
// We collect as much data as possible before compressing and re-packetizing
int AllowCompress;
unsigned char * toCompress; // Data being saved to compress
int toCompressLen;
unsigned char * unCompress; // Data being saved to uncompress
int unCompressLen;
int Sent;
int SentAfterCompression;
int Received;
int ReceivedAfterExpansion;
} TRANSPORTENTRY; } TRANSPORTENTRY;
// //
@ -195,6 +214,9 @@ typedef struct ROUTE
UCHAR NEIGHBOUR_QUAL; UCHAR NEIGHBOUR_QUAL;
UCHAR NEIGHBOUR_FLAG; // SET IF 'LOCKED' ROUTE UCHAR NEIGHBOUR_FLAG; // SET IF 'LOCKED' ROUTE
#define LOCKEDBYCONFIG 1
#define LOCKEDBYSYSOP 2
struct _LINKTABLE * NEIGHBOUR_LINK; // POINTER TO LINK FOR THIS NEIGHBOUR struct _LINKTABLE * NEIGHBOUR_LINK; // POINTER TO LINK FOR THIS NEIGHBOUR
USHORT NEIGHBOUR_TIME; // TIME LAST HEARD (HH MM) USHORT NEIGHBOUR_TIME; // TIME LAST HEARD (HH MM)
@ -445,7 +467,8 @@ typedef struct NR_DEST_ROUTE_ENTRY
struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH struct ROUTE * ROUT_NEIGHBOUR; // POINTER TO NEXT NODE IN PATH
UCHAR ROUT_QUALITY; // QUALITY UCHAR ROUT_QUALITY; // QUALITY
UCHAR ROUT_OBSCOUNT; UCHAR ROUT_OBSCOUNT;
UCHAR Padding[5]; // SO Entries are the same length UCHAR ROUT_LOCKED;
UCHAR Padding[4]; // SO Entries are the same length
} *PNR_DEST_ROUTE_ENTRY; } *PNR_DEST_ROUTE_ENTRY;
typedef struct DEST_ROUTE_ENTRY typedef struct DEST_ROUTE_ENTRY
@ -467,12 +490,12 @@ typedef struct DEST_LIST
UCHAR DEST_ALIAS[6]; UCHAR DEST_ALIAS[6];
UCHAR DEST_STATE; // CONTROL BITS - SETTING UP, ACTIVE ETC UCHAR DEST_STATE; // CONTROL BITS - SETTING UP, ACTIVE ETC
UCHAR DEST_LOCKED;
UCHAR DEST_ROUTE; // CURRENTY ACTIVE DESTINATION UCHAR DEST_ROUTE; // CURRENTY ACTIVE DESTINATION
UCHAR INP3FLAGS; UCHAR INP3FLAGS;
struct NR_DEST_ROUTE_ENTRY NRROUTE[3];// Best 3 NR neighbours for this dest struct NR_DEST_ROUTE_ENTRY NRROUTE[3];// Best 3 NR neighbours for this dest
struct DEST_ROUTE_ENTRY ROUTE[3]; // Best 3 INP neighbours for this dest struct DEST_ROUTE_ENTRY ROUTE[3]; // Best 3 INP neighbours for this dest
void * DEST_Q; // QUEUE OF FRAMES FOR THIS DESTINATION void * DEST_Q; // QUEUE OF FRAMES FOR THIS DESTINATION
@ -682,6 +705,7 @@ typedef struct PORTCONTROL
struct PORTCONTROL * HookPort; struct PORTCONTROL * HookPort;
int PortSlot; // Index in Port Table int PortSlot; // Index in Port Table
struct TNCINFO * TNC; // Associated TNC record struct TNCINFO * TNC; // Associated TNC record
int HWType; // Hardware type of Driver. In here as external apps don't have access to TNC record
int RIGPort; // Linked port for freq resporting int RIGPort; // Linked port for freq resporting
unsigned int PERMITTEDAPPLS; // Appls allowed on this port (generalisation of BBSBANNED) unsigned int PERMITTEDAPPLS; // Appls allowed on this port (generalisation of BBSBANNED)
char * CTEXT; // Port Specific CText char * CTEXT; // Port Specific CText

File diff suppressed because it is too large Load Diff

31
cMain.c
View File

@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/ */
// //
// C replacement for Main.asm // C replacement for Main.asm
// //
@ -139,6 +140,10 @@ int NODE = 1; // INCLUDE SWITCH SUPPORT
int FULL_CTEXT = 1; // CTEXT ON ALL CONNECTS IF NZ int FULL_CTEXT = 1; // CTEXT ON ALL CONNECTS IF NZ
int L4Compress = 0;
int L4CompMaxframe = 3;
int L4CompPaclen = 236;
BOOL LogL4Connects = FALSE; BOOL LogL4Connects = FALSE;
BOOL LogAllConnects = FALSE; BOOL LogAllConnects = FALSE;
BOOL AUTOSAVEMH = TRUE; BOOL AUTOSAVEMH = TRUE;
@ -822,6 +827,15 @@ BOOL Start()
MQTT_PORT = cfg->C_MQTT_PORT; MQTT_PORT = cfg->C_MQTT_PORT;
strcpy(MQTT_USER, cfg->C_MQTT_USER); strcpy(MQTT_USER, cfg->C_MQTT_USER);
strcpy(MQTT_PASS, cfg->C_MQTT_PASS); strcpy(MQTT_PASS, cfg->C_MQTT_PASS);
L4Compress = cfg->C_L4Compress;
L4CompMaxframe = cfg->C_L4CompMaxframe;
L4CompPaclen = cfg->C_L4CompPaclen;
if (L4CompMaxframe < 1 || L4CompMaxframe > 16)
L4CompMaxframe = 3;
if (L4CompPaclen < 64 || L4CompPaclen > 236)
L4CompPaclen = 236;
// Get pointers to PASSWORD and APPL1 commands // Get pointers to PASSWORD and APPL1 commands
@ -1338,7 +1352,7 @@ BOOL Start()
ROUTE->NBOUR_PACLEN = Rcfg->ppacl; ROUTE->NBOUR_PACLEN = Rcfg->ppacl;
ROUTE->OtherendsRouteQual = ROUTE->OtherendLocked = Rcfg->farQual; ROUTE->OtherendsRouteQual = ROUTE->OtherendLocked = Rcfg->farQual;
ROUTE->NEIGHBOUR_FLAG = 1; // Locked ROUTE->NEIGHBOUR_FLAG = LOCKEDBYCONFIG; // Locked
Rcfg++; Rcfg++;
ROUTE++; ROUTE++;
@ -1843,12 +1857,11 @@ VOID ReadNodes()
if (ptr == NULL) continue; if (ptr == NULL) continue;
// I don't thinlk we should load locked flag from save file - only from config // I don't thinlk we should load locked flag from save file - only from config
// Now (2025) have two locked flags, from config or by sysop. Latter is saved and restored
// But need to parse it until I stop saving it
if (ptr[0] == '!') if (ptr[0] == '!')
{ {
// ROUTE->NEIGHBOUR_FLAG = 1; // LOCKED ROUTE ROUTE->NEIGHBOUR_FLAG = LOCKEDBYSYSOP; // LOCKED ROUTE
ptr = strtok_s(NULL, seps, &Context); ptr = strtok_s(NULL, seps, &Context);
if (ptr == NULL) continue; if (ptr == NULL) continue;
} }
@ -1865,7 +1878,7 @@ VOID ReadNodes()
memcpy(ROUTE->NEIGHBOUR_DIGI1, axcall, 7); memcpy(ROUTE->NEIGHBOUR_DIGI1, axcall, 7);
ROUTE->NEIGHBOUR_FLAG = 1; // LOCKED ROUTE - Digi'ed routes must be locked ROUTE->NEIGHBOUR_FLAG = LOCKEDBYSYSOP; // LOCKED ROUTE - Digi'ed routes must be locked
ptr = strtok_s(NULL, seps, &Context); ptr = strtok_s(NULL, seps, &Context);
if (ptr == NULL) continue; if (ptr == NULL) continue;
@ -1921,6 +1934,14 @@ VOID ReadNodes()
if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0); // Not LOCKED ROUTE if (ROUTE->NEIGHBOUR_FLAG == 0 || ROUTE->OtherendLocked == 0); // Not LOCKED ROUTE
ROUTE->OtherendsRouteQual = atoi(ptr); ROUTE->OtherendsRouteQual = atoi(ptr);
ptr = strtok_s(NULL, seps, &Context); // INP3
if (ptr == NULL) continue;
if (ptr[0] == '!')
{
ROUTE->NEIGHBOUR_FLAG = LOCKEDBYSYSOP; // LOCKED ROUTE
ptr = strtok_s(NULL, seps, &Context);
}
continue; continue;
} }

View File

@ -2,7 +2,6 @@
// Prototypes for BPQ32 Node Functions // Prototypes for BPQ32 Node Functions
// //
#define DllImport #define DllImport
#define EXCLUDEBITS #define EXCLUDEBITS

View File

@ -307,7 +307,8 @@ static char *keywords[] =
"APPL5QUAL", "APPL6QUAL", "APPL7QUAL", "APPL8QUAL", "APPL5QUAL", "APPL6QUAL", "APPL7QUAL", "APPL8QUAL",
"BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXHOPS", // IPGATEWAY= no longer allowed "BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXHOPS", // IPGATEWAY= no longer allowed
"LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS", "LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS",
"EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS" "EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS",
"L4Compress", "L4CompMaxframe", "L4CompPaclen"
}; /* parameter keywords */ }; /* parameter keywords */
static void * offset[] = static void * offset[] =
@ -328,7 +329,8 @@ static void * offset[] =
&xxcfg.C_APPL[4].ApplQual, &xxcfg.C_APPL[5].ApplQual, &xxcfg.C_APPL[6].ApplQual, &xxcfg.C_APPL[7].ApplQual, &xxcfg.C_APPL[4].ApplQual, &xxcfg.C_APPL[5].ApplQual, &xxcfg.C_APPL[6].ApplQual, &xxcfg.C_APPL[7].ApplQual,
&xxcfg.C_BTEXT, &xxcfg.C_NETROMCALL, &xxcfg.C_C, &xxcfg.C_MAXRTT, &xxcfg.C_MAXHOPS, // IPGATEWAY= no longer allowed &xxcfg.C_BTEXT, &xxcfg.C_NETROMCALL, &xxcfg.C_C, &xxcfg.C_MAXRTT, &xxcfg.C_MAXHOPS, // IPGATEWAY= no longer allowed
&xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs, &xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs,
&xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS}; /* offset for corresponding data in config file */ &xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS,
&xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen}; /* offset for corresponding data in config file */
static int routine[] = static int routine[] =
{ {
@ -348,7 +350,8 @@ static int routine[] =
14, 14 ,14, 14, 14, 14 ,14, 14,
15, 0, 2, 9, 9, 15, 0, 2, 9, 9,
2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 0, 1, 20, 20} ; // Routine to process param 2, 2, 0, 1, 20, 20,
1, 1, 1} ; // Routine to process param
int PARAMLIM = sizeof(routine)/sizeof(int); int PARAMLIM = sizeof(routine)/sizeof(int);
//int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int); //int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int);
@ -370,8 +373,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", "M0LTEMapInfo", "QTSMPort", "SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort"}; /* parameter keywords */
"MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS"}; /* parameter keywords */
static void * poffset[] = static void * poffset[] =
{ {
@ -616,6 +618,10 @@ BOOL ProcessConfig()
paramok[83]=1; // MQTT Params paramok[83]=1; // MQTT Params
paramok[84]=1; // MQTT Params paramok[84]=1; // MQTT Params
paramok[85]=1; // MQTT Params paramok[85]=1; // MQTT Params
paramok[86]=1; // L4Compress
paramok[87]=1; // L4Compress Maxframe
paramok[88]=1; // L4Compress Paclen
for (i=0; i < PARAMLIM; i++) for (i=0; i < PARAMLIM; i++)
{ {

View File

@ -170,6 +170,10 @@ struct CONFIGTABLE
int C_MQTT_PORT; int C_MQTT_PORT;
char C_MQTT_USER[80]; char C_MQTT_USER[80];
char C_MQTT_PASS[80]; char C_MQTT_PASS[80];
int C_L4Compress;
int C_L4CompMaxframe;
int C_L4CompPaclen;
//#define ApplOffset 80000 // Applications offset in config buffer //#define ApplOffset 80000 // Applications offset in config buffer
//#define InfoOffset 85000 // Infomsg offset in buffer //#define InfoOffset 85000 // Infomsg offset in buffer

View File

@ -852,7 +852,14 @@ double LatFromLOC = 0;
double LonFromLOC = 0; double LonFromLOC = 0;
#endif #endif
void SendBBSDataToPktMapThread();
void SendBBSDataToPktMap() void SendBBSDataToPktMap()
{
_beginthread(SendBBSDataToPktMapThread, 0, 0);
}
void SendBBSDataToPktMapThread()
{ {
char Request[64]; char Request[64];
char * Params; char * Params;

View File

@ -1,43 +0,0 @@
# LinBPQ Makefile
# To exclude i2c support run make noi2c
OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pngwutil.o\
pngread.o pngwrite.o png.o pngerror.o pngget.o pngmem.o APRSIconData.o AISCommon.o\
upnp.o APRSStdPages.o HSMODEM.o WinRPR.o KISSHF.o TNCEmulators.o bpqhdlc.o SerialPort.o\
adif.o WebMail.o utf8Routines.o VARA.o LzFind.o Alloc.o LzmaDec.o LzmaEnc.o LzmaLib.o \
Multicast.o ARDOP.o IPCode.o FLDigi.o linether.o CMSAuth.o APRSCode.o BPQtoAGW.o KAMPactor.o\
AEAPactor.o HALDriver.o MULTIPSK.o BBSHTMLConfig.o ChatHTMLConfig.o BBSUtilities.o bpqaxip.o\
BPQINP3.o BPQNRR.o cMain.o Cmd.o CommonCode.o HTMLCommonCode.o compatbits.o config.o datadefs.o \
FBBRoutines.o HFCommon.o Housekeeping.o HTTPcode.o kiss.o L2Code.o L3Code.o L4Code.o lzhuf32.o \
MailCommands.o MailDataDefs.o LinBPQ.o MailRouting.o MailTCP.o MBLRoutines.o md5.o Moncode.o \
NNTPRoutines.o RigControl.o TelnetV6.o WINMOR.o TNCCode.o UZ7HODrv.o WPRoutines.o \
SCSTrackeMulti.o SCSPactor.o SCSTracker.o HanksRT.o UIRoutines.o AGWAPI.o AGWMoncode.o \
DRATS.o FreeDATA.o base64.o Events.o nodeapi.o mailapi.o mqtt.o
# Configuration:
CC = gcc
all: CFLAGS = -DLINBPQ -MMD -g -fcommon
all: LDFLAGS = -l:libpaho-mqtt3a.a -l:libjansson.a
all: linbpq
nomqtt: CFLAGS = -DLINBPQ -MMD -fcommon -g -DNOMQTT
nomqtt: linbpq
noi2c: CFLAGS = -DLINBPQ -MMD -DNOI2C -g -fcommon
noi2c: linbpq
linbpq: $(OBJS)
gcc $(OBJS) -Xlinker -Map=output.map -l:libminiupnpc.a -lrt -lm -lz $(LDFLAGS) -lpthread -lconfig -lpcap -o linbpq
sudo setcap "CAP_NET_ADMIN=ep CAP_NET_RAW=ep CAP_NET_BIND_SERVICE=ep" linbpq
-include *.d
clean :
rm *.d
rm linbpq $(OBJS)

View File

@ -1,858 +0,0 @@
// basic JASON API to BPQ Node
// Authentication is via Telnet USER records.
#define _CRT_SECURE_NO_DEPRECATE
#include "cheaders.h"
#include <stdlib.h>
#include "tncinfo.h"
#include "asmstrucs.h"
#include "kiss.h"
// Constants
#define TOKEN_SIZE 32 // Length of the authentication token
#define TOKEN_EXPIRATION 7200 // Token expiration time in seconds (2 hours)
// Token data structure
typedef struct Token {
char token[TOKEN_SIZE + 1];
time_t expiration_time;
struct Token* next;
} Token;
typedef struct API
{
char *URL;
int URLLen;
int (* APIRoutine)(char * response, char * token, char * param);
int Auth;
} API;
// Auth defines
#define AuthNone 0
#define AuthUser 1
#define Auth BBSUser 2
#define AuthSysop 4
// Function prototypes
void handle_request(SOCKET client_socket, char * request, char * response);
int verify_token(const char* token);
void remove_expired_tokens();
char* fetch_data(const char* endpoint);
int request_token(char * response);
int send_http_response(char * response, const char* msg);
int create_json_response(char * response, char* access_token, int expires_in, char* scope);
void add_token_to_list(Token* token);
Token* find_token(const char* token);
Token* generate_token();
int sendPortList(char * response, char * token, char * Rest);
int sendNodeList(char * response, char * token, char * Rest);
int sendUserList(char * response, char * token, char * Rest);
int sendInfo(char * response, char * token, char * Rest);
int sendLinks(char * response, char * token, char * Rest);
int sendPortMHList(char * response, char * token, char * Rest);
int sendWhatsPacState(char * response, char * token, char * param);
int sendWhatsPacConfig(char * response, char * token, char * param);
void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT);
DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
// Token list
Token* token_list = NULL;
struct API APIList[] =
{
"/api/ports", 10, sendPortList, 0,
"/api/nodes", 10, sendNodeList, 0,
"/api/info", 9, sendInfo, 0,
"/api/links", 10, sendLinks, 0,
"/api/users", 10, sendUserList, 0,
"/api/mheard", 11, sendPortMHList, 0,
"/api/v1/config", 14, sendWhatsPacConfig, 0,
"/api/v1/state", 13, sendWhatsPacState, 0
};
int APICount = sizeof(APIList) / sizeof(struct API);
extern int HTTPPort;
int xx()
{
while (1)
{
// Remove expired tokens
remove_expired_tokens();
// Handle the client request
// handle_request();
}
return 0;
}
int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE)
{
const char * auth_header = "Authorization: Bearer ";
char * token_begin = strstr(request, auth_header);
char token[TOKEN_SIZE + 1]= "";
int Flags = 0, n;
// Node Flags isn't currently used
char * Tok;
char * param;
if (token_begin)
{
// Using Auth Header
// Extract the token from the request (assuming it's present in the request headers)
if (token_begin == NULL)
{
Debugprintf("Invalid request: No authentication token provided.\n");
return send_http_response(response, "403 (Forbidden)");
}
token_begin += strlen(auth_header); // Move to the beginning of the token
strncpy(token, token_begin, TOKEN_SIZE);
token[TOKEN_SIZE] = '\0'; // Null-terminate the token
param = strlop(URL, '?');
}
else
{
// There may be a token as first param, but if auth not needed may be misisng
Tok = strlop(URL, '?');
param = strlop(Tok, '&');
if (Tok && strlen(Tok) == TOKEN_SIZE)
{
// assume auth token
strcpy(token, Tok);
}
else param = Tok;
}
remove_expired_tokens(); // Tidy up
// Check if the request is for token generation
if (strcmp(Method, "OPTIONS") == 0)
{
// CORS Request
char Resp[] =
"HTTP/1.1 200 OK\r\n"
"Access-Control-Allow-Origin: *\r\n"
"Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n"
"Access-Control-Allow-Headers: authorization";
return send_http_response(response, Resp);
}
if (strcmp(Method, "GET") != 0)
return send_http_response(response, "403 (Bad Method)");
if (_stricmp(URL, "/api/request_token") == 0)
return request_token(response);
/*
if (token[0] == 0)
{
// Extract the token from the request (assuming it's present in the request headers)
if (token_begin == NULL)
{
Debugprintf("Invalid request: No authentication token provided.\n");
return send_http_response(response, "403 (Forbidden)");
}
token_begin += strlen(auth_header); // Move to the beginning of the token
strncpy(token, token_begin, TOKEN_SIZE);
token[TOKEN_SIZE] = '\0'; // Null-terminate the token
}
// Verify the token
if (!verify_token(token))
{
Debugprintf("Invalid authentication token.\n");
return send_http_response(response, "401 Unauthorized");
}
*/
// Determine the requested API endpoint
for (n = 0; n < APICount; n++)
{
struct API * APIEntry;
char * rest;
APIEntry = &APIList[n];
if (_memicmp(URL, APIEntry->URL, APIEntry->URLLen) == 0)
{
rest = &request[4 + APIEntry->URLLen]; // Anything following?
if (rest[0] == ' ' || rest[0] == '/' || rest[0] == '?')
return APIEntry->APIRoutine(response, token, rest);
}
}
return send_http_response(response, "401 Invalid API Call");
}
int request_token(char * response)
{
Token * token = generate_token();
char scope[] = "create";
printf("Token generated: %s\n", token->token);
sprintf(response, "{\"access_token\":\"%s\", \"expires_at\":%ld,\"scope\":\"create\"}\r\n",
token->token, token->expiration_time);
return strlen(response);
}
Token * generate_token()
{
// Generate a random authentication token
int i;
Token * token = malloc(sizeof(Token));
for (i = 0; i < TOKEN_SIZE; i++)
{
token->token[i] = 'A' + rand() % 26; // Random uppercase alphabet character
}
token->token[TOKEN_SIZE] = '\0'; // Null-terminate the token
token->expiration_time = time(NULL) + TOKEN_EXPIRATION; // Set token expiration time
add_token_to_list(token);
return token;
}
// Function to add the token to the token_list
void add_token_to_list(Token* token)
{
if (token_list == NULL)
{
token_list = token;
token->next = NULL;
}
else
{
Token* current = token_list;
while (current->next != NULL)
current = current->next;
current->next = token;
token->next = NULL;
}
}
int verify_token(const char* token)
{
// Find the token in the token list
Token * existing_token = find_token(token);
if (existing_token != NULL)
{
// Check if the token has expired
time_t current_time = time(NULL);
if (current_time > existing_token->expiration_time)
{
// Token has expired, remove it from the token list
remove_expired_tokens();
return 0;
}
// Token is valid
return 1;
}
// Token doesn't exist in the token list
return 0;
}
void remove_expired_tokens()
{
time_t current_time = time(NULL);
Token* current_token = token_list;
Token* prev_token = NULL;
Token* next_token;
while (current_token != NULL)
{
if (current_time > current_token->expiration_time)
{
// Token has expired, remove it from the token list
if (prev_token == NULL)
{
token_list = current_token->next;
} else {
prev_token->next = current_token->next;
}
next_token = current_token->next;
free(current_token);
current_token = next_token;
} else {
prev_token = current_token;
current_token = current_token->next;
}
}
}
Token * find_token(const char* token)
{
Token* current_token = token_list;
while (current_token != NULL)
{
if (strcmp(current_token->token, token) == 0)
{
return current_token;
}
current_token = current_token->next;
}
return NULL;
}
int send_http_response(char * response, const char* msg)
{
return sprintf(response, "HTTP/1.1 %s\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", msg);
}
/*
{
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
"expires_in":3600,
"scope":"create"
}
*/
/*
{"ports":[
{"ID":"My Port", "Driver":"KISS", "Number":2, "State":"Active"),
{ ...},
{...}
]}
*/
extern int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific MPSK or UZ7HO host
int sendPortList(char * response, char * token, char * param)
{
char * Array = 0;
int ArrayLen = 0;
int ArrayPtr = 0;
struct _EXTPORTDATA * ExtPort;
struct PORTCONTROL * Port;
struct PORTCONTROL * SAVEPORT;
int PortNo;
int count;
char DLL[20];
char Status[32]="Unknown";
char ID[33];
char * ptr;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"ports\":[\r\n");
for (count = 1; count <= NUMBEROFPORTS; count++)
{
Port = GetPortTableEntryFromSlot(count);
ExtPort = (struct _EXTPORTDATA *)Port;
PortNo = Port->PORTNUMBER;
if (Port->PORTTYPE == 0x10)
{
strcpy(DLL, ExtPort->PORT_DLL_NAME);
strlop(DLL, '.');
strlop(DLL, ' ');
}
else if (Port->PORTTYPE == 0)
strcpy(DLL, "ASYNC");
else if (Port->PORTTYPE == 22)
strcpy(DLL, "I2C");
else if (Port->PORTTYPE == 14)
strcpy(DLL, "INTERNAL");
else if (Port->PORTTYPE > 0 && Port->PORTTYPE < 14)
strcpy(DLL, "HDLC");
if (Port->PortStopped)
{
strcpy(Status, "Stopped");
}
else
{
if (Port->PORTTYPE == 0)
{
struct KISSINFO * KISS = (struct KISSINFO *)Port;
NPASYINFO KPort;
SAVEPORT = Port;
if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS)
{
// Not first port on device
Port = (struct PORTCONTROL *)KISS->FIRSTPORT;
KPort = KISSInfo[PortNo];
}
KPort = KISSInfo[PortNo];
if (KPort)
{
// KISS like - see if connected
if (Port->PORTIPADDR.s_addr || Port->KISSSLAVE)
{
// KISS over UDP or TCP
if (Port->KISSTCP)
{
if (KPort->Connected)
strcpy(Status, "Open ");
else
if (Port->KISSSLAVE)
strcpy(Status, "Listen");
else
strcpy(Status, "Closed");
}
else
strcpy(Status, "UDP");
}
else
if (KPort->idComDev) // Serial port Open
strcpy(Status, "Open ");
else
strcpy(Status, "Closed");
Port = SAVEPORT;
}
}
if (Port->PORTTYPE == 14) // Loopback
strcpy(Status, "Open ");
else if (Port->PORTTYPE == 16) // External
{
if (Port->PROTOCOL == 10) // 'HF' Port
{
struct TNCINFO * TNC = TNCInfo[PortNo];
if (TNC)
{
switch (TNC->Hardware) // Hardware Type
{
case H_SCS:
case H_KAM:
case H_AEA:
case H_HAL:
case H_TRK:
case H_SERIAL:
// Serial
if (TNC->hDevice)
strcpy(Status, "Open ");
else
strcpy(Status, "Closed");
break;
case H_UZ7HO:
if (TNCInfo[MasterPort[PortNo]]->CONNECTED)
strcpy(Status, "Open ");
else
strcpy(Status, "Closed");
break;
case H_WINMOR:
case H_V4:
case H_MPSK:
case H_FLDIGI:
case H_UIARQ:
case H_ARDOP:
case H_VARA:
case H_KISSHF:
case H_WINRPR:
case H_FREEDATA:
// TCP
if (TNC->CONNECTED)
{
if (TNC->Streams[0].Attached)
strcpy(Status, "In Use");
else
strcpy(Status, "Open ");
}
else
strcpy(Status, "Closed");
break;
case H_TELNET:
strcpy(Status, "Open ");
}
}
}
else
{
// External but not HF - AXIP, BPQETHER VKISS, ??
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)Port;
strcpy(Status, "Open ");
}
}
}
strlop(Status, ' ');
strcpy(ID, Port->PORTDESCRIPTION);
ptr = &ID[29];
while (*(ptr) == ' ')
{
*(ptr--) = 0;
}
ArrayPtr += sprintf(&response[ArrayPtr], " {\"ID\":\"%s\", \"Driver\":\"%s\", \"Number\":%d,\"State\":\"%s\"},\r\n",
ID, DLL, Port->PORTNUMBER, Status);
}
ArrayPtr -= 3; // remove trailing comma
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}\r\n");
return ArrayPtr;
}
/*
{"Nodes":[
{"Call":"xx", "Alias":"xx", "Nbour1 ":"xx", "Quality":192),
{ ...},
{...}
]}
*/
extern int MaxNodes;
extern struct DEST_LIST * DESTS; // NODE LIST
extern int DEST_LIST_LEN;
int sendNodeList(char * response, char * token, char * param)
{
int ArrayPtr = 0;
int count, len, i;
char Normcall[10], Portcall[10];
char Alias[7];
struct DEST_LIST * Dests = DESTS ;
// struct ROUTE * Routes;
Dests = DESTS;
MaxNodes = MAXDESTS;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"nodes\":[\r\n");
Dests-=1;
for (count = 0; count < MaxNodes; count++)
{
Dests+=1;
if (Dests->DEST_CALL[0] == 0)
continue;
len = ConvFromAX25(Dests->DEST_CALL, Normcall);
Normcall[len] = 0;
memcpy(Alias, Dests->DEST_ALIAS, 6);
Alias[6]=0;
for (i=0;i<6;i++)
{
if (Alias[i] == ' ')
Alias[i] = 0;
}
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Alias\":\"%s\", \"Routes\":[", Normcall, Alias);
// Add an array with up to 6 objects (3 NR + 3 INP3 Neighbours
if (Dests->NRROUTE[0].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[0].ROUT_NEIGHBOUR->INP3Node == 0)
{
len = ConvFromAX25(Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
Portcall[len] = 0;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
Portcall, Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[0].ROUT_QUALITY);
// if (Dests->NRROUTE[0].ROUT_OBSCOUNT > 127)
// {
// len=sprintf(&line[cursor],"! ");
// cursor+=len;
// }
if (Dests->NRROUTE[1].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[1].ROUT_NEIGHBOUR->INP3Node == 0)
{
len=ConvFromAX25(Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
Portcall[len]=0;
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
Portcall, Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[1].ROUT_QUALITY);
//if (Dests->NRROUTE[1].ROUT_OBSCOUNT > 127)
//{
//len=sprintf(&line[cursor],"! ");
//cursor+=len;
//}
}
if (Dests->NRROUTE[2].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[2].ROUT_NEIGHBOUR->INP3Node == 0)
{
len=ConvFromAX25(Dests->NRROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
Portcall[len]=0;
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
Portcall, Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[1].ROUT_QUALITY);
//if (Dests->NRROUTE[2].ROUT_OBSCOUNT > 127)
//{
//len=sprintf(&line[cursor],"! ");
//cursor+=len;
}
ArrayPtr -= 1; // remove comma
}
ArrayPtr += sprintf(&response[ArrayPtr], "]},\r\n");
}
ArrayPtr -= 3; // remove comma
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}");
return ArrayPtr;
}
int sendUserList(char * response, char * token, char * param)
{
int ArrayPtr = 0;
int n = MAXCIRCUITS;
TRANSPORTENTRY * L4 = L4TABLE;
// TRANSPORTENTRY * Partner;
int MaxLinks = MAXLINKS;
char State[12] = "", Type[12] = "Uplink";
char LHS[50] = "", MID[10] = "", RHS[50] = "";
// char Line[100];
char Normcall[10];
int len;
ArrayPtr += sprintf(&response[ArrayPtr], "{\"users\":[\r\n");
while (n--)
{
if (L4->L4USER[0])
{
RHS[0] = MID[0] = 0;
len = ConvFromAX25(L4->L4USER, Normcall);
Normcall[len] = 0;
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\": \"%s\"},\r\n", Normcall);
L4++;
}
}
if (ArrayPtr == 12) //empty list
{
ArrayPtr -=2;
ArrayPtr += sprintf(&response[ArrayPtr], "]}\r\n");
}
else
{
ArrayPtr -= 3; // remove trailing comma
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}\r\n");
}
return ArrayPtr;
}
extern char MYALIASLOPPED[];
extern char TextVerstring[];
extern char LOCATOR[];
int sendInfo(char * response, char * token, char * param)
{
char call[10];
memcpy(call, MYNODECALL, 10);
strlop(call, ' ');
sprintf(response, "{\"info\":{\"NodeCall\":\"%s\", \"Alias\":\"%s\", \"Locator\":\"%s\", \"Version\":\"%s\"}}\r\n",
call, MYALIASLOPPED, LOCATOR, TextVerstring);
return strlen(response);
}
int sendLinks(char * response, char * token, char * param)
{
struct _LINKTABLE * Links = LINKS;
int MaxLinks = MAXLINKS;
int count;
char Normcall1[10];
char Normcall2[10];
char State[12] = "", Type[12] = "Uplink";
int axState;
int cctType;
int ReplyLen = 0;
ReplyLen += sprintf(&response[ReplyLen],"{\"links\":[\r\n");
for (count=0; count<MaxLinks; count++)
{
if (Links->LINKCALL[0] != 0)
{
int len = ConvFromAX25(Links->LINKCALL, Normcall1);
Normcall1[len] = 0;
len = ConvFromAX25(Links->OURCALL, Normcall2);
Normcall2[len] = 0;
axState = Links->L2STATE;
if (axState == 2)
strcpy(State, "Connecting");
else if (axState == 3)
strcpy(State, "FRMR");
else if (axState == 4)
strcpy(State, "Closing");
else if (axState == 5)
strcpy(State, "Active");
else if (axState == 6)
strcpy(State, "REJ Sent");
cctType = Links->LINKTYPE;
if (cctType == 1)
strcpy(Type, "Uplink");
else if (cctType == 2)
strcpy(Type, "Downlink");
else if (cctType == 3)
strcpy(Type, "Node-Node");
ReplyLen += sprintf(&response[ReplyLen], "{\"farCall\": \"%s\",\"ourCall\": \"%s\", \"port\": \"%d\", \"state\": \"%s\", \"linkType\": \"%s\", \"ax25Version\": \"%d\"},\r\n",
Normcall1, Normcall2, Links->LINKPORT->PORTNUMBER,
State, Type, 2 - Links->VER1FLAG );
Links+=1;
}
}
if (ReplyLen < 13)
ReplyLen -= 2; // no links
else
ReplyLen -= 3; // remove trailing comma
ReplyLen+= sprintf(&response[ReplyLen], "\r\n]}\r\n");
return ReplyLen;
}
int sendPortMHList(char * response, char * token, char * param)
{
struct PORTCONTROL * PORTVEC ;
int n;
int port = 0;
if (param[0] = '?' || param[0] == '/')
port = atoi(&param[1]);
PORTVEC = GetPortTableEntryFromPortNum(port);
response[0] = 0;
if (PORTVEC == 0)
return send_http_response(response, "401 Invalid API Call");
n = sprintf(response,"{\"mheard\":[\r\n");
BuildPortMH(&response[n], PORTVEC );
if (response[n] == 0) // No entries
{
response[strlen(response) - 2] = '\0'; // remove \r\n
strcat(response, "]}\r\n");
}
else
{
response[strlen(response)-3 ] = '\0'; // remove ,\r\n
strcat(response, "\r\n]}\r\n");
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
}
return strlen(response);
}
// WhatsPac configuration interface
// WhatsPac also uses Paula's Remote Host Protocol (RHP). This is in a separate module
extern int WhatsPacConfigured;
int sendWhatsPacState(char * response, char * token, char * param)
{
if (WhatsPacConfigured)
sprintf(response, "{\"configured\": true}\r\n");
else
sprintf(response, "{\"configured\": false}\r\n");
return strlen(response);
}
int sendWhatsPacConfig(char * response, char * token, char * param)
{
char Template[] =
"{\"MODE\": 0,"
"\"RHPPORT\": \"%d\","
"\"AGWPORT\": \"7000\","
"\"INTERFACES\": [{\"INTERFACE\": 1,\"PROTOCOL\": \"KISS\",\"TYPE\": \"TCP\",\"IOADDR\": \"127.0.0.1\",\"INTNUM\": 8100}],"
"\"PORTS\": [{\"PORT\": 1,\"ID\": \"RHPPORT\", \"INTERFACENUM\": 1}]}";
sprintf(response, Template, HTTPPort);
return strlen(response);
}

View File

@ -2,7 +2,6 @@
// Authentication is via Telnet USER records. // Authentication is via Telnet USER records.
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE
#include "cheaders.h" #include "cheaders.h"
@ -26,7 +25,7 @@ typedef struct API
{ {
char *URL; char *URL;
int URLLen; int URLLen;
int (* APIRoutine)(char * response, char * token, char * param); int (* APIRoutine)(char * response, char * token, char * param, int Local);
int Auth; int Auth;
} API; } API;
@ -34,7 +33,7 @@ typedef struct API
#define AuthNone 0 #define AuthNone 0
#define AuthUser 1 #define AuthUser 1
#define Auth BBSUser 2 #define AuthBBSUser 2
#define AuthSysop 4 #define AuthSysop 4
// Function prototypes // Function prototypes
@ -50,14 +49,14 @@ void add_token_to_list(Token* token);
Token* find_token(const char* token); Token* find_token(const char* token);
Token* generate_token(); Token* generate_token();
int sendPortList(char * response, char * token, char * Rest); int sendPortList(char * response, char * token, char * Rest, int Local);
int sendNodeList(char * response, char * token, char * Rest); int sendNodeList(char * response, char * token, char * Rest, int Local);
int sendUserList(char * response, char * token, char * Rest); int sendUserList(char * response, char * token, char * Rest, int Local);
int sendInfo(char * response, char * token, char * Rest); int sendInfo(char * response, char * token, char * Rest, int Local);
int sendLinks(char * response, char * token, char * Rest); int sendLinks(char * response, char * token, char * Rest, int Local);
int sendPortMHList(char * response, char * token, char * Rest); int sendPortMHList(char * response, char * token, char * Rest, int Local);
int sendWhatsPacState(char * response, char * token, char * param); int sendWhatsPacState(char * response, char * token, char * param, int Local);
int sendWhatsPacConfig(char * response, char * token, char * param); int sendWhatsPacConfig(char * response, char * token, char * param, int Local);
void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT); void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT);
DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot); DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
@ -74,8 +73,8 @@ struct API APIList[] =
"/api/links", 10, sendLinks, 0, "/api/links", 10, sendLinks, 0,
"/api/users", 10, sendUserList, 0, "/api/users", 10, sendUserList, 0,
"/api/mheard", 11, sendPortMHList, 0, "/api/mheard", 11, sendPortMHList, 0,
"/api/v1/config", 14, sendWhatsPacConfig, 0, "/api/v1/config", 14, sendWhatsPacConfig, AuthSysop,
"/api/v1/state", 13, sendWhatsPacState, 0 "/api/v1/state", 13, sendWhatsPacState, AuthSysop
}; };
int APICount = sizeof(APIList) / sizeof(struct API); int APICount = sizeof(APIList) / sizeof(struct API);
@ -159,6 +158,14 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
return send_http_response(response, Resp); return send_http_response(response, Resp);
} }
if (strcmp(Method, "POST") == 0)
{
if (_stricmp(URL, "/api/v1/config") == 0)
{
return send_http_response(response, "200 (OK)");
}
}
if (strcmp(Method, "GET") != 0) if (strcmp(Method, "GET") != 0)
return send_http_response(response, "403 (Bad Method)"); return send_http_response(response, "403 (Bad Method)");
@ -202,7 +209,7 @@ if (token[0] == 0)
rest = &request[4 + APIEntry->URLLen]; // Anything following? rest = &request[4 + APIEntry->URLLen]; // Anything following?
if (rest[0] == ' ' || rest[0] == '/' || rest[0] == '?') if (rest[0] == ' ' || rest[0] == '/' || rest[0] == '?')
return APIEntry->APIRoutine(response, token, rest); return APIEntry->APIRoutine(response, token, rest, LOCAL);
} }
} }
@ -349,7 +356,7 @@ int send_http_response(char * response, const char* msg)
extern int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific MPSK or UZ7HO host extern int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific MPSK or UZ7HO host
int sendPortList(char * response, char * token, char * param) int sendPortList(char * response, char * token, char * param, int Local)
{ {
char * Array = 0; char * Array = 0;
int ArrayLen = 0; int ArrayLen = 0;
@ -561,7 +568,7 @@ extern struct DEST_LIST * DESTS; // NODE LIST
extern int DEST_LIST_LEN; extern int DEST_LIST_LEN;
int sendNodeList(char * response, char * token, char * param) int sendNodeList(char * response, char * token, char * param, int Local)
{ {
int ArrayPtr = 0; int ArrayPtr = 0;
@ -665,7 +672,7 @@ int sendNodeList(char * response, char * token, char * param)
} }
int sendUserList(char * response, char * token, char * param) int sendUserList(char * response, char * token, char * param, int Local)
{ {
int ArrayPtr = 0; int ArrayPtr = 0;
int n = MAXCIRCUITS; int n = MAXCIRCUITS;
@ -711,7 +718,7 @@ extern char MYALIASLOPPED[];
extern char TextVerstring[]; extern char TextVerstring[];
extern char LOCATOR[]; extern char LOCATOR[];
int sendInfo(char * response, char * token, char * param) int sendInfo(char * response, char * token, char * param, int Local)
{ {
char call[10]; char call[10];
@ -724,7 +731,7 @@ int sendInfo(char * response, char * token, char * param)
return strlen(response); return strlen(response);
} }
int sendLinks(char * response, char * token, char * param) int sendLinks(char * response, char * token, char * param, int Local)
{ {
struct _LINKTABLE * Links = LINKS; struct _LINKTABLE * Links = LINKS;
int MaxLinks = MAXLINKS; int MaxLinks = MAXLINKS;
@ -789,7 +796,7 @@ int sendLinks(char * response, char * token, char * param)
return ReplyLen; return ReplyLen;
} }
int sendPortMHList(char * response, char * token, char * param) int sendPortMHList(char * response, char * token, char * param, int Local)
{ {
struct PORTCONTROL * PORTVEC ; struct PORTCONTROL * PORTVEC ;
int n; int n;
@ -828,8 +835,11 @@ int sendPortMHList(char * response, char * token, char * param)
extern int WhatsPacConfigured; extern int WhatsPacConfigured;
int sendWhatsPacState(char * response, char * token, char * param) int sendWhatsPacState(char * response, char * token, char * param, int Local)
{ {
if (Local == 0)
return send_http_response(response, "401 Not Authorised");
if (WhatsPacConfigured) if (WhatsPacConfigured)
sprintf(response, "{\"configured\": true}\r\n"); sprintf(response, "{\"configured\": true}\r\n");
else else
@ -839,7 +849,7 @@ int sendWhatsPacState(char * response, char * token, char * param)
} }
int sendWhatsPacConfig(char * response, char * token, char * param) int sendWhatsPacConfig(char * response, char * token, char * param, int Local)
{ {
char Template[] = char Template[] =
"{\"MODE\": 0," "{\"MODE\": 0,"
@ -848,6 +858,9 @@ int sendWhatsPacConfig(char * response, char * token, char * param)
"\"INTERFACES\": [{\"INTERFACE\": 1,\"PROTOCOL\": \"KISS\",\"TYPE\": \"TCP\",\"IOADDR\": \"127.0.0.1\",\"INTNUM\": 8100}]," "\"INTERFACES\": [{\"INTERFACE\": 1,\"PROTOCOL\": \"KISS\",\"TYPE\": \"TCP\",\"IOADDR\": \"127.0.0.1\",\"INTNUM\": 8100}],"
"\"PORTS\": [{\"PORT\": 1,\"ID\": \"RHPPORT\", \"INTERFACENUM\": 1}]}"; "\"PORTS\": [{\"PORT\": 1,\"ID\": \"RHPPORT\", \"INTERFACENUM\": 1}]}";
if (Local == 0)
return send_http_response(response, "401 Not Authorised");
sprintf(response, Template, HTTPPort); sprintf(response, Template, HTTPPort);
return strlen(response); return strlen(response);

View File

@ -871,9 +871,10 @@ typedef struct TNCINFO
VOID * zalloc(int len); VOID * zalloc(int len);
BOOL ReadConfigFile(int Port, int ProcLine()); BOOL ReadConfigFile(int Port, int ProcLine(char * buf, int Port));
int GetLine(char * buf); int GetLine(char * buf);
BOOL CreatePactorWindow(struct TNCINFO * TNC, char * ClassName, char * WindowTitle, int RigControlRow, WNDPROC WndProc, int Width, int Height, VOID ForcedCloseProc()); BOOL CreatePactorWindow(struct TNCINFO * TNC, char * ClassName, char * WindowTitle, int RigControlRow, WNDPROC WndProc,
int Width, int Height, VOID ForcedCloseProc(struct TNCINFO * TNC, int Stream));
char * CheckAppl(struct TNCINFO * TNC, char * Appl); char * CheckAppl(struct TNCINFO * TNC, char * Appl);
BOOL SendReporttoWL2K(struct TNCINFO * TNC); BOOL SendReporttoWL2K(struct TNCINFO * TNC);
struct WL2KInfo * DecodeWL2KReportLine(char * buf); struct WL2KInfo * DecodeWL2KReportLine(char * buf);