mirror of git://vps1.g8bpq.net/linbpq
parent
488630c655
commit
d5c89eccbb
@ -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="SKIGACER"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<DebugSettings
|
||||
Command="$(TargetPath)"
|
||||
WorkingDirectory=""
|
||||
CommandArguments=""
|
||||
Attach="false"
|
||||
DebuggerType="3"
|
||||
Remote="1"
|
||||
RemoteMachine="SKIGACER"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
</VisualStudioUserFile>
|
||||
@ -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="LAPTOP-Q6S4RP5Q"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<DebugSettings
|
||||
Command="$(TargetPath)"
|
||||
WorkingDirectory=""
|
||||
CommandArguments=""
|
||||
Attach="false"
|
||||
DebuggerType="3"
|
||||
Remote="1"
|
||||
RemoteMachine="LAPTOP-Q6S4RP5Q"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
</VisualStudioUserFile>
|
||||
@ -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="SKIGACER"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<DebugSettings
|
||||
Command="$(TargetPath)"
|
||||
WorkingDirectory=""
|
||||
CommandArguments=""
|
||||
Attach="false"
|
||||
DebuggerType="3"
|
||||
Remote="1"
|
||||
RemoteMachine="SKIGACER"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
</VisualStudioUserFile>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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="LAPTOP-Q6S4RP5Q"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<DebugSettings
|
||||
Command="$(TargetPath)"
|
||||
WorkingDirectory=""
|
||||
CommandArguments=""
|
||||
Attach="false"
|
||||
DebuggerType="3"
|
||||
Remote="1"
|
||||
RemoteMachine="LAPTOP-Q6S4RP5Q"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
</VisualStudioUserFile>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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="LAPTOP-Q6S4RP5Q"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<DebugSettings
|
||||
Command="$(TargetPath)"
|
||||
WorkingDirectory=""
|
||||
CommandArguments=""
|
||||
Attach="false"
|
||||
DebuggerType="3"
|
||||
Remote="1"
|
||||
RemoteMachine="LAPTOP-Q6S4RP5Q"
|
||||
RemoteCommand=""
|
||||
HttpUrl=""
|
||||
PDBPath=""
|
||||
SQLDebugging=""
|
||||
Environment=""
|
||||
EnvironmentMerge="true"
|
||||
DebuggerFlavor=""
|
||||
MPIRunCommand=""
|
||||
MPIRunArguments=""
|
||||
MPIRunWorkingDirectory=""
|
||||
ApplicationCommand=""
|
||||
ApplicationArguments=""
|
||||
ShimCommand=""
|
||||
MPIAcceptMode=""
|
||||
MPIAcceptFilter=""
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
</VisualStudioUserFile>
|
||||
@ -1,641 +0,0 @@
|
||||
/*
|
||||
Copyright 2001-2022 John Wiseman G8BPQ
|
||||
|
||||
This file is part of LinBPQ/BPQ32.
|
||||
|
||||
LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
LinBPQ/BPQ32 is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Paula (G8PZT)'s Remote Host Protocol interface.
|
||||
For now only sufficient support for WhatsPac
|
||||
|
||||
|
||||
*/
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "cheaders.h"
|
||||
#include "bpq32.h"
|
||||
|
||||
int FindFreeStreamNoSem();
|
||||
DllExport int APIENTRY DeallocateStream(int stream);
|
||||
int SendMsgNoSem(int stream, char * msg, int len);
|
||||
|
||||
static void GetJSONValue(char * _REPLYBUFFER, char * Name, char * Value, int Len);
|
||||
static int GetJSONInt(char * _REPLYBUFFER, char * Name);
|
||||
|
||||
// Generally Can have multiple RHP connections and each can have multiple RHF Sessions
|
||||
|
||||
struct RHPSessionInfo
|
||||
{
|
||||
SOCKET Socket; // Websocks Socket
|
||||
int BPQStream;
|
||||
int Handle; // RHP session ID
|
||||
int Seq;
|
||||
char Local[12];
|
||||
char Remote[12];
|
||||
BOOL Connecting; // Set while waiting for connection to complete
|
||||
BOOL Listening;
|
||||
BOOL Connected;
|
||||
};
|
||||
|
||||
struct RHPConnectionInfo
|
||||
{
|
||||
SOCKET socket;
|
||||
struct RHPSessionInfo ** RHPSessions;
|
||||
int NumberofRHPSessions;
|
||||
};
|
||||
|
||||
|
||||
struct RHPConnectionInfo ** RHPSockets = NULL;
|
||||
int NumberofRHPConnections = 0;
|
||||
|
||||
struct RHPSessionInfo ** RHPSessions;
|
||||
int NumberofRHPSessions;
|
||||
|
||||
char ErrCodes[18][24] =
|
||||
{"Ok", "Unspecified", "Bad or missing type", "Invalid handle", "No memory", "Bad or missing mode",
|
||||
|
||||
"Invalid local address",
|
||||
"Invalid remote address" ,
|
||||
"Bad or missing family" ,
|
||||
"Duplicate socket" ,
|
||||
"No such port" ,
|
||||
"Invalid protocol" ,
|
||||
"Bad parameter" ,
|
||||
"No buffers" ,
|
||||
"Unauthorised" ,
|
||||
"No Route" ,
|
||||
"Operation not supported"};
|
||||
|
||||
|
||||
|
||||
|
||||
extern char pgm[256];
|
||||
|
||||
SOCKET agwsock;
|
||||
|
||||
extern int SemHeldByAPI;
|
||||
|
||||
char szBuff[80];
|
||||
|
||||
int WhatsPacConfigured = 1;
|
||||
|
||||
|
||||
int RHPPaclen = 236;
|
||||
|
||||
|
||||
int processRHCPOpen(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer);
|
||||
int processRHCPSend(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer);
|
||||
int processRHCPClose(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer);
|
||||
|
||||
|
||||
|
||||
void SendWebSockMessage(SOCKET socket, char * Msg, int Len)
|
||||
{
|
||||
int Loops = 0;
|
||||
int Sent;
|
||||
int TxLen;
|
||||
char * OutBuffer = Msg;
|
||||
|
||||
// WebSock Encode. Buffer has 10 bytes on front for header but header len depends on Msg len
|
||||
|
||||
|
||||
if (Len < 126)
|
||||
{
|
||||
// Two Byte Header
|
||||
|
||||
OutBuffer[8] = 0x81; // Fin, Data
|
||||
OutBuffer[9] = Len;
|
||||
|
||||
TxLen = Len + 2;
|
||||
OutBuffer = &Msg[8];
|
||||
}
|
||||
else if (Len < 65536)
|
||||
{
|
||||
OutBuffer[6] = 0x81; // Fin, Data
|
||||
OutBuffer[7] = 126; // Unmasked, Extended Len 16
|
||||
OutBuffer[8] = Len >> 8;
|
||||
OutBuffer[9] = Len & 0xff;
|
||||
TxLen = Len + 4;
|
||||
OutBuffer = &Msg[6];
|
||||
}
|
||||
else
|
||||
{
|
||||
OutBuffer[0] = 0x81; // Fin, Data
|
||||
OutBuffer[1] = 127; // Unmasked, Extended Len 64 bits
|
||||
// Len is 32 bits, so pad with zeros
|
||||
OutBuffer[2] = 0;
|
||||
OutBuffer[3] = 0;
|
||||
OutBuffer[4] = 0;
|
||||
OutBuffer[5] = 0;
|
||||
OutBuffer[6] = (Len >> 24) & 0xff;
|
||||
OutBuffer[7] = (Len >> 16) & 0xff;
|
||||
OutBuffer[8] = (Len >> 8) & 0xff;
|
||||
OutBuffer[9] = Len & 0xff;
|
||||
|
||||
TxLen = Len + + 10;
|
||||
OutBuffer = &Msg[0];
|
||||
}
|
||||
|
||||
// Send may block
|
||||
|
||||
Sent = send(socket, OutBuffer, TxLen, 0);
|
||||
|
||||
while (Sent != TxLen && Loops++ < 3000) // 100 secs max
|
||||
{
|
||||
if (Sent > 0) // something sent
|
||||
{
|
||||
TxLen -= Sent;
|
||||
memmove(OutBuffer, &OutBuffer[Sent], TxLen);
|
||||
}
|
||||
|
||||
Sleep(30);
|
||||
Sent = send(socket, OutBuffer, TxLen, 0);
|
||||
if (Sent == -1)
|
||||
break;
|
||||
}
|
||||
|
||||
free(Msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE)
|
||||
{
|
||||
// RHP messages can be sent over Websocks or normal http but I think WhatsPac only uses WebSocks
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ProcessRHPWebSock(SOCKET socket, char * Msg, int MsgLen)
|
||||
{
|
||||
int Loops = 0;
|
||||
int InputLen = 0;
|
||||
int Len;
|
||||
|
||||
char Value[16];
|
||||
char * OutBuffer = malloc(250000);
|
||||
|
||||
struct RHPConnectionInfo * RHPSocket = NULL;
|
||||
int n;
|
||||
|
||||
Msg[MsgLen] = 0;
|
||||
|
||||
// Find Connection Record. If none, create one
|
||||
|
||||
for (n = 0; n < NumberofRHPConnections; n++)
|
||||
{
|
||||
if (RHPSockets[n]->socket == socket)
|
||||
{
|
||||
RHPSocket = RHPSockets[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (RHPSocket == 0)
|
||||
{
|
||||
NumberofRHPConnections;
|
||||
RHPSockets = realloc(RHPSockets, sizeof(void *) * (NumberofRHPConnections + 1));
|
||||
RHPSocket = RHPSockets[NumberofRHPConnections] = zalloc(sizeof (struct RHPConnectionInfo));
|
||||
NumberofRHPConnections++;
|
||||
RHPSocket->socket = socket;
|
||||
}
|
||||
|
||||
|
||||
// {"type":"open","id":5,"pfam":"ax25","mode":"stream","port":"1","local":"G8BPQ","remote":"G8BPQ-2","flags":128}
|
||||
// {"type": "openReply", "id": 82, "handle": 1, "errCode": 0, "errText": "Ok"}
|
||||
// {"seqno": 0, "type": "status", "handle": 1, "flags": 0}
|
||||
// ("seqno": 1, "type": "close", "handle": 1}
|
||||
// {"id":40,"type":"close","handle":1}
|
||||
|
||||
// {"seqno": 0, "type": "status", "handle": 1, "flags": 2}.~.
|
||||
// {"seqno": 1, "type": "recv", "handle": 1, "data": "Welcome to G8BPQ's Test Switch in Nottingham \rType ? for list of available commands.\r"}.
|
||||
|
||||
GetJSONValue(Msg, "\"type\":", Value, 15);
|
||||
|
||||
if (_stricmp(Value, "open") == 0)
|
||||
{
|
||||
Len = processRHCPOpen(RHPSocket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
|
||||
if (Len)
|
||||
SendWebSockMessage(RHPSocket->socket, OutBuffer, Len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_stricmp(Value, "send") == 0)
|
||||
{
|
||||
Len = processRHCPSend(RHPSocket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
|
||||
SendWebSockMessage(RHPSocket->socket, OutBuffer, Len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_stricmp(Value, "close") == 0)
|
||||
{
|
||||
Len = processRHCPClose(RHPSocket, Msg, &OutBuffer[10]); // Space at front for WebSock Header
|
||||
SendWebSockMessage(RHPSocket->socket, OutBuffer, Len);
|
||||
return;
|
||||
}
|
||||
Debugprintf(Msg);
|
||||
}
|
||||
|
||||
void ProcessRHPWebSockClosed(SOCKET socket)
|
||||
{
|
||||
// Close any connections on this scoket and delete socket entry
|
||||
|
||||
struct RHPConnectionInfo * RHPSocket = NULL;
|
||||
int n;
|
||||
|
||||
// Find Connection Record. CLear any Sessions
|
||||
|
||||
for (n = 0; n < NumberofRHPConnections; n++)
|
||||
{
|
||||
if (RHPSockets[n]->socket == socket)
|
||||
{
|
||||
RHPSocket = RHPSockets[n];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int processRHCPOpen(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer)
|
||||
{
|
||||
//{"type":"open","id":5,"pfam":"ax25","mode":"stream","port":"1","local":"G8BPQ","remote":"G8BPQ-2","flags":128}
|
||||
|
||||
struct RHPSessionInfo * RHPSession = 0;
|
||||
|
||||
char * Value = malloc(strlen(Msg)); // Will always be long enough
|
||||
int ID;
|
||||
|
||||
char pfam[16];
|
||||
char Mode[16];
|
||||
int Port;
|
||||
char Local[16];
|
||||
char Remote[16];
|
||||
int flags;
|
||||
int Handle = 1;
|
||||
int Stream;
|
||||
unsigned char AXCall[10];
|
||||
int Len;
|
||||
int n;
|
||||
|
||||
// ID seems to be used for control commands like open. SeqNo for data within a session (i Think!
|
||||
|
||||
ID = GetJSONInt(Msg, "\"id\":");
|
||||
GetJSONValue(Msg, "\"pfam\":", pfam, 15);
|
||||
GetJSONValue(Msg, "\"mode\":", Mode, 15);
|
||||
Port = GetJSONInt(Msg, "\"port\":");
|
||||
GetJSONValue(Msg, "\"local\":", Local, 15);
|
||||
GetJSONValue(Msg, "\"remote\":", Remote, 15);
|
||||
flags = GetJSONInt(Msg, "\"flags\":");
|
||||
|
||||
if (_stricmp(pfam, "ax25") != 0)
|
||||
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0);
|
||||
|
||||
if (_stricmp(Mode, "stream") == 0)
|
||||
{
|
||||
{
|
||||
// Allocate a RHP Session
|
||||
|
||||
// See if there is an old one we can reuse
|
||||
|
||||
for (n = 0; n < NumberofRHPSessions; n++)
|
||||
{
|
||||
if (RHPSessions[n]->BPQStream == 0)
|
||||
{
|
||||
RHPSession = RHPSessions[n];
|
||||
Handle = n + 1;
|
||||
Stream = RHPSessions[n]->BPQStream;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (RHPSession == 0)
|
||||
{
|
||||
RHPSessions = realloc(RHPSessions, sizeof(void *) * (NumberofRHPSessions + 1));
|
||||
RHPSession = RHPSessions[NumberofRHPSessions] = zalloc(sizeof (struct RHPSessionInfo));
|
||||
NumberofRHPSessions++;
|
||||
|
||||
Handle = NumberofRHPSessions;
|
||||
}
|
||||
|
||||
strcpy(pgm, "RHP");
|
||||
Stream = FindFreeStreamNoSem();
|
||||
strcpy(pgm, "bpq32.exe");
|
||||
|
||||
if (Stream == 255)
|
||||
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0);
|
||||
|
||||
RHPSession->BPQStream = Stream;
|
||||
RHPSession->Handle = Handle;
|
||||
RHPSession->Connecting = TRUE;
|
||||
RHPSession->Socket = RHPSocket->socket;
|
||||
|
||||
strcpy(RHPSession->Local, Local);
|
||||
strcpy(RHPSession->Remote, Remote);
|
||||
|
||||
Connect(Stream);
|
||||
|
||||
ConvToAX25(Local, AXCall);
|
||||
ChangeSessionCallsign(Stream, AXCall);
|
||||
|
||||
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 0, \"errText\": \"Ok\"}", ID, Handle);
|
||||
}
|
||||
}
|
||||
return sprintf(ReplyBuffer, "{\"type\": \"openReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errText\": \"Bad parameter\"}", ID, 0);
|
||||
}
|
||||
|
||||
int processRHCPSend(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer)
|
||||
{
|
||||
// {"type":"send","handle":1,"data":";;;;;;\r","id":70}
|
||||
|
||||
struct RHPSessionInfo * RHPSession;
|
||||
|
||||
int ID;
|
||||
char * Data;
|
||||
char * ptr;
|
||||
int c;
|
||||
int Len;
|
||||
|
||||
int Handle = 1;
|
||||
|
||||
Data = malloc(strlen(Msg));
|
||||
|
||||
ID = GetJSONInt(Msg, "\"id\":");
|
||||
Handle = GetJSONInt(Msg, "\"handle\":");
|
||||
GetJSONValue(Msg, "\"data\":", Data, strlen(Msg) - 1);
|
||||
|
||||
if (Handle < 1 || Handle > NumberofRHPSessions)
|
||||
{
|
||||
free(Data);
|
||||
return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 12, \"errtext\": \"Invalid handle\"}", ID, Handle);
|
||||
}
|
||||
|
||||
RHPSession = RHPSessions[Handle - 1];
|
||||
|
||||
// Look for \ escapes
|
||||
|
||||
ptr = Data;
|
||||
|
||||
while (ptr = strchr(ptr, '\\'))
|
||||
{
|
||||
c = ptr[1];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'r':
|
||||
|
||||
*ptr = 13;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
|
||||
*ptr = '\\';
|
||||
break;
|
||||
|
||||
case '"':
|
||||
|
||||
*ptr = '"';
|
||||
break;
|
||||
}
|
||||
memmove(ptr + 1, ptr + 2, strlen(ptr + 1));
|
||||
ptr++;
|
||||
}
|
||||
|
||||
Debugprintf(Data);
|
||||
|
||||
Len = strlen(Data);
|
||||
ptr = Data;
|
||||
|
||||
|
||||
while (Len > RHPPaclen)
|
||||
{
|
||||
SendMsgNoSem(RHPSession->BPQStream, ptr, RHPPaclen);
|
||||
Len -= RHPPaclen;
|
||||
ptr += RHPPaclen;
|
||||
}
|
||||
|
||||
SendMsgNoSem(RHPSession->BPQStream, ptr, Len);
|
||||
|
||||
free(Data);
|
||||
return sprintf(ReplyBuffer, "{\"type\": \"sendReply\", \"id\": %d, \"handle\": %d, \"errCode\": 0, \"errText\": \"Ok\", \"status\": %d}", ID, Handle, 2);
|
||||
}
|
||||
|
||||
|
||||
int processRHCPClose(struct RHPConnectionInfo * RHPSocket, char * Msg, char * ReplyBuffer)
|
||||
{
|
||||
|
||||
// {"id":70,"type":"close","handle":1}
|
||||
|
||||
|
||||
struct RHPSessionInfo * RHPSession;
|
||||
|
||||
int ID;
|
||||
int Handle = 1;
|
||||
|
||||
char * OutBuffer = malloc(256);
|
||||
|
||||
ID = GetJSONInt(Msg, "\"id\":");
|
||||
Handle = GetJSONInt(Msg, "\"handle\":");
|
||||
|
||||
if (Handle < 1 || Handle > NumberofRHPSessions)
|
||||
return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 12, \"errtext\": \"Invalid handle\"}", ID, Handle);
|
||||
|
||||
|
||||
RHPSession = RHPSessions[Handle - 1];
|
||||
Disconnect(RHPSession->BPQStream);
|
||||
RHPSession->Connected = 0;
|
||||
RHPSession->Connecting = 0;
|
||||
|
||||
DeallocateStream(RHPSession->BPQStream);
|
||||
RHPSession->BPQStream = 0;
|
||||
|
||||
return sprintf(ReplyBuffer, "{\"id\": %d, \"type\": \"closeReply\", \"handle\": %d, \"errcode\": 0, \"errtext\": \"Ok\"}", ID, Handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RHPPoll()
|
||||
{
|
||||
int Stream;
|
||||
int n;
|
||||
int state, change;
|
||||
int Len;
|
||||
char * RHPMsg;
|
||||
unsigned char Buffer[1024]; // Space to escape control chars
|
||||
int pktlen, count;
|
||||
|
||||
struct RHPSessionInfo * RHPSession;
|
||||
|
||||
for (n = 0; n < NumberofRHPSessions; n++)
|
||||
{
|
||||
RHPSession = RHPSessions[n];
|
||||
Stream = RHPSession->BPQStream;
|
||||
|
||||
// See if connected state has changed
|
||||
|
||||
SessionState(Stream, &state, &change);
|
||||
|
||||
if (change == 1)
|
||||
{
|
||||
if (state == 1)
|
||||
{
|
||||
// Connected
|
||||
|
||||
RHPSession->Seq = 0;
|
||||
RHPSession->Connecting = FALSE;
|
||||
RHPSession->Connected = TRUE;
|
||||
|
||||
RHPMsg = malloc(256);
|
||||
Len = sprintf(&RHPMsg[10], "{\"seqno\": %d, \"type\": \"status\", \"handle\": %d, \"flags\": 2}", RHPSession->Seq++, RHPSession->Handle);
|
||||
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
|
||||
|
||||
// Send RHP CTEXT
|
||||
|
||||
RHPMsg = malloc(256);
|
||||
Len = sprintf(&RHPMsg[10], "{\"seqno\": %d, \"type\": \"recv\", \"handle\": %d, \"data\": \"Connected to RHP Server\\r\"}", RHPSession->Seq++, RHPSession->Handle);
|
||||
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disconnected. Send Close to client
|
||||
|
||||
RHPMsg = malloc(256);
|
||||
Len = sprintf(&RHPMsg[10], "{\"type\": \"close\", \"seqno\": %d, \"handle\": %d}", RHPSession->Seq++, RHPSession->Handle);
|
||||
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
|
||||
|
||||
RHPSession->Connected = 0;
|
||||
RHPSession->Connecting = 0;
|
||||
|
||||
DeallocateStream(RHPSession->BPQStream);
|
||||
RHPSession->BPQStream = 0;
|
||||
}
|
||||
}
|
||||
do
|
||||
{
|
||||
GetMsg(Stream, Buffer, &pktlen, &count);
|
||||
|
||||
if (pktlen > 0)
|
||||
{
|
||||
char * ptr = Buffer;
|
||||
char c;
|
||||
|
||||
Buffer[pktlen] = 0;
|
||||
|
||||
// Message is JSON so Convert CR to \r, \ to \\ " to \"
|
||||
|
||||
while (c = *(ptr))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 13:
|
||||
|
||||
memmove(ptr + 2, ptr + 1, strlen(ptr));
|
||||
*(ptr++) = '\\';
|
||||
*(ptr++) = 'r';
|
||||
break;
|
||||
|
||||
case '"':
|
||||
|
||||
memmove(ptr + 2, ptr + 1, strlen(ptr));
|
||||
*(ptr++) = '\\';
|
||||
*(ptr++) = '"';
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
|
||||
memmove(ptr + 2, ptr + 1, strlen(ptr));
|
||||
*(ptr++) = '\\';
|
||||
*(ptr++) = '\\';
|
||||
break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
|
||||
|
||||
RHPMsg = malloc(1024);
|
||||
|
||||
Len = sprintf(&RHPMsg[10], "{\"seqno\": %d, \"type\": \"recv\", \"handle\": %d, \"data\": \"%s\"}", RHPSession->Seq++, RHPSession->Handle, Buffer);
|
||||
SendWebSockMessage(RHPSession->Socket, RHPMsg, Len);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
while (count > 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void GetJSONValue(char * _REPLYBUFFER, char * Name, char * Value, int Len)
|
||||
{
|
||||
char * ptr1, * ptr2;
|
||||
|
||||
Value[0] = 0;
|
||||
|
||||
ptr1 = strstr(_REPLYBUFFER, Name);
|
||||
|
||||
if (ptr1 == 0)
|
||||
return;
|
||||
|
||||
ptr1 += (strlen(Name) + 1);
|
||||
|
||||
// "data":"{\"t\":\"c\",\"n\":\"John\",\"c\":\"G8BPQ\",\"lm\":1737912636,\"le\":1737883907,\"led\":1737758451,\"v\":0.33,\"cc\":[{\"cid\":1,\"lp\":1737917257201,\"le\":1737913735726,\"led\":1737905249785},{\"cid\":0,\"lp\":1737324074107,\"le\":1737323831510,\"led\":1737322973662},{\"cid\":5,\"lp\":1737992107419,\"le\":1737931466510,\"led\":1737770056244}]}\r","id":28}
|
||||
|
||||
// There may be escaped " in data stream
|
||||
|
||||
ptr2 = strchr(ptr1, '"');
|
||||
|
||||
while (*(ptr2 - 1) == '\\')
|
||||
{
|
||||
ptr2 = strchr(ptr2 + 2, '"');
|
||||
}
|
||||
|
||||
|
||||
if (ptr2)
|
||||
{
|
||||
size_t ValLen = ptr2 - ptr1;
|
||||
if (ValLen > Len)
|
||||
ValLen = Len;
|
||||
|
||||
memcpy(Value, ptr1, ValLen);
|
||||
Value[ValLen] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int GetJSONInt(char * _REPLYBUFFER, char * Name)
|
||||
{
|
||||
char * ptr1;
|
||||
|
||||
ptr1 = strstr(_REPLYBUFFER, Name);
|
||||
|
||||
if (ptr1 == 0)
|
||||
return 0;
|
||||
|
||||
ptr1 += (strlen(Name));
|
||||
|
||||
return atoi(ptr1);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,125 +0,0 @@
|
||||
|
||||
#ifdef Kernel
|
||||
|
||||
#define Vers 5,2,9,2
|
||||
#define Verstring "5.2.9.2\0"
|
||||
#define Datestring "September 2012"
|
||||
#define VerComments "G8BPQ Packet Switch V5.2.9.2\0"
|
||||
#define VerCopyright "Copyright © 2001-2012 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "BPQ32 Switch\0"
|
||||
|
||||
#endif
|
||||
|
||||
#define KVers 6,0,24,59
|
||||
#define KVerstring "6.0.24.59\0"
|
||||
|
||||
#ifdef CKernel
|
||||
|
||||
#define Vers KVers
|
||||
#define Verstring KVerstring
|
||||
#define Datestring "January 2025"
|
||||
#define VerComments "G8BPQ Packet Switch (C Version)" KVerstring
|
||||
#define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "BPQ32 Switch\0"
|
||||
#define VerProduct "BPQ32"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TermTCP
|
||||
|
||||
#define Vers 1,0,16,2
|
||||
#define Verstring "1.0.16.2\0"
|
||||
#define VerComments "Internet Terminal for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 2011-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "Simple TCP Terminal Program for G8BPQ Switch\0"
|
||||
#define VerProduct "BPQTermTCP"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BPQTerm
|
||||
|
||||
#define Vers 2,2,5,2
|
||||
#define Verstring "2.2.5.2\0"
|
||||
#define VerComments "Simple Terminal for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 1999-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "Simple Terminal Program for G8BPQ Switch\0"
|
||||
#define VerProduct "BPQTerminal"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BPQTermMDI
|
||||
|
||||
#define Vers 2,2,0,3
|
||||
#define Verstring "2.2.0.3\0"
|
||||
#define VerComments "MDI Terminal for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 1999-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "MDI Terminal Program for G8BPQ Switch\0"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MAIL
|
||||
|
||||
#define Vers KVers
|
||||
#define Verstring KVerstring
|
||||
#define VerComments "Mail server for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 2009-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "Mail server for G8BPQ's 32 Bit Switch\0"
|
||||
#define VerProduct "BPQMail"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HOSTMODES
|
||||
|
||||
#define Vers 1,1,8,1
|
||||
#define Verstring "1.1.8.1\0"
|
||||
//#define SPECIALVERSION "Test 3"
|
||||
#define VerComments "Host Modes Emulator for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 2009-2019 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "Host Modes Emulator for G8BPQ's 32 Bit Switch\0"
|
||||
#define VerProduct "BPQHostModes"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef UIUTIL
|
||||
|
||||
#define Vers 0,1,3,1
|
||||
#define Verstring "0.1.3.1\0"
|
||||
#define VerComments "Beacon Utility for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 2011-2019 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "Beacon Utility for G8BPQ Switch\0"
|
||||
#define VerProduct "BPQUIUtil"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef AUTH
|
||||
|
||||
#define Vers 0,1,0,0
|
||||
#define Verstring "0.1.0.0\0"
|
||||
#define VerComments "Password Generation Utility for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 2011-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "Password Generation Utility for G8BPQ Switch\0"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef APRS
|
||||
|
||||
#define Vers KVers
|
||||
#define Verstring KVerstring
|
||||
#define VerComments "APRS Client for G8BPQ Switch\0"
|
||||
#define VerCopyright "Copyright © 2012-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "APRS Client for G8BPQ Switch\0"
|
||||
#define VerProduct "BPQAPRS"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CHAT
|
||||
|
||||
#define Vers KVers
|
||||
#define Verstring KVerstring
|
||||
#define VerComments "Chat server for G8BPQ Packet Switch\0"
|
||||
#define VerCopyright "Copyright © 2009-2025 John Wiseman G8BPQ\0"
|
||||
#define VerDesc "Chat server for G8BPQ's 32 Bit Switch\0"
|
||||
#define VerProduct "BPQChat"
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,447 +0,0 @@
|
||||
//
|
||||
// Prototypes for BPQ32 Node Functions
|
||||
//
|
||||
|
||||
#define DllImport
|
||||
|
||||
#define EXCLUDEBITS
|
||||
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
|
||||
#include "compatbits.h"
|
||||
|
||||
#include "asmstrucs.h"
|
||||
|
||||
BOOL CheckExcludeList(UCHAR * Call);
|
||||
|
||||
Dll int ConvFromAX25(unsigned char * incall,unsigned char * outcall);
|
||||
Dll BOOL ConvToAX25(unsigned char * callsign, unsigned char * ax25call);
|
||||
DllExport BOOL ConvToAX25Ex(unsigned char * callsign, unsigned char * ax25call);
|
||||
int WritetoConsoleLocal(char * buff);
|
||||
VOID Consoleprintf(const char * format, ...);
|
||||
VOID FreeConfig();
|
||||
int GetListeningPortsPID(int Port);
|
||||
|
||||
void * InitializeExtDriver(PEXTPORTDATA PORTVEC);
|
||||
|
||||
VOID PutLengthinBuffer(PDATAMESSAGE buff, USHORT datalen); // Needed for arm5 portability
|
||||
int GetLengthfromBuffer(PDATAMESSAGE buff);
|
||||
int IntDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, uint64_t Mask, BOOL APRS, BOOL MCTL);
|
||||
int IntSetTraceOptionsEx(uint64_t mask, int mtxparam, int mcomparam, int monUIOnly);
|
||||
int CountBits64(uint64_t in);Buff() _GetBuff(__FILE__, __LINE__)
|
||||
#define ReleaseBuffer(s) _ReleaseBuffer(s, __FILE__, __LINE__)
|
||||
#define CheckGuardZone() _CheckGuardZone(__FILE__, __LINE__)
|
||||
|
||||
#define Q_REM(s) _Q_REM(s, __FILE__, __LINE__)
|
||||
#define Q_REM_NP(s) _Q_REM_NP(s, __FILE__, __LINE__)
|
||||
|
||||
#define C_Q_ADD(s, b) _C_Q_ADD(s, b, __FILE__, __LINE__)
|
||||
|
||||
void _CheckGuardZone(char * File, int Line);
|
||||
|
||||
VOID * _Q_REM(VOID **Q, char * File, int Line);
|
||||
VOID * _Q_REM_NP(VOID *Q, char * File, int Line);
|
||||
|
||||
int _C_Q_ADD(VOID *Q, VOID *BU
|
||||
|
||||
#define GetFF, char * File, int Line);
|
||||
|
||||
UINT _ReleaseBuffer(VOID *BUFF, char * File, int Line);
|
||||
|
||||
VOID * _GetBuff(char * File, int Line);
|
||||
int _C_Q_ADD(VOID *PQ, VOID *PBUFF, char * File, int Line);
|
||||
|
||||
int C_Q_COUNT(VOID *Q);
|
||||
|
||||
DllExport char * APIENTRY GetApplCall(int Appl);
|
||||
DllExport char * APIENTRY GetApplAlias(int Appl);
|
||||
DllExport int APIENTRY FindFreeStream();
|
||||
DllExport int APIENTRY DeallocateStream(int stream);
|
||||
DllExport int APIENTRY SessionState(int stream, int * state, int * change);
|
||||
DllExport int APIENTRY SetAppl(int stream, int flags, int mask);
|
||||
DllExport int APIENTRY GetMsg(int stream, char * msg, int * len, int * count );
|
||||
DllExport int APIENTRY GetConnectionInfo(int stream, char * callsign,
|
||||
int * port, int * sesstype, int * paclen,
|
||||
int * maxframe, int * l4window);
|
||||
|
||||
#define LIBCONFIG_STATIC
|
||||
#include "libconfig.h"
|
||||
|
||||
int GetIntValue(config_setting_t * group, char * name);
|
||||
BOOL GetStringValue(config_setting_t * group, char * name, char * value, int maxlen);
|
||||
VOID SaveIntValue(config_setting_t * group, char * name, int value);
|
||||
VOID SaveStringValue(config_setting_t * group, char * name, char * value);
|
||||
|
||||
int EncryptPass(char * Pass, char * Encrypt);
|
||||
VOID DecryptPass(char * Encrypt, unsigned char * Pass, unsigned int len);
|
||||
Dll VOID APIENTRY CreateOneTimePassword(char * Password, char * KeyPhrase, int TimeOffset);
|
||||
Dll BOOL APIENTRY CheckOneTimePassword(char * Password, char * KeyPhrase);
|
||||
|
||||
DllExport int APIENTRY TXCount(int stream);
|
||||
DllExport int APIENTRY RXCount(int stream);
|
||||
DllExport int APIENTRY MONCount(int stream);
|
||||
|
||||
VOID ReadNodes();
|
||||
int BPQTRACE(MESSAGE * Msg, BOOL APRS);
|
||||
|
||||
VOID CommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer);
|
||||
|
||||
VOID PostStateChange(TRANSPORTENTRY * Session);
|
||||
|
||||
VOID InnerCommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer);
|
||||
VOID DoTheCommand(TRANSPORTENTRY * Session);
|
||||
char * MOVEANDCHECK(TRANSPORTENTRY * Session, char * Bufferptr, char * Source, int Len);
|
||||
VOID DISPLAYCIRCUIT(TRANSPORTENTRY * L4, char * Buffer);
|
||||
char * strlop(const char * buf, char delim);
|
||||
BOOL CompareCalls(UCHAR * c1, UCHAR * c2);
|
||||
|
||||
VOID PostDataAvailable(TRANSPORTENTRY * Session);
|
||||
int WritetoConsoleLocal(char * buff);
|
||||
char * CHECKBUFFER(TRANSPORTENTRY * Session, char * Bufferptr);
|
||||
VOID CLOSECURRENTSESSION(TRANSPORTENTRY * Session);
|
||||
|
||||
VOID SendCommandReply(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer, int Len);
|
||||
|
||||
struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum);
|
||||
|
||||
int cCOUNT_AT_L2(struct _LINKTABLE * LINK);
|
||||
VOID SENDL4CONNECT(TRANSPORTENTRY * Session);
|
||||
|
||||
VOID CloseSessionPartner(TRANSPORTENTRY * Session);
|
||||
int COUNTNODES(struct ROUTE * ROUTE);
|
||||
int DecodeNodeName(char * NodeName, char * ptr);;
|
||||
VOID DISPLAYCIRCUIT(TRANSPORTENTRY * L4, char * Buffer);
|
||||
int cCOUNT_AT_L2(struct _LINKTABLE * LINK);
|
||||
void * zalloc(int len);
|
||||
BOOL FindDestination(UCHAR * Call, struct DEST_LIST ** REQDEST);
|
||||
|
||||
BOOL ProcessConfig();
|
||||
|
||||
VOID PUT_ON_PORT_Q(struct PORTCONTROL * PORT, MESSAGE * Buffer);
|
||||
VOID CLEAROUTLINK(struct _LINKTABLE * LINK);
|
||||
VOID TellINP3LinkGone(struct ROUTE * Route);
|
||||
VOID CLEARACTIVEROUTE(struct ROUTE * ROUTE, int Reason);
|
||||
|
||||
// Reason Equates
|
||||
|
||||
#define NORMALCLOSE 0
|
||||
#define RETRIEDOUT 1
|
||||
#define SETUPFAILED 2
|
||||
#define LINKLOST 3
|
||||
#define LINKSTUCK 4
|
||||
|
||||
int COUNT_AT_L2(struct _LINKTABLE * LINK);
|
||||
VOID SENDIDMSG();
|
||||
VOID SENDBTMSG();
|
||||
VOID INP3TIMER();
|
||||
VOID REMOVENODE(dest_list * DEST);
|
||||
BOOL ACTIVATE_DEST(struct DEST_LIST * DEST);
|
||||
VOID TellINP3LinkSetupFailed(struct ROUTE * Route);
|
||||
BOOL FindNeighbour(UCHAR * Call, int Port, struct ROUTE ** REQROUTE);
|
||||
VOID PROCROUTES(struct DEST_LIST * DEST, struct ROUTE * ROUTE, int Qual);
|
||||
BOOL L2SETUPCROSSLINK(PROUTE ROUTE);
|
||||
VOID REMOVENODE(dest_list * DEST);
|
||||
char * SetupNodeHeader(struct DATAMESSAGE * Buffer);
|
||||
VOID L4CONNECTFAILED(TRANSPORTENTRY * L4);
|
||||
int CountFramesQueuedOnSession(TRANSPORTENTRY * Session);
|
||||
VOID CLEARSESSIONENTRY(TRANSPORTENTRY * Session);
|
||||
VOID __cdecl Debugprintf(const char * format, ...);
|
||||
|
||||
int APIENTRY Restart();
|
||||
int APIENTRY Reboot();
|
||||
int APIENTRY Reconfig();
|
||||
Dll int APIENTRY SaveNodes ();
|
||||
|
||||
|
||||
struct SEM;
|
||||
|
||||
void GetSemaphore(struct SEM * Semaphore, int ID);
|
||||
void FreeSemaphore(struct SEM * Semaphore);
|
||||
|
||||
void MySetWindowText(HWND hWnd, char * Msg);
|
||||
|
||||
Dll int APIENTRY SessionControl(int stream, int command, int Mask);
|
||||
|
||||
HANDLE OpenCOMPort(VOID * pPort, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet, int Stopbits);
|
||||
int ReadCOMBlock(HANDLE fd, char * Block, int MaxLength);
|
||||
BOOL WriteCOMBlock(HANDLE fd, char * Block, int BytesToWrite);
|
||||
VOID CloseCOMPort(HANDLE fd);
|
||||
|
||||
VOID initUTF8();
|
||||
int Is8Bit(unsigned char *cpt, int len);
|
||||
int WebIsUTF8(unsigned char *ptr, int len);
|
||||
int IsUTF8(unsigned char *ptr, int len);
|
||||
int Convert437toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF);
|
||||
int Convert1251toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF);
|
||||
int Convert1252toUTF8(unsigned char * MsgPtr, int len, unsigned char * UTF);
|
||||
int TrytoGuessCode(unsigned char * Char, int Len);
|
||||
|
||||
|
||||
#define CMD_TO_APPL 1 // PASS COMMAND TO APPLICATION
|
||||
#define MSG_TO_USER 2 // SEND 'CONNECTED' TO USER
|
||||
#define MSG_TO_APPL 4 // SEND 'CONECTED' TO APPL
|
||||
#define CHECK_FOR_ESC 8 // Look for ^d (^D) to disconnect session)
|
||||
|
||||
#define UI 3
|
||||
#define SABM 0x2F
|
||||
#define DISC 0x43
|
||||
#define DM 0x0F
|
||||
#define UA 0x63
|
||||
#define FRMR 0x87
|
||||
#define RR 1
|
||||
#define RNR 5
|
||||
#define REJ 9
|
||||
|
||||
// V2.2 Types
|
||||
|
||||
#define SREJ 0x0D
|
||||
#define SABME 0x6F
|
||||
#define XID 0xAF
|
||||
#define TEST 0xE3
|
||||
|
||||
#define SUPPORT2point2 1
|
||||
|
||||
// XID Optional Functions
|
||||
|
||||
#define OPMustHave 0x02A080 // Sync TEST 16 bit FCS Extended Address
|
||||
#define OPSREJ 4
|
||||
#define OPSREJMult 0x200000
|
||||
#define OPREJ 2
|
||||
#define OPMod8 0x400
|
||||
#define OPMod128 0x800
|
||||
|
||||
#define BPQHOSTSTREAMS 64
|
||||
|
||||
extern TRANSPORTENTRY * L4TABLE;
|
||||
extern unsigned char NEXTID;
|
||||
extern int MAXCIRCUITS;
|
||||
extern int L4DEFAULTWINDOW;
|
||||
extern int L4T1;
|
||||
extern APPLCALLS APPLCALLTABLE[];
|
||||
extern char * APPLS;
|
||||
extern int NEEDMH;
|
||||
extern int RFOnly;
|
||||
|
||||
extern char SESSIONHDDR[];
|
||||
|
||||
extern UCHAR NEXTID;
|
||||
|
||||
extern struct ROUTE * NEIGHBOURS;
|
||||
extern int MAXNEIGHBOURS;
|
||||
|
||||
extern struct ROUTE * NEIGHBOURS;
|
||||
extern int ROUTE_LEN;
|
||||
extern int MAXNEIGHBOURS;
|
||||
|
||||
extern struct DEST_LIST * DESTS; // NODE LIST
|
||||
extern struct DEST_LIST * ENDDESTLIST;
|
||||
extern int DEST_LIST_LEN;
|
||||
extern int MAXDESTS; // MAX NODES IN SYSTEM
|
||||
|
||||
extern struct _LINKTABLE * LINKS;
|
||||
extern int LINK_TABLE_LEN;
|
||||
extern int MAXLINKS;
|
||||
|
||||
|
||||
|
||||
extern char MYCALL[]; // DB 7 DUP (0) ; NODE CALLSIGN (BIT SHIFTED)
|
||||
extern char MYALIASTEXT[]; // {" " ; NODE ALIAS (KEEP TOGETHER)
|
||||
|
||||
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)
|
||||
|
||||
extern VOID * FREE_Q;
|
||||
|
||||
extern struct PORTCONTROL * PORTTABLE;
|
||||
extern int NUMBEROFPORTS;
|
||||
|
||||
|
||||
extern int OBSINIT; // INITIAL OBSOLESCENCE VALUE
|
||||
extern int OBSMIN; // MINIMUM TO BROADCAST
|
||||
extern int L3INTERVAL; // "NODES" INTERVAL IN MINS
|
||||
extern int IDINTERVAL; // "ID" BROADCAST INTERVAL
|
||||
extern int BTINTERVAL; // "BT" BROADCAST INTERVAL
|
||||
extern int MINQUAL; // MIN QUALITY FOR AUTOUPDATES
|
||||
extern int HIDENODES; // N * COMMAND SWITCH
|
||||
extern int BBSQUAL; // QUALITY OF BBS RELATIVE TO NODE
|
||||
|
||||
extern int NUMBEROFBUFFERS; // PACKET BUFFERS
|
||||
extern int PACLEN; //MAX PACKET SIZE
|
||||
|
||||
// L2 SYSTEM TIMER RUNS AT 3 HZ
|
||||
|
||||
extern int T3; // LINK VALIDATION TIMER (3 MINS) (+ a bit to reduce RR collisions)
|
||||
|
||||
extern int L2KILLTIME; // IDLE LINK TIMER (16 MINS)
|
||||
extern int L3LIVES; // MAX L3 HOPS
|
||||
extern int L4N2; // LEVEL 4 RETRY COUNT
|
||||
extern int L4LIMIT; // IDLE SESSION LIMIT - 15 MINS
|
||||
extern int L4DELAY; // L4 DELAYED ACK TIMER
|
||||
|
||||
extern int BBS; // INCLUDE BBS SUPPORT
|
||||
extern int NODE; // INCLUDE SWITCH SUPPORT
|
||||
|
||||
extern int FULL_CTEXT; // CTEXT ON ALL CONNECTS IF NZ
|
||||
|
||||
|
||||
// Although externally streams are numbered 1 to 64, internally offsets are 0 - 63
|
||||
|
||||
extern BPQVECSTRUC DUMMYVEC; // Needed to force correct order of following
|
||||
|
||||
extern BPQVECSTRUC BPQHOSTVECTOR[BPQHOSTSTREAMS + 5];
|
||||
|
||||
extern int NODEORDER;
|
||||
extern UCHAR LINKEDFLAG;
|
||||
|
||||
extern UCHAR UNPROTOCALL[80];
|
||||
|
||||
|
||||
extern char * INFOMSG;
|
||||
|
||||
extern char * CTEXTMSG;
|
||||
extern int CTEXTLEN;
|
||||
|
||||
extern UCHAR MYALIAS[7]; // ALIAS IN AX25 FORM
|
||||
extern UCHAR BBSALIAS[7];
|
||||
|
||||
extern VOID * TRACE_Q; // TRANSMITTED FRAMES TO BE TRACED
|
||||
|
||||
extern char HEADERCHAR; // CHAR FOR _NODE HEADER MSGS
|
||||
|
||||
extern int AUTOSAVE; // AUTO SAVE NODES ON EXIT FLAG
|
||||
extern int L4APPL; // Application for BBSCALL/ALIAS connects
|
||||
extern int CFLAG; // C =HOST Command
|
||||
|
||||
extern VOID * IDMSG_Q; // ID/BEACONS WAITING TO BE SENT
|
||||
|
||||
extern struct DATAMESSAGE BTHDDR;
|
||||
extern struct _MESSAGE IDHDDR;
|
||||
|
||||
extern VOID * IDMSG;
|
||||
|
||||
extern int L3TIMER; // TIMER FOR 'NODES' MESSAGE
|
||||
extern int IDTIMER; // TIMER FOR ID MESSAGE
|
||||
extern int BTTIMER; // TIMER FOR BT MESSAGE
|
||||
|
||||
extern int STATSTIME;
|
||||
|
||||
|
||||
extern BOOL IPRequired;
|
||||
extern int MaxHops;
|
||||
extern int MAXRTT;
|
||||
extern USHORT CWTABLE[];
|
||||
extern TRANSPORTENTRY * L4TABLE;
|
||||
extern UCHAR ROUTEQUAL;
|
||||
extern UINT BPQMsg;
|
||||
extern UCHAR ExcludeList[];
|
||||
|
||||
|
||||
extern APPLCALLS APPLCALLTABLE[];
|
||||
|
||||
extern char VersionStringWithBuild[];
|
||||
extern char VersionString[];
|
||||
|
||||
extern int MAXHEARDENTRIES;
|
||||
extern int MHLEN;
|
||||
|
||||
extern int APPL1;
|
||||
extern int PASSCMD;
|
||||
extern int NUMBEROFCOMMANDS;
|
||||
|
||||
extern char * ConfigBuffer;
|
||||
|
||||
extern char * WL2KReportLine[];
|
||||
|
||||
extern struct CMDX COMMANDS[];
|
||||
|
||||
extern int QCOUNT, MAXBUFFS, MAXCIRCUITS, L4DEFAULTWINDOW, L4T1, CMDXLEN;
|
||||
extern char CMDALIAS[ALIASLEN][NumberofAppls];
|
||||
|
||||
extern int SEMGETS;
|
||||
extern int SEMRELEASES;
|
||||
extern int SEMCLASHES;
|
||||
extern int MINBUFFCOUNT;
|
||||
|
||||
extern UCHAR BPQDirectory[];
|
||||
extern UCHAR BPQProgramDirectory[];
|
||||
|
||||
extern UCHAR WINMOR[];
|
||||
extern UCHAR PACTORCALL[];
|
||||
|
||||
extern UCHAR MCOM;
|
||||
extern UCHAR MUIONLY;
|
||||
extern UCHAR MTX;
|
||||
extern uint64_t MMASK;
|
||||
|
||||
extern UCHAR NODECALL[]; // NODES in ax.25
|
||||
|
||||
extern int L4CONNECTSOUT;
|
||||
extern int L4CONNECTSIN;
|
||||
extern int L4FRAMESTX;
|
||||
extern int L4FRAMESRX;
|
||||
extern int L4FRAMESRETRIED;
|
||||
extern int OLDFRAMES;
|
||||
extern int L3FRAMES;
|
||||
|
||||
extern char * PortConfig[];
|
||||
extern struct SEM Semaphore;
|
||||
extern UCHAR AuthorisedProgram; // Local Variable. Set if Program is on secure list
|
||||
|
||||
extern int REALTIMETICKS;
|
||||
|
||||
extern time_t CurrentSecs;
|
||||
extern time_t lastSlowSecs;
|
||||
extern time_t lastSaveSecs;
|
||||
|
||||
// SNMP Variables
|
||||
|
||||
extern int InOctets[64];
|
||||
extern int OutOctets[64];
|
||||
|
||||
extern BOOL CloseAllNeeded;
|
||||
extern int CloseOnError;
|
||||
|
||||
extern char * PortConfig[70];
|
||||
extern struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
|
||||
|
||||
#define MaxBPQPortNo 63 // Port 64 reserved for BBS Mon
|
||||
#define MAXBPQPORTS 63
|
||||
|
||||
// IP, APRS use port ocnfig slots above the real port range
|
||||
|
||||
#define IPConfigSlot MaxBPQPortNo + 1
|
||||
#define PortMapConfigSlot MaxBPQPortNo + 2
|
||||
#define APRSConfigSlot MaxBPQPortNo + 3
|
||||
|
||||
|
||||
extern char * UIUIDigi[MaxBPQPortNo + 1];
|
||||
extern char UIUIDEST[MaxBPQPortNo + 1][11]; // Dest for Beacons
|
||||
extern UCHAR FN[MaxBPQPortNo + 1][256]; // Filename
|
||||
extern int Interval[MaxBPQPortNo + 1]; // Beacon Interval (Mins)
|
||||
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);
|
||||
@ -1,43 +0,0 @@
|
||||
# LinBPQ Makefile
|
||||
|
||||
# To exclude i2c support run make noi2c
|
||||
|
||||
OBJS = pngwtran.o pngrtran.o pngset.o pngrio.o pngwio.o pngtrans.o pngrutil.o pngwutil.o\
|
||||
pngread.o pngwrite.o png.o pngerror.o pngget.o pngmem.o APRSIconData.o AISCommon.o\
|
||||
upnp.o APRSStdPages.o HSMODEM.o WinRPR.o KISSHF.o TNCEmulators.o bpqhdlc.o SerialPort.o\
|
||||
adif.o WebMail.o utf8Routines.o VARA.o LzFind.o Alloc.o LzmaDec.o LzmaEnc.o LzmaLib.o \
|
||||
Multicast.o ARDOP.o IPCode.o FLDigi.o linether.o CMSAuth.o APRSCode.o BPQtoAGW.o KAMPactor.o\
|
||||
AEAPactor.o HALDriver.o MULTIPSK.o BBSHTMLConfig.o ChatHTMLConfig.o BBSUtilities.o bpqaxip.o\
|
||||
BPQINP3.o BPQNRR.o cMain.o Cmd.o CommonCode.o HTMLCommonCode.o compatbits.o config.o datadefs.o \
|
||||
FBBRoutines.o HFCommon.o Housekeeping.o HTTPcode.o kiss.o L2Code.o L3Code.o L4Code.o lzhuf32.o \
|
||||
MailCommands.o MailDataDefs.o LinBPQ.o MailRouting.o MailTCP.o MBLRoutines.o md5.o Moncode.o \
|
||||
NNTPRoutines.o RigControl.o TelnetV6.o WINMOR.o TNCCode.o UZ7HODrv.o WPRoutines.o \
|
||||
SCSTrackeMulti.o SCSPactor.o SCSTracker.o HanksRT.o UIRoutines.o AGWAPI.o AGWMoncode.o \
|
||||
DRATS.o FreeDATA.o base64.o Events.o nodeapi.o mailapi.o mqtt.o
|
||||
|
||||
# Configuration:
|
||||
|
||||
CC = gcc
|
||||
|
||||
all: CFLAGS = -DLINBPQ -MMD -g -fcommon
|
||||
all: LDFLAGS = -l:libpaho-mqtt3a.a -l:libjansson.a
|
||||
all: linbpq
|
||||
|
||||
|
||||
nomqtt: CFLAGS = -DLINBPQ -MMD -fcommon -g -DNOMQTT
|
||||
nomqtt: linbpq
|
||||
|
||||
noi2c: CFLAGS = -DLINBPQ -MMD -DNOI2C -g -fcommon
|
||||
noi2c: linbpq
|
||||
|
||||
|
||||
linbpq: $(OBJS)
|
||||
gcc $(OBJS) -Xlinker -Map=output.map -l:libminiupnpc.a -lrt -lm -lz $(LDFLAGS) -lpthread -lconfig -lpcap -o linbpq
|
||||
sudo setcap "CAP_NET_ADMIN=ep CAP_NET_RAW=ep CAP_NET_BIND_SERVICE=ep" linbpq
|
||||
|
||||
-include *.d
|
||||
|
||||
clean :
|
||||
rm *.d
|
||||
rm linbpq $(OBJS)
|
||||
|
||||
@ -1,858 +0,0 @@
|
||||
// basic JASON API to BPQ Node
|
||||
|
||||
// Authentication is via Telnet USER records.
|
||||
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
#include "cheaders.h"
|
||||
#include <stdlib.h>
|
||||
#include "tncinfo.h"
|
||||
#include "asmstrucs.h"
|
||||
#include "kiss.h"
|
||||
|
||||
// Constants
|
||||
#define TOKEN_SIZE 32 // Length of the authentication token
|
||||
#define TOKEN_EXPIRATION 7200 // Token expiration time in seconds (2 hours)
|
||||
|
||||
// Token data structure
|
||||
typedef struct Token {
|
||||
char token[TOKEN_SIZE + 1];
|
||||
time_t expiration_time;
|
||||
struct Token* next;
|
||||
} Token;
|
||||
|
||||
typedef struct API
|
||||
{
|
||||
char *URL;
|
||||
int URLLen;
|
||||
int (* APIRoutine)(char * response, char * token, char * param);
|
||||
int Auth;
|
||||
} API;
|
||||
|
||||
// Auth defines
|
||||
|
||||
#define AuthNone 0
|
||||
#define AuthUser 1
|
||||
#define Auth BBSUser 2
|
||||
#define AuthSysop 4
|
||||
|
||||
// Function prototypes
|
||||
void handle_request(SOCKET client_socket, char * request, char * response);
|
||||
int verify_token(const char* token);
|
||||
void remove_expired_tokens();
|
||||
char* fetch_data(const char* endpoint);
|
||||
int request_token(char * response);
|
||||
int send_http_response(char * response, const char* msg);
|
||||
int create_json_response(char * response, char* access_token, int expires_in, char* scope);
|
||||
void add_token_to_list(Token* token);
|
||||
|
||||
Token* find_token(const char* token);
|
||||
Token* generate_token();
|
||||
|
||||
int sendPortList(char * response, char * token, char * Rest);
|
||||
int sendNodeList(char * response, char * token, char * Rest);
|
||||
int sendUserList(char * response, char * token, char * Rest);
|
||||
int sendInfo(char * response, char * token, char * Rest);
|
||||
int sendLinks(char * response, char * token, char * Rest);
|
||||
int sendPortMHList(char * response, char * token, char * Rest);
|
||||
int sendWhatsPacState(char * response, char * token, char * param);
|
||||
int sendWhatsPacConfig(char * response, char * token, char * param);
|
||||
|
||||
void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT);
|
||||
DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
|
||||
|
||||
// Token list
|
||||
Token* token_list = NULL;
|
||||
|
||||
|
||||
struct API APIList[] =
|
||||
{
|
||||
"/api/ports", 10, sendPortList, 0,
|
||||
"/api/nodes", 10, sendNodeList, 0,
|
||||
"/api/info", 9, sendInfo, 0,
|
||||
"/api/links", 10, sendLinks, 0,
|
||||
"/api/users", 10, sendUserList, 0,
|
||||
"/api/mheard", 11, sendPortMHList, 0,
|
||||
"/api/v1/config", 14, sendWhatsPacConfig, 0,
|
||||
"/api/v1/state", 13, sendWhatsPacState, 0
|
||||
};
|
||||
|
||||
int APICount = sizeof(APIList) / sizeof(struct API);
|
||||
|
||||
extern int HTTPPort;
|
||||
|
||||
|
||||
int xx()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
// Remove expired tokens
|
||||
remove_expired_tokens();
|
||||
|
||||
// Handle the client request
|
||||
// handle_request();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE)
|
||||
{
|
||||
const char * auth_header = "Authorization: Bearer ";
|
||||
char * token_begin = strstr(request, auth_header);
|
||||
char token[TOKEN_SIZE + 1]= "";
|
||||
int Flags = 0, n;
|
||||
|
||||
// Node Flags isn't currently used
|
||||
|
||||
char * Tok;
|
||||
char * param;
|
||||
|
||||
if (token_begin)
|
||||
{
|
||||
// Using Auth Header
|
||||
|
||||
// Extract the token from the request (assuming it's present in the request headers)
|
||||
|
||||
if (token_begin == NULL)
|
||||
{
|
||||
Debugprintf("Invalid request: No authentication token provided.\n");
|
||||
return send_http_response(response, "403 (Forbidden)");
|
||||
}
|
||||
|
||||
token_begin += strlen(auth_header); // Move to the beginning of the token
|
||||
strncpy(token, token_begin, TOKEN_SIZE);
|
||||
token[TOKEN_SIZE] = '\0'; // Null-terminate the token
|
||||
|
||||
param = strlop(URL, '?');
|
||||
}
|
||||
else
|
||||
{
|
||||
// There may be a token as first param, but if auth not needed may be misisng
|
||||
|
||||
Tok = strlop(URL, '?');
|
||||
param = strlop(Tok, '&');
|
||||
|
||||
if (Tok && strlen(Tok) == TOKEN_SIZE)
|
||||
{
|
||||
// assume auth token
|
||||
|
||||
strcpy(token, Tok);
|
||||
}
|
||||
else param = Tok;
|
||||
}
|
||||
|
||||
remove_expired_tokens(); // Tidy up
|
||||
|
||||
// Check if the request is for token generation
|
||||
|
||||
if (strcmp(Method, "OPTIONS") == 0)
|
||||
{
|
||||
// CORS Request
|
||||
|
||||
char Resp[] =
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Access-Control-Allow-Origin: *\r\n"
|
||||
"Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n"
|
||||
"Access-Control-Allow-Headers: authorization";
|
||||
|
||||
return send_http_response(response, Resp);
|
||||
}
|
||||
|
||||
if (strcmp(Method, "GET") != 0)
|
||||
return send_http_response(response, "403 (Bad Method)");
|
||||
|
||||
if (_stricmp(URL, "/api/request_token") == 0)
|
||||
return request_token(response);
|
||||
|
||||
/*
|
||||
if (token[0] == 0)
|
||||
{
|
||||
// Extract the token from the request (assuming it's present in the request headers)
|
||||
if (token_begin == NULL)
|
||||
{
|
||||
Debugprintf("Invalid request: No authentication token provided.\n");
|
||||
return send_http_response(response, "403 (Forbidden)");
|
||||
}
|
||||
token_begin += strlen(auth_header); // Move to the beginning of the token
|
||||
strncpy(token, token_begin, TOKEN_SIZE);
|
||||
token[TOKEN_SIZE] = '\0'; // Null-terminate the token
|
||||
}
|
||||
|
||||
// Verify the token
|
||||
if (!verify_token(token))
|
||||
{
|
||||
Debugprintf("Invalid authentication token.\n");
|
||||
return send_http_response(response, "401 Unauthorized");
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// Determine the requested API endpoint
|
||||
|
||||
for (n = 0; n < APICount; n++)
|
||||
{
|
||||
struct API * APIEntry;
|
||||
char * rest;
|
||||
|
||||
APIEntry = &APIList[n];
|
||||
|
||||
if (_memicmp(URL, APIEntry->URL, APIEntry->URLLen) == 0)
|
||||
{
|
||||
rest = &request[4 + APIEntry->URLLen]; // Anything following?
|
||||
|
||||
if (rest[0] == ' ' || rest[0] == '/' || rest[0] == '?')
|
||||
return APIEntry->APIRoutine(response, token, rest);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return send_http_response(response, "401 Invalid API Call");
|
||||
}
|
||||
|
||||
int request_token(char * response)
|
||||
{
|
||||
Token * token = generate_token();
|
||||
char scope[] = "create";
|
||||
|
||||
printf("Token generated: %s\n", token->token);
|
||||
|
||||
sprintf(response, "{\"access_token\":\"%s\", \"expires_at\":%ld,\"scope\":\"create\"}\r\n",
|
||||
token->token, token->expiration_time);
|
||||
|
||||
return strlen(response);
|
||||
}
|
||||
|
||||
Token * generate_token()
|
||||
{
|
||||
// Generate a random authentication token
|
||||
|
||||
int i;
|
||||
|
||||
Token * token = malloc(sizeof(Token));
|
||||
for (i = 0; i < TOKEN_SIZE; i++)
|
||||
{
|
||||
token->token[i] = 'A' + rand() % 26; // Random uppercase alphabet character
|
||||
}
|
||||
token->token[TOKEN_SIZE] = '\0'; // Null-terminate the token
|
||||
token->expiration_time = time(NULL) + TOKEN_EXPIRATION; // Set token expiration time
|
||||
add_token_to_list(token);
|
||||
return token;
|
||||
}
|
||||
|
||||
// Function to add the token to the token_list
|
||||
|
||||
void add_token_to_list(Token* token)
|
||||
{
|
||||
if (token_list == NULL)
|
||||
{
|
||||
token_list = token;
|
||||
token->next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Token* current = token_list;
|
||||
|
||||
while (current->next != NULL)
|
||||
current = current->next;
|
||||
|
||||
current->next = token;
|
||||
token->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int verify_token(const char* token)
|
||||
{
|
||||
// Find the token in the token list
|
||||
Token * existing_token = find_token(token);
|
||||
|
||||
if (existing_token != NULL)
|
||||
{
|
||||
// Check if the token has expired
|
||||
time_t current_time = time(NULL);
|
||||
if (current_time > existing_token->expiration_time)
|
||||
{
|
||||
// Token has expired, remove it from the token list
|
||||
remove_expired_tokens();
|
||||
return 0;
|
||||
}
|
||||
// Token is valid
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Token doesn't exist in the token list
|
||||
return 0;
|
||||
}
|
||||
|
||||
void remove_expired_tokens()
|
||||
{
|
||||
time_t current_time = time(NULL);
|
||||
Token* current_token = token_list;
|
||||
Token* prev_token = NULL;
|
||||
Token* next_token;
|
||||
|
||||
while (current_token != NULL)
|
||||
{
|
||||
if (current_time > current_token->expiration_time)
|
||||
{
|
||||
// Token has expired, remove it from the token list
|
||||
if (prev_token == NULL)
|
||||
{
|
||||
token_list = current_token->next;
|
||||
} else {
|
||||
prev_token->next = current_token->next;
|
||||
}
|
||||
next_token = current_token->next;
|
||||
free(current_token);
|
||||
current_token = next_token;
|
||||
} else {
|
||||
prev_token = current_token;
|
||||
current_token = current_token->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Token * find_token(const char* token)
|
||||
{
|
||||
Token* current_token = token_list;
|
||||
while (current_token != NULL)
|
||||
{
|
||||
if (strcmp(current_token->token, token) == 0)
|
||||
{
|
||||
return current_token;
|
||||
}
|
||||
current_token = current_token->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int send_http_response(char * response, const char* msg)
|
||||
{
|
||||
return sprintf(response, "HTTP/1.1 %s\r\nContent-Length: 0\r\nConnection: close\r\n\r\n", msg);
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"access_token":"MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3",
|
||||
"expires_in":3600,
|
||||
"scope":"create"
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
{"ports":[
|
||||
{"ID":"My Port", "Driver":"KISS", "Number":2, "State":"Active"),
|
||||
{ ...},
|
||||
{...}
|
||||
]}
|
||||
*/
|
||||
|
||||
extern int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific MPSK or UZ7HO host
|
||||
|
||||
int sendPortList(char * response, char * token, char * param)
|
||||
{
|
||||
char * Array = 0;
|
||||
int ArrayLen = 0;
|
||||
int ArrayPtr = 0;
|
||||
|
||||
struct _EXTPORTDATA * ExtPort;
|
||||
struct PORTCONTROL * Port;
|
||||
struct PORTCONTROL * SAVEPORT;
|
||||
int PortNo;
|
||||
|
||||
int count;
|
||||
char DLL[20];
|
||||
char Status[32]="Unknown";
|
||||
char ID[33];
|
||||
char * ptr;
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "{\"ports\":[\r\n");
|
||||
|
||||
for (count = 1; count <= NUMBEROFPORTS; count++)
|
||||
{
|
||||
Port = GetPortTableEntryFromSlot(count);
|
||||
ExtPort = (struct _EXTPORTDATA *)Port;
|
||||
PortNo = Port->PORTNUMBER;
|
||||
|
||||
if (Port->PORTTYPE == 0x10)
|
||||
{
|
||||
strcpy(DLL, ExtPort->PORT_DLL_NAME);
|
||||
strlop(DLL, '.');
|
||||
strlop(DLL, ' ');
|
||||
}
|
||||
else if (Port->PORTTYPE == 0)
|
||||
strcpy(DLL, "ASYNC");
|
||||
|
||||
else if (Port->PORTTYPE == 22)
|
||||
strcpy(DLL, "I2C");
|
||||
|
||||
else if (Port->PORTTYPE == 14)
|
||||
strcpy(DLL, "INTERNAL");
|
||||
|
||||
else if (Port->PORTTYPE > 0 && Port->PORTTYPE < 14)
|
||||
strcpy(DLL, "HDLC");
|
||||
|
||||
|
||||
if (Port->PortStopped)
|
||||
{
|
||||
strcpy(Status, "Stopped");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Port->PORTTYPE == 0)
|
||||
{
|
||||
struct KISSINFO * KISS = (struct KISSINFO *)Port;
|
||||
NPASYINFO KPort;
|
||||
|
||||
SAVEPORT = Port;
|
||||
|
||||
if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS)
|
||||
{
|
||||
// Not first port on device
|
||||
|
||||
Port = (struct PORTCONTROL *)KISS->FIRSTPORT;
|
||||
KPort = KISSInfo[PortNo];
|
||||
}
|
||||
|
||||
KPort = KISSInfo[PortNo];
|
||||
|
||||
if (KPort)
|
||||
{
|
||||
// KISS like - see if connected
|
||||
|
||||
if (Port->PORTIPADDR.s_addr || Port->KISSSLAVE)
|
||||
{
|
||||
// KISS over UDP or TCP
|
||||
|
||||
if (Port->KISSTCP)
|
||||
{
|
||||
if (KPort->Connected)
|
||||
strcpy(Status, "Open ");
|
||||
else
|
||||
if (Port->KISSSLAVE)
|
||||
strcpy(Status, "Listen");
|
||||
else
|
||||
strcpy(Status, "Closed");
|
||||
}
|
||||
else
|
||||
strcpy(Status, "UDP");
|
||||
}
|
||||
else
|
||||
if (KPort->idComDev) // Serial port Open
|
||||
strcpy(Status, "Open ");
|
||||
else
|
||||
strcpy(Status, "Closed");
|
||||
|
||||
|
||||
Port = SAVEPORT;
|
||||
}
|
||||
}
|
||||
|
||||
if (Port->PORTTYPE == 14) // Loopback
|
||||
strcpy(Status, "Open ");
|
||||
|
||||
else if (Port->PORTTYPE == 16) // External
|
||||
{
|
||||
if (Port->PROTOCOL == 10) // 'HF' Port
|
||||
{
|
||||
struct TNCINFO * TNC = TNCInfo[PortNo];
|
||||
|
||||
if (TNC)
|
||||
{
|
||||
switch (TNC->Hardware) // Hardware Type
|
||||
{
|
||||
case H_SCS:
|
||||
case H_KAM:
|
||||
case H_AEA:
|
||||
case H_HAL:
|
||||
case H_TRK:
|
||||
case H_SERIAL:
|
||||
|
||||
// Serial
|
||||
|
||||
if (TNC->hDevice)
|
||||
strcpy(Status, "Open ");
|
||||
else
|
||||
strcpy(Status, "Closed");
|
||||
|
||||
break;
|
||||
|
||||
case H_UZ7HO:
|
||||
|
||||
if (TNCInfo[MasterPort[PortNo]]->CONNECTED)
|
||||
strcpy(Status, "Open ");
|
||||
else
|
||||
strcpy(Status, "Closed");
|
||||
|
||||
break;
|
||||
|
||||
case H_WINMOR:
|
||||
case H_V4:
|
||||
|
||||
case H_MPSK:
|
||||
case H_FLDIGI:
|
||||
case H_UIARQ:
|
||||
case H_ARDOP:
|
||||
case H_VARA:
|
||||
case H_KISSHF:
|
||||
case H_WINRPR:
|
||||
case H_FREEDATA:
|
||||
|
||||
// TCP
|
||||
|
||||
if (TNC->CONNECTED)
|
||||
{
|
||||
if (TNC->Streams[0].Attached)
|
||||
strcpy(Status, "In Use");
|
||||
else
|
||||
strcpy(Status, "Open ");
|
||||
}
|
||||
else
|
||||
strcpy(Status, "Closed");
|
||||
|
||||
break;
|
||||
|
||||
case H_TELNET:
|
||||
|
||||
strcpy(Status, "Open ");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// External but not HF - AXIP, BPQETHER VKISS, ??
|
||||
|
||||
struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)Port;
|
||||
|
||||
strcpy(Status, "Open ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strlop(Status, ' ');
|
||||
strcpy(ID, Port->PORTDESCRIPTION);
|
||||
ptr = &ID[29];
|
||||
while (*(ptr) == ' ')
|
||||
{
|
||||
*(ptr--) = 0;
|
||||
}
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], " {\"ID\":\"%s\", \"Driver\":\"%s\", \"Number\":%d,\"State\":\"%s\"},\r\n",
|
||||
ID, DLL, Port->PORTNUMBER, Status);
|
||||
}
|
||||
|
||||
ArrayPtr -= 3; // remove trailing comma
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}\r\n");
|
||||
|
||||
return ArrayPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
{"Nodes":[
|
||||
{"Call":"xx", "Alias":"xx", "Nbour1 ":"xx", "Quality":192),
|
||||
{ ...},
|
||||
{...}
|
||||
]}
|
||||
*/
|
||||
|
||||
extern int MaxNodes;
|
||||
extern struct DEST_LIST * DESTS; // NODE LIST
|
||||
extern int DEST_LIST_LEN;
|
||||
|
||||
|
||||
int sendNodeList(char * response, char * token, char * param)
|
||||
{
|
||||
int ArrayPtr = 0;
|
||||
|
||||
int count, len, i;
|
||||
char Normcall[10], Portcall[10];
|
||||
char Alias[7];
|
||||
struct DEST_LIST * Dests = DESTS ;
|
||||
// struct ROUTE * Routes;
|
||||
|
||||
Dests = DESTS;
|
||||
MaxNodes = MAXDESTS;
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "{\"nodes\":[\r\n");
|
||||
|
||||
Dests-=1;
|
||||
|
||||
for (count = 0; count < MaxNodes; count++)
|
||||
{
|
||||
Dests+=1;
|
||||
|
||||
if (Dests->DEST_CALL[0] == 0)
|
||||
continue;
|
||||
|
||||
len = ConvFromAX25(Dests->DEST_CALL, Normcall);
|
||||
Normcall[len] = 0;
|
||||
|
||||
memcpy(Alias, Dests->DEST_ALIAS, 6);
|
||||
|
||||
Alias[6]=0;
|
||||
|
||||
for (i=0;i<6;i++)
|
||||
{
|
||||
if (Alias[i] == ' ')
|
||||
Alias[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Alias\":\"%s\", \"Routes\":[", Normcall, Alias);
|
||||
|
||||
|
||||
// Add an array with up to 6 objects (3 NR + 3 INP3 Neighbours
|
||||
|
||||
if (Dests->NRROUTE[0].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[0].ROUT_NEIGHBOUR->INP3Node == 0)
|
||||
{
|
||||
len = ConvFromAX25(Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
|
||||
Portcall[len] = 0;
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "{\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
|
||||
Portcall, Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[0].ROUT_QUALITY);
|
||||
|
||||
|
||||
// if (Dests->NRROUTE[0].ROUT_OBSCOUNT > 127)
|
||||
// {
|
||||
// len=sprintf(&line[cursor],"! ");
|
||||
// cursor+=len;
|
||||
// }
|
||||
|
||||
|
||||
if (Dests->NRROUTE[1].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[1].ROUT_NEIGHBOUR->INP3Node == 0)
|
||||
{
|
||||
len=ConvFromAX25(Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
|
||||
Portcall[len]=0;
|
||||
|
||||
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
|
||||
Portcall, Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[1].ROUT_QUALITY);
|
||||
//if (Dests->NRROUTE[1].ROUT_OBSCOUNT > 127)
|
||||
//{
|
||||
//len=sprintf(&line[cursor],"! ");
|
||||
//cursor+=len;
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
if (Dests->NRROUTE[2].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[2].ROUT_NEIGHBOUR->INP3Node == 0)
|
||||
{
|
||||
len=ConvFromAX25(Dests->NRROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
|
||||
Portcall[len]=0;
|
||||
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\":\"%s\", \"Port\":%d, \"Quality\":%d},",
|
||||
Portcall, Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_PORT, Dests->NRROUTE[1].ROUT_QUALITY);
|
||||
|
||||
//if (Dests->NRROUTE[2].ROUT_OBSCOUNT > 127)
|
||||
//{
|
||||
//len=sprintf(&line[cursor],"! ");
|
||||
//cursor+=len;
|
||||
|
||||
}
|
||||
ArrayPtr -= 1; // remove comma
|
||||
}
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "]},\r\n");
|
||||
}
|
||||
|
||||
ArrayPtr -= 3; // remove comma
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}");
|
||||
|
||||
return ArrayPtr;
|
||||
}
|
||||
|
||||
|
||||
int sendUserList(char * response, char * token, char * param)
|
||||
{
|
||||
int ArrayPtr = 0;
|
||||
int n = MAXCIRCUITS;
|
||||
TRANSPORTENTRY * L4 = L4TABLE;
|
||||
// TRANSPORTENTRY * Partner;
|
||||
int MaxLinks = MAXLINKS;
|
||||
char State[12] = "", Type[12] = "Uplink";
|
||||
char LHS[50] = "", MID[10] = "", RHS[50] = "";
|
||||
// char Line[100];
|
||||
char Normcall[10];
|
||||
int len;
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "{\"users\":[\r\n");
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (L4->L4USER[0])
|
||||
{
|
||||
RHS[0] = MID[0] = 0;
|
||||
|
||||
len = ConvFromAX25(L4->L4USER, Normcall);
|
||||
Normcall[len] = 0;
|
||||
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], " {\"Call\": \"%s\"},\r\n", Normcall);
|
||||
L4++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ArrayPtr == 12) //empty list
|
||||
{
|
||||
ArrayPtr -=2;
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "]}\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayPtr -= 3; // remove trailing comma
|
||||
ArrayPtr += sprintf(&response[ArrayPtr], "\r\n]}\r\n");
|
||||
}
|
||||
return ArrayPtr;
|
||||
}
|
||||
|
||||
extern char MYALIASLOPPED[];
|
||||
extern char TextVerstring[];
|
||||
extern char LOCATOR[];
|
||||
|
||||
int sendInfo(char * response, char * token, char * param)
|
||||
{
|
||||
char call[10];
|
||||
|
||||
memcpy(call, MYNODECALL, 10);
|
||||
strlop(call, ' ');
|
||||
|
||||
sprintf(response, "{\"info\":{\"NodeCall\":\"%s\", \"Alias\":\"%s\", \"Locator\":\"%s\", \"Version\":\"%s\"}}\r\n",
|
||||
call, MYALIASLOPPED, LOCATOR, TextVerstring);
|
||||
|
||||
return strlen(response);
|
||||
}
|
||||
|
||||
int sendLinks(char * response, char * token, char * param)
|
||||
{
|
||||
struct _LINKTABLE * Links = LINKS;
|
||||
int MaxLinks = MAXLINKS;
|
||||
int count;
|
||||
char Normcall1[10];
|
||||
char Normcall2[10];
|
||||
char State[12] = "", Type[12] = "Uplink";
|
||||
int axState;
|
||||
int cctType;
|
||||
int ReplyLen = 0;
|
||||
ReplyLen += sprintf(&response[ReplyLen],"{\"links\":[\r\n");
|
||||
|
||||
for (count=0; count<MaxLinks; count++)
|
||||
{
|
||||
if (Links->LINKCALL[0] != 0)
|
||||
{
|
||||
int len = ConvFromAX25(Links->LINKCALL, Normcall1);
|
||||
Normcall1[len] = 0;
|
||||
|
||||
len = ConvFromAX25(Links->OURCALL, Normcall2);
|
||||
Normcall2[len] = 0;
|
||||
|
||||
|
||||
axState = Links->L2STATE;
|
||||
|
||||
if (axState == 2)
|
||||
strcpy(State, "Connecting");
|
||||
else if (axState == 3)
|
||||
strcpy(State, "FRMR");
|
||||
else if (axState == 4)
|
||||
strcpy(State, "Closing");
|
||||
else if (axState == 5)
|
||||
strcpy(State, "Active");
|
||||
else if (axState == 6)
|
||||
strcpy(State, "REJ Sent");
|
||||
|
||||
cctType = Links->LINKTYPE;
|
||||
|
||||
if (cctType == 1)
|
||||
strcpy(Type, "Uplink");
|
||||
else if (cctType == 2)
|
||||
strcpy(Type, "Downlink");
|
||||
else if (cctType == 3)
|
||||
strcpy(Type, "Node-Node");
|
||||
|
||||
|
||||
|
||||
ReplyLen += sprintf(&response[ReplyLen], "{\"farCall\": \"%s\",\"ourCall\": \"%s\", \"port\": \"%d\", \"state\": \"%s\", \"linkType\": \"%s\", \"ax25Version\": \"%d\"},\r\n",
|
||||
Normcall1, Normcall2, Links->LINKPORT->PORTNUMBER,
|
||||
State, Type, 2 - Links->VER1FLAG );
|
||||
Links+=1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ReplyLen < 13)
|
||||
ReplyLen -= 2; // no links
|
||||
else
|
||||
ReplyLen -= 3; // remove trailing comma
|
||||
|
||||
ReplyLen+= sprintf(&response[ReplyLen], "\r\n]}\r\n");
|
||||
|
||||
return ReplyLen;
|
||||
}
|
||||
|
||||
int sendPortMHList(char * response, char * token, char * param)
|
||||
{
|
||||
struct PORTCONTROL * PORTVEC ;
|
||||
int n;
|
||||
int port = 0;
|
||||
|
||||
if (param[0] = '?' || param[0] == '/')
|
||||
port = atoi(¶m[1]);
|
||||
|
||||
PORTVEC = GetPortTableEntryFromPortNum(port);
|
||||
response[0] = 0;
|
||||
|
||||
if (PORTVEC == 0)
|
||||
return send_http_response(response, "401 Invalid API Call");
|
||||
|
||||
n = sprintf(response,"{\"mheard\":[\r\n");
|
||||
|
||||
BuildPortMH(&response[n], PORTVEC );
|
||||
|
||||
if (response[n] == 0) // No entries
|
||||
{
|
||||
response[strlen(response) - 2] = '\0'; // remove \r\n
|
||||
strcat(response, "]}\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
response[strlen(response)-3 ] = '\0'; // remove ,\r\n
|
||||
strcat(response, "\r\n]}\r\n");
|
||||
// printf("MH for port %d:\r\n%s\r\n", PORTVEC->PORTNUMBER, response);
|
||||
}
|
||||
return strlen(response);
|
||||
}
|
||||
|
||||
// WhatsPac configuration interface
|
||||
// WhatsPac also uses Paula's Remote Host Protocol (RHP). This is in a separate module
|
||||
|
||||
extern int WhatsPacConfigured;
|
||||
|
||||
|
||||
int sendWhatsPacState(char * response, char * token, char * param)
|
||||
{
|
||||
if (WhatsPacConfigured)
|
||||
sprintf(response, "{\"configured\": true}\r\n");
|
||||
else
|
||||
sprintf(response, "{\"configured\": false}\r\n");
|
||||
|
||||
return strlen(response);
|
||||
}
|
||||
|
||||
|
||||
int sendWhatsPacConfig(char * response, char * token, char * param)
|
||||
{
|
||||
char Template[] =
|
||||
"{\"MODE\": 0,"
|
||||
"\"RHPPORT\": \"%d\","
|
||||
"\"AGWPORT\": \"7000\","
|
||||
"\"INTERFACES\": [{\"INTERFACE\": 1,\"PROTOCOL\": \"KISS\",\"TYPE\": \"TCP\",\"IOADDR\": \"127.0.0.1\",\"INTNUM\": 8100}],"
|
||||
"\"PORTS\": [{\"PORT\": 1,\"ID\": \"RHPPORT\", \"INTERFACENUM\": 1}]}";
|
||||
|
||||
sprintf(response, Template, HTTPPort);
|
||||
|
||||
return strlen(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in new issue