New upstream version 6.0.24.49

This commit is contained in:
Hibby 2024-11-05 21:03:15 +00:00
parent eb0d36d3f6
commit 424c0bd3e1
71 changed files with 7593 additions and 433 deletions

View File

@ -970,7 +970,7 @@ ok:
UCHAR * data = &buffptr->Data[0];
STREAM->FramesQueued--;
txlen = (int)buffptr->Len;
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
bytes=SerialSendData(TNC, data, txlen);
WritetoTrace(TNC, data, txlen);

View File

@ -812,7 +812,7 @@ VOID AEAPoll(int Port)
{
// Limit amount in TX
if (TNC->Streams[0].BytesTXed - TNC->Streams[0].BytesAcked > 200)
if (TNC->Streams[0].bytesTXed - TNC->Streams[0].BytesAcked > 200)
continue;
// If in IRS state for too long, force turnround
@ -877,8 +877,8 @@ VOID AEAPoll(int Port)
EncodeAndSend(TNC, TXMsg, datalen + 1);
ReleaseBuffer(buffptr);
TNC->Streams[Stream].BytesTXed += datalen;
Debugprintf("Stream %d Sending %d, BytesTXED now %d", Stream, datalen, TNC->Streams[Stream].BytesTXed);
TNC->Streams[Stream].bytesTXed += datalen;
Debugprintf("Stream %d Sending %d, BytesTXED now %d", Stream, datalen, TNC->Streams[Stream].bytesTXed);
TNC->Timeout = 0;
TNC->DataBusy = TRUE;
@ -1212,7 +1212,7 @@ static VOID ProcessAEAPacket(struct TNCINFO * TNC, UCHAR * Msg, size_t Len)
// If nothing more to send, turn round link
if ((TNC->Streams[0].BPQtoPACTOR_Q == 0) && TNC->NeedTurnRound &&
(TNC->Streams[0].BytesAcked >= TNC->Streams[0].BytesTXed)) // Nothing following and all acked
(TNC->Streams[0].BytesAcked >= TNC->Streams[0].bytesTXed)) // Nothing following and all acked
{
Debugprintf("AEA Sent = Acked - sending Turnround");
@ -1247,7 +1247,7 @@ static VOID ProcessAEAPacket(struct TNCINFO * TNC, UCHAR * Msg, size_t Len)
Len--; // Remove Header
buffptr->Len = Len; // Length
TNC->Streams[Stream].BytesRXed += (int)Len;
TNC->Streams[Stream].bytesRXed += (int)Len;
memcpy(&buffptr->Data[0], Buffer, Len);
C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr);
@ -1418,7 +1418,7 @@ static VOID ProcessAEAPacket(struct TNCINFO * TNC, UCHAR * Msg, size_t Len)
Buffer[Len-2] = 0;
}
TNC->Streams[Stream].BytesRXed = TNC->Streams[Stream].BytesTXed = TNC->Streams[Stream].BytesAcked = 0;
TNC->Streams[Stream].bytesRXed = TNC->Streams[Stream].bytesTXed = TNC->Streams[Stream].BytesAcked = 0;
TNC->Streams[Stream].ConnectTime = time(NULL);
if (Stream == 0)

View File

@ -564,9 +564,27 @@ int AGWConnected(struct BPQConnectionInfo * Con, int Stream)
{
// Create Key
char callsign[10];
int port;
int sesstype;
int paclen;
int maxframe;
int l4window;
keyptr=(byte *)&Con->CallKey;
*(keyptr++)='1';
// Try using the BPQ Port Number if a L2 connect, first free port number if not
GetConnectionInfo(Stream, callsign,
&port, &sesstype, &paclen,
&maxframe, &l4window);
if (port == 0)
port = 64;
*(keyptr++)='0' + port;
memcpy(keyptr, ApplCall, 10);
keyptr+=10;
memcpy(keyptr,ConnectingCall, 10);
@ -686,8 +704,9 @@ int AGWDoMonitorData()
struct AGWSocketConnectionInfo * sockptr;
byte AGWBuffer[1000];
int n;
int Stamp, Frametype;
int Frametype;
BOOL RXFlag;
time_t Stamp;
// Look for Monitor Data
@ -708,7 +727,7 @@ int AGWDoMonitorData()
return 0;
}
Stamp = (UINT)monbuff->Timestamp;
Stamp = monbuff->Timestamp;
memcpy(Buffer, monbuff, RawLen);

View File

@ -69,7 +69,7 @@ static UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
static UCHAR * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output);
int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, int Stamp, int * FrameType, int useLocalTime, int DoNodes)
int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int DoNodes)
{
UCHAR * ptr;
int n;
@ -365,7 +365,7 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, int Stamp, int * FrameT
}
if (Output == NULL)
return NULL;
return 0;
if (Output[-1] != 13)
Output += sprintf((char *)Output, "\r");

45
ARDOP.c
View File

@ -314,7 +314,7 @@ void SendARDOPorPacketData(struct TNCINFO * TNC, int Stream, UCHAR * Buff, int t
if (Stream == 0)
{
ARDOPSendData(TNC, Buff, txlen);
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
WritetoTrace(TNC, Buff, txlen);
}
else
@ -1274,7 +1274,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
UCHAR * data = &buffptr->Data[0];
STREAM->FramesQueued--;
txlen = (int)buffptr->Len;
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
if (Stream == 0)
{
@ -1381,7 +1381,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
{
bytes=ARDOPSendData(TNC, &buff->L2DATA[0], txlen);
TNC->Streams[Stream].BytesOutstanding += bytes; // So flow control works - will be updated by BUFFER response
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
WritetoTrace(TNC, &buff->L2DATA[0], txlen);
}
else
@ -1627,6 +1627,8 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
ARDOPChangeMYC(TNC, TNC->Streams[0].MyCall);
hookL4SessionAttempt(STREAM, &buff->L2DATA[2], TNC->Streams[0].MyCall);
// See if Busy
if (InterlockedCheckBusy(TNC))
@ -2263,7 +2265,7 @@ VOID TNCLost(struct TNCINFO * TNC)
if (Stream == 0)
{
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - STREAM->BytesOutstanding, STREAM->BytesRXed, STREAM->BytesOutstanding);
STREAM->bytesTXed - STREAM->BytesOutstanding, STREAM->bytesRXed, STREAM->BytesOutstanding);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
}
@ -3063,7 +3065,7 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
}
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - STREAM->BytesOutstanding, STREAM->BytesRXed, STREAM->BytesOutstanding);
STREAM->bytesTXed - STREAM->BytesOutstanding, STREAM->bytesRXed, STREAM->BytesOutstanding);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
return;
}
@ -3083,7 +3085,7 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
WritetoTrace(TNC, Buffer, MsgLen - 1);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->PacketsSent = 0;
memcpy(Call, &Buffer[10], 10);
@ -3260,7 +3262,7 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->NeedDisc = 100; // 10 secs
}
}
strcpy(STREAM->MyCall, TNC->TargetCall);
return;
}
else
@ -3347,29 +3349,13 @@ VOID ARDOPProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
WritetoTrace(TNC, Buffer, MsgLen - 1);
// Release Session3
// Release Session
if (TNC->Streams[0].Connected)
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1;
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
STREAM->ConnectTime = 0; // Prevent retrigger
hookL4SessionDeleted(TNC, STREAM);
}
@ -3850,13 +3836,12 @@ VOID ARDOPProcessDataPacket(struct TNCINFO * TNC, UCHAR * Type, UCHAR * Data, in
return;
}
STREAM->BytesRXed += Length;
STREAM->bytesRXed += Length;
Data[Length] = 0;
Debugprintf("ARDOP: RXD %d bytes", Length);
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - STREAM->BytesOutstanding, STREAM->BytesRXed, STREAM->BytesOutstanding);
STREAM->bytesTXed - STREAM->BytesOutstanding, STREAM->bytesRXed, STREAM->BytesOutstanding);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
@ -3959,6 +3944,8 @@ VOID ARDOPProcessDataPacket(struct TNCINFO * TNC, UCHAR * Type, UCHAR * Data, in
BPQTRACE((MESSAGE *)buffptr, TRUE);
ReleaseBuffer(buffptr);
}
else
{
@ -5003,7 +4990,7 @@ tcpHostFrame:
WritetoTrace(TNC, Buffer, len);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->PacketsSent = 0;
memcpy(Call, &Buffer[19], 10);
ptr = strchr(Call, ' ');

View File

@ -116,7 +116,7 @@ int SendWebMailHeader(char * Reply, char * Key, struct HTTPConnectionInfo * Sess
struct UserInfo * FindBBS(char * Name);
void ReleaseWebMailStruct(WebMailInfo * WebMail);
VOID TidyWelcomeMsg(char ** pPrompt);
int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param);
int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char * Param, char * Token);
char UNC[] = "";
char CHKD[] = "checked=checked ";
@ -447,7 +447,7 @@ void ConvertTitletoUTF8(WebMailInfo * WebMail, char * Title, char * UTF8Title, i
BOOL GotFirstMessage = 0;
void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen)
void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen, char * Token)
{
char * Context = 0, * NodeURL;
int ReplyLen;
@ -477,6 +477,13 @@ void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method,
}
if (_memicmp(URL, "/Mail/API/v1/", 13) == 0)
{
*RLen = MailAPIProcessHTTPMessage(Session, Reply, Method, URL, input, LOCAL, Context, Token);
return;
}
// There is a problem if Mail is reloaded without reloading the node
if (GotFirstMessage == 0)
@ -494,12 +501,6 @@ void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method,
return;
}
if (_memicmp(URL, "/Mail/API/", 10) == 0)
{
*RLen = MailAPIProcessHTTPMessage(Reply, Method, URL, input, LOCAL, Context);
return;
}
if (strcmp(Method, "POST") == 0)
{
@ -2996,6 +2997,8 @@ int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer);
static char PipeFileName[] = "\\\\.\\pipe\\BPQMailWebPipe";
// Constants
static DWORD WINAPI InstanceThread(LPVOID lpvParam)
// This routine is a thread processing function to read from and reply to a client
@ -3016,6 +3019,7 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam)
char URL[100001];
char * Context, * Method;
int n;
char token[16]= "";
char * ptr;
@ -3051,18 +3055,43 @@ static DWORD WINAPI InstanceThread(LPVOID lpvParam)
}
else
{
strcpy(URL, MsgPtr);
// look for auth header
ptr = strstr(URL, " HTTP");
const char * auth_header = "Authorization: Bearer ";
char * token_begin = strstr(MsgPtr, auth_header);
int Flags = 0, n;
if (ptr)
*ptr = 0;
// Node Flags isn't currently used
Method = strtok_s(URL, " ", &Context);
char * Tok;
char * param;
ProcessMailHTTPMessage(&Session, Method, Context, MsgPtr, OutBuffer, &OutputLen, InputLen);
if (token_begin)
{
// Using Auth Header
// Extract the token from the request (assuming it's present in the request headers)
token_begin += strlen(auth_header); // Move to the beginning of the token
strncpy(token, token_begin, 13);
token[13] = '\0'; // Null-terminate the token
}
}
strcpy(URL, MsgPtr);
ptr = strstr(URL, " HTTP");
if (ptr)
*ptr = 0;
Method = strtok_s(URL, " ", &Context);
ProcessMailHTTPMessage(&Session, Method, Context, MsgPtr, OutBuffer, &OutputLen, InputLen, token);
WriteFile(hPipe, &Session, sizeof (struct HTTPConnectionInfo), &n, NULL);
WriteFile(hPipe, OutBuffer, OutputLen, &cbWritten, NULL);

View File

@ -269,6 +269,8 @@ char FilesNames[4][100] = {"", "", "", ""};
char * Logs[4] = {"BBS", "CHAT", "TCP", "DEBUG"};
extern struct SEM ConfigSEM;
BOOL OpenLogfile(int Flags)
{
@ -2209,7 +2211,7 @@ BOOL CheckValidCall(char * From)
if (DontCheckFromCall)
return TRUE;
if (strcmp(From, "SYSOP") == 0 || strcmp(From, "SYSTEM") == 0 ||
if (strcmp(From, "SYSOP") == 0 || strcmp(From, "SYSTEM") == 0 || strcmp(From, "SERVIC") == 0 ||
strcmp(From, "IMPORT") == 0 || strcmp(From, "SMTP:") == 0 || strcmp(From, "RMS:") == 0)
return TRUE;
@ -8136,6 +8138,15 @@ BOOL ProcessBBSConnectScript(CIRCUIT * conn, char * Buffer, int len)
Line = Scripts[n];
}
if (Line == NULL)
{
// No more lines - Disconnect
conn->BBSFlags &= ~RunningConnectScript; // so it doesn't get reentered
Disconnect(conn->BPQStream);
return FALSE;
}
if (_memicmp(Line, "TIMES", 5) == 0)
{
NextBand:
@ -9523,6 +9534,8 @@ VOID SaveConfig(char * ConfigName)
FBBFilter * p = Filters;
char * ptr = FBBString;
GetSemaphore(&ConfigSEM, 60);
if (configSaved == 0)
{
// only create backup once per run
@ -9945,10 +9958,11 @@ VOID SaveConfig(char * ConfigName)
#ifdef LINBPQ
if(! config_write_file(&cfg,"/dev/shm/linmail.cfg.temp" ))
if(!config_write_file(&cfg,"/dev/shm/linmail.cfg.temp" ))
{
print("Error while writing file.\n");
config_destroy(&cfg);
FreeSemaphore(&ConfigSEM);
return;
}
@ -9960,6 +9974,8 @@ VOID SaveConfig(char * ConfigName)
{
fprintf(stderr, "Error while writing file.\n");
config_destroy(&cfg);
FreeSemaphore(&ConfigSEM);
return;
}
@ -9988,6 +10004,8 @@ VOID SaveConfig(char * ConfigName)
}
#endif
*/
FreeSemaphore(&ConfigSEM);
}
int GetIntValue(config_setting_t * group, char * name)

View File

@ -1140,6 +1140,8 @@
// Rewrite PG server code on Lunux (41)
// Fix SendPToMultiple not stopping at Implied AT match (45)
// Log Our HA when checking for flood bulls (45)
// Semaphore calls to SaveConfig
// Include SERVIC as valid from call (for Winlink Service messages) (49)
#include "bpqmail.h"
#include "winstdint.h"
@ -1392,7 +1394,7 @@ DWORD Stack[16];
BOOL Restarting = FALSE;
Dump_Process_State(struct _EXCEPTION_POINTERS * exinfo, char * Msg)
void Dump_Process_State(struct _EXCEPTION_POINTERS * exinfo, char * Msg)
{
unsigned int SPPtr;
unsigned int SPVal;

View File

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

View File

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

View File

@ -1227,8 +1227,12 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Allow interlocking of KISS and Session mode ports (eg ARDOP and VARA) (45)
// Add ARDOP UI Packets to MH (45)
// Add support for Qtsm Mgmt Interface (45)
// NodeAPI improvements (46)
// Add MQTT Interface (46)
// Fix buffer leak in ARDOP code(46)
// Fix possible crash if MQTT not in use (47)
// Add optional ATTACH time limit for VARA (48)
// API format fixes (48)
#define CKernel

View File

@ -20,7 +20,7 @@
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="d:\devprogs\bpq32"
OutputDirectory="C:\Dev\Msdev2005\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
IntermediateDirectory="C:\Dev\Msdev2005\Intermed\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="0"
@ -50,7 +50,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\CInclude;..\CommonSource;..\CKernel"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BPQ32_EXPORTS;MDIKERNEL;_USE_32BIT_TIME_T;BPQ32"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BPQ32_EXPORTS;MDIKERNEL;_USE_32BIT_TIME_T;BPQ32;NOMQTT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -159,7 +159,7 @@
Optimization="0"
WholeProgramOptimization="false"
AdditionalIncludeDirectories="..\CInclude;..\CommonSource;..\CKernel"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BPQ32_EXPORTS;MDIKERNEL;_USE_32BIT_TIME_T"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BPQ32_EXPORTS;MDIKERNEL;_USE_32BIT_TIME_T;NOMQTT"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
AssemblerOutput="2"
@ -438,6 +438,18 @@
RelativePath="..\CommonSource\Moncode.c"
>
</File>
<File
RelativePath=".\mqtt.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\CommonSource\MULTIPSK.c"
>

View File

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

View File

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

View File

@ -153,6 +153,7 @@ int APIENTRY Reboot();
int APIENTRY Reconfig();
Dll int APIENTRY SaveNodes ();
struct SEM;
void GetSemaphore(struct SEM * Semaphore, int ID);
@ -251,6 +252,7 @@ extern UCHAR MYCALLWITHALIAS[13];
extern APPLCALLS APPLCALLTABLE[NumberofAppls];
extern UCHAR MYNODECALL[]; // NODE CALLSIGN (ASCII)
extern char NODECALLLOPPED[]; // NODE CALLSIGN (ASCII). Null terminated
extern UCHAR MYNETROMCALL[]; // NETROM CALLSIGN (ASCII)
extern UCHAR NETROMCALL[]; // NETORM CALL (AX25)
@ -427,4 +429,19 @@ extern char Message[MaxBPQPortNo + 1][1000]; // Beacon Text
extern int MinCounter[MaxBPQPortNo + 1]; // Interval Countdown
extern BOOL SendFromFile[MaxBPQPortNo + 1];
extern BOOL MQTT;
extern char MQTT_HOST[80];
extern int MQTT_PORT;
extern char MQTT_USER[80];
extern char MQTT_PASS[80];
DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqStringMhz);
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK);
void hookL4SessionAttempt(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionAccepted(void * STREAM, char * remotecall, char * ourcall);
void hookL4SessionDeleted(struct TNCINFO * TNC, void * STREAM);

6
Cmd.c
View File

@ -2838,12 +2838,6 @@ noFlip3:
RESET2(LINK); // RESET ALL FLAGS
toCall[ConvFromAX25(LINK->LINKCALL, toCall)] = 0;
fromCall[ConvFromAX25(LINK->OURCALL, fromCall)] = 0;
hookL2SessionAttempt(CONNECTPORT, fromCall, toCall, LINK);
if (CMD->String[0] == 'N' && SUPPORT2point2)
LINK->L2STATE = 1; // New (2.2) send XID
else

View File

@ -28,6 +28,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "mqtt.h"
#pragma data_seg("_BPQDATA")
@ -735,22 +736,7 @@ VOID CheckForDetach(struct TNCINFO * TNC, int Stream, struct STREAMINFO * STREAM
// Create a traffic record
if (STREAM->Connected && STREAM->ConnectTime)
{
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1; // Or will get divide by zero error
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
STREAM->ConnectTime = 0;
}
hookL4SessionDeleted(TNC, STREAM);
if (STREAM->BPQtoPACTOR_Q) // Still data to send?
return; // Will close when all acked
@ -920,6 +906,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
int Totallen = 0;
UCHAR * ptr;
struct PORTCONTROL * PORT = (struct PORTCONTROL *)TNC->PortRecord;
struct STREAMINFO * STREAM = &TNC->Streams[Stream];
// Stop Scanner
@ -952,7 +939,11 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
memset(Session, 0, sizeof(TRANSPORTENTRY));
memcpy(TNC->Streams[Stream].RemoteCall, Call, 9); // Save Text Callsign
memcpy(STREAM->RemoteCall, Call, 9); // Save Text Callsign
// May be subsequently rejected but a good place to capture calls
hookL4SessionAccepted(STREAM, Call, TNC->TargetCall);
if (AllowTR)
ConvToAX25Ex(Call, Session->L4USER); // Allow -T and -R SSID's for MPS
@ -965,7 +956,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
if (NEXTID == 0) NEXTID++; // Keep non-zero
TNC->PortRecord->ATTACHEDSESSIONS[Stream] = Session;
TNC->Streams[Stream].Attached = TRUE;
STREAM->Attached = TRUE;
Session->L4TARGET.EXTPORT = TNC->PortRecord;
@ -976,7 +967,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
Session->SESSPACLEN = TNC->PortRecord->PORTCONTROL.PORTPACLEN;
Session->KAMSESSION = Stream;
TNC->Streams[Stream].Connected = TRUE; // Subsequent data to data channel
STREAM->Connected = TRUE; // Subsequent data to data channel
if (LogAllConnects)
{
@ -3716,6 +3707,11 @@ VOID OpenReportingSockets()
Chatreportdest.sin_port = htons(81);
_beginthread(ResolveUpdateThread, 0, NULL);
printf("MQTT Enabled %d\n", MQTT);
if (MQTT)
MQTTConnect(MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASS);
}
VOID WriteMiniDumpThread();

118
Events.c
View File

@ -23,6 +23,8 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "compatbits.h"
#include <string.h>
#include "asmstrucs.h"
#include "tncinfo.h"
VOID __cdecl Debugprintf(const char * format, ...);
@ -37,6 +39,11 @@ VOID __cdecl Debugprintf(const char * format, ...);
#endif
extern BOOL EventsEnabled;
void MQTTReportSession(char * Msg);
extern int MQTT;
extern char Modenames[19][10];
// Runs use specified routine on certain event
#ifndef WIN32
@ -110,13 +117,122 @@ DllExport void APIENTRY RunEventProgram(char * Program, char * Param)
void hookL2SessionAccepted(int Port, char * remotecall, char * ourcall, struct _LINKTABLE * LINK)
{
// Incoming SABM
LINK->ConnectTime = time(NULL);
LINK->bytesTXed = LINK->bytesRXed = 0;
strcpy(LINK->callingCall, remotecall);
strcpy(LINK->receivingCall, ourcall);
strcpy(LINK->Direction, "In");
}
void hookL2SessionDeleted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK)
void hookL2SessionDeleted(struct _LINKTABLE * LINK)
{
// calculate session time and av bytes/min in and out
if (LINK->ConnectTime)
{
if (LINK->bytesTXed == 0 && LINK->bytesRXed == 0)
{
// assume failed connect and ignore for now - maybe log later
}
else
{
char Msg[256];
char timestamp[16];
time_t sessionTime = time(NULL) - LINK->ConnectTime;
double avBytesSent = LINK->bytesTXed / (sessionTime / 60.0);
double avBytesRXed = LINK->bytesRXed / (sessionTime / 60.0);
time_t Now = time(NULL);
struct tm * TM = localtime(&Now);
sprintf(timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
if (sessionTime == 0)
sessionTime = 1; // Or will get divide by zero error
Debugprintf("KISS Session Stats Port %d %s %s %d secs Bytes Sent %d BPM %4.2f Bytes Received %d %4.2f BPM ",
LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, sessionTime, LINK->bytesTXed, avBytesSent, LINK->bytesRXed, avBytesRXed, timestamp);
sprintf(Msg, "{\"mode\": \"%s\", \"direction\": \"%s\", \"port\": %d, \"callfrom\": \"%s\", \"callto\": \"%s\", \"time\": %d, \"bytesSent\": %d,"
"\"BPMSent\": %4.2f, \"BytesReceived\": %d, \"BPMReceived\": %4.2f, \"timestamp\": \"%s\"}",
"KISS", LINK->Direction, LINK->LINKPORT->PORTNUMBER, LINK->callingCall, LINK->receivingCall, sessionTime,
LINK->bytesTXed, avBytesSent, LINK->bytesRXed, avBytesRXed, timestamp);
if (MQTT)
MQTTReportSession(Msg);
}
LINK->ConnectTime = 0;
}
}
void hookL2SessionAttempt(int Port, char * ourcall, char * remotecall, struct _LINKTABLE * LINK)
{
LINK->ConnectTime = time(NULL);
LINK->bytesTXed = LINK->bytesRXed = 0;
strcpy(LINK->callingCall, ourcall);
strcpy(LINK->receivingCall, remotecall);
strcpy(LINK->Direction, "Out");
}
void hookL4SessionAttempt(struct STREAMINFO * STREAM, char * remotecall, char * ourcall)
{
// Outgoing Connect
STREAM->ConnectTime = time(NULL);
STREAM->bytesTXed = STREAM->bytesRXed = 0;
strcpy(STREAM->callingCall, ourcall);
strcpy(STREAM->receivingCall, remotecall);
strcpy(STREAM->Direction, "Out");
}
void hookL4SessionAccepted(struct STREAMINFO * STREAM, char * remotecall, char * ourcall)
{
// Incoming Connect
STREAM->ConnectTime = time(NULL);
STREAM->bytesTXed = STREAM->bytesRXed = 0;
strcpy(STREAM->callingCall, remotecall);
strcpy(STREAM->receivingCall, ourcall);
strcpy(STREAM->Direction, "In");
}
void hookL4SessionDeleted(struct TNCINFO * TNC, struct STREAMINFO * STREAM)
{
char Msg[256];
char timestamp[16];
if (STREAM->ConnectTime)
{
time_t sessionTime = time(NULL) - STREAM->ConnectTime;
double avBytesRXed = STREAM->bytesRXed / (sessionTime / 60.0);
double avBytesSent = STREAM->bytesTXed / (sessionTime / 60.0);
time_t Now = time(NULL);
struct tm * TM = localtime(&Now);
sprintf(timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
if (sessionTime == 0)
sessionTime = 1; // Or will get divide by zero error
sprintf(Msg, "{\"mode\": \"%s\", \"direction\": \"%s\", \"port\": %d, \"callfrom\": \"%s\", \"callto\": \"%s\", \"time\": %d, \"bytesSent\": %d,"
"\"BPMSent\": %4.2f, \"BytesReceived\": %d, \"BPMReceived\": %4.2f, \"timestamp\": \"%s\"}",
Modenames[TNC->Hardware - 1], STREAM->Direction, TNC->Port, STREAM->callingCall, STREAM->receivingCall, sessionTime,
STREAM->bytesTXed, avBytesSent, STREAM->bytesRXed, avBytesRXed, timestamp);
if (MQTT)
MQTTReportSession(Msg);
STREAM->ConnectTime = 0;
}
}

View File

@ -1637,7 +1637,7 @@ static VOID ConnecttoFLDigiThread(void * portptr)
VOID UpdateStatsLine(struct TNCINFO * TNC, struct STREAMINFO * STREAM)
{
sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %d Resent %d Queued %d",
STREAM->BytesRXed, STREAM->BytesTXed, STREAM->BytesAcked, STREAM->BytesResent, STREAM->BytesOutstanding);
STREAM->bytesRXed, STREAM->bytesTXed, STREAM->BytesAcked, STREAM->BytesResent, STREAM->BytesOutstanding);
SetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
}
@ -2531,7 +2531,7 @@ VOID ProcessFLDigiData(struct TNCINFO * TNC, UCHAR * Input, int Len, char Channe
strcpy(STREAM->MyCall, call2);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
if (TNC->RIG && TNC->RIG != &TNC->DummyRig && strcmp(TNC->RIG->RigName, "PTT"))
{
@ -2690,7 +2690,7 @@ AckConnectRequest:
goto SendKReply; // Repeated ACK
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
STREAM->Connected = TRUE;
ARQ->ARQTimerState = 0;
@ -2951,22 +2951,7 @@ SendKReply:
if (STREAM->Connected)
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1;
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
hookL4SessionDeleted(TNC, STREAM);
}
STREAM->Connecting = FALSE;
@ -3029,7 +3014,7 @@ SendKReply:
buffptr->Len = Len;
memcpy(buffptr->Data, &Input[1], Len);
STREAM->BytesRXed += Len;
STREAM->bytesRXed += Len;
UpdateStatsLine(TNC, STREAM);
@ -3146,7 +3131,7 @@ VOID SendARQData(struct TNCINFO * TNC, PMSGWITHLEN Buffer)
ARQ->TXHOLDQ[ARQ->TXSeq] = Buffer;
STREAM->BytesTXed += Origlen;
STREAM->bytesTXed += Origlen;
UpdateStatsLine(TNC, STREAM);

View File

@ -971,7 +971,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
memset(STREAM->RemoteCall, 0, 10);
strcpy(STREAM->RemoteCall, &buff->L2DATA[2]);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->PacketsSent = 0;
sprintf(TNC->WEB_TNCSTATE, "%s Connecting to %s", STREAM->MyCall, STREAM->RemoteCall);
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
@ -1950,7 +1950,7 @@ VOID FreeDataProcessTNCMessage(struct TNCINFO * TNC, char * Call, unsigned char
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->PacketsSent = 0;
STREAM->Connected = TRUE;
// Send Connect ACK
@ -2019,20 +2019,7 @@ VOID FreeDataProcessTNCMessage(struct TNCINFO * TNC, char * Call, unsigned char
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1;
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
hookL4SessionDeleted(TNC, STREAM);
}
STREAM->Connected = FALSE; // Back to Command Mode
@ -2062,7 +2049,7 @@ VOID FreeDataProcessTNCMessage(struct TNCINFO * TNC, char * Call, unsigned char
WritetoTrace(TNC, Msg, 256);
Len -= 256;
Msg += 256;
STREAM->BytesRXed += 256;
STREAM->bytesRXed += 256;
}
@ -2071,9 +2058,9 @@ VOID FreeDataProcessTNCMessage(struct TNCINFO * TNC, char * Call, unsigned char
memcpy(buffptr->Data, Msg, Len);
C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr);
WritetoTrace(TNC, Msg, Len);
STREAM->BytesRXed += Len;
STREAM->bytesRXed += Len;
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->BytesRXed, TNC->FreeDataInfo->toSendCount);
STREAM->bytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->bytesRXed, TNC->FreeDataInfo->toSendCount);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
return;
@ -2326,7 +2313,7 @@ VOID FreeDataProcessNewConnect(struct TNCINFO * TNC, char * fromCall, char * toC
MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->PacketsSent = 0;
STREAM->Connected = TRUE;
return;
@ -2426,7 +2413,7 @@ void FlushData(struct TNCINFO * TNC)
Info->toSendTimeout = 0;
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->BytesRXed, TNC->FreeDataInfo->toSendCount);
STREAM->bytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->bytesRXed, TNC->FreeDataInfo->toSendCount);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
}
@ -2449,10 +2436,10 @@ static int SendAsFile(struct TNCINFO * TNC, char * Call, char * Msg, int Len)
Info->toSendCount += Len;
Info->toSendTimeout = 10; // About a second
STREAM->BytesTXed += Len;
STREAM->bytesTXed += Len;
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->BytesRXed, TNC->FreeDataInfo->toSendCount);
STREAM->bytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->bytesRXed, TNC->FreeDataInfo->toSendCount);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
return Len;
@ -2719,7 +2706,7 @@ void ProcessMessageObject(struct TNCINFO * TNC, char * This)
WritetoTrace(TNC, Line, 256);
Len -= 256;
Line += 256;
STREAM->BytesRXed += 256;
STREAM->bytesRXed += 256;
}
buffptr = GetBuff();
@ -2727,12 +2714,12 @@ void ProcessMessageObject(struct TNCINFO * TNC, char * This)
memcpy(buffptr->Data, Line, Len);
C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr);
WritetoTrace(TNC, Line, Len);
STREAM->BytesRXed += Len;
STREAM->bytesRXed += Len;
}
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->BytesRXed, TNC->FreeDataInfo->toSendCount);
STREAM->bytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->bytesRXed, TNC->FreeDataInfo->toSendCount);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
}
return;
@ -2811,7 +2798,7 @@ void ProcessMessageObject(struct TNCINFO * TNC, char * This)
WritetoTrace(TNC, Line, 256);
Len -= 256;
TEXT += 256;
STREAM->BytesRXed += 256;
STREAM->bytesRXed += 256;
}
buffptr = GetBuff();
@ -2819,14 +2806,14 @@ void ProcessMessageObject(struct TNCINFO * TNC, char * This)
memcpy(buffptr->Data, Line, Len);
C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr);
WritetoTrace(TNC, Line, Len);
STREAM->BytesRXed += Len;
STREAM->bytesRXed += Len;
TEXT = rest;
rest = strlop(TEXT, 10); // FreeData chat ues LF
}
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->BytesRXed, TNC->FreeDataInfo->toSendCount);
STREAM->bytesTXed - TNC->FreeDataInfo->toSendCount, STREAM->bytesRXed, TNC->FreeDataInfo->toSendCount);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
}
}
@ -3158,22 +3145,8 @@ void ProcessTNCJSON(struct TNCINFO * TNC, char * Msg, int Len)
if (STREAM->Connected)
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1;
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
hookL4SessionDeleted(TNC, STREAM);
STREAM->Connected = FALSE; // Back to Command Mode
STREAM->ReportDISC = TRUE; // Tell Node
@ -3351,20 +3324,7 @@ void ProcessTNCJSON(struct TNCINFO * TNC, char * Msg, int Len)
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1;
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
hookL4SessionDeleted(TNC, STREAM);
STREAM->Connected = FALSE; // Back to Command Mode
STREAM->ReportDISC = TRUE; // Tell Node

View File

@ -749,7 +749,7 @@ VOID HALPoll(int Port)
STREAM->Attached = TRUE;
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->BytesAcked = 0;
calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4USER, STREAM->MyCall);
STREAM->MyCall[calllen] = 0;
@ -829,7 +829,7 @@ VOID HALPoll(int Port)
//for (Stream = 0; Stream <= MaxStreams; Stream++)
{
if (TNC->TNCOK && STREAM->BPQtoPACTOR_Q && (STREAM->BytesTXed - STREAM->BytesAcked < 600))
if (TNC->TNCOK && STREAM->BPQtoPACTOR_Q && (STREAM->bytesTXed - STREAM->BytesAcked < 600))
{
int datalen;
PMSGWITHLEN buffptr;
@ -872,7 +872,7 @@ VOID HALPoll(int Port)
ReleaseBuffer(buffptr);
WriteLogLine(2, MsgPtr, datalen);
STREAM->BytesTXed += datalen;
STREAM->bytesTXed += datalen;
STREAM->FramesQueued--;
ShowTraffic(TNC);
@ -1090,10 +1090,10 @@ VOID ProcessHALData(struct TNCINFO * TNC)
STREAM->BytesAcked += Len;
// Debugprintf("Acked %d", Len);
if (STREAM->BytesAcked > STREAM->BytesTXed)
if (STREAM->BytesAcked > STREAM->bytesTXed)
Debugprintf("Too Much Acked");
if ((STREAM->BPQtoPACTOR_Q == 0) && STREAM->BytesAcked >= STREAM->BytesTXed)
if ((STREAM->BPQtoPACTOR_Q == 0) && STREAM->BytesAcked >= STREAM->bytesTXed)
{
// All sent
@ -1121,7 +1121,7 @@ VOID ProcessHALData(struct TNCINFO * TNC)
WriteLogLine(1, TNC->DataBuffer, Len);
STREAM->BytesRXed += Len;
STREAM->bytesRXed += Len;
memcpy(buffptr->Data, TNC->DataBuffer, Len);
@ -1756,7 +1756,7 @@ BOOL HALConnected(struct TNCINFO * TNC, char * Call)
strcpy(CallCopy, Call);
strcat(CallCopy, " "); // Some routines expect 10 char calls
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->BytesAcked = 0;
STREAM->ConnectTime = time(NULL);
// Stop Scanner
@ -1804,7 +1804,7 @@ BOOL HALConnected(struct TNCINFO * TNC, char * Call)
EncodeAndSend(TNC, CTEXTMSG, CTEXTLEN);
WriteLogLine(2, CTEXTMSG, CTEXTLEN);
STREAM->BytesTXed += CTEXTLEN;
STREAM->bytesTXed += CTEXTLEN;
}
return TRUE;
}

View File

@ -1602,7 +1602,7 @@ VOID ShowTraffic(struct TNCINFO * TNC)
char Status[80];
sprintf(Status, "RX %d TX %d ACKED %d ",
TNC->Streams[0].BytesRXed, TNC->Streams[0].BytesTXed, TNC->Streams[0].BytesAcked);
TNC->Streams[0].bytesRXed, TNC->Streams[0].bytesTXed, TNC->Streams[0].BytesAcked);
#ifndef LINBPQ
SetDlgItemText(TNC->hDlg, IDC_TRAFFIC, Status);
#endif

View File

@ -589,7 +589,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
UCHAR * data = &buffptr->Data[0];
STREAM->FramesQueued--;
txlen = (int)buffptr->Len;
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
bytes=HSMODEMSendData(TNC, data, txlen);
WritetoTrace(TNC, data, txlen);
@ -668,7 +668,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
bytes=HSMODEMSendData(TNC, TXMsg, txlen);
TNC->Streams[Stream].BytesOutstanding += bytes; // So flow control works - will be updated by BUFFER response
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
// WritetoTrace(TNC, &buff->L2DATA[0], txlen);
return 1;

View File

@ -106,12 +106,13 @@ char * strlop(char * buf, char delim);
VOID sendandcheck(SOCKET sock, const char * Buffer, int Len);
int CompareNode(const void *a, const void *b);
int CompareAlias(const void *a, const void *b);
void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen);
void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen, char * Token);
void ProcessChatHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen);
struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
int SetupNodeMenu(char * Buff, int SYSOP);
int StatusProc(char * Buff);
int ProcessMailSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL);
int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL);
int ProcessChatSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, int LOCAL);
VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE);
@ -1167,6 +1168,9 @@ int SendMessageFile(SOCKET sock, char * FN, BOOL OnlyifExists, int allowDeflate)
if (_stricmp(ptr, "js") == 0)
strcpy(Type, "Content-Type: text/javascript\r\n");
if (_stricmp(ptr, "css") == 0)
strcpy(Type, "Content-Type: text/css\r\n");
if (_stricmp(ptr, "pdf") == 0)
strcpy(Type, "Content-Type: application/pdf\r\n");
@ -1180,7 +1184,8 @@ int SendMessageFile(SOCKET sock, char * FN, BOOL OnlyifExists, int allowDeflate)
Compressed = MsgBytes;
}
if (_stricmp(ptr, "jpg") == 0 || _stricmp(ptr, "jpeg") == 0 || _stricmp(ptr, "png") == 0 || _stricmp(ptr, "gif") == 0 || _stricmp(ptr, "ico") == 0)
if (_stricmp(ptr, "jpg") == 0 || _stricmp(ptr, "jpeg") == 0 || _stricmp(ptr, "png") == 0 ||
_stricmp(ptr, "gif") == 0 || _stricmp(ptr, "bmp") == 0 || _stricmp(ptr, "ico") == 0)
strcpy(Type, "Content-Type: image\r\n");
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n"
@ -1793,38 +1798,61 @@ int InnerProcessHTTPMessage(struct ConnectionInfo * conn)
if (_memicmp(Context, "/api/", 5) == 0 || _stricmp(Context, "/api") == 0)
{
char * Compressed;
ReplyLen = APIProcessHTTPMessage(_REPLYBUFFER, Method, Context, MsgPtr, LOCAL, COOKIE);
if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0)
// if for mail api process signon here and rearrange url from
// api/v1/mail to mail/api/v1 so it goes to mail handler later
if (_memicmp(Context, "/api/v1/mail/", 13) == 0)
{
// Full Message - just send it
memcpy(MsgPtr, "GET /mail/api/v1/", 17);
sendandcheck(sock, _REPLYBUFFER, ReplyLen);
if (memcmp(&Context[13], "login", 5) == 0)
{
ReplyLen = ProcessMailAPISignon(TCP, MsgPtr, "M", Reply, &Session, FALSE, LOCAL);
memcpy(MsgPtr, "GET /mail/api/v1/", 17);
if (ReplyLen) // Error message
goto Returnit;
}
memcpy(Context, "/mail/api/v1/", 13);
goto doHeader;
}
else
{
ReplyLen = APIProcessHTTPMessage(_REPLYBUFFER, Method, Context, MsgPtr, LOCAL, COOKIE);
if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0)
{
// Full Message - just send it
sendandcheck(sock, _REPLYBUFFER, ReplyLen);
return 0;
}
if (allowDeflate)
Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen);
else
Compressed = _REPLYBUFFER;
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\n"
"Content-Length: %d\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"Access-Control-Allow-Origin: *\r\n"
"%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, Compressed, ReplyLen);
if (allowDeflate)
free (Compressed);
return 0;
}
if (allowDeflate)
Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen);
else
Compressed = _REPLYBUFFER;
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\n"
"Content-Length: %d\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, Compressed, ReplyLen);
if (allowDeflate)
free (Compressed);
return 0;
}
// APRS process internally
if (_memicmp(Context, "/APRS/", 6) == 0 || _stricmp(Context, "/APRS") == 0)
@ -2095,11 +2123,7 @@ Returnit:
Compressed = Reply;
if (NodeURL && _memicmp(NodeURL, "/mail/api/", 10) == 0)
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\n"
"Content-Length: %d\r\n"
"Content-Type: application/json\r\n"
"Connection: close\r\n"
"%s\r\n", ReplyLen, Encoding);
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json\r\nConnection: close\r\n%s\r\n", ReplyLen, Encoding);
else
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n%s\r\n", ReplyLen, Encoding);
@ -2122,15 +2146,82 @@ doHeader:
char _REPLYBUFFER[250000];
struct HTTPConnectionInfo Dummy = {0};
int Sent, Loops = 0;
char token[16] = "";
// look for auth header
const char * auth_header = "Authorization: Bearer ";
char * token_begin = strstr(MsgPtr, auth_header);
int Flags = 0, n;
char * Tok;
char * param;
if (token_begin)
{
// Using Auth Header
// Extract the token from the request (assuming it's present in the request headers)
token_begin += strlen(auth_header); // Move to the beginning of the token
strncpy(token, token_begin, 13);
token[13] = '\0'; // Null-terminate the token
}
ReplyLen = 0;
if (Session == 0)
Session = &Dummy;
Session->TNC = (void *)LOCAL; // TNC only used for Web Terminal Sessions
if (LOCAL)
Session->TNC = (void *)1; // TNC only used for Web Terminal Sessions
else
Session->TNC = (void *)0;
ProcessMailHTTPMessage(Session, Method, Context, MsgPtr, _REPLYBUFFER, &ReplyLen, MsgLen);
ProcessMailHTTPMessage(Session, Method, Context, MsgPtr, _REPLYBUFFER, &ReplyLen, MsgLen, token);
if (Context && _memicmp(Context, "/mail/api/", 10) == 0)
{
if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0)
{
// Full Header provided by appl - just send it
// Send may block
Sent = send(sock, _REPLYBUFFER, ReplyLen, 0);
while (Sent != ReplyLen && Loops++ < 3000) // 100 secs max
{
// Debugprintf("%d out of %d sent %d Loops", Sent, InputLen, Loops);
if (Sent > 0) // something sent
{
InputLen -= Sent;
memmove(_REPLYBUFFER, &_REPLYBUFFER[Sent], ReplyLen);
}
Sleep(30);
Sent = send(sock, _REPLYBUFFER, ReplyLen, 0);
}
return 0;
}
// compress if allowed
if (allowDeflate)
Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen);
else
Compressed = _REPLYBUFFER;
HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json\r\nConnection: close\r\n%s\r\n", ReplyLen, Encoding);
sendandcheck(sock, Header, HeaderLen);
sendandcheck(sock, Compressed, ReplyLen);
if (allowDeflate)
free (Compressed);
return 0;
}
if (memcmp(_REPLYBUFFER, "HTTP", 4) == 0)
{
@ -2156,11 +2247,16 @@ doHeader:
return 0;
}
if (Context && _memicmp(Context, "/mail/api/", 10) != 0)
{
// Add tail
strcpy(&_REPLYBUFFER[ReplyLen], Tail);
ReplyLen += strlen(Tail);
}
// compress if allowed
if (allowDeflate)
@ -2250,6 +2346,8 @@ doHeader:
// Pass to MailChat if active
NodeURL = Context;
if ((_memicmp(Context, "/MAIL/", 6) == 0) || (_memicmp(Context, "/WebMail", 8) == 0))
{
// If for Mail, Pass to Mail Server via Named Pipe
@ -4183,6 +4281,78 @@ int ProcessNodeSignon(SOCKET sock, struct TCPINFO * TCP, char * MsgPtr, char * A
return ReplyLen;
}
int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL)
{
int ReplyLen = 0;
char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers
char * user, * password, * Key;
struct HTTPConnectionInfo * NewSession;
int i;
struct UserRec * USER;
if (strchr(MsgPtr, '?'))
{
// Check Password
user = strlop(MsgPtr, '?');
password = strlop(user, '&');
strlop(password, ' ');
for (i = 0; i < TCP->NumberofUsers; i++)
{
USER = TCP->UserRecPtr[i];
if (user && _stricmp(user, USER->UserName) == 0)
{
if ((strcmp(password, USER->Password) == 0) && (USER->Secure || WebMail))
{
// ok
NewSession = AllocateSession(Appl[0], 'M');
*Session = NewSession;
if (NewSession)
{
ReplyLen = 0;
strcpy(NewSession->Callsign, USER->Callsign);
}
else
{
ReplyLen = SetupNodeMenu(Reply, LOCAL);
ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError);
}
return ReplyLen;
}
}
}
// Pass failed attempt to BBS code so it can try a bbs user login
// Need to put url back together
if (user && user[0] && password && password[0])
{
sprintf(MsgPtr, "%s?%s&%s", MsgPtr, user, password);
}
}
NewSession = AllocateSession(Appl[0], 'M');
*Session = NewSession;
if (NewSession)
ReplyLen = 0;
else
{
ReplyLen = SetupNodeMenu(Reply, LOCAL);
ReplyLen += sprintf(&Reply[ReplyLen], "%s", BusyError);
}
return ReplyLen;
}

View File

@ -1099,7 +1099,7 @@ VOID KAMPoll(int Port)
// Limit amount in TX, so we keep some on the TX Q and don't send turnround too early
if (TNC->Streams[0].BytesTXed - TNC->Streams[0].BytesAcked > 200)
if (TNC->Streams[0].bytesTXed - TNC->Streams[0].BytesAcked > 200)
continue;
// Dont send if IRS State
@ -1132,7 +1132,7 @@ VOID KAMPoll(int Port)
}
Next = 0;
STREAM->BytesTXed += datalen;
STREAM->bytesTXed += datalen;
if (Stream == 0)
{
@ -1157,7 +1157,7 @@ VOID KAMPoll(int Port)
if (Stream == 0)
{
sprintf(Status, "RX %d TX %d ACKED %d ",
TNC->Streams[0].BytesRXed, TNC->Streams[0].BytesTXed, TNC->Streams[0].BytesAcked);
TNC->Streams[0].bytesRXed, TNC->Streams[0].bytesTXed, TNC->Streams[0].BytesAcked);
SetWindowText(TNC->xIDC_TRAFFIC, Status);
if ((TNC->HFPacket == 0) && (TNC->Streams[0].BPQtoPACTOR_Q == 0)) // Nothing following
@ -1532,14 +1532,14 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len)
{
if (Msg[1] == '2') // HF Port
{
if (TNC->Streams[0].BytesTXed)
if (TNC->Streams[0].bytesTXed)
TNC->Streams[0].BytesAcked += Len - 3; // We get an ack before the first send
sprintf(Status, "RX %d TX %d ACKED %d ",
TNC->Streams[0].BytesRXed, TNC->Streams[0].BytesTXed, TNC->Streams[0].BytesAcked);
TNC->Streams[0].bytesRXed, TNC->Streams[0].bytesTXed, TNC->Streams[0].BytesAcked);
SetWindowText(TNC->xIDC_TRAFFIC, Status);
if (TNC->Streams[0].BytesTXed - TNC->Streams[0].BytesAcked < 500)
if (TNC->Streams[0].bytesTXed - TNC->Streams[0].BytesAcked < 500)
TNC->Streams[0].FramesOutstanding = 0;
}
return;
@ -1555,7 +1555,7 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len)
Len-=3; // Remove Header
buffptr->Len = Len; // Length
STREAM->BytesRXed += Len;
STREAM->bytesRXed += Len;
memcpy(buffptr->Data, Buffer, Len);
C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr);
@ -1563,7 +1563,7 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len)
if (Stream == 0)
{
sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %d ",
TNC->Streams[0].BytesRXed, TNC->Streams[0].BytesTXed, TNC->Streams[0].BytesAcked);
TNC->Streams[0].bytesRXed, TNC->Streams[0].bytesTXed, TNC->Streams[0].BytesAcked);
SetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
}
@ -1762,7 +1762,7 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len)
Buffer[Len-4] = 0;
}
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->BytesAcked = 0;
STREAM->ConnectTime = time(NULL);
if (Stream == 0)
@ -1776,7 +1776,7 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len)
Rig_Command( (TRANSPORTENTRY *) -1, Msg);
sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %d ",
TNC->Streams[0].BytesRXed, TNC->Streams[0].BytesTXed, TNC->Streams[0].BytesAcked);
TNC->Streams[0].bytesRXed, TNC->Streams[0].bytesTXed, TNC->Streams[0].BytesAcked);
SetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
}
@ -1874,7 +1874,7 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len)
memcpy(&CTBuff[3], &CTEXTMSG[Next], Len);
EncodeAndSend(TNC, CTBuff, Len + 3);
EncodeAndSend(TNC, "E", 1); // Changeover when all sent
TNC->Streams[0].BytesTXed += CTEXTLEN;
TNC->Streams[0].bytesTXed += CTEXTLEN;
}
return;

View File

@ -358,7 +358,7 @@ ok:
UCHAR * data = &buffptr->Data[0];
STREAM->FramesQueued--;
txlen = (int)buffptr->Len;
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
bytes=SerialSendData(TNC, data, txlen);
WritetoTrace(TNC, data, txlen);

View File

@ -110,7 +110,7 @@ int seeifInterlockneeded(struct PORTCONTROL * PORT);
int seeifUnlockneeded(struct _LINKTABLE * LINK);
int CheckKissInterlock(struct PORTCONTROL * MYPORT, int Exclusive);
void hookL2SessionAccepted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
void hookL2SessionDeleted(struct _LINKTABLE * LINK);
void hookL2SessionAttempt(int Port, char * fromCall, char * toCall, struct _LINKTABLE * LINK);
@ -1131,6 +1131,9 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
return;
}
toCall[ConvFromAX25(ADJBUFFER->DEST, toCall)] = 0;
fromCall[ConvFromAX25(ADJBUFFER->ORIGIN, fromCall)] = 0;
SETUPNEWL2SESSION(LINK, PORT, Buffer, MSGFLAG);
if (LINK->L2STATE != 5) // Setup OK?
@ -1143,10 +1146,6 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
seeifInterlockneeded(PORT);
toCall[ConvFromAX25(ADJBUFFER->DEST, toCall)] = 0;
fromCall[ConvFromAX25(ADJBUFFER->ORIGIN, fromCall)] = 0;
// IF CONNECT TO APPL ADDRESS, SET UP APPL SESSION
if (APPLMASK == 0)
@ -1162,12 +1161,7 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
UCHAR * ptr;
if (LogAllConnects)
{
char toCall[12], fromCall[12];
toCall[ConvFromAX25(ADJBUFFER->DEST, toCall)] = 0;
fromCall[ConvFromAX25(ADJBUFFER->ORIGIN, fromCall)] = 0;
WriteConnectLog(fromCall, toCall, "AX.25");
}
hookL2SessionAccepted(PORT->PORTNUMBER, fromCall, toCall, LINK);
@ -1285,6 +1279,8 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
L2SENDUA(PORT, Buffer, ADJBUFFER);
hookL2SessionAccepted(PORT->PORTNUMBER, fromCall, toCall, LINK);
if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF)
{
struct DATAMESSAGE * Msg;
@ -1383,6 +1379,9 @@ VOID L2SABM(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE * Buffe
L2SENDUA(PORT, Buffer, ADJBUFFER);
hookL2SessionAccepted(PORT->PORTNUMBER, fromCall, toCall, LINK);
if (PORT->TNC && PORT->TNC->Hardware == H_KISSHF)
{
struct DATAMESSAGE * Msg;
@ -2442,6 +2441,8 @@ VOID PROC_I_FRAME(struct _LINKTABLE * LINK, struct PORTCONTROL * PORT, MESSAGE *
Length = Buffer->LENGTH - (MSGHDDRLEN + 15); // Buffer Header + addrs + CTL
Info = &Buffer->PID;
LINK->bytesRXed += Length;
// Adjust for DIGIS
EOA = &Buffer->ORIGIN[6]; // End of address Bit
@ -2647,6 +2648,13 @@ VOID RESET2(struct _LINKTABLE * LINK)
VOID SENDSABM(struct _LINKTABLE * LINK)
{
char toCall[10];
char fromCall[10];
toCall[ConvFromAX25(LINK->LINKCALL, toCall)] = 0;
fromCall[ConvFromAX25(LINK->OURCALL, fromCall)] = 0;
hookL2SessionAttempt(LINK->LINKPORT->PORTNUMBER, fromCall, toCall, LINK);
L2SENDCOMMAND(LINK, SABM | PFBIT);
}
@ -3260,12 +3268,7 @@ VOID SENDFRMR(struct _LINKTABLE * LINK)
VOID CLEAROUTLINK(struct _LINKTABLE * LINK)
{
char toCall[12], fromCall[12];
toCall[ConvFromAX25(LINK->LINKCALL, toCall)] = 0;
fromCall[ConvFromAX25(LINK->OURCALL, fromCall)] = 0;
hookL2SessionDeleted(LINK->LINKPORT->PORTNUMBER, fromCall, toCall, LINK);
hookL2SessionDeleted(LINK);
seeifUnlockneeded(LINK);

View File

@ -603,6 +603,9 @@ VOID L4BG()
// If we want to enforce PACLEN this may be a good place to do it
Msglen = Msg->LENGTH - (MSGHDDRLEN + 1); //Dont include PID
LINK->bytesTXed += Msglen;
Paclen = L4->SESSPACLEN;
if (Paclen == 0)

View File

@ -1269,6 +1269,7 @@ int main(int argc, char * argv[])
}
}
for (i = optind; i < argc; i++)
{
if (_stricmp(argv[i], "tidymail") == 0)
DeleteRedundantMessages();
@ -1288,6 +1289,10 @@ int main(int argc, char * argv[])
AGWActive = AGWAPIInit();
if (Redirected == 0)
ConTerm.BPQStream = FindFreeStream();
#ifndef WIN32
for (i = 1; i < argc; i++)

2383
MQTTAsync.h Normal file

File diff suppressed because it is too large Load Diff

1980
MQTTClient.h Normal file

File diff suppressed because it is too large Load Diff

277
MQTTClientPersistence.h Normal file
View File

@ -0,0 +1,277 @@
/*******************************************************************************
* Copyright (c) 2009, 2020 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
/**
* @file
* \brief This structure represents a persistent data store, used to store
* outbound and inbound messages, in order to achieve reliable messaging.
*
* The MQTT Client persists QoS1 and QoS2 messages in order to meet the
* assurances of delivery associated with these @ref qos levels. The messages
* are saved in persistent storage
* The type and context of the persistence implementation are specified when
* the MQTT client is created (see MQTTClient_create()). The default
* persistence type (::MQTTCLIENT_PERSISTENCE_DEFAULT) uses a file system-based
* persistence mechanism. The <i>persistence_context</i> argument passed to
* MQTTClient_create() when using the default peristence is a string
* representing the location of the persistence directory. If the context
* argument is NULL, the working directory will be used.
*
* To use memory-based persistence, an application passes
* ::MQTTCLIENT_PERSISTENCE_NONE as the <i>persistence_type</i> to
* MQTTClient_create(). This can lead to message loss in certain situations,
* but can be appropriate in some cases (see @ref qos).
*
* Client applications can provide their own persistence mechanism by passing
* ::MQTTCLIENT_PERSISTENCE_USER as the <i>persistence_type</i>. To implement a
* custom persistence mechanism, the application must pass an initialized
* ::MQTTClient_persistence structure as the <i>persistence_context</i>
* argument to MQTTClient_create().
*
* If the functions defined return an ::MQTTCLIENT_PERSISTENCE_ERROR then the
* state of the persisted data should remain as it was prior to the function
* being called. For example, if Persistence_put() returns
* ::MQTTCLIENT_PERSISTENCE_ERROR, then it is assumed tha tthe persistent store
* does not contain the data that was passed to the function. Similarly, if
* Persistence_remove() returns ::MQTTCLIENT_PERSISTENCE_ERROR then it is
* assumed that the data to be removed is still held in the persistent store.
*
* It is up to the persistence implementation to log any error information that
* may be required to diagnose a persistence mechanism failure.
*/
/*
/// @cond EXCLUDE
*/
#if !defined(MQTTCLIENTPERSISTENCE_H)
#define MQTTCLIENTPERSISTENCE_H
/*
/// @endcond
*/
/**
* This <i>persistence_type</i> value specifies the default file system-based
* persistence mechanism (see MQTTClient_create()).
*/
#define MQTTCLIENT_PERSISTENCE_DEFAULT 0
/**
* This <i>persistence_type</i> value specifies a memory-based
* persistence mechanism (see MQTTClient_create()).
*/
#define MQTTCLIENT_PERSISTENCE_NONE 1
/**
* This <i>persistence_type</i> value specifies an application-specific
* persistence mechanism (see MQTTClient_create()).
*/
#define MQTTCLIENT_PERSISTENCE_USER 2
/**
* Application-specific persistence functions must return this error code if
* there is a problem executing the function.
*/
#define MQTTCLIENT_PERSISTENCE_ERROR -2
/**
* @brief Initialize the persistent store.
*
* Either open the existing persistent store for this client ID or create a new
* one if one doesn't exist. If the persistent store is already open, return
* without taking any action.
*
* An application can use the same client identifier to connect to many
* different servers. The <i>clientid</i> in conjunction with the
* <i>serverURI</i> uniquely identifies the persistence store required.
*
* @param handle The address of a pointer to a handle for this persistence
* implementation. This function must set handle to a valid reference to the
* persistence following a successful return.
* The handle pointer is passed as an argument to all the other
* persistence functions. It may include the context parameter and/or any other
* data for use by the persistence functions.
* @param clientID The client identifier for which the persistent store should
* be opened.
* @param serverURI The connection string specified when the MQTT client was
* created (see MQTTClient_create()).
* @param context A pointer to any data required to initialize the persistent
* store (see ::MQTTClient_persistence).
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_open)(void** handle, const char* clientID, const char* serverURI, void* context);
/**
* @brief Close the persistent store referred to by the handle.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_close)(void* handle);
/**
* @brief Put the specified data into the persistent store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key A string used as the key for the data to be put in the store. The
* key is later used to retrieve data from the store with Persistence_get().
* @param bufcount The number of buffers to write to the persistence store.
* @param buffers An array of pointers to the data buffers associated with
* this <i>key</i>.
* @param buflens An array of lengths of the data buffers. <i>buflen[n]</i>
* gives the length of <i>buffer[n]</i>.
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_put)(void* handle, char* key, int bufcount, char* buffers[], int buflens[]);
/**
* @brief Retrieve the specified data from the persistent store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key A string that is the key for the data to be retrieved. This is
* the same key used to save the data to the store with Persistence_put().
* @param buffer The address of a pointer to a buffer. This function sets the
* pointer to point at the retrieved data, if successful.
* @param buflen The address of an int that is set to the length of
* <i>buffer</i> by this function if successful.
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_get)(void* handle, char* key, char** buffer, int* buflen);
/**
* @brief Remove the data for the specified key from the store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key A string that is the key for the data to be removed from the
* store. This is the same key used to save the data to the store with
* Persistence_put().
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_remove)(void* handle, char* key);
/**
* @brief Returns the keys in this persistent data store.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param keys The address of a pointer to pointers to strings. Assuming
* successful execution, this function allocates memory to hold the returned
* keys (strings used to store the data with Persistence_put()). It also
* allocates memory to hold an array of pointers to these strings. <i>keys</i>
* is set to point to the array of pointers to strings.
* @param nkeys A pointer to the number of keys in this persistent data store.
* This function sets the number of keys, if successful.
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_keys)(void* handle, char*** keys, int* nkeys);
/**
* @brief Clears the persistence store, so that it no longer contains any
* persisted data.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @return Return 0 if the function completes successfully, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_clear)(void* handle);
/**
* @brief Returns whether any data has been persisted using the specified key.
*
* @param handle The handle pointer from a successful call to
* Persistence_open().
* @param key The string to be tested for existence in the store.
* @return Return 0 if the key was found in the store, otherwise return
* ::MQTTCLIENT_PERSISTENCE_ERROR.
*/
typedef int (*Persistence_containskey)(void* handle, char* key);
/**
* @brief A structure containing the function pointers to a persistence
* implementation and the context or state that will be shared across all
* the persistence functions.
*/
typedef struct {
/**
* A pointer to any data required to initialize the persistent store.
*/
void* context;
/**
* A function pointer to an implementation of Persistence_open().
*/
Persistence_open popen;
/**
* A function pointer to an implementation of Persistence_close().
*/
Persistence_close pclose;
/**
* A function pointer to an implementation of Persistence_put().
*/
Persistence_put pput;
/**
* A function pointer to an implementation of Persistence_get().
*/
Persistence_get pget;
/**
* A function pointer to an implementation of Persistence_remove().
*/
Persistence_remove premove;
/**
* A function pointer to an implementation of Persistence_keys().
*/
Persistence_keys pkeys;
/**
* A function pointer to an implementation of Persistence_clear().
*/
Persistence_clear pclear;
/**
* A function pointer to an implementation of Persistence_containskey().
*/
Persistence_containskey pcontainskey;
} MQTTClient_persistence;
/**
* A callback which is invoked just before a write to persistence. This can be
* used to transform the data, for instance to encrypt it.
* @param context The context as set in ::MQTTAsync_setBeforePersistenceWrite
* @param bufcount The number of buffers to write to the persistence store.
* @param buffers An array of pointers to the data buffers.
* @param buflens An array of lengths of the data buffers.
* @return Return 0 if the function completes successfully, otherwise non 0.
*/
typedef int MQTTPersistence_beforeWrite(void* context, int bufcount, char* buffers[], int buflens[]);
/**
* A callback which is invoked just after a read from persistence. This can be
* used to transform the data, for instance to decrypt it.
* @param context The context as set in ::MQTTAsync_setAfterPersistenceRead
* @param buffer The address of a pointer to a buffer.
* @param buflen The address of an int that is the length of the buffer.
* @return Return 0 if the function completes successfully, otherwise non 0.
*/
typedef int MQTTPersistence_afterRead(void* context, char** buffer, int* buflen);
#endif

36
MQTTExportDeclarations.h Normal file
View File

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2020, 2020 Andreas Walter
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Andreas Walter - initially moved export declarations into separate fle
*******************************************************************************/
#if !defined(EXPORTDECLARATIONS_H)
#define EXPORTDECLARATIONS_H
#if defined(_WIN32) || defined(_WIN64)
# if defined(PAHO_MQTT_EXPORTS)
# define LIBMQTT_API __declspec(dllexport)
# elif defined(PAHO_MQTT_IMPORTS)
# define LIBMQTT_API __declspec(dllimport)
# else
# define LIBMQTT_API
# endif
#else
# if defined(PAHO_MQTT_EXPORTS)
# define LIBMQTT_API __attribute__ ((visibility ("default")))
# else
# define LIBMQTT_API extern
# endif
#endif
#endif

222
MQTTProperties.h Normal file
View File

@ -0,0 +1,222 @@
/*******************************************************************************
* Copyright (c) 2017, 2023 IBM Corp. and others
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTPROPERTIES_H)
#define MQTTPROPERTIES_H
#include "MQTTExportDeclarations.h"
#define MQTT_INVALID_PROPERTY_ID -2
/** The one byte MQTT V5 property indicator */
enum MQTTPropertyCodes {
MQTTPROPERTY_CODE_PAYLOAD_FORMAT_INDICATOR = 1, /**< The value is 1 */
MQTTPROPERTY_CODE_MESSAGE_EXPIRY_INTERVAL = 2, /**< The value is 2 */
MQTTPROPERTY_CODE_CONTENT_TYPE = 3, /**< The value is 3 */
MQTTPROPERTY_CODE_RESPONSE_TOPIC = 8, /**< The value is 8 */
MQTTPROPERTY_CODE_CORRELATION_DATA = 9, /**< The value is 9 */
MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIER = 11, /**< The value is 11 */
MQTTPROPERTY_CODE_SESSION_EXPIRY_INTERVAL = 17, /**< The value is 17 */
MQTTPROPERTY_CODE_ASSIGNED_CLIENT_IDENTIFER = 18,/**< The value is 18 */
MQTTPROPERTY_CODE_SERVER_KEEP_ALIVE = 19, /**< The value is 19 */
MQTTPROPERTY_CODE_AUTHENTICATION_METHOD = 21, /**< The value is 21 */
MQTTPROPERTY_CODE_AUTHENTICATION_DATA = 22, /**< The value is 22 */
MQTTPROPERTY_CODE_REQUEST_PROBLEM_INFORMATION = 23,/**< The value is 23 */
MQTTPROPERTY_CODE_WILL_DELAY_INTERVAL = 24, /**< The value is 24 */
MQTTPROPERTY_CODE_REQUEST_RESPONSE_INFORMATION = 25,/**< The value is 25 */
MQTTPROPERTY_CODE_RESPONSE_INFORMATION = 26, /**< The value is 26 */
MQTTPROPERTY_CODE_SERVER_REFERENCE = 28, /**< The value is 28 */
MQTTPROPERTY_CODE_REASON_STRING = 31, /**< The value is 31 */
MQTTPROPERTY_CODE_RECEIVE_MAXIMUM = 33, /**< The value is 33*/
MQTTPROPERTY_CODE_TOPIC_ALIAS_MAXIMUM = 34, /**< The value is 34 */
MQTTPROPERTY_CODE_TOPIC_ALIAS = 35, /**< The value is 35 */
MQTTPROPERTY_CODE_MAXIMUM_QOS = 36, /**< The value is 36 */
MQTTPROPERTY_CODE_RETAIN_AVAILABLE = 37, /**< The value is 37 */
MQTTPROPERTY_CODE_USER_PROPERTY = 38, /**< The value is 38 */
MQTTPROPERTY_CODE_MAXIMUM_PACKET_SIZE = 39, /**< The value is 39 */
MQTTPROPERTY_CODE_WILDCARD_SUBSCRIPTION_AVAILABLE = 40,/**< The value is 40 */
MQTTPROPERTY_CODE_SUBSCRIPTION_IDENTIFIERS_AVAILABLE = 41,/**< The value is 41 */
MQTTPROPERTY_CODE_SHARED_SUBSCRIPTION_AVAILABLE = 42/**< The value is 241 */
};
/**
* Returns a printable string description of an MQTT V5 property code.
* @param value an MQTT V5 property code.
* @return the printable string description of the input property code.
* NULL if the code was not found.
*/
LIBMQTT_API const char* MQTTPropertyName(enum MQTTPropertyCodes value);
/** The one byte MQTT V5 property type */
enum MQTTPropertyTypes {
MQTTPROPERTY_TYPE_BYTE,
MQTTPROPERTY_TYPE_TWO_BYTE_INTEGER,
MQTTPROPERTY_TYPE_FOUR_BYTE_INTEGER,
MQTTPROPERTY_TYPE_VARIABLE_BYTE_INTEGER,
MQTTPROPERTY_TYPE_BINARY_DATA,
MQTTPROPERTY_TYPE_UTF_8_ENCODED_STRING,
MQTTPROPERTY_TYPE_UTF_8_STRING_PAIR
};
/**
* Returns the MQTT V5 type code of an MQTT V5 property.
* @param value an MQTT V5 property code.
* @return the MQTT V5 type code of the input property. -1 if the code was not found.
*/
LIBMQTT_API int MQTTProperty_getType(enum MQTTPropertyCodes value);
/**
* The data for a length delimited string
*/
typedef struct
{
int len; /**< the length of the string */
char* data; /**< pointer to the string data */
} MQTTLenString;
/**
* Structure to hold an MQTT version 5 property of any type
*/
typedef struct
{
enum MQTTPropertyCodes identifier; /**< The MQTT V5 property id. A multi-byte integer. */
/** The value of the property, as a union of the different possible types. */
union {
unsigned char byte; /**< holds the value of a byte property type */
unsigned short integer2; /**< holds the value of a 2 byte integer property type */
unsigned int integer4; /**< holds the value of a 4 byte integer property type */
struct {
MQTTLenString data; /**< The value of a string property, or the name of a user property. */
MQTTLenString value; /**< The value of a user property. */
};
} value;
} MQTTProperty;
/**
* MQTT version 5 property list
*/
typedef struct MQTTProperties
{
int count; /**< number of property entries in the array */
int max_count; /**< max number of properties that the currently allocated array can store */
int length; /**< mbi: byte length of all properties */
MQTTProperty *array; /**< array of properties */
} MQTTProperties;
#define MQTTProperties_initializer {0, 0, 0, NULL}
/**
* Returns the length of the properties structure when serialized ready for network transmission.
* @param props an MQTT V5 property structure.
* @return the length in bytes of the properties when serialized.
*/
int MQTTProperties_len(MQTTProperties* props);
/**
* Add a property pointer to the property array. Memory is allocated in this function,
* so MQTTClient_create or MQTTAsync_create must be called first to initialize the
* internal heap tracking. Alternatively MQTTAsync_global_init() can be called first
* or build with the HIGH_PERFORMANCE option which disables the heap tracking.
* @param props The property list to add the property to.
* @param prop The property to add to the list.
* @return 0 on success, -1 on failure.
*/
LIBMQTT_API int MQTTProperties_add(MQTTProperties* props, const MQTTProperty* prop);
/**
* Serialize the given property list to a character buffer, e.g. for writing to the network.
* @param pptr pointer to the buffer - move the pointer as we add data
* @param properties pointer to the property list, can be NULL
* @return whether the write succeeded or not: number of bytes written, or < 0 on failure.
*/
int MQTTProperties_write(char** pptr, const MQTTProperties* properties);
/**
* Reads a property list from a character buffer into an array.
* @param properties pointer to the property list to be filled. Should be initalized but empty.
* @param pptr pointer to the character buffer.
* @param enddata pointer to the end of the character buffer so we don't read beyond.
* @return 1 if the properties were read successfully.
*/
int MQTTProperties_read(MQTTProperties* properties, char** pptr, char* enddata);
/**
* Free all memory allocated to the property list, including any to individual properties.
* @param properties pointer to the property list.
*/
LIBMQTT_API void MQTTProperties_free(MQTTProperties* properties);
/**
* Copy the contents of a property list, allocating additional memory if needed.
* @param props pointer to the property list.
* @return the duplicated property list.
*/
LIBMQTT_API MQTTProperties MQTTProperties_copy(const MQTTProperties* props);
/**
* Checks if property list contains a specific property.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return 1 if found, 0 if not.
*/
LIBMQTT_API int MQTTProperties_hasProperty(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns the number of instances of a property id. Most properties can exist only once.
* User properties and subscription ids can exist more than once.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return the number of times found. Can be 0.
*/
LIBMQTT_API int MQTTProperties_propertyCount(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns the integer value of a specific property. The property given must be a numeric type.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return the integer value of the property. -9999999 on failure.
*/
LIBMQTT_API int MQTTProperties_getNumericValue(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns the integer value of a specific property when it's not the only instance.
* The property given must be a numeric type.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @param index the instance number, starting at 0.
* @return the integer value of the property. -9999999 on failure.
*/
LIBMQTT_API int MQTTProperties_getNumericValueAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index);
/**
* Returns a pointer to the property structure for a specific property.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @return the pointer to the property structure if found. NULL if not found.
*/
LIBMQTT_API MQTTProperty* MQTTProperties_getProperty(MQTTProperties *props, enum MQTTPropertyCodes propid);
/**
* Returns a pointer to the property structure for a specific property when it's not the only instance.
* @param props pointer to the property list.
* @param propid the property id to check for.
* @param index the instance number, starting at 0.
* @return the pointer to the property structure if found. NULL if not found.
*/
LIBMQTT_API MQTTProperty* MQTTProperties_getPropertyAt(MQTTProperties *props, enum MQTTPropertyCodes propid, int index);
#endif /* MQTTPROPERTIES_H */

79
MQTTReasonCodes.h Normal file
View File

@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2017, 2020 IBM Corp. and others
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTREASONCODES_H)
#define MQTTREASONCODES_H
#include "MQTTExportDeclarations.h"
/** The MQTT V5 one byte reason code */
enum MQTTReasonCodes {
MQTTREASONCODE_SUCCESS = 0,
MQTTREASONCODE_NORMAL_DISCONNECTION = 0,
MQTTREASONCODE_GRANTED_QOS_0 = 0,
MQTTREASONCODE_GRANTED_QOS_1 = 1,
MQTTREASONCODE_GRANTED_QOS_2 = 2,
MQTTREASONCODE_DISCONNECT_WITH_WILL_MESSAGE = 4,
MQTTREASONCODE_NO_MATCHING_SUBSCRIBERS = 16,
MQTTREASONCODE_NO_SUBSCRIPTION_FOUND = 17,
MQTTREASONCODE_CONTINUE_AUTHENTICATION = 24,
MQTTREASONCODE_RE_AUTHENTICATE = 25,
MQTTREASONCODE_UNSPECIFIED_ERROR = 128,
MQTTREASONCODE_MALFORMED_PACKET = 129,
MQTTREASONCODE_PROTOCOL_ERROR = 130,
MQTTREASONCODE_IMPLEMENTATION_SPECIFIC_ERROR = 131,
MQTTREASONCODE_UNSUPPORTED_PROTOCOL_VERSION = 132,
MQTTREASONCODE_CLIENT_IDENTIFIER_NOT_VALID = 133,
MQTTREASONCODE_BAD_USER_NAME_OR_PASSWORD = 134,
MQTTREASONCODE_NOT_AUTHORIZED = 135,
MQTTREASONCODE_SERVER_UNAVAILABLE = 136,
MQTTREASONCODE_SERVER_BUSY = 137,
MQTTREASONCODE_BANNED = 138,
MQTTREASONCODE_SERVER_SHUTTING_DOWN = 139,
MQTTREASONCODE_BAD_AUTHENTICATION_METHOD = 140,
MQTTREASONCODE_KEEP_ALIVE_TIMEOUT = 141,
MQTTREASONCODE_SESSION_TAKEN_OVER = 142,
MQTTREASONCODE_TOPIC_FILTER_INVALID = 143,
MQTTREASONCODE_TOPIC_NAME_INVALID = 144,
MQTTREASONCODE_PACKET_IDENTIFIER_IN_USE = 145,
MQTTREASONCODE_PACKET_IDENTIFIER_NOT_FOUND = 146,
MQTTREASONCODE_RECEIVE_MAXIMUM_EXCEEDED = 147,
MQTTREASONCODE_TOPIC_ALIAS_INVALID = 148,
MQTTREASONCODE_PACKET_TOO_LARGE = 149,
MQTTREASONCODE_MESSAGE_RATE_TOO_HIGH = 150,
MQTTREASONCODE_QUOTA_EXCEEDED = 151,
MQTTREASONCODE_ADMINISTRATIVE_ACTION = 152,
MQTTREASONCODE_PAYLOAD_FORMAT_INVALID = 153,
MQTTREASONCODE_RETAIN_NOT_SUPPORTED = 154,
MQTTREASONCODE_QOS_NOT_SUPPORTED = 155,
MQTTREASONCODE_USE_ANOTHER_SERVER = 156,
MQTTREASONCODE_SERVER_MOVED = 157,
MQTTREASONCODE_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED = 158,
MQTTREASONCODE_CONNECTION_RATE_EXCEEDED = 159,
MQTTREASONCODE_MAXIMUM_CONNECT_TIME = 160,
MQTTREASONCODE_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED = 161,
MQTTREASONCODE_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED = 162
};
/**
* Returns a printable string description of an MQTT V5 reason code.
* @param value an MQTT V5 reason code.
* @return the printable string description of the input reason code.
* NULL if the code was not found.
*/
LIBMQTT_API const char* MQTTReasonCode_toString(enum MQTTReasonCodes value);
#endif

46
MQTTSubscribeOpts.h Normal file
View File

@ -0,0 +1,46 @@
/*******************************************************************************
* Copyright (c) 2018 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* https://www.eclipse.org/legal/epl-2.0/
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(SUBOPTS_H)
#define SUBOPTS_H
/** The MQTT V5 subscribe options, apart from QoS which existed before V5. */
typedef struct MQTTSubscribe_options
{
/** The eyecatcher for this structure. Must be MQSO. */
char struct_id[4];
/** The version number of this structure. Must be 0.
*/
int struct_version;
/** To not receive our own publications, set to 1.
* 0 is the original MQTT behaviour - all messages matching the subscription are received.
*/
unsigned char noLocal;
/** To keep the retain flag as on the original publish message, set to 1.
* If 0, defaults to the original MQTT behaviour where the retain flag is only set on
* publications sent by a broker if in response to a subscribe request.
*/
unsigned char retainAsPublished;
/** 0 - send retained messages at the time of the subscribe (original MQTT behaviour)
* 1 - send retained messages on subscribe only if the subscription is new
* 2 - do not send retained messages at all
*/
unsigned char retainHandling;
} MQTTSubscribe_options;
#define MQTTSubscribe_options_initializer { {'M', 'Q', 'S', 'O'}, 0, 0, 0, 0 }
#endif

View File

@ -1317,7 +1317,7 @@ VOID ProcessMSPKData(struct TNCINFO * TNC)
C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr);
STREAM->BytesRXed += TNC->DataLen;
STREAM->bytesRXed += TNC->DataLen;
}
TNC->DataLen = 0;
@ -1387,7 +1387,7 @@ DataLoop:
STREAM->Connected = TRUE;
STREAM->Connecting = FALSE;
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = 0;
STREAM->bytesRXed = STREAM->bytesTXed = 0;
buffptr = GetBuff();
if (buffptr)
@ -1402,7 +1402,7 @@ DataLoop:
STREAM->Connected = TRUE;
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = 0;
STREAM->bytesRXed = STREAM->bytesTXed = 0;
UpdateMH(TNC, CallFrom, '+', 'I');
@ -1483,7 +1483,7 @@ VOID SendData(struct TNCINFO * TNC, char * Msg, int MsgLen)
char * inptr = Msg;
SOCKET sock = TNCInfo[MasterPort[TNC->Port]]->TCPSock;
TNC->Streams[0].BytesTXed += MsgLen;
TNC->Streams[0].bytesTXed += MsgLen;
for (n = 0; n < MsgLen; n++)
{

View File

@ -43,6 +43,7 @@ struct SEM AllocSemaphore = {0, 0};
struct SEM ConSemaphore = {0, 0};
struct SEM Semaphore = {0, 0};
struct SEM OutputSEM = {0, 0};
struct SEM ConfigSEM = {0, 0};
struct UserInfo ** UserRecPtr=NULL;
int NumberofUsers=0;

View File

@ -41,7 +41,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\CKernel;..\CommonSource;..\CInclude"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;LINBPQ;_USE_32BIT_TIME_T"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;LINBPQ;_USE_32BIT_TIME_T;NOMQTT"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -456,6 +456,10 @@
RelativePath="..\CommonSource\Moncode.c"
>
</File>
<File
RelativePath=".\mqtt.c"
>
</File>
<File
RelativePath="..\CommonSource\Multicast.c"
>

View File

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

View File

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

View File

@ -9422,7 +9422,7 @@ return TRUE;
#include <stdio.h>
#include <stdlib.h>
//#include <stdint.h>
//
//#include <windows.h>
#include <setupapi.h>
//#include <ddk/hidsdi.h>

View File

@ -1972,7 +1972,7 @@ VOID SCSPoll(int Port)
}
Poll[3] = 0; // Data?
TNC->Streams[Stream].BytesTXed += datalen;
TNC->Streams[Stream].bytesTXed += datalen;
Poll[4] = datalen - 1;
memcpy(&Poll[5], Buffer, datalen);
@ -2324,7 +2324,7 @@ void SCSTryToSendDATA(struct TNCINFO * TNC, int Stream)
}
Poll[3] = 0; // Data
STREAM->BytesTXed += datalen;
STREAM->bytesTXed += datalen;
Poll[4] = datalen - 1;
memcpy(&Poll[5], Buffer, datalen);
@ -3402,7 +3402,7 @@ VOID ProcessDEDFrame(struct TNCINFO * TNC, UCHAR * Msg, int framelen)
{
if (TNC->TXBuffer[6]== 'T') // TX count Status
{
sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %s", TNC->Streams[Stream].BytesRXed, TNC->Streams[Stream].BytesTXed, Buffer);
sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %s", TNC->Streams[Stream].bytesRXed, TNC->Streams[Stream].bytesTXed, Buffer);
SetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
return;
}
@ -3501,7 +3501,7 @@ VOID ProcessDEDFrame(struct TNCINFO * TNC, UCHAR * Msg, int framelen)
STREAM->Connected = TRUE; // Subsequent data to data channel
STREAM->Connecting = FALSE;
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = 0;
STREAM->bytesRXed = STREAM->bytesTXed = 0;
// Stop Scanner
@ -3897,7 +3897,7 @@ VOID ProcessDEDFrame(struct TNCINFO * TNC, UCHAR * Msg, int framelen)
if (buffptr == NULL) return; // No buffers, so ignore
buffptr->Len = Msg[4] + 1; // Length
TNC->Streams[Stream].BytesRXed += (int)buffptr->Len;
TNC->Streams[Stream].bytesRXed += (int)buffptr->Len;
memcpy(buffptr->Data, &Msg[5], buffptr->Len);
WritetoTrace(TNC, &Msg[5], (int)buffptr->Len);

View File

@ -825,7 +825,7 @@ static VOID DEDPoll(int Port)
}
Poll[1] = 0; // Data
TNC->Streams[Stream].BytesTXed += datalen;
TNC->Streams[Stream].bytesTXed += datalen;
Poll[2] = datalen - 1;
memcpy(&Poll[3], Buffer, datalen);
@ -1508,7 +1508,7 @@ static VOID ProcessDEDFrame(struct TNCINFO * TNC)
STREAM->Connected = TRUE; // Subsequent data to data channel
STREAM->Connecting = FALSE;
STREAM->BytesRXed = STREAM->BytesTXed = 0;
STREAM->bytesRXed = STREAM->bytesTXed = 0;
memcpy(MHCall, Call, 9);
MHCall[9] = 0;
@ -1677,7 +1677,7 @@ static VOID ProcessDEDFrame(struct TNCINFO * TNC)
if (buffptr == NULL) return; // No buffers, so ignore
buffptr->Len = framelen; // Length
TNC->Streams[Stream].BytesRXed += buffptr->Len;
TNC->Streams[Stream].bytesRXed += buffptr->Len;
memcpy(buffptr->Data, Msg, buffptr->Len);
C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr);

View File

@ -1267,7 +1267,7 @@ reinit:
}
Poll[1] = 0; // Data
TNC->Streams[Stream].BytesTXed += datalen;
TNC->Streams[Stream].bytesTXed += datalen;
Poll[2] = datalen - 1;
memcpy(&Poll[3], Buffer, datalen);
@ -1888,7 +1888,7 @@ VOID TrkProcessDEDFrame(struct TNCINFO * TNC)
{
if (TNC->TXBuffer[4]== 'T') // TX count Status
{
sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %s", TNC->Streams[Stream].BytesRXed, TNC->Streams[Stream].BytesTXed, Buffer);
sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %s", TNC->Streams[Stream].bytesRXed, TNC->Streams[Stream].bytesTXed, Buffer);
SetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
TNC->WEB_CHANGED = TRUE;
return;
@ -2027,7 +2027,7 @@ VOID TrkProcessDEDFrame(struct TNCINFO * TNC)
STREAM->Connected = TRUE; // Subsequent data to data channel
STREAM->Connecting = FALSE;
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = 0;
STREAM->bytesRXed = STREAM->bytesTXed = 0;
if (TNC->SlowTimer)
Debugprintf("RP Incoming call to APPLCALL completed");
@ -2385,7 +2385,7 @@ VOID TrkProcessDEDFrame(struct TNCINFO * TNC)
if (buffptr == NULL) return; // No buffers, so ignore
buffptr->Len = framelen; // Length
TNC->Streams[Stream].BytesRXed += (int)buffptr->Len;
TNC->Streams[Stream].bytesRXed += (int)buffptr->Len;
memcpy(buffptr->Data, Msg, buffptr->Len);
WritetoTrace(TNC, Msg, (int)buffptr->Len);

View File

@ -402,7 +402,7 @@ ok:
UCHAR * data = &buffptr->Data[0];
STREAM->FramesQueued--;
txlen = (int)buffptr->Len;
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
bytes=SerialSendData(TNC, data, txlen);
WritetoTrace(TNC, data, txlen);
@ -491,7 +491,7 @@ ok:
bytes=SerialSendData(TNC, TXMsg, txlen);
TNC->Streams[Stream].BytesOutstanding += bytes; // So flow control works - will be updated by BUFFER response
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
// WritetoTrace(TNC, &buff->L2DATA[0], txlen);
return 1;

View File

@ -2382,7 +2382,7 @@ nosocks:
{
char logmsg[120];
sprintf(logmsg,"%d Disconnected. Bytes Sent = %d Bytes Received %d\n",
sockptr->Number, STREAM->BytesTXed, STREAM->BytesRXed);
sockptr->Number, STREAM->bytesTXed, STREAM->bytesRXed);
WriteLog (logmsg);
}
@ -2407,7 +2407,7 @@ nosocks:
{
char logmsg[120];
sprintf(logmsg,"%d Disconnected. Bytes Sent = %d Bytes Received %d Time %d Seconds\r\n",
sockptr->Number, STREAM->BytesTXed, STREAM->BytesRXed, (int)(time(NULL) - sockptr->ConnectTime));
sockptr->Number, STREAM->bytesTXed, STREAM->bytesRXed, (int)(time(NULL) - sockptr->ConnectTime));
WriteCMSLog (logmsg);
}
@ -2415,7 +2415,7 @@ nosocks:
// Don't report if Internet down unless ReportRelayTraffic set)
if (sockptr->RelaySession == FALSE || TCP->ReportRelayTraffic)
SendWL2KSessionRecord(sockptr->ADIF, STREAM->BytesTXed, STREAM->BytesRXed);
SendWL2KSessionRecord(sockptr->ADIF, STREAM->bytesTXed, STREAM->bytesRXed);
WriteADIFRecord(sockptr->ADIF);
@ -3285,7 +3285,7 @@ int Socket_Accept(struct TNCINFO * TNC, SOCKET SocketId, int Port)
sockptr->Keepalive = FALSE;
sockptr->UTF8 = 0;
TNC->Streams[n].BytesRXed = TNC->Streams[n].BytesTXed = 0;
TNC->Streams[n].bytesRXed = TNC->Streams[n].bytesTXed = 0;
TNC->Streams[n].FramesQueued = 0;
sockptr->HTTPMode = FALSE;
@ -3834,7 +3834,7 @@ MsgLoop:
// Normal Data State
STREAM->BytesRXed += MsgLen;
STREAM->bytesRXed += MsgLen;
SendIndex = 0;
// Line could be up to 500 chars if coming from a program rather than an interative user
@ -3986,7 +3986,7 @@ MsgLoop:
if (ctlen > 0) send(sock, ct, ctlen, 0);
STREAM->BytesTXed = ctlen;
STREAM->bytesTXed = ctlen;
if (LogEnabled)
{
@ -4067,7 +4067,7 @@ int DataSocket_ReadRelay(struct TNCINFO * TNC, struct ConnectionInfo * sockptr,
MsgPtr = &sockptr->InputBuffer[0];
InputLen = sockptr->InputLen;
STREAM->BytesRXed += InputLen;
STREAM->bytesRXed += InputLen;
if (sockptr->LoginState == 2)
{
@ -4077,7 +4077,7 @@ int DataSocket_ReadRelay(struct TNCINFO * TNC, struct ConnectionInfo * sockptr,
// Queue to Node. Data may arrive it large quatities, possibly exceeding node buffer capacity
STREAM->BytesRXed += InputLen;
STREAM->bytesRXed += InputLen;
if (sockptr->FromHostBuffPutptr + InputLen > sockptr->FromHostBufferSize)
{
@ -4347,7 +4347,7 @@ int DataSocket_ReadSync(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S
InputLen = sockptr->InputLen;
MsgPtr[InputLen] = 0;
STREAM->BytesRXed += InputLen;
STREAM->bytesRXed += InputLen;
if (sockptr->LoginState == 0) // Initial connection
{
@ -4495,7 +4495,7 @@ MsgLoop:
// Queue to Node. Data may arrive it large quantities, possibly exceeding node buffer capacity
STREAM->BytesRXed += InputLen;
STREAM->bytesRXed += InputLen;
BuffertoNode(sockptr, MsgPtr, InputLen);
sockptr->InputLen = 0;
@ -4677,7 +4677,7 @@ MsgLoop:
if (strstr(MsgPtr, "Password :"))
{
// Send “CMSTelnet” + gateway callsign + frequency + emission type if info is available
// Send "CMSTelnet" + gateway callsign + frequency + emission type if info is available
TRANSPORTENTRY * Sess1 = TNC->PortRecord->ATTACHEDSESSIONS[Stream];
TRANSPORTENTRY * Sess2 = NULL;
@ -5650,7 +5650,7 @@ int Telnet_Connected(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, SOCK
sockptr->FromHostBuffPutptr = sockptr->FromHostBuffGetptr = 0;
TNC->Streams[Stream].BytesRXed = TNC->Streams[Stream].BytesTXed = 0;
TNC->Streams[Stream].bytesRXed = TNC->Streams[Stream].bytesTXed = 0;
return 0;
}
@ -6508,7 +6508,7 @@ BOOL TelSendPacket(int Stream, struct STREAMINFO * STREAM, PMSGWITHLEN buffptr,
datalen = (int)buffptr->Len;
MsgPtr = &buffptr->Data[0];
STREAM->BytesTXed += datalen;
STREAM->bytesTXed += datalen;
sock = sockptr->socket;

27
UIARQ.c
View File

@ -367,10 +367,10 @@ static VOID UpdateStatsLine(struct TNCINFO * TNC, struct STREAMINFO * STREAM)
{
char Count[16];
sprintf(Count, "%d", STREAM->BytesRXed);
sprintf(Count, "%d", STREAM->bytesRXed);
SetWindowText(STREAM->xIDC_RXED, Count);
sprintf(Count, "%d", STREAM->BytesTXed);
sprintf(Count, "%d", STREAM->bytesTXed);
SetWindowText(STREAM->xIDC_SEND, Count);
sprintf(Count, "%d", STREAM->BytesResent);
@ -849,7 +849,7 @@ static VOID ProcessFLDigiData(struct TNCINFO * TNC, UCHAR * Input, int Len, int
strcpy(STREAM->MyCall, call2);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
if (WL2K)
strcpy(SESS->RMSCall, WL2K->RMSCall);
@ -1001,7 +1001,7 @@ AckConnectRequest:
goto SendKReply; // Repeated ACK
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0;
STREAM->Connected = TRUE;
ARQ->ARQTimerState = 0;
@ -1240,20 +1240,7 @@ SendKReply:
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1;
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
hookL4SessionDeleted(TNC, STREAM);
}
STREAM->Connecting = FALSE;
@ -1313,7 +1300,7 @@ SendKReply:
buffptr->Len = Len;
memcpy(buffptr->Data, &Input[1], Len);
STREAM->BytesRXed += Len;
STREAM->bytesRXed += Len;
UpdateStatsLine(TNC, STREAM);
@ -1401,7 +1388,7 @@ static VOID SendARQData(struct TNCINFO * TNC, PMSGWITHLEN Buffer, int Stream)
ARQ->TXHOLDQ[ARQ->TXSeq] = Buffer;
STREAM->BytesTXed += Origlen;
STREAM->bytesTXed += Origlen;
UpdateStatsLine(TNC, STREAM);

View File

@ -884,6 +884,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
if (STREAM->ReportDISC)
{
hookL4SessionDeleted(TNC, STREAM);
STREAM->ReportDISC = FALSE;
buff->PORT = Stream;
@ -1229,6 +1230,9 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
ViaList[0] = Digis;
}
hookL4SessionAttempt(STREAM,&STREAM->AGWKey[1], &STREAM->AGWKey[11]);
sent = send(TNCInfo[MasterPort[port]]->TCPSock, (char *)&AGW->TXHeader, AGWHDDRLEN, 0);
if (Digis)
send(TNCInfo[MasterPort[port]]->TCPSock, ViaList, Digis * 10 + 1, 0);
@ -2230,6 +2234,8 @@ VOID ProcessAGWPacket(struct TNCINFO * TNC, UCHAR * Message)
buffptr->Len = RXHeader->DataLength;
memcpy(buffptr->Data, Message, RXHeader->DataLength);
STREAM->bytesRXed += RXHeader->DataLength;
C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr);
return;
}
@ -2370,7 +2376,7 @@ GotStream:
memcpy(STREAM->AGWKey, Key, 21);
STREAM->Connected = TRUE;
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = 0;
STREAM->bytesRXed = STREAM->bytesTXed = 0;
SuspendOtherPorts(TNC);
@ -2467,6 +2473,8 @@ GotStream:
}
strcpy(STREAM->MyCall, TNC->TargetCall);
if (App < 32)
{
char AppName[13];
@ -2503,6 +2511,9 @@ GotStream:
}
}
strcpy(STREAM->MyCall, TNC->TargetCall);
// Not to a known appl - drop through to Node
return;
@ -2526,7 +2537,7 @@ GotStream:
STREAM->Connected = TRUE;
STREAM->Connecting = FALSE;
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = 0;
STREAM->bytesRXed = STREAM->bytesTXed = 0;
buffptr = GetBuff();
if (buffptr == 0) return; // No buffers, so ignore
@ -2740,7 +2751,7 @@ GotStream:
// Capabilities - along with Version used to indicate QtSoundModem
// with ability to set and read Modem type and frequency/
if (Message[2] == 24 && Message[3] == 3 && Message[4] == 100)
if ((Message[2] == 24 && Message[3] == 3 && Message[4] == 100) || TNC->AGWInfo->isQTSM)
{
// Set flag on any other ports on same TNC (all ports with this as master port)
@ -2928,6 +2939,9 @@ VOID SendData(int Stream, struct TNCINFO * TNC, char * Key, char * Msg, int MsgL
memcpy(AGW->TXHeader.callfrom, &Key[11], 10);
memcpy(AGW->TXHeader.callto, &Key[1], 10);
TNC->Streams[Stream].bytesTXed += MsgLen;
// If Length is greater than Paclen we should fragment
if (TNC->PortRecord->ATTACHEDSESSIONS[Stream])

68
VARA.c
View File

@ -394,6 +394,18 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
}
}
// Check ATTACH time limit
if (STREAM->Attached)
{
if (STREAM->AttachTime && TNC->AttachTimeLimit && time(NULL) > (TNC->AttachTimeLimit + STREAM->AttachTime))
{
STREAM->ReportDISC = 1;
STREAM->AttachTime = 0;
}
}
while (TNC->PortRecord->UI_Q)
{
buffptr = Q_REM(&TNC->PortRecord->UI_Q);
@ -506,6 +518,8 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
int calllen;
char Msg[80];
memset(STREAM, 0, sizeof(struct STREAMINFO));
TNC->Streams[0].Attached = TRUE;
calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4USER, TNC->Streams[0].MyCall);
@ -516,6 +530,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
VARASendCommand(TNC, "LISTEN OFF\r", TRUE);
TNC->SessionTimeLimit = TNC->DefaultSessionTimeLimit; // Reset Limit
STREAM->AttachTime = time(NULL);
// Stop other ports in same group
@ -568,7 +583,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
buffptr->Data[txlen] = 0; // Null terminate
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
WritetoTrace(TNC, buffptr->Data, txlen);
// Always add to stored data and set timer. If it expires send message
@ -599,7 +614,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
memcpy(txbuff, buffptr->Data, txlen);
bytes = VARASendData(TNC, &txbuff[0], txlen);
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
ReleaseBuffer(buffptr);
}
@ -647,7 +662,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
txlen = (int)buffptr->Len;
memcpy(txbuff, buffptr->Data, txlen);
bytes=send(TNC->TCPDataSock, buff->L2DATA, txlen, 0);
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
WritetoTrace(TNC, txbuff, txlen);
ReleaseBuffer(buffptr);
}
@ -674,7 +689,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
memcpy(txbuff, buff->L2DATA, txlen);
bytes=send(TNC->TCPDataSock, txbuff, txlen, 0);
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
WritetoTrace(TNC, buff->L2DATA, txlen);
return 0;
}
@ -690,7 +705,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
buff->L2DATA[txlen] = 0; // Null terminate
STREAM->BytesTXed += txlen;
STREAM->bytesTXed += txlen;
WritetoTrace(TNC, buff->L2DATA, txlen);
// Always add to stored data and set timer. If it expires send message
@ -816,6 +831,8 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
TNC->Streams[0].Connecting = TRUE;
hookL4SessionAttempt(STREAM, &buff->L2DATA[2], TNC->Streams[0].MyCall);
// See if Busy
if (InterlockedCheckBusy(TNC))
@ -2000,7 +2017,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
}
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %s",
STREAM->BytesTXed, STREAM->BytesRXed, &Buffer[7]);
STREAM->bytesTXed, STREAM->bytesRXed, &Buffer[7]);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
return;
@ -2020,8 +2037,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
Debugprintf(Buffer);
WritetoTrace(TNC, Buffer, MsgLen - 1);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->PacketsSent = 0;
if (TNC->VARACMsg)
free(TNC->VARACMsg);
@ -2088,6 +2104,10 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
// Stop other ports in same group
memset(STREAM, 0, sizeof(struct STREAMINFO));
STREAM->ConnectTime = time(NULL);
SuspendOtherPorts(TNC);
TNC->SessionTimeLimit = TNC->DefaultSessionTimeLimit; // Reset Limit
@ -2183,7 +2203,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->PacketsSent++;
bytes = send(TNC->TCPDataSock, TNC->NetRomTxBuffer, TNC->NetRomTxLen, 0);
STREAM->BytesTXed += TNC->NetRomTxLen;
STREAM->bytesTXed += TNC->NetRomTxLen;
free(TNC->NetRomTxBuffer);
TNC->NetRomTxBuffer = NULL;
@ -2264,6 +2284,8 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->NeedDisc = 100; // 10 secs
}
}
strcpy(STREAM->MyCall, TNC->TargetCall);
return;
}
else
@ -2273,6 +2295,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
char Reply[80];
int ReplyLen;
STREAM->ConnectTime = time(NULL);
if (TNC->NetRomMode)
{
@ -2285,7 +2308,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
STREAM->PacketsSent++;
bytes = send(TNC->TCPDataSock, TNC->NetRomTxBuffer, TNC->NetRomTxLen, 0);
STREAM->BytesTXed += TNC->NetRomTxLen;
STREAM->bytesTXed += TNC->NetRomTxLen;
free(TNC->NetRomTxBuffer);
TNC->NetRomTxBuffer = NULL;
TNC->NetRomTxLen = 0;
@ -2374,22 +2397,7 @@ VOID VARAProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1;
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
STREAM->ConnectTime= 0; //Prevent retrigger
hookL4SessionDeleted(TNC, STREAM);
}
@ -2742,13 +2750,13 @@ VOID VARAProcessDataPacket(struct TNCINFO * TNC, UCHAR * Data, int Length)
TNC->TimeSinceLast = 0;
STREAM->BytesRXed += Length;
STREAM->bytesRXed += Length;
Data[Length] = 0;
// Debugprintf("VARA: RXD %d bytes", Length);
sprintf(TNC->WEB_TRAFFIC, "Sent %d RXed %d Queued %d",
STREAM->BytesTXed, STREAM->BytesRXed,STREAM->BytesOutstanding);
STREAM->bytesTXed, STREAM->bytesRXed,STREAM->BytesOutstanding);
MySetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC);
// if VARAAC Mode, remove byte count from front and add cr
@ -2891,7 +2899,7 @@ int VARASendData(struct TNCINFO * TNC, UCHAR * Buff, int Len)
struct STREAMINFO * STREAM = &TNC->Streams[0];
int bytes=send(TNC->TCPDataSock,(const char FAR *)Buff, Len, 0);
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
WritetoTrace(TNC, Buff, Len);
return bytes;
}
@ -2990,7 +2998,7 @@ void SendVARANetrom(struct TNCINFO * TNC, unsigned char * Data, int Len)
STREAM->PacketsSent++;
bytes = send(TNC->TCPDataSock, TNC->NetRomTxBuffer, TNC->NetRomTxLen, 0);
STREAM->BytesTXed += TNC->NetRomTxLen;
STREAM->bytesTXed += TNC->NetRomTxLen;
free(TNC->NetRomTxBuffer);
TNC->NetRomTxBuffer = NULL;

View File

@ -10,8 +10,8 @@
#endif
#define KVers 6,0,24,45
#define KVerstring "6.0.24.45\0"
#define KVers 6,0,24,49
#define KVerstring "6.0.24.49\0"
#ifdef CKernel

View File

@ -915,7 +915,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
txlen = buffptr->Len;
memcpy(txbuff, buffptr->Data, txlen);
bytes = send(TNC->TCPDataSock, txbuff, (int)txlen, 0);
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
WritetoTrace(TNC, txbuff, (int)txlen);
ReleaseBuffer(buffptr);
}
@ -941,7 +941,7 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff)
}
bytes = send(TNC->TCPDataSock,buff->L2DATA, (int)txlen, 0);
STREAM->BytesTXed += bytes;
STREAM->bytesTXed += bytes;
WritetoTrace(TNC, &buff->L2DATA[0], (int)txlen);
}
@ -2106,7 +2106,7 @@ VOID ProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
FreeSemaphore(&Semaphore);
STREAM->ConnectTime = time(NULL);
STREAM->BytesRXed = STREAM->BytesTXed = STREAM->PacketsSent = 0;
STREAM->bytesRXed = STREAM->bytesTXed = STREAM->PacketsSent = 0;
if (TNC->StartInRobust)
send(TNC->TCPSock, "ROBUST TRUE\r\n", 13, 0);
@ -2207,7 +2207,7 @@ VOID ProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
PMSGWITHLEN buffptr = Q_REM(&STREAM->BPQtoPACTOR_Q);
send(TNC->TCPDataSock, buffptr->Data, (int)buffptr->Len, 0);
STREAM->BytesTXed += (int)buffptr->Len;
STREAM->bytesTXed += (int)buffptr->Len;
WritetoTrace(TNC, buffptr->Data, (int)buffptr->Len);
ReleaseBuffer(buffptr);
}
@ -2368,22 +2368,7 @@ VOID ProcessResponse(struct TNCINFO * TNC, UCHAR * Buffer, int MsgLen)
if (TNC->Streams[0].Connected)
{
// Create a traffic record
char logmsg[120];
time_t Duration;
Duration = time(NULL) - STREAM->ConnectTime;
if (Duration == 0)
Duration = 1; // Avoid zero divide
sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds",
TNC->Port, STREAM->RemoteCall,
STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration),
STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration);
Debugprintf(logmsg);
hookL4SessionDeleted(TNC, STREAM);
GetSemaphore(&Semaphore, 50);
WritetoTrace(TNC, Buffer, MsgLen - 2);
@ -2708,7 +2693,7 @@ loop:
return;
}
STREAM->BytesRXed += InputLen;
STREAM->bytesRXed += InputLen;
msg = &buffptr->Data[0];
msg[InputLen] = 0;

View File

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

View File

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

View File

@ -756,7 +756,6 @@ typedef struct KISSINFO
int QtSMFreq;
int QtSMStats; // Set if stats received as KISS Command
// UCHAR WIN32INFO[16]; // FOR WINDOWS DRIVER
} *PKISSINFO;
@ -880,6 +879,11 @@ typedef struct _LINKTABLE
UCHAR OURCALL[7]; // CALLSIGN OF OUR END
UCHAR DIGIS[56]; // LEVEL 2 DIGIS IN PATH
char callingCall[10]; // for reporting. Link and Our calls depand on which end connected
char receivingCall[10]; // for reporting. Link and Our calls depand on which end connected
char Direction[4]; // In or Out
PPORTCONTROL LINKPORT; // PORT NUMBER
UCHAR LINKTYPE; // 1 = UP, 2= DOWN, 3 = INTERNODE
@ -927,6 +931,10 @@ typedef struct _LINKTABLE
int IFrameRetryCounter; // Number of times an I frame in repeated without a frame being acked
time_t ConnectTime; // For session stats
int bytesRXed; // Info bytes only
int bytesTXed;
} LINKTABLE;
#pragma pack(1)

View File

@ -55,7 +55,7 @@ extern int ProgramErrors;
extern struct _EXCEPTION_POINTERS exinfox;
#ifdef WIN32
Dump_Process_State(struct _EXCEPTION_POINTERS * exinfo, char * Msg);
void Dump_Process_State(struct _EXCEPTION_POINTERS * exinfo, char * Msg);
#define My__except_Routine(Message) \
__except(memcpy(&exinfo, GetExceptionInformation(), sizeof(struct _EXCEPTION_POINTERS)), EXCEPTION_EXECUTE_HANDLER)\

30
cMain.c
View File

@ -36,6 +36,7 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
#include "kernelresource.h"
#include "CHeaders.h"
#include "tncinfo.h"
#include "mqtt.h"
VOID L2Routine(struct PORTCONTROL * PORT, PMESSAGE Buffer);
VOID ProcessIframe(struct _LINKTABLE * LINK, PDATAMESSAGE Buffer);
@ -48,6 +49,7 @@ void ADSBTimer();
VOID SendSmartID(struct PORTCONTROL * PORT);
int CanPortDigi(int Port);
int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
void MQTTTimer();
#include "configstructs.h"
@ -82,6 +84,7 @@ char MYCALL[7] = ""; // DB 7 DUP (0) ; NODE CALLSIGN (BIT SHIFTED)
char MYALIASTEXT[6] = ""; // DB ' ' ; NODE ALIAS (KEEP TOGETHER)
char MYALIASLOPPED[10];
char MYCALLLOPPED[10];
UCHAR MYCALLWITHALIAS[13] = "";
@ -91,6 +94,7 @@ APPLCALLS APPLCALLTABLE[NumberofAppls] = {0};
UCHAR MYNODECALL[10] = ""; // NODE CALLSIGN (ASCII)
UCHAR MYNETROMCALL[10] = ""; // NETROM CALLSIGN (ASCII)
char NODECALLLOPPED[10];
VOID * FREE_Q = NULL;
@ -142,6 +146,15 @@ extern UCHAR LogDirectory[260];
extern BOOL EventsEnabled;
extern BOOL SaveAPRSMsgs;
BOOL M0LTEMap = FALSE;
BOOL MQTT = FALSE;
char MQTT_HOST[80] = "";
int MQTT_PORT = 0;
char MQTT_USER[80] = "";
char MQTT_PASS[80] = "";
int MQTT_Connecting = 0;
int MQTT_Connected = 0;
//TNCTABLE DD 0
//NUMBEROFSTREAMS DD 0
@ -438,7 +451,6 @@ Loop:
if (TNC->DisconnectScript)
{
int n = 0;
char command[256];
struct DATAMESSAGE * Buffer;
TRANSPORTENTRY Session = {0}; // = TNC->PortRecord->ATTACHEDSESSIONS[Sessno];
@ -729,6 +741,10 @@ BOOL Start()
memcpy(MYNETROMCALL, cfg->C_NETROMCALL, 10);
strlop(MYNETROMCALL, ' ');
strlop(MYNODECALL, ' ');
memcpy(NODECALLLOPPED, MYNODECALL, 10);
strlop(NODECALLLOPPED, ' ');
APPLCALLTABLE[0].APPLQUAL = BBSQUAL;
@ -793,7 +809,11 @@ BOOL Start()
EventsEnabled = cfg->C_EVENTS;
SaveAPRSMsgs = cfg->C_SaveAPRSMsgs;
M0LTEMap = cfg->C_M0LTEMap;
MQTT = cfg->C_MQTT;
strcpy(MQTT_HOST, cfg->C_MQTT_HOST);
MQTT_PORT = cfg->C_MQTT_PORT;
strcpy(MQTT_USER, cfg->C_MQTT_USER);
strcpy(MQTT_PASS, cfg->C_MQTT_PASS);
// Get pointers to PASSWORD and APPL1 commands
@ -2067,6 +2087,9 @@ VOID TIMERINTERRUPT()
sendFreqReport();
sendModeReport();
if (MQTT)
MQTTTimer();
/*
if (QCOUNT < 200)
{
@ -2219,6 +2242,9 @@ L2Packet:
Message->PORT = CURRENTPORT;
if (MQTT && PORT->PROTOCOL == 0)
MQTTKISSRX(Buffer);
// Bridge if requested
for (toPort = 1; toPort <= MaxBPQPortNo; toPort++)

239
compatbits.h.bak Normal file
View File

@ -0,0 +1,239 @@
/*
Stuff to make compiling on WINDOWS and LINUX easier
*/
#ifndef _COMPATBITS_
#define _COMPATBITS_
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stddef.h>
#ifdef WIN32
#define _CRT_SECURE_NO_DEPRECATE
#include <crtdbg.h>
#define strtoll _strtoi64
#ifdef _WIN64
#include "stdint.h"
#else
#include "winstdint.h"
#endif
#include "winsock2.h"
#include "WS2tcpip.h"
#include <windowsx.h>
#include <Richedit.h>
#include "commctrl.h"
#include "Commdlg.h"
#include <shellapi.h>
#define Dll __declspec(dllexport)
#define DllExport __declspec(dllexport)
#define ioctl ioctlsocket
#define pthread_t uintptr_t
int pthread_equal(pthread_t T1, pthread_t T2);
uintptr_t _beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist);
#else
int Sleep(int ms);
#define ioctlsocket ioctl
#define Dll
#define DllExport
#include <unistd.h>
#include <time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/select.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <netdb.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <fcntl.h>
#include <syslog.h>
#include <pthread.h>
#define BOOL int
#define VOID void
#define UCHAR unsigned char
#define USHORT unsigned short
#define ULONG unsigned long
#define UINT unsigned int
#define SHORT short
#define DWORD unsigned int
#define BYTE unsigned char
#define APIENTRY
#define WINAPI
#define WINUSERAPI
#define TCHAR char
#define TRUE 1
#define FALSE 0
#define FAR
#define byte UCHAR
//#define Byte UCHAR
#define Word WORD
typedef DWORD COLORREF;
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((USHORT)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
#define GetRValue(rgb) rgb & 0xFF
#define GetGValue(rgb) (rgb >> 8) & 0xFF
#define GetBValue(rgb) (rgb >> 16) & 0xFF
#define HWND unsigned int
#define HINSTANCE unsigned int
#define HKEY unsigned int
#define UINT_PTR unsigned int *
#define HANDLE UINT
#define SOCKET int
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define HMENU UINT
#define WNDPROC UINT
#define __cdecl
#define strtok_s strtok_r
#define _memicmp memicmp
#define _stricmp stricmp
#define _strdup strdup
#define _strupr strupr
#define _strlwr strlwr
#define _snprintf snprintf
#define _gcvt gcvt
#define _fcvt fcvt
#define _atoi64 atoll
#define DeleteFile unlink
#define MoveFile rename
#define CreateDirectory mkdir
uint64_t GetTickCount();
int sprintf_s(char * string, int plen, const char * format, ...);
int memicmp(unsigned char *a, unsigned char *b, int n);
int stricmp(const unsigned char * pStr1, const unsigned char *pStr2);
char * strupr(char* s);
char * strlwr(char* s);
pthread_t _beginthread(void(*start_address)(), unsigned stack_size, VOID * arglist);
#define WSAGetLastError() errno
#define GetLastError() errno
void closesocket(int sock);
#define GetCurrentProcessId getpid
#define GetCurrentThreadId pthread_self
char * inet_ntoa(struct in_addr in);
#define LOBYTE(w) ((BYTE)((ULONG *)(w) & 0xff))
#define HIBYTE(w) ((BYTE)((ULONG *)(w) >> 8))
#define LOWORD(l) ((SHORT) ((l) & 0xffff))
#define WSAEWOULDBLOCK 11
#define MAX_PATH 250
typedef int (*PROC)();
typedef struct tagRECT
{
unsigned int left;
unsigned int top;
unsigned int right;
unsigned int bottom;
} RECT, *PRECT, *NPRECT, *LPRECT;
#define HBRUSH int
#define _timezone timezone
#endif
#ifdef LINBPQ
#ifndef WIN32
void SetWindowText(HWND hWnd, char * lpString);
BOOL MySetDlgItemText(HWND hWnd, int item, char * lpString);
BOOL CopyFile(char * In, char * Out, BOOL Failifexists);
int GetNumberofPorts();
int SendMsg(int stream, char * msg, int len);
int SendRaw(int port, char * msg, int len);
VOID md5(char *arg, unsigned char * checksum);
// Send Raw (KISS mode) frame to port (BPQHOST function 10)
int APIENTRY SendRaw(int port, char * msg, int len);
BOOL MySetDlgItemText();
VOID OutputDebugString(char * string);
#endif
#ifdef APIENTRY
#undef APIENTRY
#endif
#define APIENTRY
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr_in *PSOCKADDR_IN;
typedef struct sockaddr_in *LPSOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
typedef struct sockaddr *PSOCKADDR;
typedef struct sockaddr *LPSOCKADDR;
#define __int16 short
#define __int32 long
#endif
#endif

View File

@ -302,7 +302,7 @@ static char *keywords[] =
"APPL5QUAL", "APPL6QUAL", "APPL7QUAL", "APPL8QUAL",
"BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXHOPS", // IPGATEWAY= no longer allowed
"LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS",
"EnableM0LTEMap"
"EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS"
}; /* parameter keywords */
static void * offset[] =
@ -323,7 +323,7 @@ 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_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_M0LTEMap}; /* 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}; /* offset for corresponding data in config file */
static int routine[] =
{
@ -343,7 +343,7 @@ static int routine[] =
14, 14 ,14, 14,
15, 0, 2, 9, 9,
2, 2, 2, 2, 2, 2,
2} ; // Routine to process param
2, 2, 0, 1, 20, 20} ; // Routine to process param
int PARAMLIM = sizeof(routine)/sizeof(int);
//int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int);
@ -365,7 +365,8 @@ static char *pkeywords[] =
"BCALL", "DIGIMASK", "NOKEEPALIVES", "COMPORT", "DRIVER", "WL2KREPORT", "UIONLY",
"UDPPORT", "IPADDR", "I2CBUS", "I2CDEVICE", "UDPTXPORT", "UDPRXPORT", "NONORMALIZE",
"IGNOREUNLOCKEDROUTES", "INP3ONLY", "TCPPORT", "RIGPORT", "PERMITTEDAPPLS", "HIDE",
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort"}; /* parameter keywords */
"SMARTID", "KISSCOMMAND", "SendtoM0LTEMap", "PortFreq", "M0LTEMapInfo", "QTSMPort",
"MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS"}; /* parameter keywords */
static void * poffset[] =
{
@ -606,6 +607,11 @@ BOOL ProcessConfig()
paramok[79]=1; // SaveAPRSMsgs optional
paramok[79]=1; // SaveAPRSMsgs optional
paramok[80]=1; // EnableM0LTEMap optional
paramok[81]=1; // MQTT Params
paramok[82]=1; // MQTT Params
paramok[83]=1; // MQTT Params
paramok[84]=1; // MQTT Params
paramok[85]=1; // MQTT Params
for (i=0; i < PARAMLIM; i++)
{
@ -1153,6 +1159,26 @@ NextAPRS:
}
if (_memicmp("MQTT_HOST=", rec, 10) == 0)
{
strcpy(xxcfg.C_MQTT_HOST, &rec[10]);
xxcfg.C_MQTT_HOST[strlen(xxcfg.C_MQTT_HOST)-1] = '\0';
return 0;
}
if (_memicmp("MQTT_USER=", rec, 10) == 0)
{
strcpy(xxcfg.C_MQTT_USER, &rec[10]);
xxcfg.C_MQTT_USER[strlen(xxcfg.C_MQTT_USER)-1] = '\0';
return 0;
}
if (_memicmp("MQTT_PASS=", rec, 10) == 0)
{
strcpy(xxcfg.C_MQTT_PASS, &rec[10]);
xxcfg.C_MQTT_PASS[strlen(xxcfg.C_MQTT_PASS)-1] = '\0';
return 0;
}
if (xindex(rec,"=") >= 0)
sscanf(rec,"%[^=]=%s",key_word,value);
else

View File

@ -165,6 +165,11 @@ struct CONFIGTABLE
struct ROUTECONFIG C_ROUTE[MaxLockedRoutes];
struct APPLCONFIG C_APPL[NumberofAppls];
struct PORTCONFIG C_PORT[MaxBPQPortNo + 4];
int C_MQTT;
char C_MQTT_HOST[80];
int C_MQTT_PORT;
char C_MQTT_USER[80];
char C_MQTT_PASS[80];
//#define ApplOffset 80000 // Applications offset in config buffer
//#define InfoOffset 85000 // Infomsg offset in buffer

BIN
debug/bpq32.pdb Normal file

Binary file not shown.

12
kiss.c
View File

@ -78,6 +78,7 @@ int i2c_smbus_read_byte()
#include "CHeaders.h"
#include "mqtt.h"
#include "kiss.h"
int i2cPoll(struct PORTCONTROL * PORT, NPASYINFO npKISSINFO);
@ -994,6 +995,10 @@ DONTCHECKDCD:
*/
SENDFRAME(KISS, Buffer);
if (MQTT)
MQTTKISSTX(Buffer);
}
VOID SENDFRAME(struct KISSINFO * KISS, PMESSAGE Buffer)
@ -1180,6 +1185,10 @@ VOID SENDFRAME(struct KISSINFO * KISS, PMESSAGE Buffer)
ASYSEND(PORT, ENCBUFF, (int)(ptr2 - (char *)ENCBUFF));
if (MQTT)
MQTTKISSTX_RAW((char *)ENCBUFF, (int)(ptr2 - (char *)ENCBUFF), PORT);
// Pass buffer to trace routines
C_Q_ADD(&TRACE_Q, Buffer);
@ -1739,6 +1748,9 @@ SeeifMore:
}
else
*/
if (MQTT)
MQTTKISSRX_RAW((char *)Buffer, len, PORT);
C_Q_ADD(&KISS->PORT.PORTRX_Q, (UINT *)Buffer);
}

564
mailapi.c
View File

@ -1,6 +1,6 @@
// basic JASON API to BPQ Node
// Authentication is via Telnet USER records.
// Authentication is via Telnet USER records or bbs records
#define _CRT_SECURE_NO_DEPRECATE
@ -10,6 +10,11 @@
#include "CHeaders.h"
#include <stdlib.h>
#include "bpqmail.h"
#include "httpconnectioninfo.h"
struct MsgInfo * GetMsgFromNumber(int msgno);
BOOL CheckUserMsg(struct MsgInfo * Msg, char * Call, BOOL SYSOP);
char * doXMLTransparency(char * string);
// Constants
@ -22,17 +27,92 @@ typedef struct MailToken {
time_t expiration_time;
struct UserInfo * User;
char Call[10];
int Auth; // Security level of user
struct MailToken* next;
} MailToken;
static MailToken * token_list = NULL;
typedef struct MailAPI
{
char *URL;
int URLLen;
int (* APIRoutine)();
int Auth;
} MailAPI;
// Auth defines
#define AuthNone 0
#define AuthUser 1
#define AuthBBSUser 2
#define AuthSysop 4
static int verify_token(const char* token);
static void remove_expired_tokens();
static int request_token(char * response);
static void add_token_to_list(MailToken* token);
static MailToken * find_token(const char* token);
int sendMsgList(struct HTTPConnectionInfo * Session, char * response, char * Rest, int Auth);
int sendFwdQueueLen(struct HTTPConnectionInfo * Session, char * response, char * Rest, int Auth);
int sendFwdConfig(struct HTTPConnectionInfo * Session, char * response, char * Rest, int Auth);
static struct MailAPI APIList[] =
{
"/mail/api/v1/msgs", 17, sendMsgList, 0,
"/mail/api/v1/FwdQLen", 20, sendFwdQueueLen, AuthSysop,
"/mail/api/v1/FwdConfig", 22, sendFwdConfig, AuthSysop,
};
static int APICount = sizeof(APIList) / sizeof(struct MailAPI);
#ifndef WIN32
iconv_t * icu = NULL;
#endif
void APIConvertTitletoUTF8(char * Title, char * UTF8Title, int Len)
{
if (WebIsUTF8(Title, (int)strlen(Title)) == FALSE)
{
// With Windows it is simple - convert using current codepage
// I think the only reliable way is to convert to unicode and back
int origlen = (int)strlen(Title) + 1;
#ifdef WIN32
WCHAR BufferW[128];
int wlen;
int len = origlen;
wlen = MultiByteToWideChar(CP_ACP, 0, Title, len, BufferW, origlen * 2);
len = WideCharToMultiByte(CP_UTF8, 0, BufferW, wlen, UTF8Title, origlen * 2, NULL, NULL);
#else
size_t left = Len - 1;
size_t len = origlen;
if (icu == NULL)
icu = iconv_open("UTF-8//IGNORE", "CP1252");
if (icu == (iconv_t)-1)
{
strcpy(UTF8Title, Title);
icu = NULL;
return;
}
char * orig = UTF8Title;
iconv(icu, NULL, NULL, NULL, NULL); // Reset State Machine
iconv(icu, &Title, &len, (char ** __restrict__)&UTF8Title, &left);
#endif
}
else
strcpy(UTF8Title, Title);
}
static MailToken * generate_token()
{
// Generate a random authentication token
@ -72,29 +152,6 @@ static void add_token_to_list(MailToken * token)
}
}
static int verify_token(const char* token)
{
// Find the token in the token list
MailToken * 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;
}
static void remove_expired_tokens()
{
time_t current_time = time(NULL);
@ -126,6 +183,7 @@ static void remove_expired_tokens()
static MailToken * find_token(const char* token)
{
MailToken * current_token = token_list;
while (current_token != NULL)
{
if (strcmp(current_token->token, token) == 0)
@ -143,7 +201,160 @@ static int send_http_response(char * response, const char* msg)
}
int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, char *Params)
int MailAPIProcessHTTPMessage(struct HTTPConnectionInfo * Session, char * response, char * Method, char * URL, char * request, BOOL LOCAL, char *Params, char * TokenString)
{
char * pass = strlop(Params, '&');
int Flags = 0, n;
MailToken * Token;
char Msg[64];
struct UserInfo * User;
int Auth = 0;
if (LOCAL)
Auth = AuthSysop;
// Check if the request is for token generation
if (strcmp(Method, "GET") != 0)
return send_http_response(response, "403 (Bad Method)");
if (_stricmp(URL, "/mail/api/v1/login") == 0)
{
// Key is in Session->Key
// Signon may have been validated in Node. If Session->Callsign is set
if (Session->Callsign[0] == 0)
{
// Try BBS logon
User = LookupCall(Params);
if (User)
{
// Check Password
if (pass[0] == 0 || strcmp(User->pass, pass) != 0 || User->flags & F_Excluded)
return send_http_response(response, "403 (Login Failed)");
strcpy(Session->Callsign, User->Call);
Auth = AuthBBSUser;
if (User->flags & F_SYSOP)
Auth |= AuthSysop;
}
}
else
{
User = LookupCall(Session->Callsign);
if (User)
{
Auth = AuthUser;
if (User->flags & F_SYSOP)
Auth |= AuthSysop;
}
}
n = sprintf_s(Msg, sizeof(Msg), "API Connect from %s", _strupr(Params));
WriteLogLine(NULL, '|',Msg, n, LOG_BBS);
Token = zalloc(sizeof(MailToken));
strcpy(Token->token, Session->Key);
strcpy(Token->Call, Session->Callsign);
Token->Auth = Auth;
Token->expiration_time = time(NULL) + TOKEN_EXPIRATION; // Set token expiration time
add_token_to_list(Token);
// Return Token
sprintf(response, "{\"access_token\":\"%s\", \"expires_at\":%d, \"scope\":\"create\"}\r\n",
Token->token, Token->expiration_time);
return strlen(response);
}
// Find Token
if (TokenString[0]) // Token form Auth Header
Token = find_token(TokenString);
else
Token = find_token(Params); // Token form URL
if (Token != NULL)
{
// Check if the token has expired
time_t current_time = time(NULL);
if (current_time > Token->expiration_time)
{
// Token has expired, remove it from the token list
remove_expired_tokens();
Token = NULL;
}
}
if (Token)
Auth |= Token->Auth;
// Determine the requested API endpoint
for (n = 0; n < APICount; n++)
{
struct MailAPI * APIEntry;
char * rest;
APIEntry = &APIList[n];
if (_memicmp(URL, APIEntry->URL, APIEntry->URLLen) == 0)
{
rest = &request[4 + APIEntry->URLLen]; // Anything following?
if (rest[0] =='?')
{
//Key
strlop(rest, ' ');
strlop(rest, '&');
Token = find_token(&rest[1]);
if (Token)
{
strcpy(Session->Callsign, Token->Call);
strcpy(Session->Key, Token->token);
}
else
return send_http_response(response, "403 (Invalid Security Token)");
}
if (APIEntry->Auth)
{
// Check Level
if ((Auth & APIEntry->Auth) == 0)
return send_http_response(response, "403 (Not Authorized)");
}
if (rest[0] == ' ' || rest[0] == '/' || rest[0] == '?')
{
return APIEntry->APIRoutine(Session, response, rest, Auth);
}
}
}
return send_http_response(response, "401 Invalid API Call");
return 0;
}
int WebMailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, char *Params)
{
char * pass = strlop(Params, '&');
int Flags = 0;
@ -185,7 +396,7 @@ int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char *
// Return Token
sprintf(response, "{\"access_token\":\"%s\", \"expires_in\":%d, \"scope\":\"create\"}\r\n",
Token->token, TOKEN_EXPIRATION);
Token->token, Token->expiration_time);
return strlen(response);
@ -194,3 +405,304 @@ int MailAPIProcessHTTPMessage(char * response, char * Method, char * URL, char *
return 0;
}
// Unauthorised users can only get bulls.
// Autothorised may read only users message or all messages depending on sysop status
int sendMsgList(struct HTTPConnectionInfo * Session, char * response, char * Rest, int Auth)
{
struct UserInfo * User = LookupCall(Session->Callsign);
int m;
struct MsgInfo * Msg;
char * ptr = response;
int n = NumberofMessages; //LineCount;
char Via[64];
int Count = 0;
struct UserInfo DummyUser = {""};
ptr[0] = 0;
if (User == 0)
User=&DummyUser;
n = sprintf(ptr,"{\"msgs\":[\r\n");
ptr += n;
for (m = LatestMsg; m >= 1; m--)
{
if (ptr > &response[244000])
break; // protect buffer
Msg = GetMsgFromNumber(m);
if (Msg == 0 || Msg->type == 0 || Msg->status == 0)
continue; // Protect against corrupt messages
if (Msg && CheckUserMsg(Msg, User->Call, Auth & AuthSysop))
{
char UTF8Title[4096];
char * EncodedTitle;
// List if it is the right type and in the page range we want
if (Count++ < Session->WebMailSkip)
continue;
ptr += sprintf(ptr, "{\r\n");
strcpy(Via, Msg->via);
strlop(Via, '.');
// make sure title is HTML safe (no < > etc) and UTF 8 encoded
EncodedTitle = doXMLTransparency(Msg->title);
memset(UTF8Title, 0, 4096); // In case convert fails part way through
APIConvertTitletoUTF8(EncodedTitle, UTF8Title, 4095);
ptr += sprintf(ptr, "\"id\": \"%d\",\r\n", Msg->number);
ptr += sprintf(ptr, "\"mid\": \"%s\",\r\n", Msg->bid);
ptr += sprintf(ptr, "\"rcvd\": \"%d\",\r\n", Msg->datecreated);
ptr += sprintf(ptr, "\"type\": \"%c\",\r\n", Msg->type);
ptr += sprintf(ptr, "\"status\": \"%c\",\r\n", Msg->status);
ptr += sprintf(ptr, "\"to\": \"%s\",\r\n", Msg->to);
ptr += sprintf(ptr, "\"from\": \"%s\",\r\n", Msg->from);
ptr += sprintf(ptr, "\"size\": \"%d\",\r\n", Msg->length);
ptr += sprintf(ptr, "\"subject\": \"%s\"\r\n", UTF8Title);
free(EncodedTitle);
// ptr += sprintf(ptr, "<a href=/WebMail/WM?%s&%d>%6d</a> %s %c%c %5d %-8s%-8s%-8s%s\r\n",
// Session->Key, Msg->number, Msg->number,
// FormatDateAndTime((time_t)Msg->datecreated, TRUE), Msg->type,
// Msg->status, Msg->length, Msg->to, Via,
// Msg->from, UTF8Title);
ptr += sprintf(ptr, "},\r\n");
n--;
if (n == 0)
break;
}
}
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");
}
return strlen(response);
}
int sendFwdQueueLen(struct HTTPConnectionInfo * Session, char * response, char * Rest, int Auth)
{
struct UserInfo * USER;
char * ptr = response;
int n;
int i = 0;
int Len = 0;
n = sprintf(ptr,"{\"forwardqueuelength\":[\r\n");
ptr += n;
for (USER = BBSChain; USER; USER = USER->BBSNext)
{
int Count = CountMessagestoForward (USER);
ptr += sprintf(ptr, "{");
ptr += sprintf(ptr, "\"call\": \"%s\",", USER->Call);
ptr += sprintf(ptr, "\"queueLength\": \"%d\"", Count);
ptr += sprintf(ptr, "},\r\n");
}
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");
}
return strlen(response);
}
VOID APIMultiStringValue(char ** values, char * Multi)
{
char ** Calls;
char * ptr = &Multi[0];
*ptr = 0;
if (values)
{
Calls = values;
while(Calls[0])
{
ptr += sprintf(ptr, "\"%s\",", Calls[0]);
Calls++;
}
if (ptr != &Multi[0])
*(--ptr) = 0;
}
}
char * APIConvTime(int ss)
{
int hh, mm;
static char timebuf[64];
hh = ss / 3600;
mm = (ss - (hh * 3600)) / 60;
ss = ss % 60;
sprintf(timebuf, "\"%02d:%02d:%02d\"", hh, mm, ss);
return timebuf;
}
int sendFwdConfig(struct HTTPConnectionInfo * Session, char * response, char * Rest, int Auth)
{
struct UserInfo * USER;
char * ptr = response;
int n = 0;
int i = 0;
int Len = 0;
response[n] = 0;
n = sprintf(ptr, "{\r\n");
ptr += n;
for (USER = BBSChain; USER; USER = USER->BBSNext)
{
struct BBSForwardingInfo * FWDInfo = USER->ForwardingInfo;
int Count = CountMessagestoForward (USER);
char TO[2048] = "";
char AT[2048] = "";
char TIMES[2048] = "";
char FWD[100000] = "";
char HRB[2048] = "";
char HRP[2048] = "";
APIMultiStringValue(FWDInfo->TOCalls, TO);
APIMultiStringValue(FWDInfo->ATCalls, AT);
APIMultiStringValue(FWDInfo->FWDTimes, TIMES);
APIMultiStringValue(FWDInfo->ConnectScript, FWD);
APIMultiStringValue(FWDInfo->Haddresses, HRB);
APIMultiStringValue(FWDInfo->HaddressesP, HRP);
ptr += sprintf(ptr, " \"%s\": {\r\n", USER->Call);
ptr += sprintf(ptr, " \"queueLength\": %d,\r\n", Count);
ptr += sprintf(ptr, " \"to\": [%s],\r\n", TO);
ptr += sprintf(ptr, " \"at\": [%s],\r\n", AT);
ptr += sprintf(ptr, " \"hrp\": [%s],\r\n",HRP);
ptr += sprintf(ptr, " \"hrb\": [%s],\r\n",HRB);
ptr += sprintf(ptr, " \"times\": [%s],\r\n",TIMES);
ptr += sprintf(ptr, " \"connectScript\": [%s],\r\n",FWD);
ptr += sprintf(ptr, " \"bbsHa\": \"%s\",\r\n", (FWDInfo->BBSHA)?FWDInfo->BBSHA:"");
ptr += sprintf(ptr, " \"enableForwarding\": %s,\r\n", (FWDInfo->Enabled)?"true":"false");
ptr += sprintf(ptr, " \"forwardingInterval\": %s,\r\n", APIConvTime(FWDInfo->FwdInterval));
ptr += sprintf(ptr, " \"requestReverse\": %s,\r\n", (FWDInfo->ReverseFlag)?"true":"false");
ptr += sprintf(ptr, " \"reverseInterval\": %s,\r\n", APIConvTime(FWDInfo->RevFwdInterval));
ptr += sprintf(ptr, " \"sendNewMessagesWithoutWaiting\": %s,\r\n", (FWDInfo->SendNew)?"true":"false");
ptr += sprintf(ptr, " \"fbbBlocked\": %s,\r\n", (FWDInfo->AllowBlocked)?"true":"false");
ptr += sprintf(ptr, " \"maxBlock\": %d,\r\n", FWDInfo->MaxFBBBlockSize);
ptr += sprintf(ptr, " \"sendPersonalMailOnly\": %s,\r\n", (FWDInfo->PersonalOnly)?"true":"false");
ptr += sprintf(ptr, " \"allowBinary\": %s,\r\n", (FWDInfo->AllowCompressed)?"true":"false");
ptr += sprintf(ptr, " \"useB1Protocol\": %s,\r\n", (FWDInfo->AllowB1)?"true":"false");
ptr += sprintf(ptr, " \"useB2Protocol\": %s,\r\n", (FWDInfo->AllowB2)?"true":"false");
ptr += sprintf(ptr, " \"incomingConnectTimeout\": %s\r\n", APIConvTime(FWDInfo->ConTimeout));
ptr += sprintf(ptr, " },\r\n");
}
if (response[n] == 0) // No entries
{
strcpy(response, "{}\r\n");
}
else
{
response[strlen(response)-3 ] = '\0'; // remove ,\r\n
strcat(response, "\r\n}\r\n");
}
return strlen(response);
}
/*
{
"GB7BEX": {
"queueLength": 0,
"forwardingConfig": {
"to": [],
"at": [
"OARC",
"GBR",
"WW"
],
"times": [],
"connectScript": [
"PAUSE 3",
"INTERLOCK 3",
"NC 3 !GB7BEX"
],
"hierarchicalRoutes": [],
"hr": [
"#38.GBR.EURO"
],
"bbsHa": "GB7BEX.#38.GBR.EURO",
"enableForwarding": true,
"forwardingInterval": "00:56:40",
"requestReverse": false,
"reverseInterval": "00:56:40",
"sendNewMessagesWithoutWaiting": true,
"fbbBlocked": true,
"maxBlock": 1000,
"sendPersonalMailOnly": false,
"allowBinary": true,
"useB1Protocol": false,
"useB2Protocol": true,
"sendCtrlZInsteadOfEx": false,
"incomingConnectTimeout": "00:02:00"
}
},
"GB7RDG": {
"queueLength": 0,
"forwardingConfig": {
"to": [],
...
"incomingConnectTimeout": "00:02:00"
}
}
}
# HELP packetmail_queue_length The number of messages in the packetmail queue
# TYPE packetmail_queue_length gauge
packetmail_queue_length{partner="DM4RW"} 0 1729090716916
packetmail_queue_length{partner="G8BPQ"} 3 1729090716916
packetmail_queue_length{partner="GB7BEX"} 0 1729090716916
packetmail_queue_length{partner="GB7BPQ"} 1 1729090716916
packetmail_queue_length{partner="GB7MNS"} 0 1729090716916
packetmail_queue_length{partner="GB7NOT"} 0 1729090716916
packetmail_queue_length{partner="GB7NWL"} 0 1729090716916
packetmail_queue_length{partner="GM8BPQ"} 0 1729090716916
*/

View File

@ -13,22 +13,26 @@ OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pn
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
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 -lpthread -lconfig -lpcap -o linbpq
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

382
mqtt.c Normal file
View File

@ -0,0 +1,382 @@
#define _CRT_SECURE_NO_DEPRECATE
#ifndef NOMQTT
#include "MQTTAsync.h"
#ifndef WIN32
#include <jansson.h>
#endif
#include "CHeaders.h"
#include "asmstrucs.h"
#include "mqtt.h"
extern int MQTT_Connecting;
extern int MQTT_Connected;
DllExport int APIENTRY MQTTSend(char * topic, char * Msg, int MsgLen);
MQTTAsync client = NULL;
time_t MQTTLastStatus = 0;
void MQTTSendStatus()
{
char topic[256];
char payload[128];
sprintf(topic, "PACKETNODE/%s", NODECALLLOPPED);
strcpy(payload,"{\"status\":\"online\"}");
MQTTSend(topic, payload, strlen(payload));
MQTTLastStatus = time(NULL);
}
void MQTTTimer()
{
if (MQTT_Connecting == 0 && MQTT_Connected == 0)
MQTTConnect(MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASS);
if ((time(NULL) - MQTTLastStatus) > 1800)
MQTTSendStatus();
}
void MQTTDisconnect()
{
if (MQTT_Connected)
{
MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
MQTTAsync_disconnect(client, &disc_opts);
MQTT_Connecting = MQTT_Connected = 0;
// Try to recconect. If it fails system will rety every minute
MQTTConnect(MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASS);
}
}
DllExport int APIENTRY MQTTSend(char * topic, char * Msg, int MsgLen)
{
int rc;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
pubmsg.payload = Msg;
pubmsg.payloadlen = MsgLen;
rc = MQTTAsync_sendMessage(client, topic, &pubmsg, &opts);
if (rc)
MQTTDisconnect();
return rc;
}
void onConnect(void* context, MQTTAsync_successData* response)
{
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
MQTT_Connecting = 0;
MQTT_Connected = 1;
printf("Successful MQTT connection\n");
// Send start up message
MQTTSendStatus();
}
void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
printf("MQTT connection failed, rc %d\n", response ? response->code : 0);
MQTT_Connecting = 0;
}
char* jsonEncodeMessage(MESSAGE *msg)
{
char From[10];
char To[10];
char buffer[1024];
unsigned long long SaveMMASK = MMASK;
BOOL SaveMTX = MTX;
BOOL SaveMCOM = MCOM;
BOOL SaveMUI = MUIONLY;
int len;
char *msg_str;
char payload_timestamp[16];
struct tm * TM = localtime(&msg->Timestamp);
sprintf(payload_timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
IntSetTraceOptionsEx(MMASK, TRUE, TRUE, FALSE);
From[ConvFromAX25(msg->ORIGIN, From)] = 0;
To[ConvFromAX25(msg->DEST, To)] = 0;
len = IntDecodeFrame(msg, buffer, msg->Timestamp, 0xffffffffffffffff, FALSE, FALSE);
IntSetTraceOptionsEx(SaveMMASK, SaveMTX, SaveMCOM, SaveMUI);
buffer[len] = 0;
#ifdef WIN32
msg_str = zalloc(2048);
sprintf(msg_str, "{\"from\": \"%s\", \"to\": \"%s\", \"payload\": \"%s\", \"port\": %d, \"timestamp\": \"%s\"}",
From, To, buffer, msg->PORT, payload_timestamp);
#else
json_t *root;
root = json_object();
json_object_set_new(root, "from", json_string(From));
json_object_set_new(root, "to", json_string(To));
json_object_set_new(root, "payload", json_string(buffer));
json_object_set_new(root, "port", json_integer(msg->PORT));
sprintf(payload_timestamp, "%02d:%02d:%02d", TM->tm_hour, TM->tm_min, TM->tm_sec);
json_object_set_new(root, "timestamp", json_string(payload_timestamp));
msg_str = json_dumps(root, 0);
json_decref(root);
#endif
return msg_str;
}
void MQTTKISSTX(void *message)
{
MESSAGE *msg = (MESSAGE *)message;
char topic[256];
char *msg_str;
sprintf(topic, "PACKETNODE/ax25/trace/bpqformat/%s/sent/%d", NODECALLLOPPED, msg->PORT);
msg_str = jsonEncodeMessage(msg);
MQTTSend(topic, msg_str, strlen(msg_str));
free(msg_str);
}
void MQTTKISSTX_RAW(char* buffer, int bufferLength, void* PORT)
{
PPORTCONTROL PPORT = (PPORTCONTROL)PORT;
char topic[256];
sprintf(topic, "PACKETNODE/kiss/%s/sent/%d", NODECALLLOPPED, PPORT->PORTNUMBER);
MQTTSend(topic, buffer, bufferLength);
}
void MQTTKISSRX(void *message)
{
MESSAGE *msg = (MESSAGE *)message;
char topic[256];
char *msg_str;
sprintf(topic, "PACKETNODE/ax25/trace/bpqformat/%s/rcvd/%d", NODECALLLOPPED, msg->PORT);
msg_str = jsonEncodeMessage(msg);
MQTTSend(topic, msg_str, strlen(msg_str));
free(msg_str);
}
void MQTTKISSRX_RAW(char* buffer, int bufferLength, void* PORT)
{
PPORTCONTROL PPORT = (PPORTCONTROL)PORT;
char topic[256];
sprintf(topic, "PACKETNODE/kiss/%s/rcvd/%d", NODECALLLOPPED, PPORT->PORTNUMBER);
MQTTSend(topic, buffer, bufferLength);
}
void MQTTReportSession(char * Msg)
{
char topic[256];
sprintf(topic, "PACKETNODE/stats/session/%s", NODECALLLOPPED);
MQTTSend(topic, Msg, strlen(Msg));
}
char* replace(char* str, char* a, char* b)
{
int len = strlen(str);
int lena = strlen(a), lenb = strlen(b);
char * p;
for (p = str; p = strstr(p, a); p) {
if (lena != lenb) // shift end as needed
memmove(p + lenb, p + lena,
len - (p - str) + lenb);
memcpy(p, b, lenb);
}
return str;
}
int MQTTPublish(void *message, char *topic)
{
MESSAGE *msg = (MESSAGE *)message;
char From[10];
char To[10];
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
unsigned long long SaveMMASK = MMASK;
BOOL SaveMTX = MTX;
BOOL SaveMCOM = MCOM;
BOOL SaveMUI = MUIONLY;
int len;
char* replaced_buffer;
char buffer[1024];
time_t timestamp = msg->Timestamp;
From[ConvFromAX25(msg->ORIGIN, From)] = 0;
To[ConvFromAX25(msg->DEST, To)] = 0;
IntSetTraceOptionsEx(8, TRUE, TRUE, FALSE);
len = IntDecodeFrame(msg, buffer, timestamp, 1, FALSE, FALSE);
IntSetTraceOptionsEx(SaveMMASK, SaveMTX, SaveMCOM, SaveMUI);
// MQTT _really_ doesn't like \r, so replace it with something
// that is at least human readable
replaced_buffer = replace(buffer, "\r", "\r\n");
pubmsg.payload = replaced_buffer;
pubmsg.payloadlen = strlen(replaced_buffer);
printf("%s\n", replaced_buffer);
return MQTTAsync_sendMessage(client, topic, &pubmsg, &opts);
}
int MQTTConnect(char* host, int port, char* user, char* pass)
{
MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
int rc;
char hostString[256];
sprintf(hostString, "tcp://%s:%d", host, port);
printf("MQTT Connect to %s\n", hostString);
rc = MQTTAsync_create(&client, hostString, NODECALLLOPPED, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTASYNC_SUCCESS)
{
printf("Failed to create client, return code %d\n", rc);
return rc;
}
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.username = user;
conn_opts.password = pass;
conn_opts.onSuccess = onConnect;
conn_opts.onFailure = onConnectFailure;
// conn_opts.automaticReconnect = 1;
// conn_opts.minRetryInterval = 30;
// conn_opts.maxRetryInterval = 300;
rc = MQTTAsync_connect(client, &conn_opts);
if (rc != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
return rc;
}
MQTT_Connecting = 1;
return 0;
}
/*
void MQTTMessageEvent(void* message)
{
struct MsgInfo* msg = (struct MsgInfo *)message;
char *msg_str;
char * ptr;
MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
char topic[256];
json_t *root = json_object();
json_object_set_new(root, "id", json_integer(msg->number));
json_object_set_new(root, "size", json_integer(msg->length));
json_object_set_new(root, "type", json_string(msg->type == 'P' ? "P" : "B"));
json_object_set_new(root, "to", json_string(msg->to));
json_object_set_new(root, "from", json_string(msg->from));
json_object_set_new(root, "subj", json_string(msg->title));
switch(msg->status) {
case 'N':
json_object_set_new(root, "event", json_string("newmsg"));
break;
case 'F':
json_object_set_new(root, "event", json_string("fwded"));
break;
case 'R':
json_object_set_new(root, "event", json_string("read"));
break;
case 'K':
json_object_set_new(root, "event", json_string("killed"));
break;
}
msg_str = json_dumps(root, 0);
pubmsg.payload = msg_str;
pubmsg.payloadlen = strlen(msg_str);
sprintf(topic, "PACKETNODE/event/%s/pmsg", NODECALLLOPPED);
MQTTAsync_sendMessage(client, topic, &pubmsg, &opts);
}
*/
#else
// Dummies ofr build without MQTT libraries
int MQTTConnect(char* host, int port, char* user, char* pass)
{
return 0;
}
void MQTTKISSTX(void *message) {};
void MQTTKISSTX_RAW(char* buffer, int bufferLength, void* PORT) {};
void MQTTKISSRX(void *message) {};
void MQTTKISSRX_RAW(char* buffer, int bufferLength, void* PORT) {};
void MQTTTimer() {};
void MQTTReportSession(char * Msg) {};
#endif

10
mqtt.h Normal file
View File

@ -0,0 +1,10 @@
int MQTTConnect(char* host, int port, char* user, char* pass);
int MQTTPublish(void * msg, char *topic);
void MQTTKISSTX(void *message);
void MQTTKISSTX_RAW(char* buffer, int bufferLength, void* PORT);
void MQTTKISSRX(void *message);
void MQTTKISSRX_RAW(char* buffer, int bufferLength, void* PORT);
void MQTTMessageEvent(void *message);

136
nodeapi.c
View File

@ -22,6 +22,20 @@ typedef struct Token {
struct Token* next;
} Token;
typedef struct API
{
char *URL;
int URLLen;
int (* APIRoutine)();
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);
@ -36,12 +50,12 @@ void add_token_to_list(Token* token);
Token* find_token(const char* token);
Token* generate_token();
int sendPortList(char * response, char * token,int Flags);
int sendNodeList(char * response, char * token,int Flags);
int sendUserList(char * response, char * token,int Flags);
int sendInfo(char * response, char * token, int Flags);
int sendLinks(char * response, char * token, int Flags);
int sendPortMHList(char * response, char * token, int param);
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);
void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT);
DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
@ -49,6 +63,21 @@ 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
};
int APICount = sizeof(APIList) / sizeof(struct API);
int xx()
{
while (1)
@ -67,7 +96,7 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
const char * auth_header = "Authorization: Bearer ";
char * token_begin = strstr(request, auth_header);
char token[TOKEN_SIZE + 1]= "";
int Flags = 0;
int Flags = 0, n;
// Node Flags isn't currently used
@ -94,7 +123,7 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
}
else
{
// Token must be first param of URL
// There may be a token as first param, but if auth not needed may be misisng
Tok = strlop(URL, '?');
param = strlop(Tok, '&');
@ -105,19 +134,34 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
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)
/*
if (token[0] == 0)
{
// Extract the token from the request (assuming it's present in the request headers)
if (token_begin == NULL)
@ -137,20 +181,26 @@ int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * req
return send_http_response(response, "401 Unauthorized");
}
*/
// Determine the requested API endpoint
if (_stricmp(URL, "/api/ports") == 0)
return sendPortList(response, token, Flags);
else if (_stricmp(URL, "/api/nodes") == 0)
return sendNodeList(response, token, Flags);
else if (_stricmp(URL, "/api/users") == 0)
return sendUserList(response, token, Flags);
else if (_stricmp(URL, "/api/info") == 0)
return sendInfo(response, token, Flags);
else if (_stricmp(URL, "/api/links") == 0)
return sendLinks(response, token, Flags);
else if (strstr(URL, "/api/mheardport") != 0)
return sendPortMHList(response, token, atoi(param));
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");
}
@ -294,7 +344,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
int sendPortList(char * response, char * token, int Flags)
int sendPortList(char * response, char * token, char * param)
{
char * Array = 0;
int ArrayLen = 0;
@ -506,7 +556,7 @@ extern struct DEST_LIST * DESTS; // NODE LIST
extern int DEST_LIST_LEN;
int sendNodeList(char * response, char * token, int Flags)
int sendNodeList(char * response, char * token, char * param)
{
int ArrayPtr = 0;
@ -610,16 +660,16 @@ int sendNodeList(char * response, char * token, int Flags)
}
int sendUserList(char * response, char * token, int Flags)
int sendUserList(char * response, char * token, char * param)
{
int ArrayPtr = 0;
int n = MAXCIRCUITS;
TRANSPORTENTRY * L4 = L4TABLE;
TRANSPORTENTRY * Partner;
// TRANSPORTENTRY * Partner;
int MaxLinks = MAXLINKS;
char State[12] = "", Type[12] = "Uplink";
char LHS[50] = "", MID[10] = "", RHS[50] = "";
char Line[100];
// char Line[100];
char Normcall[10];
int len;
@ -634,7 +684,7 @@ int sendUserList(char * response, char * token, int Flags)
len = ConvFromAX25(L4->L4USER, Normcall);
Normcall[len] = 0;
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\", \"%s\"},\r\n", Normcall);
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\": \"%s\"},\r\n", Normcall);
L4++;
}
}
@ -656,7 +706,7 @@ extern char MYALIASLOPPED[];
extern char TextVerstring[];
extern char LOCATOR[];
int sendInfo(char * response, char * token, int Flags)
int sendInfo(char * response, char * token, char * param)
{
char call[10];
@ -669,7 +719,7 @@ int sendInfo(char * response, char * token, int Flags)
return strlen(response);
}
int sendLinks(char * response, char * token, int Flags)
int sendLinks(char * response, char * token, char * param)
{
struct _LINKTABLE * Links = LINKS;
int MaxLinks = MAXLINKS;
@ -734,19 +784,37 @@ int sendLinks(char * response, char * token, int Flags)
return ReplyLen;
}
int sendPortMHList(char * response, char * token, int param)
int sendPortMHList(char * response, char * token, char * param)
{
struct PORTCONTROL * PORTVEC = GetPortTableEntryFromPortNum(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");
BuildPortMH( response, PORTVEC );
response[ strlen(response)-3 ] = '\0'; // remove ,\r\n
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);
}
return strlen(response);
}

BIN
paho-mqtt3a-static.lib Normal file

Binary file not shown.

BIN
paho-mqtt3a.lib Normal file

Binary file not shown.

View File

@ -222,14 +222,20 @@ struct STREAMINFO
char MyCall[10] ; // Call we are using
char RemoteCall[10]; // Callsign
char callingCall[10]; // for reporting. Link and Our calls depand on which end connected
char receivingCall[10]; // for reporting. Link and Our calls depand on which end connected
char Direction[4]; // In or Out
char AGWKey[21]; // Session Key for AGW Session Based Drivers
time_t ConnectTime; // Time connection made
time_t AttachTime;
int BytesTXed;
int bytesTXed;
int BytesAcked;
int BytesRXed;
int bytesRXed;
int PacketsSent;
int BytesResent;
int BytesOutstanding; // For Packet Channels

BIN
xpaho-mqtt3a.dll Normal file

Binary file not shown.