master
John Wiseman 10 months ago
parent 83bc496f33
commit 74c5d023fd

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

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

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

@ -1249,7 +1249,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix problem with L4 frames being delivered out of sequence (60)
// Add Compression of Netrom connections (62)
// Improve handling of Locked Routes (62)
// Add L4 RESET (Paula G8PZT's extension to NETROM)
// Fix problem using SENDRAW from BPQMail (63)
// Fix compatibility with latest ardopcf (64)
#define CKernel
#include "Versions.h"

17
Cmd.c

@ -3988,7 +3988,7 @@ VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc
if (ret & 0x8000) // Disconnecting
{
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use\r");
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use (Disconnecting)\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
@ -4039,14 +4039,25 @@ VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc
if (EXTPORT->ATTACHEDSESSIONS[sess] || PORT->PortSuspended)
if (EXTPORT->ATTACHEDSESSIONS[sess])
{
// In use
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use\r");
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port in use (Session Attached\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
if (PORT->PortSuspended)
{
// In use
Bufferptr = Cmdprintf(Session, Bufferptr, "Error - Port Suspended\r");
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
return;
}
// GET CIRCUIT TABLE ENTRY FOR OTHER END OF LINK
NewSess = SetupNewSession(Session, Bufferptr);

@ -17,8 +17,6 @@ You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/
// General C Routines common to bpq32 and linbpq. Mainly moved from BPQ32.c
#pragma data_seg("_BPQDATA")
@ -914,7 +912,7 @@ BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BO
sprintf(Msg, "%d SCANSTOP", TNC->Port);
Rig_Command( (TRANSPORTENTRY *) -1, Msg);
Rig_Command((TRANSPORTENTRY *) -1, Msg);
UpdateMH(TNC, Call, '+', 'I');
}
@ -1623,7 +1621,7 @@ DllExport int APIENTRY SendRaw(int port, char * msg, int len)
MSG->LENGTH = len + MSGHDDRLEN;
if (PORT->PROTOCOL == 10 && PORT->TNC && PORT->TNC->Hardware != H_KISSHF) // PACTOR/WINMOR Style
if (PORT->PROTOCOL == 10 && PORT->HWType != H_KISSHF) // PACTOR/WINMOR Style
{
// Pactor Style. Probably will only be used for Tracker unless we do APRS over V4 or WINMOR
@ -2687,7 +2685,7 @@ int DoRoutes()
{
if (Routes->NEIGHBOUR_CALL[0] != 0)
{
// Dont save routes from config file here or they are diccicult to get rid of
// Dont save routes from config file here or they are difficult to get rid of
if (Routes->NEIGHBOUR_FLAG & LOCKEDBYCONFIG)
{

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

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

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

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

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

@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/
//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
@ -2414,7 +2413,10 @@ doHeader:
if (Session == 0)
Session = &Dummy;
Session->TNC = LOCAL; // TNC is only used on Web Terminal Sessions so can reuse as LOCAL flag
if (LOCAL)
Session->TNC = (struct TNCINFO *)(uintptr_t)1; // TNC is only used on Web Terminal Sessions so can reuse as LOCAL flag
else
Session->TNC = 0;
WriteFile(hPipe, Session, sizeof (struct HTTPConnectionInfo), &InputLen, NULL);
WriteFile(hPipe, MsgPtr, MsgLen, &InputLen, NULL);
@ -4328,7 +4330,7 @@ int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char
{
int ReplyLen = 0;
char * input = strstr(MsgPtr, "\r\n\r\n"); // End of headers
char * user, * password, * Key;
char * user, * password;
struct HTTPConnectionInfo * NewSession;
int i;
struct UserRec * USER;

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

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

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

@ -1802,6 +1802,25 @@ VOID SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
C_Q_ADD(&LINK->TX_Q, L3MSG);
}
VOID SendL4RESET(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG)
{
// Paula's extension
L3MSG->L4FLAGS = L4RESET;
L3SWAPADDRESSES(L3MSG);
L3MSG->L3TTL = L3LIVES;
L3MSG->LENGTH = (int)(&L3MSG->L4DATA[0] - (UCHAR *)L3MSG);
C_Q_ADD(&LINK->TX_Q, L3MSG);
}
VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG,
TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE)
{
@ -1946,7 +1965,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
{
// INTERNODE LINK
TRANSPORTENTRY * L4;
TRANSPORTENTRY * L4 = 0;
struct DEST_LIST * DEST;
int Opcode;
char Nodename[20];
@ -1993,22 +2012,48 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
CONNECTREQUEST(LINK, L3MSG, ApplMask, ApplCall);
return;
}
// OTHERS NEED A SESSION
L4 = &L4TABLE[L3MSG->L4INDEX];
// OTHERS NEED A SESSION
if (L4->CIRCUITID!= L3MSG->L4ID)
if (Opcode == L4RESET)
{
// Paula's extension - other end dosn't know about session so disconnect
// A reset has our far index and id, not our index and id so have to search table for L4 entry
int n = MAXCIRCUITS;
L4 = L4TABLE;
while (n--)
{
if (L4->L4USER[0] && L4->FARID == L3MSG->L4ID && L4->FARINDEX == L3MSG->L4INDEX)
{
// Check L3 source call to be sure (should that be L4 source call??
L3MSG->L3SRCE[6] &= 0xfe; // mask end of call
if (memcmp(L3MSG->L3SRCE, L4->L4TARGET.DEST->DEST_CALL, 7) == 0)
{
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
}
ReleaseBuffer(L3MSG);
return;
}
L4++;
}
ReleaseBuffer(L3MSG);
return;
}
if ((L4->L4CIRCUITTYPE & SESSION) == 0)
{
// Not an L4 Session - must be an old connection
if (L3MSG->L4INDEX < MAXCIRCUITS)
L4 = &L4TABLE[L3MSG->L4INDEX];
ReleaseBuffer(L3MSG);
// If wrong ID or not an L4 session we must have restarted or cleared session
if (L4 == 0 || L4->CIRCUITID != L3MSG->L4ID || (L4->L4CIRCUITTYPE & SESSION) == 0)
{
SendL4RESET(LINK, L3MSG); // Paula's extension
return;
}
@ -2019,9 +2064,9 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
case L4CACK:
// CONNECT ACK
DEST = L4->L4TARGET.DEST;
// EXTRACT EXTENDED PARAMS IF PRESENT
if (L3MSG->LENGTH > MSGHDDRLEN + 22) // Standard Msg
@ -2032,7 +2077,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
L3MSG->L4DATA[1] &= 0x7f;
}
DEST->DEST_STATE &= 0x80;
DEST->DEST_STATE &= 0x80;
DEST->DEST_STATE |= (L3MSG->L4DATA[1] - L3MSG->L3TTL) + 0x41; // Hops to dest + x40
}
@ -2098,13 +2143,13 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
// DISCONNECT REQUEST
L3MSG->L4INDEX = L4->FARINDEX;
L3MSG->L4ID = L4->FARID;
L3MSG->L4FLAGS = L4DACK;
L3MSG->L4INDEX = L4->FARINDEX;
L3MSG->L4ID = L4->FARID;
L3SWAPADDRESSES(L3MSG); // EXCHANGE SOURCE AND DEST
L3MSG->L3TTL = L3LIVES;
L3MSG->L4FLAGS = L4DACK;
L3SWAPADDRESSES(L3MSG); // EXCHANGE SOURCE AND DEST
L3MSG->L3TTL = L3LIVES;
TNC = LINK->LINKPORT->TNC;
@ -2113,11 +2158,11 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
else
C_Q_ADD(&LINK->TX_Q, L3MSG);
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return;
CloseSessionPartner(L4); // SEND CLOSE TO PARTNER (IF PRESENT)
return;
case L4DACK:
CLEARSESSIONENTRY(L4);
ReleaseBuffer(L3MSG);
return;
@ -2134,16 +2179,16 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
// Randomly drop packets
/*
/*
Debugprintf("L4 Test Received packet %d ", L3MSG->L4TXNO);
if ((rand() % 7) > 5)
{
Debugprintf("L4 Test Drop packet %d ", L3MSG->L4TXNO);
ReleaseBuffer(L3MSG);
return;
Debugprintf("L4 Test Drop packet %d ", L3MSG->L4TXNO);
ReleaseBuffer(L3MSG);
return;
}
*/
*/
ACKFRAMES(L3MSG, L4, L3MSG->L4RXNO);
@ -2175,7 +2220,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
ReleaseBuffer(L3MSG);
return;
}
if (FramesMissing > 0)
{
// EXPECTED FRAME HAS BEEN MISSED - ASK FOR IT AGAIN,
@ -2183,7 +2228,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
L4->NAKBITS |= L4NAK; // SET NAK REQUIRED
SENDL4IACK(L4); // SEND DATA ACK COMMAND TO ACK OUTSTANDING FRAMES
// SEE IF WE ALREADY HAVE A COPY OF THIS ONE
Saved = L4->L4RESEQ_Q;
@ -2196,7 +2241,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask,
if (Saved->L4TXNO == L3MSG->L4TXNO)
{
// ALREADY HAVE A COPY - DISCARD IT
Debugprintf("L4 Already have seq %d - discarding", L3MSG->L4TXNO);
ReleaseBuffer(L3MSG);
return;
@ -2222,7 +2267,7 @@ L4INFO_OK:
L4->NAKBITS &= ~L4NAK; // CLEAR MESSAGE LOST STATE
L4->RXSEQNO++;
// REMOVE HEADERS, AND QUEUE INFO
L3MSG->LENGTH -= 20; // L3/L4 Header
@ -2293,14 +2338,14 @@ L4INFO_OK:
else
{
// Just inflate this bit
Len = doinflate(L3MSG->L4DATA, Buffer, L3MSG->LENGTH - MSGHDDRLEN - 1, 8192, &outLen);
}
free(L4->unCompress);
L4->unCompress = 0;
L4->unCompressLen = 0;
sendLen = outLen;
sendptr = Buffer;
@ -2322,9 +2367,9 @@ L4INFO_OK:
while (outLen > 0)
{
sendLen = outLen;
if (sendLen > 236)
sendLen = 236;
sendLen = 236;
Msg = GetBuff();
@ -2339,7 +2384,7 @@ L4INFO_OK:
IFRM150(L4, Msg); // CHECK IF SETTING UP AND PASS ON
}
outLen -= sendLen;
sendptr += sendLen;
}
@ -2367,7 +2412,7 @@ checkReseq:
*Prev = Saved->Next; // CHAIN NEXT IN CHAIN TO PREVIOUS
OLDFRAMES++; // COUNT FOR STATS
L3MSG = Saved;
Debugprintf("L4 Processing Saved Message %d Address %x", L4->RXSEQNO, L3MSG);
goto L4INFO_OK;
@ -2386,7 +2431,9 @@ checkReseq:
ACKFRAMES(L3MSG, L4, L3MSG->L4RXNO);
REFRESHROUTE(L4);
// Drop Through
ReleaseBuffer(L3MSG);
return;
}
// Unrecognised - Ignore
@ -2437,9 +2484,9 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR)
if (L4->RTT_TIMER)
{
// FRAME BEING TIMED HAS BEEN ACKED - UPDATE DEST RTT TIMER
DEST = L4->L4TARGET.DEST;
RTT = GetTickCount() - L4->RTT_TIMER;
if (RTT < 180) // Sanity Check
@ -2470,7 +2517,7 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR)
if ((L4->FLAGS & DISCPENDING) && L4->L4TX_Q == 0)
{
// All Acked and DISC Pending, so send it
SENDL4DISC(L4);
return;
}
@ -2479,7 +2526,7 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR)
// SEE IF CHOKE SET
L4->FLAGS &= ~L4BUSY;
if (L3MSG->L4FLAGS & L4BUSY)
{
L4->FLAGS |= L3MSG->L4FLAGS & L4BUSY; // Get Busy flag from message
@ -2493,10 +2540,10 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR)
// RETRANSMIT REQUESTED MESSAGE - WILL BE FIRST ON HOLD QUEUE
Msg = L4->L4HOLD_Q;
if (Msg == 0)
return;
Copy = GetBuff();
if (Copy == 0)
@ -2536,7 +2583,7 @@ VOID SENDL4IACK(TRANSPORTENTRY * Session)
MSG->L4TXNO = 0;
MSG->L4RXNO = Session->RXSEQNO;
Session->L4LASTACKED = Session->RXSEQNO; // SAVE LAST NUMBER ACKED
@ -2544,7 +2591,7 @@ VOID SENDL4IACK(TRANSPORTENTRY * Session)
MSG->LENGTH = MSGHDDRLEN + 22;
// Debugprintf("Sending L4 IACK %d %x", MSG->L4RXNO, MSG->L4FLAGS);
// Debugprintf("Sending L4 IACK %d %x", MSG->L4RXNO, MSG->L4FLAGS);
C_Q_ADD(&DEST->DEST_Q, (UINT *)MSG);

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

@ -124,7 +124,7 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\CKernel;..\CommonSource;..\CInclude"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;LINBPQ;_USE_32BIT_TIME_T"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;LINBPQ;_USE_32BIT_TIME_T;NOMQTT"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
@ -552,6 +552,10 @@
RelativePath=".\pngwutil.c"
>
</File>
<File
RelativePath=".\RHP.c"
>
</File>
<File
RelativePath="..\CommonSource\RigControl.c"
>

@ -728,6 +728,10 @@ char * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen)
return Output + sprintf((char *)Output, " <DISC ACK>");
case L4RESET:
return Output + sprintf((char *)Output, " <RESET>");
case L4INFO:
{
char Infofield[257];

1500
RHP.c

File diff suppressed because it is too large Load Diff

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

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

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

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

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

@ -0,0 +1,111 @@
#ifndef TELNETSERVER
#define TELNETSERVER
#ifndef LINBPQ
//#include "resource.h"
#endif
#define WSA_ACCEPT WM_USER + 1
#define WSA_CONNECT WM_USER + 2
#define WSA_DATA WM_USER + 3
#define InputBufferLen 100000
struct ConnectionInfo
{
int Number; // Number of record - for Connections display
SOCKET socket;
union
{
struct sockaddr_in6 sin6;
struct sockaddr_in sin;
};
BOOL SocketActive;
int BPQStream;
char Callsign[10];
BOOL GotHeader;
unsigned char InputBuffer[InputBufferLen];
int InputLen;
struct UserRec * UserPointer;
int Retries;
int LoginState; // 1 = user ok, 2 = password ok
BOOL DoingCommand; // Processing Telnet Command
BOOL DoEcho; // Telnet Echo option accepted
BOOL CMSSession; // Set if connect to CMS
BOOL FBBMode; // Pure TCP for FBB forwarding
BOOL NeedLF; // FBB mode, but with cr > crlf outbound
BOOL RelayMode; // Pure TCP for RMS Relay Emulation forwarding
BOOL DRATSMode; // HTML Terminal Emulator
BOOL SyncMode; // RMS Relay Sync
BOOL HTTPMode; // HTTP Server
BOOL APIMode; // REST API Server
BOOL TriMode; // Trimode emulation
BOOL TriModeConnected; // Set when remote session is connected - now send data to DataSock
SOCKET TriModeDataSock; // Data Socket
BOOL Auth; // Set if User is flagged as a Secure User
BOOL BPQTermMode; // Set if connected to BPQTermTCP
BOOL ClientSession; // Set if acting as a client (ie Linux HOST Mode)
BOOL MonitorNODES; // Monitor Control Flags
unsigned long long MMASK;
BOOL MCOM;
BOOL MonitorColour;
BOOL MTX;
BOOL MUIOnly;
int CMSIndex; // Pointer to CMS used for this connect
UCHAR * FromHostBuffer; // Somewhere to store msg from CMS - it sends the whole message at once
int FromHostBufferSize;
int FromHostBuffPutptr;
int FromHostBuffGetptr;
struct TNCINFO * TNC; // Used to pass TCP struct to http code (for passwood list)
time_t ConnectTime;
BOOL UTF8; // Set if BPQTerminal in UTF8 Mode
BOOL RelaySession; // Set if connection to RMS Relay
BOOL LogonSent; // To ignore second callsign: prompt
char Signon[100]; // User/Pass/Appl for Outgoing Connects
BOOL Keepalive; // For HOST (esp CCC) Keepalives
time_t LastSendTime;
BOOL NoCallsign; // Don't Send Callsign to host if no Signon
UCHAR * ResendBuffer; // Used if send() returns EWOULDBLOCK
int ResendLen; // Len to resend
struct ADIF * ADIF; // ADIF Logging info
int WebSocks;
char WebURL[32]; // URL for WebSocket Connection
int WebSecure; // Set if secure session
};
#define Disconnect(stream) SessionControl(stream,2,0)
#define Connect(stream) SessionControl(stream,1,0)
#define SE 240 // End of subnegotiation parameters
#define NOP 241 //No operation
#define xDM 242 //Data mark Indicates the position of a Synch event within the data stream. This should always be accompanied by a TCP urgent notification.
#define BRK 243 //Break Indicates that the "break" or "attention" key was hi.
#define IPx 244 //Suspend Interrupt or abort the process to which the NVT is connected.
#define AO 245 //Abort output Allows the current process to run to completion but does not send its output to the user.
#define AYT 246 //Are you there Send back to the NVT some visible evidence that the AYT was received.
#define EC 247 //Erase character The receiver should delete the last preceding undeleted character from the data stream.
#define EL 248 //Erase line Delete characters from the data stream back to but not including the previous CRLF.
#define GA 249 //Go ahead Under certain circumstances used to tell the other end that it can transmit.
#define SB 250 //Subnegotiation Subnegotiation of the indicated option follows.
#define WILL 251 //will Indicates the desire to begin performing, or confirmation that you are now performing, the indicated option.
#define WONT 252 //wont Indicates the refusal to perform, or continue performing, the indicated option.
#define DOx 253 //do Indicates the request that the other party perform, or confirmation that you are expecting the other party to perform, the indicated option.
#define DONT 254 //dont Indicates the demand that the other party stop performing, or confirmation that you are no longer expecting the other party to perform, the indicated option.
#define IAC 255
#define suppressgoahead 3 //858
#define xStatus 5 //859
#define echo 1 //857
#define timingmark 6 //860
#define terminaltype 24 //1091
#define windowsize 31 //1073
#define terminalspeed 32 //1079
#define remoteflowcontrol 33 //1372
#define linemode 34 //1184
#define environmentvariables 36 //1408
#endif

@ -0,0 +1,963 @@
//
// Common definitons for Pactor-like Modules
#include "kernelresource.h"
#include "rigcontrol.h"
#define MAXBLOCK 4096
#define MAXFREQS 20 // RigControl freqs to scan
extern char HFCTEXT[81];
extern int HFCTEXTLEN;
extern HANDLE hInstance;
extern HMENU hMainFrameMenu;
extern HMENU hWndMenu;
/*
struct WL2KInfo
{
struct WL2KInfo * Next;
char * Host;
short WL2KPort;
char RMSCall[10];
char BaseCall[10];
char GridSquare[7];
char Times[80];
char ServiceCode[17];
BOOL UseRigCtrlFreqs;
char WL2KFreq[12];
char WL2KMode; // WL2K reporting mode
char WL2KModeChar; // W or N
BOOL DontReportNarrowOnWideFreqs;
// char NARROWMODE;
// char WIDEMODE; // Mode numbers to report to WL2K
// struct WL2KInfo WL2KInfoList[MAXFREQS]; // Freqs for sending to WL2K
int Freq;
char Bandwidth;
// char * TimeList; // eg 06-10,12-15
int mode; // see below (an integer)
int baud; // see below (an integer)
int power; // actual power if known, default to 100 for HF, 30 for VHF/UHF (an integer)
int height; // antenna height in feet if known, default to 25
int gain; // antenna gain if known, default to 0
int direction; // primary antenna direction in degrees if known, use 000 for omni (an integer)
BOOL RPonPTC; // Set if scanning for Robust Packet on a PTC
};
*/
#pragma pack(1)
// AGWPE Header Structure
struct AGWHEADER
{
UCHAR Port;
UCHAR filler1[3];
char DataKind;
UCHAR filler2;
unsigned char PID;
UCHAR filler3;
unsigned char callfrom[10];
unsigned char callto[10];
int DataLength;
int reserved;
};
#pragma pack()
// Telnet Server User Record
struct UserRec
{
char * Callsign;
char * UserName;
char * Password;
char * Appl; // Autoconnect APPL
BOOL Secure; // Authorised User
};
struct LOCALNET
{
struct LOCALNET * Next;
uint32_t Network;
uint32_t Mask;
};
#define MaxCMS 10 // Number of addresses we can keep - currently 4 are used.
struct TCPINFO
{
int NumberofUsers;
struct UserRec ** UserRecPtr;
int CurrentConnections;
struct UserRec RelayUser;
int CurrentSockets;
int TCPPort;
int FBBPort[100];
int RelayPort;
int HTTPPort;
int APIPort;
int TriModePort;
int SyncPort;
int SNMPPort;
int DRATSPort;
int CMDPort[33];
char RELAYHOST[64];
char CMSServer[64];
BOOL FallbacktoRelay; // Use Relsy if can't connect to CMS
BOOL IPV4; // Allow Connect using IPV4
BOOL IPV6; // Allow Connect using IPV6
BOOL CMS; // Allow Connect to CMS
BOOL CMSOK; // Internet link is ok.
BOOL UseCachedCMSAddrs;
struct in_addr CMSAddr[MaxCMS];
BOOL CMSFailed[MaxCMS]; // Set if connect to CMS failed.
char * CMSName[MaxCMS]; // Reverse DNS Name of Server
int NumberofCMSAddrs;
int NextCMSAddr; // Round Robin Pointer
int CheckCMSTimer; // CMS Poll Timer
char SecureCMSPassword[80]; // For Secure CMS Signin
char GatewayCall[10]; // Call for CMS access
char GatewayLoc[10]; // Loc - Needed to report Hybrid Mode
int ReportHybrid; // Report as Hybrod Station
char * HybridServiceCode;
char * HybridFrequencies;
char * HybridCoLocatedRMS;
BOOL DisconnectOnClose;
char PasswordMsg[100];
char cfgHOSTPROMPT[100];
char cfgCTEXT[300];
char cfgLOCALECHO[100];
int MaxSessions;
char LoginMsg[100];
char RelayAPPL[20];
char SyncAPPL[20];
SOCKET TCPSock;
SOCKET FBBsock[100];
SOCKET Relaysock;
SOCKET HTTPsock;
SOCKET APIsock;
SOCKET TriModeSock;
SOCKET TriModeDataSock;
SOCKET Syncsock;
SOCKET DRATSsock;
SOCKET SNMPsock;
struct ConnectionInfo * TriModeControlSession;
SOCKET sock6;
SOCKET FBBsock6[100];
SOCKET Relaysock6;
SOCKET HTTPsock6;
SOCKET APIsock6;
SOCKET Syncsock6;
SOCKET DRATSsock6;
fd_set ListenSet;
SOCKET maxsock;
HMENU hActionMenu;
HMENU hLogMenu;
HMENU hDisMenu; // Disconnect Menu Handle
HWND hCMSWnd;
int SecureTelnet;
int ReportRelayTraffic; // Send WL2K Reports for Relay Traffic
char * WebTermCSS; // css override for web terminal
struct LOCALNET * LocalNets;
};
struct STREAMINFO
{
// TRANSPORTENTRY * AttachedSession;
void * PACTORtoBPQ_Q; // Frames for BPQ
void * BPQtoPACTOR_Q; // Frames for PACTOR
int FramesOutstanding; // Frames Queued - used for flow control
int FramesQueued; // Frames Queued - used for flow control
BOOL InternalCmd; // Last Command was generated internally
int IntCmdDelay; // To limit internal commands
BOOL CheckingCall; // Set on PTC if waiting for I response after a Connect RXed
BOOL Attached; // Set what attached to a BPQ32 stream
BOOL Connected; // When set, all data is passed as data instead of commands
BOOL Connecting; // Set when Outward Connect in progress
BOOL Disconnecting; // Set when disconnect in progress
// Used when appplication disconnects the bpq session, and
// prevents new attaches while a dirty disconnect is in progress
int DisconnectingTimeout; // A hard disconnect occurs if this expires before the disconnect complete
int ReportDISC; // Need to report an incoming DISC to kernel
BOOL DiscWhenAllSent; // Close session when all msgs have been sent to node
BOOL ARQENDSent; // Set when V4 ARQEND Sent
int DEDStream; // Stream number for DED interface (same as index except for pactor)
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 BytesAcked;
int bytesRXed;
int PacketsSent;
int BytesResent;
int BytesOutstanding; // For Packet Channels
UCHAR PTCStatus0; // Status Bytes
UCHAR PTCStatus1; // Status Bytes
UCHAR PTCStatus2; // Status Bytes
UCHAR PTCStatus3; // Status Bytes
char * CmdSet; // A series of commands to send to the TNC
char * CmdSave; // Base address for free
struct ConnectionInfo * ConnectionInfo; // TCP Server Connection Info
int TimeInRX; // Too long in send mode timer
int NeedDisc; // Timer to send DISC if appl not available
BOOL NoCMSFallback; // Dont use relay if CMS not available
struct ARQINFO * ARQInfo; // FLDIGI/FLARQ Stream Mode Specific Data
HWND xIDC_MYCALL;
HWND xIDC_DESTCALL;
HWND xIDC_STATUS;
HWND xIDC_SEND;
HWND xIDC_RXED;
HWND xIDC_RESENT;
HWND xIDC_ACKED;
HWND xIDC_DIRN;
int RelaySyncStream;
int VaraACMode;
};
typedef struct AGWINFO
{
// Fields for AGW Session based Ports (eg UZ7HO Modem)
struct AGWHEADER TXHeader;
struct AGWHEADER RXHeader;
int MaxSessions;
int ConnTimeOut;
int PollDelay;
time_t LastParamTime;
#ifdef WIN32
// For selecting UZ7HO Mode and Freq
COMBOBOXINFO cbinfo; // UZ7HO Modem Combo Box info
HWND hFreq; // UZ7HO Frequency Box
HWND hSpin; // UZ7HO Spin Button
#endif
int isQTSM; // Flag to Identify QtSM
int CenterFreq;
int Modem; // Modem number in list
char ModemName[20];
unsigned char Version[4];
unsigned char fx25Flags;
unsigned char il2pFlags;
unsigned char il2pcrc;
} *PAGWINFO;
typedef struct ARQINFO
{
// Fields for FLDIGI/FLARQ Ports
// Max window is 64, though often will use less
char OurStream;
char FarStream;
PMSGWITHLEN TXHOLDQ[64]; // Frames waiting ACK
PMSGWITHLEN RXHOLDQ[64]; // Frames waiting missing frames.
int TXWindow;
int RXWindow;
int MaxBlock; // Max sending block size
int TXSeq;
int TXLastACK; // Last frame ACK'ed
int RXHighest;
int RXNext;
int RXNoGaps;
int Retries;
int NoAckRetries; // Status received but no data acked
int ARQTimer;
int ARQState;
#define ARQ_ACTIVE 1 // Have a session of some type
int ARQTimerState;
#define ARQ_CONNECTING 1
#define ARQ_CONNECTACK 2
#define ARQ_DISC 3
#define ARQ_WAITACK 4
#define ARQ_WAITDATA 5 // Waiting for more data before polling
char LastMsg[80]; // Last message sent that expects an ack
int LastLen;
char TXMsg[80]; // Message to aend after TXDELAY
int TXLen;
int TurnroundTimer; // RX to TX delay.
int TXDelay;
} *ARQINFO;
typedef struct FLINFO
{
// Fields for MPSK Session Ports )
BOOL TX; // Set when FLDigi is transmitting
char DefaultMode[64]; // Mode to return to after session
int DefaultFreq; // Freq to return to after session
BOOL Beacon; // Use ALE Beacons
char LastXML[128]; // Last XML Request Sent
int XMLControl; // Controlls polling FLDigi by XML
int CmdControl; // Controlls polling FLDigi by KISS Command
BOOL FLARQ; // Connection from FLARQ
BOOL Busy;
BOOL CONOK; // Allow incoming connects
BOOL KISSMODE; // Using KISS instead of socket interface
BOOL RAW; // Raw (ARQ Socket or KISS RAW, depening on above)
int CenterFreq;
char CurrentMode[20]; // Mode to return to after session
int Responding; // If FLDigi is responding to conmands
BOOL MCASTMODE; // If port is in MCAST RX MOde
} *FLINFO;
typedef struct MPSKINFO
{
// Fields for MPSK Session Ports )
int ConnTimeOut;
BOOL TX; // Set when Multipsk is transmitting
char DefaultMode[20]; // Mode to return to after session
BOOL Beacon; // Use ALE Beacons
int MaxSessions;
} *MPSKINFO;
struct FreeDataINFO
{
int startingTNC;
int TNCRunning;
int Conecting;
int Connected;
char ourCall[10];
char toCall[10];
char farCall[10]; // TNC Call
char useBaseCall; // Use base call (without ssid) for TNC Call
char * Capture; // Capture Device Name
char * Playback; // Playback Device Name
char * hamlibHost;
int hamlibPort;
unsigned char toSendData[8192]; // Buffer data from node for more efficiency
int toSendCount;
int toSendTimeout;
unsigned char toSendMsg[256]; // Buffer data from node for more efficiency
int toSendMsgCount;
int toSendMsgTimeout;
char * RXDir; // Directory for Received Files
int CONOK; // Virtual Lisren Flag
int Chat; // In Chat Mode
char ChatCall[10];
int needPoll; // Set if get data needed
int arqstate; // 1 = Disc / 2 - connecting 3 - connected
int TuningRange; // Must be 50, 100, 150, 200, 250
int LimitBandWidth;
int TXLevel;
int Explorer; // Enable reporting to Freedata Explorer
char SSIDList[256];
char * SSIDS[16];
};
struct sixPackInfo;
typedef struct TNCINFO
{
HWND hDlg; // Status Window Handle
int (FAR * WebWindowProc)(struct TNCINFO * TNC, char * Buff, BOOL LOCAL); // Routine to build web status window
int WebWinX;
int WebWinY; // Size of window
char * WebBuffer; // Buffer for logs
int RigControlRow; // Rig Control Line in Dialog
struct _EXTPORTDATA * PortRecord; // BPQ32 port record for this port
struct RIGINFO * RIG; // Pointer to Rig Control RIG record for RX or Both
struct RIGINFO * TXRIG; // Pointer to Rig Control RIG record for TX
char * InitScript; // Initialisation Commands
int InitScriptLen; // Length
time_t SessionTimeLimit; // Optional limit to total session time
time_t DefaultSessionTimeLimit; // Configured value
time_t AttachTimeLimit; // to trap port left attached for a long time without other activity
time_t AttachTime;
int Hardware; // Hardware Type
#define H_WINMOR 1
#define H_SCS 2
#define H_KAM 3
#define H_AEA 4
#define H_HAL 5
#define H_TELNET 6
#define H_TRK 7
#define H_TRKM 7
#define H_V4 8
#define H_UZ7HO 9
#define H_MPSK 10
#define H_FLDIGI 11
#define H_UIARQ 12
#define H_ARDOP 13
#define H_VARA 14
#define H_SERIAL 15
#define H_KISSHF 16
#define H_WINRPR 17
#define H_HSMODEM 18
#define H_FREEDATA 19
#define H_SIXPACK 20
int Port; // BPQ Port Number
struct RIGINFO DummyRig; // Used if not using Rigcontrol
BOOL Minimized; // Start Minimized flag
void * WINMORtoBPQ_Q; // Frames for BPQ, indexed by BPQ Port
void * BPQtoWINMOR_Q; // Frames for WINMOR. indexed by WINMOR port. Only used it TCP session is blocked
SOCKET TCPSock; // Control Socket
SOCKET TCPDataSock; // Data Socket
SOCKET PacketSock; // Packet Over TCP (ARDOP)
char * WINMORSignon; // Pointer to message for secure signin
char * HostName; // WINMOR Host - may be dotted decimal or DNS Name
int TCPPort; //
int PacketPort; // Packet Over TCP (ARDOP)
char * ApplCmd; // Application to connect to on incoming connect (null = leave at command handler)
BOOL SwallowSignon; // Set to suppress *** connected to APPL
union
{
UCHAR TCPBuffer[1000]; // For converting byte stream to messages
UCHAR DEDBuffer[1000]; // For converting byte stream to messages
UCHAR KISSBuffer[1000]; // For KISS over Host Mode
};
UCHAR * ARDOPBuffer; // Needs to be pretty big, so Malloc
UCHAR * ARDOPDataBuffer; // Needs to be pretty big, so Malloc
int InputLen; // Data we have already = Offset of end of an incomplete packet;
int DataInputLen; // Data we have already = Offset of end of an incomplete packet;
int KISSInputLen; // Data we have already = Offset of end of an incomplete packet;
int ESCFLAG; // KISS Escape received
int MSGCOUNT; // DED WORKING FIELD
int MSGLENGTH; // DED Msg Len
int MSGCHANNEL; // DED Msg Channel Number
int MSGTYPE; // DED Msg Type
int HOSTSTATE; // ded HOST state machine
BOOL StartSent; // Codec Start send (so will get a disconnect)
int ConnectPending; // Set if Connect Pending Received. If so, mustn't allow freq change.
BOOL GavePermission; // Set if we allowed freq change
BOOL DiscPending; // Set if Disconnect Pending Received. So we can time out stuck in Disconnecting
BOOL HadConnect; // Flag to say have been in session
BOOL FECMode; // In FEC Mode
BOOL FEC1600; // Use 1600 Hz FEC Mode
int FECIDTimer; // Time in FEC Mode. Used to trigger ID broadcasts
BOOL RestartAfterFailure;
BOOL StartInRobust; // For WINMOR, set to Robust Mode for first few packets
int Busy; // Channel Busy Timer/Counter . Non-zero = Busy
int BusyFlags; // Channel Busy Flags
#define CDBusy 1 // For WINMOR - reported busy (set till reported clear)
#define PTTBusy 2 // PTT Active
BOOL FECPending; // Need an FEC Send when channel is next idle
time_t lasttime;
BOOL CONNECTING; // TCP Session Flags
BOOL CONNECTED;
BOOL Alerted; // Connect Failed Prompt sent
BOOL DATACONNECTING;
BOOL DATACONNECTED;
BOOL TNCCONNECTING; // For FreeData
BOOL TNCCONNECTED;
BOOL QtSMConnected;
char NodeCall[10]; // Call we listen for (PORTCALL or NODECALL
char CurrentMYC[10]; // Save current call so we don't change it unnecessarily
char * LISTENCALLS; // Calls TNC will respond to (currently only for VARA)
char TargetCall[10]; // Call incoming connect is addressed to (for appl call support)
struct sockaddr_in destaddr;
struct sockaddr_in Datadestaddr;
int PTTMode; // PTT Mode Flags
int PTTState; // Current State
uint64_t PTTActivemS; // For Stats
uint64_t PTTonTime; //
uint64_t BusyActivemS; // For channel busy stats
uint64_t BusyonTime;
char PTTOn[60]; // Port override of RIGCONTROL config
char PTTOff[60];
int PTTOnLen;
int PTTOffLen;
int TXRadio; // Rigcontrol Radio Number for TX
int RXRadio; // Rigcontrol Radio Number for RX
long long int TXFreq; // Freq to set on tx before ptt
double ActiveTXFreq; // Freq to set on tx after attach
double ActiveRXFreq; // Freq to set on rx after attach
double DefaultTXFreq; // Freq to set on tx after close
double DefaultRXFreq; // Freq to set on rx after close
char ** DisconnectScript; // May replace above 2 params
int TXOffset; // Correction to TXFreq
int PID; // Process ID for Software TNC
HWND hWnd; // Main window handle for Software TNC
char * CaptureDevices;
char * PlaybackDevices;
char * ProgramPath;
BOOL WeStartedTNC;
int Restarts; // TNC Kill/Restarts done
time_t LastRestart;
int TimeSinceLast; // Time since last message from TNC (10ths of a sec)
int HeartBeat;
// int Interlock; // Port Interlock Group
HWND hMonitor; // Handle to Monitor control
// HMENU hPopMenu; // Actions Menu Handle
int MaxConReq; // For ARDOP
int BusyHold; // Hold Time from SCS reporting channel free till we call
int BusyWait; // Time to wait for clear channel before connect
BOOL OverrideBusy;
int BusyDelay; // Timer for busy timeout
int AutoStartDelay; // Time to wait for TNC to start
char * ConnectCmd; // Saved command if waiting for busy to clear
BOOL UseAPPLCalls; // Robust Packet to use Applcalls
BOOL UseAPPLCallsforPactor; // Pactor to use Applcalls
// Fields for reporting to WL2K Map
struct WL2KInfo * WL2K;
/*
char * Host;
short WL2KPort;
int UpdateWL2KTimer;
BOOL UpdateWL2K;
char RMSCall[10];
char BaseCall[10];
char GridSquare[7];
char Comment[80];
char ServiceCode[17];
BOOL UseRigCtrlFreqs;
char WL2KFreq[12];
char WL2KModeChar; // W or N
BOOL DontReportNarrowOnWideFreqs;
// char NARROWMODE;
// char WIDEMODE; // Mode numbers to report to WL2K
struct WL2KInfo WL2KInfoList[MAXFREQS]; // Freqs for sending to WL2K
*/
char WL2KMode; // WL2K reporting mode
struct STREAMINFO Streams[27]; // 0 is Pactor 1 - 10 are ax.25.
int LastStream; // Last one polled for status or send
void * BPQtoRadio_Q; // Frames to Rig Interface
void * RadiotoBPQ_Q; // Frames from Rig Interface
void * KISSTX_Q; // Frames to Host Mode KISS interface
struct PORTCONTROL * VirtualPORT; // Pointer to Virtual Packet Port of Host Mode KISS
char * InitPtr; // Next Command
int ReinitState; // Reinit State Machine
int ReinitCount; // Count for DED Recovery
int TermReinitCount; // Count for DED Term Mode Recovery
BOOL TNCOK; // TNC is reponding
int FramesOutstanding; // Frames Queued - used for flow control
BOOL InternalCmd; // Last Command was generated internally
int IntCmdDelay; // To limit internal commands
HANDLE hDevice;
int ReopenTimer; // Used to reopen device if failed (eg USB port removed)
BOOL HostMode; // Set if in DED Host Mode
// BOOL CRCMode; // Set if using SCS Extended DED Mode (JHOST4)
BOOL UsingTermMode; // Set if tnc should be left in term mode
int Timeout; // Timeout response counter
int Retries;
int Window; // Window Size for ARQ
UCHAR TXBuffer[500]; // Last message sent - saved for Retry
int TXLen; // Len of last sent
UCHAR RXBuffer[520]; // Message being received - may not arrive all at once
UINT RXLen; // Data in RXBUffer
UCHAR Toggle; // Sequence bit
int Buffers; // Free buffers in TNC
BOOL WantToChangeFreq; // Request from Scanner to Change
int OKToChangeFreq; // 1 = SCS Says OK to change, -1 = Dont Change zero = still waiting
BOOL DontWantToChangeFreq; // Change done - ok to SCS
BOOL DontReleasePermission; // Hold Permission to prevent calls on this frequency
time_t TimeEnteredSYNCMode; // To detect scan lock when using applcalls on PTC
BOOL SyncSupported; // TNC reports sync
time_t TimeScanLocked; // ditto for TNCs that don't report SYNC
int PTCStatus; // Sync, Idle, Traffic, etc
UCHAR NexttoPoll[20]; // Streams with data outstanding (from General Poll)
BOOL PollSent; // Toggle to ensure we issue a general poll regularly
int StreamtoPoll;
char Bandwidth; // Currently set Mode W or N
int Mode; // Mode Flag
BOOL Dragon; // Set if P4Dragon
BOOL DragonSingle; // Set if P4Dragon using Pactor and Packet on same port
BOOL DragonKISS; // Set if P4Dragon supports sending KISS frames in Hostmode
BOOL EnterExit; // Switching to Term mode to change bandwidth
int PktStream; // Stream in use for Packet when in single port mode
BOOL MaxLevel; // Pactor Level to set for Wide Mode (3 or 4)
int MinLevel; // Mimimum accepted Pactor Level
int MinLevelTimer; // Time left to achieve Min Level
int PacketChannels;
int RobustTime; // For PTC, Spend this part of scan cycle (in 10th secs) in Robust Packet Mode
int SwitchToPactor; // Countdown to switch
BOOL OldMode; // Use PACTOR instead of TOR (for old software)
BOOL VeryOldMode; // Use MYCALL instead of MYPTCALL (for old software)
int Mem1; // Free Bytes (VHF /HF)
int Mem2;
BOOL HFPacket; // Set if HF port is in Packet mode instead of Pactor Mode
BOOL Robust; // Set if SCS Tracker is in Robust Packet mode or WINMOR TNC is in Robust Mode
BOOL RobustDefault; // Set if SCS Tracker default is Robust Packet mode
BOOL ForceRobust; // Don't allow Normal Packet even if scan requests it.
BOOL TeensyRPR; // Teensy RPR TNC - don't send %R
char NormSpeed[8]; // Speed Param for Normal Packet on Tracker
char RobustSpeed[8]; // Speed Param for Robust Packet on Tracker
BOOL RPBEACON; // Send Beacon after each session
int TimeInRX; // Time waiting for ISS before sending
char TXRXState; // Current ISS/IRS State
BOOL NeedPACTOR; // Set if need to send PACTOR to put into Standby Mode
int CmdStream; // Stream last command was issued on
union
{
struct TCPINFO * TCPInfo; // Telnet Server Specific Data
struct AGWINFO * AGWInfo; // AGW Stream Mode Specific Data
struct MPSKINFO * MPSKInfo; // MPSK Stream Mode Specific Data
struct FLINFO * FLInfo; // FLDIGI Stream Mode Specific Data
};
struct ARQINFO * ARQInfo; // FLDIGI/FLARQ Stream Mode Specific Data
BOOL DataBusy; // Waiting for Data Ack - Don't send any more data
BOOL CommandBusy; // Waiting for Command ACK
BOOL TEXTMODE; // Set if AEA in text mode
BOOL NeedTurnRound; // Set if we have sent data, so need to send ctrl/z
BOOL NeedTRANS; // Set if we have to send TRANS when ctrl/z is acked.
char * CmdSet; // A series of commands to send to the TNC
char * CmdSave; // Base address for free
BOOL PktUpdateMap; // Set if Packet MH data to be sent to NodeMap
int DefaultMode;
int CurrentMode; // Used on HAL
char * DefaultRadioCmd; // RADIO command to send at end of session
char * Frequency;
// For Mode Map if no Rigcontrol
// Mode Equates
#define Clover 'C'
#define Pactor 'P'
#define AMTOR 'A'
UCHAR DataBuffer[500]; // Data Chars split from received stream
UCHAR CmdBuffer[500]; // Cmd/Response chars split from received stream
int DataLen; // Data in DataBuffer
int CmdLen; // Data in CmdBuffer
BOOL CmdEsc; // Set if last char rxed was 0x80
BOOL DataEsc; // Set if last char rxed was 0x81
int PollDelay; // Don't poll too often;
int InData; // FLDigi - MCAST <....> received
int InPacket; // FLDigi - SOH or < received.
int MCASTLen; // Data still to get
int DataMode; // How to treat data
#define RXDATA 0x30 // Switch to Receive Data characters
#define TXDATA 0x31 // Switch to Transmit Data characters
#define SECDATA 0x32 // Switch to RX data from secondary port
int TXMode; // Where to send data
#define TXMODEM 0x33 // Send TX data to modem
#define TXSEC 0x34 // Send TX data to secondary port
BOOL XONXOFF; // Set if hardware is using XON/XOFF
double LastFreq; // Used by V4 to see if freq has changed
int ModemCentre; // Modem centre frequency
int ClientHeight;
int ClientWidth;
HWND xIDC_TNCSTATE;
HWND xIDC_COMMSSTATE;
HWND xIDC_MODE;
HWND xIDC_LEDS;
HWND xIDC_TRAFFIC;
HWND xIDC_BUFFERS;
HWND xIDC_CHANSTATE;
HWND xIDC_LEVELS;
HWND xIDC_STATE;
HWND xIDC_TXRX;
HWND xIDC_PROTOSTATE;
HWND xIDC_RESTARTTIME;
HWND xIDC_RESTARTS;
HWND xIDC_PACTORLEVEL;
HWND xIDC_TXTUNE;
HWND xIDC_TXTUNEVAL;
char * WEB_TNCSTATE;
char * WEB_COMMSSTATE;
char * WEB_MODE;
char * WEB_LEDS;
char * WEB_TRAFFIC;
char * WEB_BUFFERS;
char * WEB_CHANSTATE;
char * WEB_STATE;
char * WEB_TXRX;
char * WEB_PROTOSTATE;
char * WEB_RESTARTTIME;
char * WEB_RESTARTS;
char * WEB_PACTORLEVEL;
char * WEB_LEVELS;
int WEB_CHANGED; // Used to speed up refresh when active
HMENU hMenu;
HMENU hWndMenu;
VOID (* SuspendPortProc) (struct TNCINFO * TNC, struct TNCINFO * ThisTNC);
VOID (* ReleasePortProc) (struct TNCINFO * TNC);
VOID (* ForcedCloseProc) (struct TNCINFO * TNC, int Stream);
time_t WinmorRestartCodecTimer;
int WinmorCurrentMode;
char ARDOPCurrentMode[10];
char ARDOPCommsMode;
char * ARDOPSerialPort; // Have Bus/Device for I2C
int ARDOPSerialSpeed;
BOOL TCPCONNECTED; // ARDOP over TCP Connected
int SlowTimer;
int ARQPorts[32]; // For ARQ over KISS
char * LogPath;
FILE * LogHandle; // Ardop Logging File
FILE * DebugHandle; // Ardop Debug File
char LastLogType; // For split packets
UCHAR * ARDOPAPRS; // Used to reconstruct APRS datagram from FEC packets
int ARDOPAPRSLen;
BOOL WRITELOG; // Enable debug logging
int InputLevelMin; // Sound card levels
int InputLevelMax; // Sound card levels
int DiscardNextOK; // Used by VARA to suppress OK response to LISTEN commands
int SeenCancelPending; // Used by VARA to suppress duplicate cancel pendings
MESSAGE * Monframe; // Used by DED Host for receiving Packet Monitor Frame
// split over 2 packets
struct HSMODEMINFO * HSModemInfo;
struct FreeDataINFO * FreeDataInfo;
int DontRestart; // Don't automatically restart failed TNC
int SendTandRtoRelay; // Send T and R suffix messages to RELAY instead of CMS
double SNR; // S/N Ratio (VARA)
int NetRomMode;
unsigned char * NetRomTxBuffer; // For Netrom over VARA
int NetRomTxLen;
char * NRNeighbour;
int NRCloseTimer;
struct _LINKTABLE * DummyLink; // Simulated link to simplify interface to ax,25 netrom code
struct sixPackPortInfo * sixPack;
int VaraACAllowed; // Set by config
int VaraACMode; // Set by first message received
int VaraModeSet; // Have decicded if VarAC mode or not
char * VARACMsg; // to build message from packets
int VarACTimer; // delayed send timer
size_t VARACSize; // malloc'ed size
} *PTNCINFO;
VOID * zalloc(int len);
BOOL ReadConfigFile(int Port, int ProcLine());
int GetLine(char * buf);
BOOL CreatePactorWindow(struct TNCINFO * TNC, char * ClassName, char * WindowTitle, int RigControlRow, WNDPROC WndProc, int Width, int Height, VOID ForcedCloseProc());
char * CheckAppl(struct TNCINFO * TNC, char * Appl);
BOOL SendReporttoWL2K(struct TNCINFO * TNC);
struct WL2KInfo * DecodeWL2KReportLine(char * buf);
VOID UpdateMH(struct TNCINFO * TNC, UCHAR * Call, char Mode, char Direction);
VOID UpdateMHEx(struct TNCINFO * TNC, UCHAR * Call, char Mode, char Direction, char * LOC, BOOL Report);
VOID SaveWindowPos(int port);
VOID SaveMDIWindowPos(HWND hWnd, char * RegKey, char * Value, BOOL Minimized);
BOOL ProcessIncommingConnect(struct TNCINFO * TNC, char * Call, int Stream, BOOL SENDCTEXT);
BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BOOL SENDCTEXT, BOOL AllowTR);
VOID ShowTraffic(struct TNCINFO * TNC);
int OpenCOMMPort(struct TNCINFO * conn, char * Port, int Speed, BOOL Quiet);
VOID SendMH(struct TNCINFO * TNC, char * call, char * freq, char * LOC, char * Mode);
VOID MoveWindows(struct TNCINFO * TNC);
static VOID TidyClose(struct TNCINFO * TNC, int Stream);
static VOID ForcedClose(struct TNCINFO * TNC, int Stream);
static VOID CloseComplete(struct TNCINFO * TNC, int Stream);
VOID CheckForDetach(struct TNCINFO * TNC, int Stream, struct STREAMINFO * STREAM,
VOID TidyCloseProc(struct TNCINFO * TNC, int Stream), VOID ForcedCloseProc(struct TNCINFO * TNC, int Stream),
VOID CloseComplete(struct TNCINFO * TNC, int Stream));
BOOL InterlockedCheckBusy(struct TNCINFO * ThisTNC);
extern UINT CRCTAB;
int BPQTRACE(MESSAGE * Msg, BOOL TOAPRS);
static int ProcessLine(char * buf, int Port);
VOID __cdecl Debugprintf(const char * format, ...);
VOID __cdecl Consoleprintf(const char * format, ...);
extern BOOL MinimizetoTray;
int standardParams(struct TNCINFO * TNC, char * buf);
void DecodePTTString(struct TNCINFO * TNC, char * ptr);
int Rig_Command(TRANSPORTENTRY * Session, char * Command);
BOOL Rig_Poll();
VOID Rig_PTT(struct TNCINFO * TNC, BOOL PTTState);
VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC);
struct RIGINFO * Rig_GETPTTREC(int Port);
struct ScanEntry ** CheckTimeBands(struct RIGINFO * RIG);
#ifndef LINBPQ
LRESULT CALLBACK PacWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
#endif
#define Report_P1 11
#define Report_P12 12
#define Report_P123 13
#define Report_P2 14
#define Report_P23 15
#define Report_P3 16
#define Report_P1234 17
#define Report_P234 18
#define Report_P34 19
#define Report_P4 20
#define Report_WINMOR500 21
#define Report_WINMOR1600 22
#define Report_Robust 30
#define IOCTL_SERIAL_IS_COM_OPEN CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_GETDATA CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_SETDATA CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_SET_CTS CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x803,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_SET_DSR CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x804,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_SET_DCD CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x805,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_CLR_CTS CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x806,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_CLR_DSR CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x807,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_SERIAL_CLR_DCD CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x808,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_BPQ_ADD_DEVICE CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x809,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define IOCTL_BPQ_DELETE_DEVICE CTL_CODE(FILE_DEVICE_SERIAL_PORT,0x80a,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define W98_SERIAL_GETDATA 0x801
#define W98_SERIAL_SETDATA 0x802

@ -0,0 +1,43 @@
# 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 RHP.o
# Configuration:
CC = gcc
all: CFLAGS = -DLINBPQ -MMD -g -rdynamic -fcommon
all: LDFLAGS = -l:libpaho-mqtt3a.a -l:libjansson.a
all: linbpq
nomqtt: CFLAGS = -DLINBPQ -MMD -fcommon -g -rdynamic -DNOMQTT
nomqtt: linbpq
noi2c: CFLAGS = -DLINBPQ -MMD -DNOI2C -g -rdynamic -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)

@ -0,0 +1,71 @@
//Microsoft Developer Studio generated resource script.
//
//#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "windows.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
#define BPQICON 400
BPQICON ICON DISCARDABLE "..\\bpqicon.ico"
//
// Version
//
#define TEXTVER "2. 0. 1. 1\0"
#define BINVER 2, 0, 1, 1
VS_VERSION_INFO VERSIONINFO
FILEVERSION BINVER
PRODUCTVERSION BINVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "Comments", "Program to hold BPQ32.dll in memory\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "bpq32\0"
VALUE "FileVersion", TEXTVER
VALUE "InternalName", "bpq32\0"
VALUE "LegalCopyright", "Copyright © 2006-2011 G8BPQ\0"
VALUE "OriginalFilename", "bpq32.exe\0"
VALUE "ProductName", " bpq32\0"
VALUE "ProductVersion", TEXTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
#endif // not APSTUDIO_INVOKED

@ -0,0 +1,223 @@
/* LzmaDec.h -- LZMA Decoder
2008-10-04 : Igor Pavlov : Public domain */
#ifndef __LZMADEC_H
#define __LZMADEC_H
#include "types.h"
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
#ifdef _LZMA_PROB32
#define CLzmaProb LZ_UInt32
#else
#define CLzmaProb UInt16
#endif
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps
{
unsigned lc, lp, pb;
LZ_UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20
typedef struct
{
CLzmaProps prop;
CLzmaProb *probs;
Byte *dic;
const Byte *buf;
LZ_UInt32 range, code;
SizeT dicPos;
SizeT dicBufSize;
LZ_UInt32 processedPos;
LZ_UInt32 checkDicSize;
unsigned state;
LZ_UInt32 reps[4];
unsigned remainLen;
int needFlush;
int needInitState;
LZ_UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Constr()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
/* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
*/
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
#endif

@ -0,0 +1,135 @@
/* LzmaLib.h -- LZMA library interface
2008-08-05
Igor Pavlov
Public domain */
#ifndef __LZMALIB_H
#define __LZMALIB_H
#include "types.h"
#ifdef __cplusplus
#define MY_EXTERN_C extern "C"
#else
#define MY_EXTERN_C extern
#endif
#define MY_STDAPI MY_EXTERN_C int MY_STD_CALL
#define LZMA_PROPS_SIZE 5
/*
RAM requirements for LZMA:
for compression: (dictSize * 11.5 + 6 MB) + state_size
for decompression: dictSize + state_size
state_size = (4 + (1.5 << (lc + lp))) KB
by default (lc=3, lp=0), state_size = 16 KB.
LZMA properties (5 bytes) format
Offset Size Description
0 1 lc, lp and pb in encoded form.
1 4 dictSize (little endian).
*/
/*
LzmaCompress
------------
outPropsSize -
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
LZMA Encoder will use defult values for any parameter, if it is
-1 for any from: level, loc, lp, pb, fb, numThreads
0 for dictSize
level - compression level: 0 <= level <= 9;
level dictSize algo fb
0: 16 KB 0 32
1: 64 KB 0 32
2: 256 KB 0 32
3: 1 MB 0 32
4: 4 MB 0 32
5: 16 MB 1 32
6: 32 MB 1 32
7+: 64 MB 1 64
The default value for "level" is 5.
algo = 0 means fast method
algo = 1 means normal method
dictSize - The dictionary size in bytes. The maximum value is
128 MB = (1 << 27) bytes for 32-bit version
1 GB = (1 << 30) bytes for 64-bit version
The default value is 16 MB = (1 << 24) bytes.
It's recommended to use the dictionary that is larger than 4 KB and
that can be calculated as (1 << N) or (3 << N) sizes.
lc - The number of literal context bits (high bits of previous literal).
It can be in the range from 0 to 8. The default value is 3.
Sometimes lc=4 gives the gain for big files.
lp - The number of literal pos bits (low bits of current position for literals).
It can be in the range from 0 to 4. The default value is 0.
The lp switch is intended for periodical data when the period is equal to 2^lp.
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
better to set lc=0, if you change lp switch.
pb - The number of pos bits (low bits of current position).
It can be in the range from 0 to 4. The default value is 2.
The pb switch is intended for periodical data when the period is equal 2^pb.
fb - Word size (the number of fast bytes).
It can be in the range from 5 to 273. The default value is 32.
Usually, a big number gives a little bit better compression ratio and
slower compression process.
numThreads - The number of thereads. 1 or 2. The default value is 2.
Fast mode (algo = 0) can use only 1 thread.
Out:
destLen - processed output size
Returns:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */
int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */
);
/*
LzmaUncompress
--------------
In:
dest - output data
destLen - output data size
src - input data
srcLen - input data size
Out:
destLen - processed output size
srcLen - processed input size
Returns:
SZ_OK - OK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation arror
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
*/
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

@ -0,0 +1,30 @@
/* See md5.c for explanation and copyright information. */
/*
* $FreeBSD: src/contrib/cvs/lib/md5.h,v 1.2 1999/12/11 15:10:02 peter Exp $
*/
#ifndef MD5_H
#define MD5_H
/* Unlike previous versions of this code, uint32 need not be exactly
32 bits, merely 32 bits or more. Choosing a data type which is 32
bits instead of 64 is not important; speed is considerably more
important. ANSI guarantees that "unsigned long" will be big enough,
and always using it seems to have few disadvantages. */
typedef unsigned long cvs_uint32;
struct cvs_MD5Context {
cvs_uint32 buf[4];
cvs_uint32 bits[2];
unsigned char in[64];
};
void cvs_MD5Init(struct cvs_MD5Context *context);
void cvs_MD5Update(struct cvs_MD5Context *context,
unsigned char const *buf, unsigned len);
void cvs_MD5Final(unsigned char digest[16],
struct cvs_MD5Context *context);
void cvs_MD5Transform(cvs_uint32 buf[4], const unsigned char in[64]);
#endif /* !MD5_H */

@ -0,0 +1,424 @@
// Mail and Chat Server for BPQ32 Packet Switch
//
// Monitor Window(s) Module
#include "bpqmail.h"
static char ClassName[]="BPQMONWINDOW";
char SYSOPCall[50];
static WNDPROC wpOrigInputProc;
static WNDPROC wpOrigOutputProc;
HWND hMonitor;
static HWND hwndInput;
static HWND hwndOutput;
static HMENU hMenu; // handle of menu
#define InputBoxHeight 25
RECT MonitorRect;
RECT OutputRect;
int Height, Width, LastY;
static char kbbuf[160];
static int kbptr=0;
static char * readbuff;
static int readbufflen;
static BOOL StripLF = TRUE;
BOOL MonBBS = TRUE;
BOOL MonCHAT = TRUE;
BOOL MonTCP = TRUE;
BOOL LogBBS = TRUE;
BOOL LogCHAT = TRUE;
BOOL LogTCP = TRUE;
static int PartLinePtr=0;
static int PartLineIndex=0; // Listbox index of (last) incomplete line
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY MonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static void MoveWindows();
static void MoveMCWindows();
#define BGCOLOUR RGB(236,233,216)
BOOL CreateMonitor()
{
WNDCLASS wc;
HBRUSH bgBrush;
if (hMonitor)
{
ShowWindow(hMonitor, SW_SHOWNORMAL);
SetForegroundWindow(hMonitor);
return FALSE; // Alreaqy open
}
bgBrush = CreateSolidBrush(BGCOLOUR);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MonWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
RegisterClass(&wc);
hMonitor=CreateDialog(hInst,ClassName,0,NULL);
if (!hMonitor)
return (FALSE);
readbuff = zalloc(1000);
readbufflen = 1000;
hMenu=GetMenu(hMonitor);
CheckMenuItem(hMenu,MONBBS, MonBBS ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONCHAT, MonCHAT ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONTCP, MonTCP ? MF_CHECKED : MF_UNCHECKED);
DrawMenuBar(hWnd);
// Retrieve the handlse to the edit controls.
hwndOutput = GetDlgItem(hMonitor, 121);
// Set our own WndProcs for the controls.
wpOrigOutputProc = (WNDPROC)SetWindowLong(hwndOutput, GWL_WNDPROC, (LONG)OutputProc);
if (cfgMinToTray)
AddTrayMenuItem(hMonitor, "Mail Monitor");
ShowWindow(hMonitor, SW_SHOWNORMAL);
if (MonitorRect.right < 100 || MonitorRect.bottom < 100)
{
GetWindowRect(hMonitor, &MonitorRect);
}
MoveWindow(hMonitor,MonitorRect.left,MonitorRect.top, MonitorRect.right-MonitorRect.left, MonitorRect.bottom-MonitorRect.top, TRUE);
MoveWindows();
return TRUE;
}
static void MoveWindows()
{
RECT rcMain, rcClient;
int ClientHeight, ClientWidth;
GetWindowRect(hMonitor, &rcMain);
GetClientRect(hMonitor, &rcClient);
ClientHeight = rcClient.bottom;
ClientWidth = rcClient.right;
// MoveWindow(hwndMon,2, 0, ClientWidth-4, SplitPos, TRUE);
MoveWindow(hwndOutput,2, 2, ClientWidth-4, ClientHeight-4, TRUE);
// MoveWindow(hwndSplit,0, SplitPos, ClientWidth, SplitBarHeight, TRUE);
}
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
LPRECT lprc;
switch (message)
{
case WM_ACTIVATE:
SetFocus(hwndInput);
break;
case WM_CLOSE:
if (wParam) // Used by Close All Programs.
return 0;
return (DefWindowProc(hWnd, message, wParam, lParam));
case WM_COMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case MONBBS:
ToggleParam(hMenu, hWnd, &MonBBS, MONBBS);
break;
case MONCHAT:
ToggleParam(hMenu, hWnd, &MonCHAT, MONCHAT);
break;
case MONTCP:
ToggleParam(hMenu, hWnd, &MonTCP, MONTCP);
break;
case BPQCLEAROUT:
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
break;
case BPQCOPYOUT:
CopyToClipboard(hwndOutput);
break;
//case BPQHELP:
// HtmlHelp(hWnd,"BPQTerminal.chm",HH_HELP_FINDER,0);
// break;
default:
return 0;
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case SC_MINIMIZE:
if (cfgMinToTray)
return ShowWindow(hWnd, SW_HIDE);
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SIZING:
lprc = (LPRECT) lParam;
Height = lprc->bottom-lprc->top;
Width = lprc->right-lprc->left;
MoveWindows();
return TRUE;
case WM_DESTROY:
// Remove the subclass from the edit control.
GetWindowRect(hWnd, &MonitorRect); // For save soutine
SetWindowLong(hwndInput, GWL_WNDPROC,
(LONG) wpOrigInputProc);
if (cfgMinToTray)
DeleteTrayMenuItem(hWnd);
hMonitor = NULL;
free(readbuff);
readbufflen = 0;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Trap mouse messages, so we cant select stuff in output and mon windows,
// otherwise scrolling doesnt work.
if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_LBUTTONDBLCLK)
return TRUE;
return CallWindowProc(wpOrigOutputProc, hwnd, uMsg, wParam, lParam);
}
int WritetoMonitorWindow(char * Msg, int len)
{
char * ptr1, * ptr2;
int index;
if (len+PartLinePtr > readbufflen)
{
readbufflen += len+PartLinePtr;
readbuff = realloc(readbuff, readbufflen);
}
if (PartLinePtr != 0)
SendMessage(hwndOutput,LB_DELETESTRING,PartLineIndex,(LPARAM)(LPCTSTR) 0 );
memcpy(&readbuff[PartLinePtr], Msg, len);
len=len+PartLinePtr;
ptr1=&readbuff[0];
readbuff[len]=0;
do {
ptr2=memchr(ptr1,7,len);
if (ptr2)
*(ptr2)=32;
} while (ptr2);
lineloop:
// if (PartLinePtr > 300)
// PartLinePtr = 0;
if (len > 0)
{
// copy text to control a line at a time
ptr2=memchr(ptr1,13,len);
if (ptr2 == 0)
{
// no newline. Move data to start of buffer and Save pointer
PartLinePtr=len;
memmove(readbuff,ptr1,len);
PartLineIndex=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) PartLineIndex, MAKELPARAM(FALSE, 0));
return (0);
}
*(ptr2++)=0;
index=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
// if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1);
PartLinePtr=0;
len-=(ptr2-ptr1);
ptr1=ptr2;
if ((len > 0) && StripLF)
{
if (*ptr1 == 0x0a) // Line Feed
{
ptr1++;
len--;
}
}
if (index > 1200)
do{
index=SendMessage(hwndOutput,LB_DELETESTRING, 0, 0);
} while (index > 1000);
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) index, MAKELPARAM(FALSE, 0));
goto lineloop;
}
return (0);
}
static int ToggleParam(HMENU hMenu, HWND hWnd, BOOL * Param, int Item)
{
*Param = !(*Param);
CheckMenuItem(hMenu,Item, (*Param) ? MF_CHECKED : MF_UNCHECKED);
return (0);
}
static void CopyToClipboard(HWND hWnd)
{
int i,n, len=0;
HGLOBAL hMem;
char * ptr;
//
// Copy List Box to clipboard
//
n = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
for (i=0; i<n; i++)
{
len+=SendMessage(hWnd, LB_GETTEXTLEN, i, 0);
}
hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len+n+n+1);
if (hMem != 0)
{
ptr=GlobalLock(hMem);
if (OpenClipboard(MainWnd))
{
// CopyScreentoBuffer(GlobalLock(hMem));
for (i=0; i<n; i++)
{
ptr+=SendMessage(hWnd, LB_GETTEXT, i, (LPARAM) ptr);
*(ptr++)=13;
*(ptr++)=10;
}
*(ptr)=0; // end of data
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(CF_TEXT,hMem);
CloseClipboard();
}
else
GlobalFree(hMem);
}
}

@ -0,0 +1,161 @@
/* pngrio.c - functions for data input
*
* libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This file provides a location for all input. Users who need
* special handling are expected to write a function that has the same
* arguments as this and performs a similar function, but that possibly
* has a different input method. Note that you shouldn't change this
* function, but rather write a replacement function and then make
* libpng use it at run time with png_set_read_fn(...).
*/
#define PNG_INTERNAL
#include "png.h"
/* Read the data from whatever input you are using. The default routine
reads from a file pointer. Note that this routine sometimes gets called
with very small lengths, so you should implement some kind of simple
buffering if you are using unbuffered reads. This should never be asked
to read more then 64K on a 16 bit machine. */
void /* PRIVATE */
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_debug1(4,"reading %d bytes\n", (int)length);
if (png_ptr->read_data_fn != NULL)
(*(png_ptr->read_data_fn))(png_ptr, data, length);
else
png_error(png_ptr, "Call to NULL read function");
}
#if !defined(PNG_NO_STDIO)
/* This is the function that does the actual reading of data. If you are
not reading from a standard C stream, you should create a replacement
read_data function and use it at run time with png_set_read_fn(), rather
than changing the library. */
#ifndef USE_FAR_KEYWORD
void PNGAPI
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_size_t check;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
#if defined(_WIN32_WCE)
if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
check = 0;
#else
check = (png_size_t)fread(data, (png_size_t)1, length,
(png_FILE_p)png_ptr->io_ptr);
#endif
if (check != length)
png_error(png_ptr, "Read Error");
}
#else
/* this is the model-independent version. Since the standard I/O library
can't handle far buffers in the medium and small models, we have to copy
the data.
*/
#define NEAR_BUF_SIZE 1024
#define MIN(a,b) (a <= b ? a : b)
static void /* PRIVATE */
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
int check;
png_byte *n_data;
png_FILE_p io_ptr;
/* Check if data really is near. If so, use usual code. */
n_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)n_data == data)
{
#if defined(_WIN32_WCE)
if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
check = 0;
#else
check = fread(n_data, 1, length, io_ptr);
#endif
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t read, remaining, err;
check = 0;
remaining = length;
do
{
read = MIN(NEAR_BUF_SIZE, remaining);
#if defined(_WIN32_WCE)
if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
err = 0;
#else
err = fread(buf, (png_size_t)1, read, io_ptr);
#endif
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
if(err != read)
break;
else
check += err;
data += read;
remaining -= read;
}
while (remaining != 0);
}
if ((png_uint_32)check != (png_uint_32)length)
png_error(png_ptr, "read Error");
}
#endif
#endif
/* This function allows the application to supply a new input function
for libpng if standard C streams aren't being used.
This function takes as its arguments:
png_ptr - pointer to a png input data structure
io_ptr - pointer to user supplied structure containing info about
the input functions. May be NULL.
read_data_fn - pointer to a new input function that takes as its
arguments a pointer to a png_struct, a pointer to
a location where input data can be stored, and a 32-bit
unsigned int that is the number of bytes to be read.
To exit and output any fatal error messages the new write
function should call png_error(png_ptr, "Error msg"). */
void PNGAPI
png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
png_rw_ptr read_data_fn)
{
png_ptr->io_ptr = io_ptr;
#if !defined(PNG_NO_STDIO)
if (read_data_fn != NULL)
png_ptr->read_data_fn = read_data_fn;
else
png_ptr->read_data_fn = png_default_read_data;
#else
png_ptr->read_data_fn = read_data_fn;
#endif
/* It is an error to write to a read device */
if (png_ptr->write_data_fn != NULL)
{
png_ptr->write_data_fn = NULL;
png_warning(png_ptr,
"It's an error to set both read_data_fn and write_data_fn in the ");
png_warning(png_ptr,
"same structure. Resetting write_data_fn to NULL.");
}
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
png_ptr->output_flush_fn = NULL;
#endif
}

@ -0,0 +1,22 @@
Chat :
{
ApplNum = 2;
MaxStreams = 11;
OtherChatNodes = "RDGCHT:GB7RDG-1|C STHGTE|C 1 MB7NCR-2|C RDGCHT\r\nRDGCHT:GB7RDG-1|C STHGTE|C 1 MB7NCR-2|C RDGCHT\r\n\r\n";
ChatWelcomeMsg = "G8BPQ Chat Server.$WType /h for command summary.$WBringing up links to other nodes.$WThis may take a minute or two.$WThe /p command shows what nodes are linked.$W";
MapPosition = "MapPosition=5259.04N, 00107.01W";
MapPopup = "MapPopup=G8BPQ Nottingham<p><a href=\"http://www.g8bpq.org.uk\">BPQ32 Home Page</a";
PopupMode = 0;
Bells = 1;
FlashOnBell = 0;
StripLF = 0;
WarnWrap = 0;
WrapInput = 0;
FlashOnConnect = 0;
CloseWindowOnBye = 0;
ConsoleSize = "821,1629,283,893";
MonitorSize = "828,1644,148,770";
DebugSize = "0,0,0,0";
WindowSize = "231,835,254,602";
Version = "6,0,24,32";
};

@ -0,0 +1,82 @@
//
// Standard __except handler to dump stack and code around eip
//
__except(memcpy(&exinfo, GetExceptionInformation(), sizeof(struct _EXCEPTION_POINTERS)), EXCEPTION_EXECUTE_HANDLER)
{
unsigned __int32 SPPtr = 0;
unsigned __int32 SPVal = 0;
unsigned __int32 eip = 0;
unsigned __int32 rev = 0;
int i;
DWORD Stack[16];
DWORD CodeDump[16];
#ifndef _WIN64
eip = exinfo.ContextRecord->Eip;
SPPtr = exinfo.ContextRecord->Esp;
__asm
{
mov eax, SPPtr
mov SPVal,eax
lea edi,Stack
mov esi,eax
mov ecx,64
rep movsb
lea edi,CodeDump
mov esi,eip
mov ecx,64
rep movsb
}
Debugprintf("BPQ32 *** Program Error %x at %x in %s",
exinfo.ExceptionRecord->ExceptionCode, exinfo.ExceptionRecord->ExceptionAddress, EXCEPTMSG);
Debugprintf("EAX %x EBX %x ECX %x EDX %x ESI %x EDI %x ESP %x",
exinfo.ContextRecord->Eax, exinfo.ContextRecord->Ebx, exinfo.ContextRecord->Ecx,
exinfo.ContextRecord->Edx, exinfo.ContextRecord->Esi, exinfo.ContextRecord->Edi, SPVal);
#endif
Debugprintf("Stack:");
Debugprintf("%08x %08x %08x %08x %08x %08x %08x %08x %08x ",
SPVal, Stack[0], Stack[1], Stack[2], Stack[3], Stack[4], Stack[5], Stack[6], Stack[7]);
Debugprintf("%08x %08x %08x %08x %08x %08x %08x %08x %08x ",
SPVal+32, Stack[8], Stack[9], Stack[10], Stack[11], Stack[12], Stack[13], Stack[14], Stack[15]);
Debugprintf("Code:");
for (i = 0; i < 16; i++)
{
rev = (CodeDump[i] & 0xff) << 24;
rev |= (CodeDump[i] & 0xff00) << 8;
rev |= (CodeDump[i] & 0xff0000) >> 8;
rev |= (CodeDump[i] & 0xff000000) >> 24;
CodeDump[i] = rev;
}
Debugprintf("%08x %08x %08x %08x %08x %08x %08x %08x %08x ",
eip, CodeDump[0], CodeDump[1], CodeDump[2], CodeDump[3], CodeDump[4], CodeDump[5], CodeDump[6], CodeDump[7]);
Debugprintf("%08x %08x %08x %08x %08x %08x %08x %08x %08x ",
eip+32, CodeDump[8], CodeDump[9], CodeDump[10], CodeDump[11], CodeDump[12], CodeDump[13], CodeDump[14], CodeDump[15]);
WriteMiniDump();
// Note - no closing } so additional code may be run in the __except block
#ifdef MDIKERNEL
if (CloseOnError == 1)
CloseAllNeeded = 1;
#endif
#undef EXCEPTMSG

@ -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

@ -0,0 +1,237 @@
/*
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
*/
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#include "compatbits.h"
#include <string.h>
#include "asmstrucs.h"
#include "tncinfo.h"
VOID __cdecl Debugprintf(const char * format, ...);
#ifndef WIN32
#define APIENTRY
#define DllExport
#define VOID void
#else
#include <windows.h>
#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
void RunEventProgram(char * Program, char * Param)
{
char * arg_list[] = {Program, NULL, NULL};
pid_t child_pid;
if (EventsEnabled == 0)
return;
signal(SIGCHLD, SIG_IGN); // Silently (and portably) reap children.
if (Param && Param[0])
arg_list[1] = Param;
// Fork and Exec Specified program
// Duplicate this process.
child_pid = fork ();
if (child_pid == -1)
{
printf ("Event fork() Failed\n");
return;
}
if (child_pid == 0)
{
execvp (arg_list[0], arg_list);
// The execvp function returns only if an error occurs.
printf ("Failed to run %s\n", arg_list[0]);
exit(0); // Kill the new process
}
#else
DllExport void APIENTRY RunEventProgram(char * Program, char * Param)
{
int n = 0;
char cmdLine[256];
STARTUPINFO SInfo; // pointer to STARTUPINFO
PROCESS_INFORMATION PInfo; // pointer to PROCESS_INFORMATION
if (EventsEnabled == 0)
return;
SInfo.cb=sizeof(SInfo);
SInfo.lpReserved=NULL;
SInfo.lpDesktop=NULL;
SInfo.lpTitle=NULL;
SInfo.dwFlags=0;
SInfo.cbReserved2=0;
SInfo.lpReserved2=NULL;
sprintf(cmdLine, "%s %s", Program, Param);
if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE,0 ,NULL ,NULL, &SInfo, &PInfo))
Debugprintf("Failed to Start %s Error %d ", Program, GetLastError());
#endif
return;
}
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(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;
}
}

@ -0,0 +1,988 @@
// Program to Convert RTS changes on Virtual COM Port to hamlib PTT commands
// Version 1. 0. 0. 1 December 2020
// Version 1. 0. 2. 1 April 2018
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <Psapi.h>
#define LIBCONFIG_STATIC
#include "libconfig.h"
#include "BPQRemotePTTRes.h"
#define BPQICON 400
WSADATA WsaData; // receives data from WSAStartup
#define WSA_READ WM_USER + 1
HINSTANCE hInst;
char AppName[] = "BPQRemotePTT";
char Title[80] = "BPQRemotePTT";
TCHAR szTitle[]="GPSMuxPC"; // The title bar text
TCHAR szWindowClass[]="GPSMAINWINDOW"; // the main window class name
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap);
VOID WINAPI txCompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap);
VOID CATThread();
VOID runTimer();
int TimerHandle = 0;
LOGFONT LFTTYFONT ;
HFONT hFont;
struct sockaddr_in sinx;
struct sockaddr rx;
int addrlen = sizeof(struct sockaddr_in);
int HAMLIBPORT; // Port Number for HAMLIB (rigctld) Emulator
char * HAMLIBHOST[128];
BOOL MinimizetoTray=FALSE;
VOID __cdecl Debugprintf(const char * format, ...)
{
char Mess[255];
va_list(arglist);
va_start(arglist, format);
vsprintf(Mess, format, arglist);
strcat(Mess, "\r\n");
OutputDebugString(Mess);
return;
}
char * strlop(char * buf, char delim)
{
// Terminate buf at delim, and return rest of string
char * ptr = strchr(buf, delim);
if (ptr == NULL) return NULL;
*(ptr)++=0;
return ptr;
}
char * RigPort = NULL;
char * RigSpeed = NULL;
HANDLE RigHandle = 0;
int RigType = 0; // Flag for possible RTS/DTR
char BPQHostIP[128];
char PTTCATPort[4][16];
HANDLE PTTCATHandle[4];
short HamLibPort[4];
SOCKET HamLibSock[4]; // rigctld socket
HWND comWnd[4];
HWND portWnd[4];
HWND stateWnd[4];
int stateCtl[4];
struct sockaddr_in remoteDest[4];
int RealMux[4]; // BPQ Virtual or Real
int EndPTTCATThread = 0;
char ConfigName[256] = "BPQRemotePTT.cfg";
BOOL GetStringValue(config_setting_t * group, char * name, char * value)
{
const char * str;
config_setting_t *setting;
setting = config_setting_get_member (group, name);
if (setting)
{
str = config_setting_get_string (setting);
strcpy(value, str);
return TRUE;
}
return FALSE;
}
int GetIntValue(config_setting_t * group, char * name)
{
config_setting_t *setting;
setting = config_setting_get_member (group, name);
if (setting)
return config_setting_get_int (setting);
return 0;
}
VOID SaveStringValue(config_setting_t * group, char * name, char * value)
{
config_setting_t *setting;
setting = config_setting_add(group, name, CONFIG_TYPE_STRING);
if (setting)
config_setting_set_string(setting, value);
}
VOID SaveIntValue(config_setting_t * group, char * name, int value)
{
config_setting_t *setting;
setting = config_setting_add(group, name, CONFIG_TYPE_INT);
if(setting)
config_setting_set_int(setting, value);
}
VOID GetConfig()
{
config_setting_t *group;
config_t cfg;
memset((void *)&cfg, 0, sizeof(config_t));
config_init(&cfg);
if(!config_read_file(&cfg, ConfigName))
{
fprintf(stderr, "Config read error line %d - %s\n", config_error_line(&cfg), config_error_text(&cfg));
config_destroy(&cfg);
return;
}
group = config_lookup(&cfg, "main");
if (group == NULL)
{
config_destroy(&cfg);
return;
}
GetStringValue(group, "BPQHostIP", BPQHostIP);
GetStringValue(group, "COM1", PTTCATPort[0]);
GetStringValue(group, "COM2", PTTCATPort[1]);
GetStringValue(group, "COM3", PTTCATPort[2]);
GetStringValue(group, "COM4", PTTCATPort[3]);
HamLibPort[0] = GetIntValue(group, "HamLibPort1");
HamLibPort[1] = GetIntValue(group, "HamLibPort2");
HamLibPort[2] = GetIntValue(group, "HamLibPort3");
HamLibPort[3] = GetIntValue(group, "HamLibPort4");
config_destroy(&cfg);
}
VOID SaveConfig()
{
config_setting_t *root, *group;
config_t cfg;
// Get rid of old config before saving
config_init(&cfg);
root = config_root_setting(&cfg);
group = config_setting_add(root, "main", CONFIG_TYPE_GROUP);
SaveStringValue(group, "BPQHostIP", BPQHostIP);
SaveStringValue(group, "COM1", PTTCATPort[0]);
SaveStringValue(group, "COM2", PTTCATPort[1]);
SaveStringValue(group, "COM3", PTTCATPort[2]);
SaveStringValue(group, "COM4", PTTCATPort[3]);
SaveIntValue(group, "HamLibPort1", HamLibPort[0]);
SaveIntValue(group, "HamLibPort2", HamLibPort[1]);
SaveIntValue(group, "HamLibPort3", HamLibPort[2]);
SaveIntValue(group, "HamLibPort4", HamLibPort[3]);
if(!config_write_file(&cfg, ConfigName))
{
fprintf(stderr, "Error while writing file.\n");
config_destroy(&cfg);
return;
}
config_destroy(&cfg);
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
if (lpCmdLine[0])
{
// Port Name and Speed for Remote CAT
RigPort = _strdup(lpCmdLine);
RigSpeed = strlop(RigPort, ':');
}
MyRegisterClass(hInstance);
GetConfig();
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
KillTimer(NULL, TimerHandle);
return (msg.wParam);
}
//
//
// FUNCTION: InitApplication(HANDLE)
//
// PURPOSE: Initializes window data and registers window class
//
// COMMENTS:
//
// In this function, we initialize a window class by filling out a data
// structure of type WNDCLASS and calling either RegisterClass or
// the internal MyRegisterClass.
//
#define BGCOLOUR RGB(236,233,216)
HBRUSH bgBrush;
HBRUSH RedBrush;
HBRUSH GreenBrush;
HWND hWnd;
BOOL InitApplication(HINSTANCE hInstance)
{
return TRUE;
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
HFONT FAR PASCAL MyCreateFont( void )
{
CHOOSEFONT cf;
LOGFONT lf;
HFONT hfont;
// Initialize members of the CHOOSEFONT structure.
cf.lStructSize = sizeof(CHOOSEFONT);
cf.hwndOwner = (HWND)NULL;
cf.hDC = (HDC)NULL;
cf.lpLogFont = &lf;
cf.iPointSize = 0;
cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY;
cf.rgbColors = RGB(0,0,0);
cf.lCustData = 0L;
cf.lpfnHook = (LPCFHOOKPROC)NULL;
cf.lpTemplateName = (LPSTR)NULL;
cf.hInstance = (HINSTANCE) NULL;
cf.lpszStyle = (LPSTR)NULL;
cf.nFontType = SCREEN_FONTTYPE;
cf.nSizeMin = 0;
cf.nSizeMax = 0;
// Display the CHOOSEFONT common-dialog box.
ChooseFont(&cf);
// Create a logical font based on the user's
// selection and return a handle identifying
// that font.
hfont = CreateFontIndirect(cf.lpLogFont);
return (hfont);
}
VOID Rig_PTT(int n, BOOL PTTState)
{
char Msg[16];
int Len = sprintf(Msg, "T %d\n", PTTState);
if (HamLibSock[n])
{
send(HamLibSock[n], Msg, Len, 0);
if (PTTState)
SetDlgItemText(hWnd, stateCtl[n], "PTT");
else
SetDlgItemText(hWnd, stateCtl[n], "");
}
}
VOID PTTCATThread()
{
DWORD dwLength = 0;
int Length, ret, i;
UCHAR * ptr1;
UCHAR * ptr2;
UCHAR c;
UCHAR Block[4][80];
UCHAR CurrentState[4] = {0};
#define RTS 2
#define DTR 4
HANDLE Event;
DWORD EvtMask[4];
OVERLAPPED Overlapped[4];
char Port[32];
int PIndex = 0;
int HIndex = 0;
int rc;
EndPTTCATThread = FALSE;
while (PIndex < 4 && PTTCATPort[PIndex][0])
{
RealMux[HIndex] = 0;
sprintf(Port, "\\\\.\\pipe\\BPQ%s", PTTCATPort[PIndex]);
PTTCATHandle[HIndex] = CreateFile(Port, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (PTTCATHandle[HIndex] == INVALID_HANDLE_VALUE)
{
int Err = GetLastError();
// Consoleprintf("PTTMUX port BPQCOM%s Open failed code %d", RIG->PTTCATPort[PIndex], Err);
// See if real com port
sprintf(Port, "\\\\.\\\\%s", PTTCATPort[PIndex]);
PTTCATHandle[HIndex] = CreateFile(Port, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
RealMux[HIndex] = 1;
if (PTTCATHandle[HIndex] == INVALID_HANDLE_VALUE)
{
int Err = GetLastError();
PTTCATHandle[HIndex] = 0;
Debugprintf("PTTMUX port COM%s Open failed code %d", PTTCATPort[PIndex], Err);
}
else
{
rc = SetCommMask(PTTCATHandle[HIndex], EV_CTS | EV_DSR); // Request notifications
HIndex++;
}
}
else
HIndex++;
PIndex++;
}
if (PIndex == 0)
return; // No ports
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
for (i = 0; i < HIndex; i ++)
{
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
Overlapped[i].hEvent = Event;
if (RealMux[i])
{
// Request Interface change notifications
rc = WaitCommEvent(PTTCATHandle[i], &EvtMask[i], &Overlapped[i]);
rc = GetLastError();
}
else
{
// Prime a read on each PTTCATHandle
ReadFile(PTTCATHandle[i], Block[i], 80, &Length, &Overlapped[i]);
}
}
while (EndPTTCATThread == FALSE)
{
WaitAgain:
ret = WaitForSingleObject(Event, 1000);
if (ret == WAIT_TIMEOUT)
{
if (EndPTTCATThread)
{
for (i = 0; i < HIndex; i ++)
{
CancelIo(PTTCATHandle[i]);
CloseHandle(PTTCATHandle[i]);
PTTCATHandle[i] = INVALID_HANDLE_VALUE;
}
CloseHandle(Event);
return;
}
goto WaitAgain;
}
ResetEvent(Event);
// See which request(s) have completed
for (i = 0; i < HIndex; i ++)
{
ret = GetOverlappedResult(PTTCATHandle[i], &Overlapped[i], &Length, FALSE);
if (ret)
{
if (RealMux[i])
{
// Request Interface change notifications
DWORD Mask;
GetCommModemStatus(PTTCATHandle[i], &Mask);
if (Mask & MS_CTS_ON)
Rig_PTT(i, TRUE);
else
Rig_PTT(i, FALSE);
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
Overlapped[i].hEvent = Event;
WaitCommEvent(PTTCATHandle[i], &EvtMask[i], &Overlapped[i]);
}
else
{
ptr1 = Block[i];
ptr2 = Block[i];
while (Length > 0)
{
c = *(ptr1++);
Length--;
if (c == 0xff)
{
c = *(ptr1++);
Length--;
if (c == 0xff) // ff ff means ff
{
Length--;
}
else
{
// This is connection / RTS/DTR statua from other end
// Convert to CAT Command
if (c == CurrentState[i])
continue;
if (c & RTS)
Rig_PTT(i, TRUE);
else
Rig_PTT(i, FALSE);
CurrentState[i] = c;
continue;
}
}
}
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
Overlapped[i].hEvent = Event;
ReadFile(PTTCATHandle[i], Block[i], 80, &Length, &Overlapped[i]);
}
}
}
}
EndPTTCATThread = FALSE;
}
char ClassName[]="BPQMAIL";
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
bgBrush = CreateSolidBrush(BGCOLOUR);
RedBrush = CreateSolidBrush(RGB(255,0,0));
GreenBrush = CreateSolidBrush(RGB(0,255,0));
// BlueBrush = CreateSolidBrush(RGB(0,0,255));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInstance;
wc.hIcon = NULL; //LoadIcon( hInstance, MAKEINTRESOURCE(IDI_GPSMUXPC));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;//"MENU_1";
wc.lpszClassName = szWindowClass;
// RegisterClass(&wc);
// wc.lpfnWndProc = TraceWndProc;
// wc.lpszClassName = TraceClassName;
// RegisterClass(&wc);
// wc.lpfnWndProc = ConfigWndProc;
// wc.lpszClassName = ConfigClassName;
return (RegisterClass(&wc));
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
u_long param=1;
BOOL bcopt=TRUE;
int ret;
WNDCLASS wc = {0};
int n = 0;
hInst = hInstance; // Store instance handle in our global variable
WSAStartup(MAKEWORD(2, 0), &WsaData);
hWnd=CreateDialog(hInst,szWindowClass,0,NULL);
if (!hWnd)
{
ret=GetLastError();
return FALSE;
}
// setup default font information
LFTTYFONT.lfHeight = 12;
LFTTYFONT.lfWidth = 8 ;
LFTTYFONT.lfEscapement = 0 ;
LFTTYFONT.lfOrientation = 0 ;
LFTTYFONT.lfWeight = 0 ;
LFTTYFONT.lfItalic = 0 ;
LFTTYFONT.lfUnderline = 0 ;
LFTTYFONT.lfStrikeOut = 0 ;
LFTTYFONT.lfCharSet = OEM_CHARSET ;
LFTTYFONT.lfOutPrecision = OUT_DEFAULT_PRECIS ;
LFTTYFONT.lfClipPrecision = CLIP_DEFAULT_PRECIS ;
LFTTYFONT.lfQuality = DEFAULT_QUALITY ;
LFTTYFONT.lfPitchAndFamily = FIXED_PITCH | FF_MODERN ;
lstrcpy( LFTTYFONT.lfFaceName, "Fixedsys" ) ;
hFont = CreateFontIndirect(&LFTTYFONT) ;
// hFont = MyCreateFont();
SetWindowText(hWnd,Title);
comWnd[0] = GetDlgItem(hWnd, IDC_COM1);
comWnd[1] = GetDlgItem(hWnd, IDC_COM2);
comWnd[2] = GetDlgItem(hWnd, IDC_COM3);
comWnd[3] = GetDlgItem(hWnd, IDC_COM4);
portWnd[0] = GetDlgItem(hWnd, IDC_HAMLIBPORT1);
portWnd[1] = GetDlgItem(hWnd, IDC_HAMLIBPORT2);
portWnd[2] = GetDlgItem(hWnd, IDC_HAMLIBPORT3);
portWnd[3] = GetDlgItem(hWnd, IDC_HAMLIBPORT4);
stateWnd[0] = GetDlgItem(hWnd, IDC_STATE1);
stateWnd[1] = GetDlgItem(hWnd, IDC_STATE2);
stateWnd[2] = GetDlgItem(hWnd, IDC_STATE3);
stateWnd[3] = GetDlgItem(hWnd, IDC_STATE4);
stateCtl[0] = IDC_STATE1;
stateCtl[1] = IDC_STATE2;
stateCtl[2] = IDC_STATE3;
stateCtl[3] = IDC_STATE4;
ShowWindow(hWnd, nCmdShow);
SetDlgItemText(hWnd, IDC_BPQHOST, BPQHostIP);
SetDlgItemText(hWnd, IDC_COM1, PTTCATPort[0]);
SetDlgItemText(hWnd, IDC_COM2, PTTCATPort[1]);
SetDlgItemText(hWnd, IDC_COM3, PTTCATPort[2]);
SetDlgItemText(hWnd, IDC_COM4, PTTCATPort[3]);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT1, HamLibPort[0], 0);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT2, HamLibPort[1], 0);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT3, HamLibPort[2], 0);
SetDlgItemInt(hWnd, IDC_HAMLIBPORT4, HamLibPort[3], 0);
// ioctlsocket (sock, FIONBIO, &param);
if (RigPort)
{
int Speed = 9600;
if (RigSpeed)
Speed = atoi(RigSpeed);
}
TimerHandle = SetTimer(hWnd, 1, 10000, NULL);
runTimer(); // Open Hamlib connections
_beginthread(PTTCATThread, 0);
return TRUE;
}
VOID ConnecttoHAMLIB(int n);
VOID runTimer()
{
int n;
for (n = 0; n < 4; n++)
{
if (HamLibPort[n] && HamLibSock[n] == 0)
{
// try to connect
ConnecttoHAMLIB(n);
}
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message)
{
case WM_TIMER:
runTimer();
break;
case WM_CTLCOLOREDIT:
{
HDC hdc = (HDC) wParam; // handle to display context
HWND hwnd = (HWND) lParam; // handle to control window
int n;
for (n = 0; n < 4; n++)
{
if (hwnd == comWnd[n] && PTTCATPort[n][0])
if (PTTCATHandle[n])
return (INT_PTR)GreenBrush;
else
return (INT_PTR)RedBrush;
if (hwnd == portWnd[n] && HamLibPort[n])
if (HamLibSock[n])
return (INT_PTR)GreenBrush;
else
return (INT_PTR)RedBrush;
}
//return (INT_PTR)RedBrush;
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId)
{
case SC_MINIMIZE:
if (MinimizetoTray)
return ShowWindow(hWnd, SW_HIDE);
else
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
int OK;
case IDC_TEST1:
Rig_PTT(0, 1);
Sleep(1500);
Rig_PTT(0, 0);
break;
case IDC_TEST2:
Rig_PTT(1, 1);
Sleep(1500);
Rig_PTT(1, 0);
break;
case IDC_TEST3:
Rig_PTT(2, 1);
Sleep(1500);
Rig_PTT(2, 0);
break;
case IDC_TEST4:
Rig_PTT(3, 1);
Sleep(1500);
Rig_PTT(3, 0);
break;
case IDOK:
GetDlgItemText(hWnd, IDC_BPQHOST, BPQHostIP, 127);
GetDlgItemText(hWnd, IDC_COM1, PTTCATPort[0], 15);
GetDlgItemText(hWnd, IDC_COM2, PTTCATPort[1], 15);
GetDlgItemText(hWnd, IDC_COM3, PTTCATPort[2], 15);
GetDlgItemText(hWnd, IDC_COM4, PTTCATPort[3], 15);
HamLibPort[0] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT1, &OK, 0);
HamLibPort[1] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT2, &OK, 0);
HamLibPort[2] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT3, &OK, 0);
HamLibPort[3] = GetDlgItemInt(hWnd, IDC_HAMLIBPORT4, &OK, 0);
SaveConfig();
// EndPTTCATThread = 1;
// Sleep(1100);
// _beginthread(PTTCATThread, 0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
}
return (DefWindowProc(hWnd, message, wParam, lParam));
}
void HAMLIBProcessMessage(int n)
{
char RXBuffer[256];
int InputLen = recv(HamLibSock[n], RXBuffer, 256, 0);
if (InputLen == 0 || InputLen == SOCKET_ERROR)
{
if (HamLibSock[n])
closesocket(HamLibSock[n]);
HamLibSock[n] = 0;
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
return;
}
}
VOID HAMLIBThread(int n);
VOID ConnecttoHAMLIB(int n)
{
_beginthread(HAMLIBThread, 0, n);
return ;
}
VOID HAMLIBThread(int n)
{
// Opens sockets and looks for data
char Msg[255];
int err, i, ret;
u_long param=1;
BOOL bcopt=TRUE;
fd_set readfs;
fd_set errorfs;
struct timeval timeout;
if (HamLibSock[n])
closesocket(HamLibSock[n]);
// Param is IPADDR:PORT. Only Allow numeric addresses
if (HamLibPort[n] == 0)
return;
remoteDest[n].sin_family = AF_INET;
remoteDest[n].sin_addr.s_addr = inet_addr(BPQHostIP);
remoteDest[n].sin_port = htons(HamLibPort[n]);
HamLibSock[n] = 0;
HamLibSock[n] = socket(AF_INET,SOCK_STREAM,0);
if (HamLibSock[n] == INVALID_SOCKET)
{
i=sprintf(Msg, "Socket Failed for HAMLIB socket - error code = %d\r\n", WSAGetLastError());
Debugprintf(Msg);
return;
}
setsockopt(HamLibSock[n], SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
setsockopt(HamLibSock[n], IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&bcopt, 4);
if (connect(HamLibSock[n],(LPSOCKADDR)&remoteDest[n],sizeof(remoteDest[n])) == 0)
{
//
// Connected successful
//
}
else
{
err=WSAGetLastError();
i=sprintf(Msg, "Connect Failed for HAMLIB socket %d - error code = %d\r\n", n, err);
Debugprintf(Msg);
closesocket(HamLibSock[n]);
HamLibSock[n] = 0;
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
return;
}
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE);
ret = GetLastError();
while (HamLibSock[n])
{
FD_ZERO(&readfs);
FD_ZERO(&errorfs);
FD_SET(HamLibSock[n],&readfs);
FD_SET(HamLibSock[n],&errorfs);
timeout.tv_sec = 60;
timeout.tv_usec = 0;
ret = select((int)HamLibSock[n] + 1, &readfs, NULL, &errorfs, &timeout);
if (ret == SOCKET_ERROR)
{
Debugprintf("HAMLIB Select failed %d ", WSAGetLastError());
goto Lost;
}
if (ret > 0)
{
// See what happened
if (FD_ISSET(HamLibSock[n], &readfs))
{
HAMLIBProcessMessage(n);
}
if (FD_ISSET(HamLibSock[n], &errorfs))
{
Lost:
sprintf(Msg, "HAMLIB Connection lost for Port %d\r\n", n);
Debugprintf(Msg);
closesocket(HamLibSock[n]);
HamLibSock[n] = 0;
RedrawWindow(hWnd, NULL, NULL, 0);
return;
}
continue;
}
else
{
}
}
sprintf(Msg, "HAMLIB Thread Terminated Port %d\r\n", n);
Debugprintf(Msg);
}

@ -0,0 +1,45 @@
//
// HTTP Session Control. Used In Kernel HTTPCode, BBSHTMLConfig
// and ChatHTMLConfig
// On Windows changes to layout or length of this struct require rebuilding BPQ32.dll, BPQMail and BPQChat
struct HTTPConnectionInfo // Used for Web Server for thread-specific stuff
{
struct HTTPConnectionInfo * Next;
struct STATIONRECORD * SelCall; // Station Record for individual station display
char Callsign[12];
int WindDirn, WindSpeed, WindGust, Temp, RainLastHour, RainLastDay, RainToday, Humidity, Pressure; //WX Fields
char * ScreenLines[100]; // Screen Image for Teminal access mode - max 100 lines (cyclic buffer)
int ScreenLineLen[100]; // Length of each lime
int LastLine; // Pointer to last line of data
BOOL PartLine; // Last line does not have CR on end
char HTTPCall[10]; // Call of HTTP user
BOOL Changed; // Changed since last poll. If set, reply immediately, else set timer and wait
SOCKET sock; // Socket for pending send
int ResponseTimer; // Timer for delayed response
int KillTimer; // Clean up timer (no activity timeout)
int Stream; // BPQ Stream Number
char Key[20]; // Session Key
BOOL Connected;
// Use by Mail Module
#ifdef MAIL
struct UserInfo * User; // Selected User
struct MsgInfo * Msg; // Selected Message
WPRec * WP; // Selected WP record
WebMailInfo * WebMail; // Webmail Forms Info
#else
VOID * User; // Selected User
VOID * Msg; // Selected Message
VOID * WP; // Selected WP record
VOID * WebMail; // Webmail Forms Info
#endif
struct UserRec * USER; // Telnet Server USER record
int WebMailSkip; // Number to skip at start of list (for paging)
char WebMailTypes[4]; // Types To List
BOOL WebMailMine; // List all meessage to or from me
BOOL WebMailMyTX; // List all meessage from me
BOOL WebMailMyRX; // List all meessage to me
time_t WebMailLastUsed;
struct TNCINFO * TNC; // Session -> TNC link
};

@ -0,0 +1,706 @@
/*
Copyright 2001-2015 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
*/
//
// DLL to provide BPQEther support for G8BPQ switch in a
// 32bit environment,
//
// Uses BPQ EXTERNAL interface
//
// Uses WINPACAP library
// Version 1.0 December 2005
// Version 1.1 January 2006
//
// Get config file location from Node (will check bpq directory)
// Version 1.2 October 2006
// Write diagnostics to BPQ console window instead of STDOUT
// Version 1.3 February 2008
// Changes for dynamic unload of bpq32.dll
// Version 1.3.1 Spetmber 2010
// Add option to get config from bpq32.dll
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
//#include <time.h>
#include "CHeaders.h"
#include <process.h>
#include "pcap.h"
#include "../CommonSource/bpq32.h"
//#include "packet32.h"
//#include "ntddndis.h"
extern char * PortConfig[33];
typedef struct PCAPStruct
{
pcap_t *adhandle;
UCHAR EthSource[6];
UCHAR EthDest[6];
short EtherType;
BOOL RLITX;
BOOL RLIRX;
BOOL Promiscuous;
int pcap_reopen_delay;
char Adapter[256];
} PCAPINFO, *PPCAPINFO ;
PCAPINFO * PCAPInfo[32];
//PPCAPINFO PCAPInfo[16]={0};
UCHAR EthDest[7]={01,'B','P','Q',0,0};
char EtherType[10]="0x08FF";
//pcap_t *adhandle;
struct tagMSG Msg;
short udpport=0;
extern UCHAR BPQDirectory[];
unsigned int OurInst = 0;
HWND hWnd;
BOOL GotMsg;
DWORD n;
#ifdef WIN32
static HINSTANCE PcapDriver=0;
typedef int (FAR *FARPROCX)();
int (FAR * pcap_sendpacketx)();
FARPROCX pcap_compilex;
FARPROCX pcap_setfilterx;
FARPROCX pcap_datalinkx;
FARPROCX pcap_next_exx;
FARPROCX pcap_geterrx;
pcap_t * (FAR * pcap_open_livex)(const char *, int, int, int, char *);
static char Dllname[6]="wpcap";
FARPROCX GetAddress(char * Proc);
#else
#define pcap_compilex pcap_compile
#define pcap_open_livex pcap_open_live
#define pcap_setfilterx pcap_setfilter
#define pcap_datalinkx pcap_datalink
#define pcap_next_exx pcap_next_ex
#define pcap_geterrx pcap_geterr
#define pcap_sendpacketx pcap_sendpacket
#endif
int InitPCAP(void);
static FARPROCX GetAddress(char * Proc);
static BOOL ReadConfigFile(int Port);
static int ProcessLine(char * buf,int Port, BOOL CheckPort);
static int OpenPCAP(PPCAPINFO PCAP);
int ExtProc(int fn, int port,unsigned char * buff)
{
int len,txlen=0,res;
char txbuff[500];
struct pcap_pkthdr *header;
u_char *pkt_data;
PPCAPINFO PCAP = PCAPInfo[port];
// char dcall[10],scall[10];
if (PCAP->adhandle == 0)
{
// No handle.
if (PCAP->Adapter[0])
{
// Try reopening periodically
PCAP->pcap_reopen_delay --;
if (PCAP->pcap_reopen_delay < 0)
if (OpenPCAP(PCAP) == FALSE)
PCAP->pcap_reopen_delay = 300; // Retry every 30 seconds
}
return 0;
}
switch (fn)
{
case 1: // poll
res = pcap_next_exx(PCAP->adhandle, &header, &pkt_data);
if (res == 0)
/* Timeout elapsed */
return 0;
if (res == -1)
{
// Failed - try to reopen
if (OpenPCAP(PCAP) == FALSE)
PCAP->pcap_reopen_delay = 300;
return 0;
}
if (PCAP->RLIRX)
// RLI MODE - An extra 3 bytes before len, seem to be 00 00 41
{
len=pkt_data[18]*256 + pkt_data[17];
if ((len < 16) || (len > 320)) return 0; // Probably BPQ Mode Frame
len-=3;
memcpy(&buff[7],&pkt_data[19],len);
len+=5;
}
else
{
len=pkt_data[15]*256 + pkt_data[14];
if ((len < 16) || (len > 320)) return 0; // Probably RLI Mode Frame
len-=3;
memcpy(&buff[7],&pkt_data[16],len);
len+=5;
}
buff[5]=(len & 0xff);
buff[6]=(len >> 8);
return 1;
case 2: // send
if (PCAP->RLITX)
// RLI MODE - An extra 3 bytes before len, seem to be 00 00 41
{
txlen=(buff[6]<<8) + buff[5]; // BPQEther is DOS-based - chain word is 2 bytes
txlen-=2;
txbuff[16]=0x41;
txbuff[17]=(txlen & 0xff);
txbuff[18]=(txlen >> 8);
if (txlen < 1 || txlen > 400)
return 0;
memcpy(&txbuff[19],&buff[7],txlen);
}
else
{
txlen=(buff[6]<<8) + buff[5]; // BPQEther is DOS-based - chain word is 2 bytes
txlen-=2;
txbuff[14]=(txlen & 0xff);
txbuff[15]=(txlen >> 8);
if (txlen < 1 || txlen > 400)
return 0;
memcpy(&txbuff[16],&buff[7],txlen);
}
memcpy(&txbuff[0],&PCAP->EthDest[0],6);
memcpy(&txbuff[6],&PCAP->EthSource[0],6);
memcpy(&txbuff[12],&PCAP->EtherType,2);
txlen+=14;
if (txlen < 60) txlen = 60;
// Send down the packet
if (pcap_sendpacketx(PCAP->adhandle, // Adapter
txbuff, // buffer with the packet
txlen // size
) != 0)
{
// n=sprintf(buf,"\nError sending the packet: \n", pcap_geterrx(PCAPInfo[port].adhandle));
// WritetoConsole(buf);
return 3;
}
return (0);
case 3: // CHECK IF OK TO SEND
return (0); // OK
case 4: // reinit
return 0;
case 5: // reinit
return 0;
}
return (0);
}
UINT ETHERExtInit(struct PORTCONTROL * PortEntry)
{
// Can have multiple ports, each mapping to a different Ethernet Adapter
// The Adapter number is in IOADDR
int Port = PortEntry->PORTNUMBER;
PPCAPINFO PCAP;
char buf[80];
if (InitPCAP()) // Make sure pcap is installed
{
WritetoConsole("BPQEther ");
//
// Read config first, to get UDP info if needed
//
PCAP = PCAPInfo[Port] = zalloc(sizeof(struct PCAPStruct));
if (!ReadConfigFile(Port))
return (FALSE);
if (OpenPCAP(PCAP))
sprintf(buf,"Using %s\n", PCAP->Adapter);
else
sprintf(buf,"Failed to open %s\n", PCAP->Adapter);
WritetoConsole(buf);
}
return ((int) ExtProc);
}
InitPCAP()
{
char Msg[255];
int err;
u_long param=1;
BOOL bcopt=TRUE;
// Use LoadLibrary/GetProcADDR to get round link problem
#ifndef WIN32
return TRUE;
#endif
if (PcapDriver)
return TRUE; // Already loaded
PcapDriver=LoadLibrary(Dllname);
if (PcapDriver == NULL)
{
err=GetLastError();
sprintf(Msg,"Error loading Driver %s - Error code %d", Dllname,err);
WritetoConsole(Msg);
return(FALSE);
}
if ((pcap_sendpacketx=GetAddress("pcap_sendpacket")) == 0 ) return FALSE;
if ((pcap_datalinkx=GetAddress("pcap_datalink")) == 0 ) return FALSE;
if ((pcap_compilex=GetAddress("pcap_compile")) == 0 ) return FALSE;
if ((pcap_setfilterx=GetAddress("pcap_setfilter")) == 0 ) return FALSE;
if ((pcap_open_livex = (pcap_t * (__cdecl *)())
GetProcAddress(PcapDriver,"pcap_open_live")) == 0 ) return FALSE;
if ((pcap_geterrx=GetAddress("pcap_geterr")) == 0 ) return FALSE;
if ((pcap_next_exx=GetAddress("pcap_next_ex")) == 0 ) return FALSE;
return (TRUE);
}
#ifdef WIN32
FARPROCX GetAddress(char * Proc)
{
FARPROCX ProcAddr;
int err=0;
char buf[256];
int n;
ProcAddr=(FARPROCX) GetProcAddress(PcapDriver,Proc);
if (ProcAddr == 0)
{
err=GetLastError();
n=sprintf(buf,"Error finding %s - %d\n", Proc,err);
WritetoConsole(buf);
return(0);
}
return ProcAddr;
}
#endif
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int OpenPCAP(PPCAPINFO PCAP)
{
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
char packet_filter[30];
struct bpf_program fcode;
char buf[256];
int n;
/* Open the adapter */
if ((PCAP->adhandle= pcap_open_livex(PCAP->Adapter, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
PCAP->Promiscuous, // promiscuous mode (nonzero means promiscuous)
1, // read timeout
errbuf // error buffer
)) == NULL)
{
return FALSE;
}
/* Check the link layer. We support only Ethernet for simplicity. */
if(pcap_datalinkx(PCAP->adhandle) != DLT_EN10MB)
{
n=sprintf(buf,"This program works only on Ethernet networks.\n");
WritetoConsole(buf);
return FALSE;
}
netmask=0xffffff;
sprintf(packet_filter,"ether[12:2]=0x%x",
ntohs(PCAP->EtherType));
//compile the filter
if (pcap_compilex(PCAP->adhandle, &fcode, packet_filter, 1, netmask) <0 )
{
n=sprintf(buf,"Unable to compile the packet filter. Check the syntax.\n");
WritetoConsole(buf);
/* Free the device list */
return FALSE;
}
//set the filter
if (pcap_setfilterx(PCAP->adhandle, &fcode)<0)
{
n=sprintf(buf,"Error setting the filter.\n");
WritetoConsole(buf);
/* Free the device list */
return FALSE;
}
return TRUE;
}
static BOOL ReadConfigFile(int Port)
{
//TYPE 1 08FF # Ethernet Type
//ETH 1 FF:FF:FF:FF:FF:FF # Target Ethernet AddrMAP G8BPQ-7 10.2.77.1 # IP 93 for compatibility
//ADAPTER 1 \Device\NPF_{21B601E8-8088-4F7D-96 29-EDE2A9243CF4} # Adapter Name
char buf[256],errbuf[256];
char * Config;
PPCAPINFO PCAP = PCAPInfo[Port];
Config = PortConfig[Port];
PCAP->Promiscuous = 1; // Defaults
PCAP->EtherType=htons(0x08FF);
memset(PCAP->EthDest, 0xff, 6);
if (Config)
{
// Using config from bpq32.cfg
char * ptr1 = Config, * ptr2;
ptr2 = strchr(ptr1, 13);
while(ptr2)
{
memcpy(buf, ptr1, ptr2 - ptr1);
buf[ptr2 - ptr1] = 0;
ptr1 = ptr2 + 2;
ptr2 = strchr(ptr1, 13);
strcpy(errbuf,buf); // save in case of error
if (!ProcessLine(buf, Port, FALSE))
{
WritetoConsole("BPQEther - Bad config record ");
WritetoConsole(errbuf);
WritetoConsole("\n");
}
}
return (TRUE);
}
n=sprintf(buf,"No config info found in bpq32.cfg\n");
WritetoConsole(buf);
return (FALSE);
}
static int ProcessLine(char * buf, int Port, BOOL CheckPort)
{
char * ptr;
char * p_port;
char * p_mac;
char * p_Adapter;
char * p_type;
int port;
int a,b,c,d,e,f,num;
PPCAPINFO PCAP = PCAPInfo[Port];
ptr = strtok(buf, " \t\n\r");
if(ptr == NULL) return (TRUE);
if(*ptr =='#') return (TRUE); // comment
if(*ptr ==';') return (TRUE); // comment
if (CheckPort)
{
p_port = strtok(NULL, " \t\n\r");
if (p_port == NULL) return (FALSE);
port = atoi(p_port);
if (Port != port) return TRUE; // Not for us
}
if(_stricmp(ptr,"ADAPTER") == 0)
{
IP_ADAPTER_INFO AdapterInfo[16]; // Allocate information for up to 16 NICs
DWORD dwBufLen = sizeof(AdapterInfo); // Save memory size of buffer
DWORD dwStatus = GetAdaptersInfo(AdapterInfo, &dwBufLen);
PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;
p_Adapter = strtok(NULL, " \t\n\r");
strcpy(PCAP->Adapter, p_Adapter);
// Look for MAC Address
do
{
if (strcmp(pAdapterInfo->AdapterName, &PCAP->Adapter[12]) == 0)
{
memcpy(PCAP->EthSource, pAdapterInfo->Address, 6);
break;
}
pAdapterInfo = pAdapterInfo->Next; // Progress through linked list
} while(pAdapterInfo); // Terminate if last adapter
return (TRUE);
}
if(_stricmp(ptr,"TYPE") == 0)
{
p_type = strtok(NULL, " \t\n\r");
if (p_type == NULL) return (FALSE);
num=sscanf(p_type,"%x",&a);
if (num != 1) return FALSE;
PCAP->EtherType=htons(a);
return (TRUE);
}
if(_stricmp(ptr,"promiscuous") == 0)
{
ptr = strtok(NULL, " \t\n\r");
if (ptr == NULL) return (FALSE);
PCAP->Promiscuous = atoi(ptr);
return (TRUE);
}
if(_stricmp(ptr,"RXMODE") == 0)
{
p_port = strtok(NULL, " \t\n\r");
if (p_port == NULL) return (FALSE);
if(_stricmp(p_port,"RLI") == 0)
{
PCAP->RLIRX=TRUE;
return (TRUE);
}
if(_stricmp(p_port,"BPQ") == 0)
{
PCAP->RLIRX=FALSE;
return (TRUE);
}
return FALSE;
}
if(_stricmp(ptr,"TXMODE") == 0)
{
p_port = strtok(NULL, " \t\n\r");
if (p_port == NULL) return (FALSE);
if(_stricmp(p_port,"RLI") == 0)
{
PCAP->RLITX=TRUE;
return (TRUE);
}
if(_stricmp(p_port,"BPQ") == 0)
{
PCAP->RLITX=FALSE;
return (TRUE);
}
return FALSE;
}
if(_stricmp(ptr,"DEST") == 0)
{
p_mac = strtok(NULL, " \t\n\r");
if (p_mac == NULL) return (FALSE);
num=sscanf(p_mac,"%x-%x-%x-%x-%x-%x",&a,&b,&c,&d,&e,&f);
if (num != 6) return FALSE;
PCAP->EthDest[0]=a;
PCAP->EthDest[1]=b;
PCAP->EthDest[2]=c;
PCAP->EthDest[3]=d;
PCAP->EthDest[4]=e;
PCAP->EthDest[5]=f;
// strcpy(Adapter,p_Adapter);
return (TRUE);
}
if(_stricmp(ptr,"SOURCE") == 0)
{
p_mac = strtok(NULL, " \t\n\r");
if (p_mac == NULL) return (FALSE);
num=sscanf(p_mac,"%x-%x-%x-%x-%x-%x",&a,&b,&c,&d,&e,&f);
if (num != 6) return FALSE;
PCAP->EthSource[0]=a;
PCAP->EthSource[1]=b;
PCAP->EthSource[2]=c;
PCAP->EthSource[3]=d;
PCAP->EthSource[4]=e;
PCAP->EthSource[5]=f;
// strcpy(Adapter,p_Adapter);
return (TRUE);
}
//
// Bad line
//
return (FALSE);
}

@ -0,0 +1,333 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define deflateBound z_deflateBound
# define deflatePrime z_deflatePrime
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateCopy z_inflateCopy
# define inflateReset z_inflateReset
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define zError z_zError
# define alloc_func z_alloc_func
# define free_func z_free_func
# define in_func z_in_func
# define out_func z_out_func
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# ifdef FAR
# undef FAR
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(deflateBound,"DEBND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(compressBound,"CMBND")
# pragma map(inflate_table,"INTABL")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

@ -0,0 +1,451 @@
//
// 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);
#define GetSemaphore(Semaphore,ID) _GetSemaphore(Semaphore, ID, __FILE__, __LINE__)
#define GetBuff() _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 *BUFF, 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(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, char * File, int Line);
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);

@ -0,0 +1,190 @@
/*
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
*/
/*
Stuff to make compiling on WINDOWS and LINUX easier
*/
#ifdef WIN32
typedef unsigned int uint32_t;
#define pthread_t uint32_t
int pthread_equal(pthread_t T1, pthread_t T2)
{
return (T1 == T2);
}
#else
#include <stdio.h>
#include <ctype.h>
#include <syslog.h>
#include <stdarg.h>
#include <unistd.h>
#define BOOL int
#define VOID void
#define UCHAR unsigned char
#define USHORT unsigned short
#define ULONG uint32_t
#define UINT unsigned int
#define SHORT short
#define DWORD int32_t
#define APIENTRY
#define TRUE 1
#define FALSE 0
#define FAR
#define HWND unsigned int
#define HINSTANCE unsigned int
#define strtok_s strtok_r
VOID Debugprintf(const char * format, ...);
int memicmp(unsigned char *a, unsigned char *b, int n)
{
if (n)
{
while (n && (toupper(*a) == toupper(*b)))
n--, a++, b++;
if (n)
return toupper(*a) - toupper(*b);
}
return 0;
}
int stricmp(const unsigned char * pStr1, const unsigned char *pStr2)
{
unsigned char c1, c2;
int v;
if (pStr1 == NULL)
{
if (pStr2)
Debugprintf("stricmp called with NULL 1st param - 2nd %s ", pStr2);
else
Debugprintf("stricmp called with two NULL params");
return 1;
}
do {
c1 = *pStr1++;
c2 = *pStr2++;
/* The casts are necessary when pStr1 is shorter & char is signed */
v = tolower(c1) - tolower(c2);
} while ((v == 0) && (c1 != '\0') && (c2 != '\0') );
return v;
}
char * strupr(char* s)
{
char* p = s;
if (s == 0)
return 0;
while (*p = toupper( *p )) p++;
return s;
}
char * strlwr(char* s)
{
char* p = s;
while (*p = tolower( *p )) p++;
return s;
}
int sprintf_s(char * string, int plen, const char * format, ...)
{
va_list(arglist);
int Len;
va_start(arglist, format);
Len = vsprintf(string, format, arglist);
va_end(arglist);
return Len;
}
#include <pthread.h>
pthread_t _beginthread(void(*start_address)(), unsigned stack_size, VOID * arglist)
{
pthread_t thread;
// Need to set stack size for Mac
int s, tnum, opt, num_threads;
struct thread_info *tinfo;
pthread_attr_t attr;
void *res;
s = pthread_attr_init(&attr);
if (s != 0)
{
perror("pthread_attr_init");
return 0;
}
if (stack_size > 0)
{
s = pthread_attr_setstacksize(&attr, stack_size);
if (s != 0)
{
perror("pthread_attr_setstacksize");
return 0;
}
}
if (pthread_create(&thread, &attr, (void * (*)(void *))start_address, (void*) arglist) != 0)
perror("New Thread");
else
pthread_detach(thread);
return thread;
}
int Sleep(int ms)
{
usleep(ms * 1000);
return 0;
}
VOID OutputDebugString(char * string)
{
syslog(LOG_DEBUG, "%s", string);
}
void closesocket(int sock)
{
if (sock)
close(sock);
}
#endif

@ -0,0 +1,399 @@
/*
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
*/
//
// C replacement for TNCCode.asm
//
#define Kernel
#define _CRT_SECURE_NO_DEPRECATE
#pragma data_seg("_BPQDATA")
#include "time.h"
#include "stdio.h"
#include <fcntl.h>
#include "cheaders.h"
#include "tncinfo.h"
int C_Q_COUNT(VOID *PQ);
VOID SENDUIMESSAGE(struct DATAMESSAGE * Msg);
VOID TNCTimerProc()
{
// CALLED AT 10 HZ
int n = BPQHOSTSTREAMS;
PBPQVECSTRUC HOSTSESS = BPQHOSTVECTOR;
TRANSPORTENTRY * Session;
UCHAR DISCFLAG = 0;
while (n--)
{
// Action any DISC Requests (must be done in timer owning process)
if (HOSTSESS->HOSTFLAGS & 0x40) // DISC REQUEST
{
if (HOSTSESS->HOSTFLAGS & 0x20) // Stay?
DISCFLAG = 'S';
HOSTSESS->HOSTFLAGS &= 0x9F; // Clear Flags
Session = HOSTSESS->HOSTSESSION;
if (Session == 0) // Gone??
{
HOSTSESS->HOSTFLAGS |= 3; // STATE CHANGE
#ifndef LINBPQ
if (HOSTSESS->HOSTHANDLE);
{
PostMessage(HOSTSESS->HOSTHANDLE, BPQMsg, HOSTSESS->HOSTSTREAM, 4);
}
#endif
continue;
}
if (Session->L4CROSSLINK)
Session->L4CROSSLINK->STAYFLAG = DISCFLAG;
HOSTSESS->HOSTSESSION = 0;
HOSTSESS->HOSTFLAGS |= 3; // STATE CHANGE
PostStateChange(Session);
CloseSessionPartner(Session); // SEND CLOSE TO PARTNER (IF PRESENT)
}
// Check Trace Q
if (HOSTSESS->HOSTAPPLFLAGS & 0x80)
{
if (HOSTSESS->HOSTTRACEQ)
{
int Count = C_Q_COUNT(&HOSTSESS->HOSTTRACEQ);
if (Count > 100)
ReleaseBuffer((void *)Q_REM((void *)&HOSTSESS->HOSTTRACEQ));
}
}
HOSTSESS++;
}
}
VOID SendSmartID(struct PORTCONTROL * PORT)
{
struct _MESSAGE * ID = IDMSG;
struct _MESSAGE * Buffer;
PORT->SmartIDNeeded = 0;
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer, ID, ID->LENGTH);
Buffer->PORT = PORT->PORTNUMBER;
// IF PORT HAS A CALLSIGN DEFINED, SEND THAT INSTEAD
if (PORT->PORTCALL[0] > 0x40)
{
memcpy(Buffer->ORIGIN, PORT->PORTCALL, 7);
Buffer->ORIGIN[6] |= 1; // SET END OF CALL BIT
}
// If Pactor Style add to UI_Q
if (PORT->PROTOCOL == 10 && PORT->TNC && PORT->TNC->Hardware != H_KISSHF && PORT->UICAPABLE)
{
EXTPORTDATA * EXTPORT = (EXTPORTDATA *) PORT;
C_Q_ADD(&EXTPORT->UI_Q, Buffer);
return;
}
PUT_ON_PORT_Q(PORT, Buffer);
}
}
VOID SENDIDMSG()
{
struct PORTCONTROL * PORT = PORTTABLE;
struct _MESSAGE * ID = IDMSG;
struct _MESSAGE * Buffer;
while (PORT)
{
if (PORT->PROTOCOL < 10) // Not Pactor-style
{
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer, ID, ID->LENGTH);
Buffer->PORT = PORT->PORTNUMBER;
// IF PORT HAS A CALLSIGN DEFINED, SEND THAT INSTEAD
if (PORT->PORTCALL[0] > 0x40)
{
memcpy(Buffer->ORIGIN, PORT->PORTCALL, 7);
Buffer->ORIGIN[6] |= 1; // SET END OF CALL BIT
}
C_Q_ADD(&IDMSG_Q, Buffer);
}
}
PORT = PORT->PORTPOINTER;
}
}
VOID SENDBTMSG()
{
struct PORTCONTROL * PORT = PORTTABLE;
struct _MESSAGE * Buffer;
char * ptr1, * ptr2;
while (PORT)
{
if (PORT->PROTOCOL >= 10 || PORT->PORTUNPROTO == 0) // Pactor-style or no UNPROTO ADDR?
{
PORT = PORT->PORTPOINTER;
continue;
}
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer->DEST, PORT->PORTUNPROTO, 7);
Buffer->DEST[6] |= 0xC0; // Set Command bits
// Send from BBSCALL unless PORTBCALL defined
if (PORT->PORTBCALL[0] > 32)
memcpy(Buffer->ORIGIN, PORT->PORTBCALL, 7);
else if (APPLCALLTABLE->APPLCALL[0] > 32)
memcpy(Buffer->ORIGIN, APPLCALLTABLE->APPLCALL, 7);
else
memcpy(Buffer->ORIGIN, MYCALL, 7);
ptr1 = &PORT->PORTUNPROTO[7]; // First Digi
ptr2 = &Buffer->CTL; // Digi field in buffer
// Copy any digis
while (*(ptr1))
{
memcpy(ptr2, ptr1, 7);
ptr1 += 7;
ptr2 += 7;
}
*(ptr2 - 1) |= 1; // Set End of Address
*(ptr2++) = UI;
memcpy(ptr2, &BTHDDR.PID, BTHDDR.LENGTH);
ptr2 += BTHDDR.LENGTH;
Buffer->LENGTH = (int)(ptr2 - (char *)Buffer);
Buffer->PORT = PORT->PORTNUMBER;
C_Q_ADD(&IDMSG_Q, Buffer);
}
PORT = PORT->PORTPOINTER;
}
}
VOID SENDUIMESSAGE(struct DATAMESSAGE * Msg)
{
struct PORTCONTROL * PORT = PORTTABLE;
struct _MESSAGE * Buffer;
char * ptr1, * ptr2;
Msg->LENGTH -= MSGHDDRLEN; // Remove Header
while (PORT)
{
if ((PORT->PROTOCOL == 10 && PORT->UICAPABLE == 0) || PORT->PORTUNPROTO == 0) // Pactor-style or no UNPROTO ADDR?
{
PORT = PORT->PORTPOINTER;
continue;
}
Buffer = GetBuff();
if (Buffer)
{
memcpy(Buffer->DEST, PORT->PORTUNPROTO, 7);
Buffer->DEST[6] |= 0xC0; // Set Command bits
// Send from BBSCALL unless PORTBCALL defined
if (PORT->PORTBCALL[0] > 32)
memcpy(Buffer->ORIGIN, PORT->PORTBCALL, 7);
else if (APPLCALLTABLE->APPLCALL[0] > 32)
memcpy(Buffer->ORIGIN, APPLCALLTABLE->APPLCALL, 7);
else
memcpy(Buffer->ORIGIN, MYCALL, 7);
ptr1 = &PORT->PORTUNPROTO[7]; // First Digi
ptr2 = &Buffer->CTL; // Digi field in buffer
// Copy any digis
while (*(ptr1))
{
memcpy(ptr2, ptr1, 7);
ptr1 += 7;
ptr2 += 7;
}
*(ptr2 - 1) |= 1; // Set End of Address
*(ptr2++) = UI;
memcpy(ptr2, &Msg->PID, Msg->LENGTH);
ptr2 += Msg->LENGTH;
Buffer->LENGTH = (int)(ptr2 - (char *)Buffer);
Buffer->PORT = PORT->PORTNUMBER;
if (PORT->PROTOCOL == 10)
{
EXTPORTDATA * EXTPORT = (EXTPORTDATA *) PORT;
C_Q_ADD(&EXTPORT->UI_Q, Buffer);
}
else
C_Q_ADD(&IDMSG_Q, Buffer);
}
PORT = PORT->PORTPOINTER;
}
}
Dll VOID APIENTRY Send_AX(UCHAR * Block, DWORD Len, UCHAR Port)
{
// Block included the 7/11 byte header, Len does not
struct PORTCONTROL * PORT;
PMESSAGE Copy;
if (Len > 360 - 15)
return;
if (QCOUNT < 50)
return; // Running low
PORT = GetPortTableEntryFromPortNum(Port);
if (PORT == 0)
return;
Copy = GetBuff();
if (Copy == 0)
return;
memcpy(&Copy->DEST[0], &Block[MSGHDDRLEN], Len);
Copy->LENGTH = (USHORT)Len + MSGHDDRLEN;
if (PORT->PROTOCOL == 10 && PORT->TNC && PORT->TNC->Hardware != H_KISSHF)
{
// Pactor Style. Probably will only be used for Tracker uneless we do APRS over V4 or WINMOR
EXTPORTDATA * EXTPORT = (EXTPORTDATA *) PORT;
C_Q_ADD(&EXTPORT->UI_Q, Copy);
return;
}
Copy->PORT = Port;
PUT_ON_PORT_Q(PORT, Copy);
}
TRANSPORTENTRY * SetupSessionFromHost(PBPQVECSTRUC HOST, UINT ApplMask)
{
// Create a Transport (L4) session linked to an incoming HOST (API) Session
TRANSPORTENTRY * NewSess = L4TABLE;
int Index = 0;
while (Index < MAXCIRCUITS)
{
if (NewSess->L4USER[0] == 0)
{
// Got One
UCHAR * ourcall = &MYCALL[0];
// IF APPL PORT USE APPL CALL, ELSE NODE CALL
if (ApplMask)
{
// Circuit for APPL - look for an APPLCALL
APPLCALLS * APPL = APPLCALLTABLE;
while ((ApplMask & 1) == 0)
{
ApplMask >>= 1;
APPL++;
}
if (APPL->APPLCALL[0] > 0x40) // We have an applcall
ourcall = &APPL->APPLCALL[0];
}
memcpy(NewSess->L4USER, ourcall, 7);
memcpy(NewSess->L4MYCALL, ourcall, 7);
NewSess->CIRCUITINDEX = Index; //OUR INDEX
NewSess->CIRCUITID = NEXTID;
NEXTID++;
if (NEXTID == 0)
NEXTID++; // Keep Non-Zero
NewSess->L4TARGET.HOST = HOST;
NewSess->L4STATE = 5;
NewSess->SESSIONT1 = L4T1;
NewSess->L4WINDOW = (UCHAR)L4DEFAULTWINDOW;
NewSess->SESSPACLEN = PACLEN; // Default;
return NewSess;
}
Index++;
NewSess++;
}
// Table Full
return NULL;
}

@ -0,0 +1,650 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
* libpng 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/
#define PNG_INTERNAL
#include "png.h"
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* turn on BGR-to-RGB mapping */
void PNGAPI
png_set_bgr(png_structp png_ptr)
{
png_debug(1, "in png_set_bgr\n");
png_ptr->transformations |= PNG_BGR;
}
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* turn on 16 bit byte swapping */
void PNGAPI
png_set_swap(png_structp png_ptr)
{
png_debug(1, "in png_set_swap\n");
if (png_ptr->bit_depth == 16)
png_ptr->transformations |= PNG_SWAP_BYTES;
}
#endif
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
/* turn on pixel packing */
void PNGAPI
png_set_packing(png_structp png_ptr)
{
png_debug(1, "in png_set_packing\n");
if (png_ptr->bit_depth < 8)
{
png_ptr->transformations |= PNG_PACK;
png_ptr->usr_bit_depth = 8;
}
}
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
/* turn on packed pixel swapping */
void PNGAPI
png_set_packswap(png_structp png_ptr)
{
png_debug(1, "in png_set_packswap\n");
if (png_ptr->bit_depth < 8)
png_ptr->transformations |= PNG_PACKSWAP;
}
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
void PNGAPI
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
{
png_debug(1, "in png_set_shift\n");
png_ptr->transformations |= PNG_SHIFT;
png_ptr->shift = *true_bits;
}
#endif
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
defined(PNG_WRITE_INTERLACING_SUPPORTED)
int PNGAPI
png_set_interlace_handling(png_structp png_ptr)
{
png_debug(1, "in png_set_interlace handling\n");
if (png_ptr->interlaced)
{
png_ptr->transformations |= PNG_INTERLACE;
return (7);
}
return (1);
}
#endif
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
/* Add a filler byte on read, or remove a filler or alpha byte on write.
* The filler type has changed in v0.95 to allow future 2-byte fillers
* for 48-bit input data, as well as to avoid problems with some compilers
* that don't like bytes as parameters.
*/
void PNGAPI
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_filler\n");
png_ptr->transformations |= PNG_FILLER;
png_ptr->filler = (png_byte)filler;
if (filler_loc == PNG_FILLER_AFTER)
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
/* This should probably go in the "do_read_filler" routine.
* I attempted to do that in libpng-1.0.1a but that caused problems
* so I restored it in libpng-1.0.2a
*/
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
{
png_ptr->usr_channels = 4;
}
/* Also I added this in libpng-1.0.2a (what happens when we expand
* a less-than-8-bit grayscale to GA? */
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
{
png_ptr->usr_channels = 2;
}
}
#if !defined(PNG_1_0_X)
/* Added to libpng-1.2.7 */
void PNGAPI
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_add_alpha\n");
png_set_filler(png_ptr, filler, filler_loc);
png_ptr->transformations |= PNG_ADD_ALPHA;
}
#endif
#endif
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void PNGAPI
png_set_swap_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_swap_alpha\n");
png_ptr->transformations |= PNG_SWAP_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void PNGAPI
png_set_invert_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_alpha\n");
png_ptr->transformations |= PNG_INVERT_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
void PNGAPI
png_set_invert_mono(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_mono\n");
png_ptr->transformations |= PNG_INVERT_MONO;
}
/* invert monochrome grayscale data */
void /* PRIVATE */
png_do_invert(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_invert\n");
/* This test removed from libpng version 1.0.13 and 1.2.0:
* if (row_info->bit_depth == 1 &&
*/
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row == NULL || row_info == NULL)
return;
#endif
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop = row_info->rowbytes;
for (i = 0; i < istop; i++)
{
*rp = (png_byte)(~(*rp));
rp++;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 8)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop = row_info->rowbytes;
for (i = 0; i < istop; i+=2)
{
*rp = (png_byte)(~(*rp));
rp+=2;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
row_info->bit_depth == 16)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop = row_info->rowbytes;
for (i = 0; i < istop; i+=4)
{
*rp = (png_byte)(~(*rp));
*(rp+1) = (png_byte)(~(*(rp+1)));
rp+=4;
}
}
}
#endif
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
/* swaps byte order on 16 bit depth images */
void /* PRIVATE */
png_do_swap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_swap\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
row_info->bit_depth == 16)
{
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop= row_info->width * row_info->channels;
for (i = 0; i < istop; i++, rp += 2)
{
png_byte t = *rp;
*rp = *(rp + 1);
*(rp + 1) = t;
}
}
}
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
static png_byte onebppswaptable[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
static png_byte twobppswaptable[256] = {
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
};
static png_byte fourbppswaptable[256] = {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
};
/* swaps pixel packing order within bytes */
void /* PRIVATE */
png_do_packswap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_packswap\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
row_info->bit_depth < 8)
{
png_bytep rp, end, table;
end = row + row_info->rowbytes;
if (row_info->bit_depth == 1)
table = onebppswaptable;
else if (row_info->bit_depth == 2)
table = twobppswaptable;
else if (row_info->bit_depth == 4)
table = fourbppswaptable;
else
return;
for (rp = row; rp < end; rp++)
*rp = table[*rp];
}
}
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
/* remove filler or alpha byte(s) */
void /* PRIVATE */
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
{
png_debug(1, "in png_do_strip_filler\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL)
#endif
{
png_bytep sp=row;
png_bytep dp=row;
png_uint_32 row_width=row_info->width;
png_uint_32 i;
if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 4)
{
if (row_info->bit_depth == 8)
{
/* This converts from RGBX or RGBA to RGB */
if (flags & PNG_FLAG_FILLER_AFTER)
{
dp+=3; sp+=4;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp++;
}
}
/* This converts from XRGB or ARGB to RGB */
else
{
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 24;
row_info->rowbytes = row_width * 3;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
sp += 8; dp += 6;
for (i = 1; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
for (i = 0; i < row_width; i++)
{
/* This could be (although png_memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
sp+=2;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 48;
row_info->rowbytes = row_width * 6;
}
row_info->channels = 3;
}
else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
(row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
(flags & PNG_FLAG_STRIP_ALPHA))) &&
row_info->channels == 2)
{
if (row_info->bit_depth == 8)
{
/* This converts from GX or GA to G */
if (flags & PNG_FLAG_FILLER_AFTER)
{
for (i = 0; i < row_width; i++)
{
*dp++ = *sp++;
sp++;
}
}
/* This converts from XG or AG to G */
else
{
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 8;
row_info->rowbytes = row_width;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
/* This converts from GGXX or GGAA to GG */
sp += 4; dp += 2;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
/* This converts from XXGG or AAGG to GG */
for (i = 0; i < row_width; i++)
{
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 16;
row_info->rowbytes = row_width * 2;
}
row_info->channels = 1;
}
if (flags & PNG_FLAG_STRIP_ALPHA)
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
}
}
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* swaps red and blue bytes within a pixel */
void /* PRIVATE */
png_do_bgr(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_bgr\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{
png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 3)
{
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 4)
{
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
}
else if (row_info->bit_depth == 16)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 6)
{
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 5) = save;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row; i < row_width; i++, rp += 8)
{
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 5) = save;
}
}
}
}
}
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_LEGACY_SUPPORTED)
void PNGAPI
png_set_user_transform_info(png_structp png_ptr, png_voidp
user_transform_ptr, int user_transform_depth, int user_transform_channels)
{
png_debug(1, "in png_set_user_transform_info\n");
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
png_ptr->user_transform_ptr = user_transform_ptr;
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
#else
if(user_transform_ptr || user_transform_depth || user_transform_channels)
png_warning(png_ptr,
"This version of libpng does not support user transform info");
#endif
}
#endif
/* This function returns a pointer to the user_transform_ptr associated with
* the user transform functions. The application should free any memory
* associated with this pointer before png_write_destroy and png_read_destroy
* are called.
*/
png_voidp PNGAPI
png_get_user_transform_ptr(png_structp png_ptr)
{
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
return ((png_voidp)png_ptr->user_transform_ptr);
#else
if(png_ptr)
return (NULL);
return (NULL);
#endif
}

@ -0,0 +1,602 @@
/*
Declarations of BPQ32 API funtions
There are two sets of definitions, one for static linking against bpq32.lib, and one for
dynamic linking using LoadLibrary/GetProcAddress
Define symbol DYNLOADBPQ before including this file to use the dynamic form.
If you are writing an External Driver, rather than an application,
you must use Dynamic Linking, and you must also define symbol EXTDLL, which will
make the code use GetProcAddress rather than LoadLibrary. Without this the reference
count on BPQ32.dll gets messed up, and the code will not unload cleanly.
*/
#ifndef DYNLOADBPQ
// Definitions for Statically Linked DLL
struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portslot);
struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
// Returns number of free buffers
// (BPQHOST function 7 (part)).
int APIENTRY GetFreeBuffs();
// Returns count of packets waiting on stream
// (BPQHOST function 7 (part)).
int APIENTRY RXCount(int Stream);
// Returns number of packets on TX queue for stream
// (BPQHOST function 7 (part)).
int APIENTRY TXCount(int Stream);
// Returns number of monitor frames available
// (BPQHOST function 7 (part)).
int APIENTRY MONCount(int Stream);
// Returns call connecten on stream (BPQHOST function 8 (part)).
int APIENTRY GetCallsign(int stream, char * callsign);
// Returns connection info for stream (BPQHOST function 8).
int APIENTRY GetConnectionInfo(int stream, char * callsign,
int * port, int * sesstype, int * paclen,
int * maxframe, int * l4window);
int APIENTRY GetStreamPID(int Stream);
// Returns Path of BPQDirectroy
char * APIENTRY GetBPQDirectory();
char * APIENTRY GetProgramDirectory();
UCHAR * APIENTRY GetLogDirectory();
HKEY APIENTRY GetRegistryKey();
char * APIENTRY GetRegistryKeyText();
char * APIENTRY GetSignOnMsg();
char * APIENTRY GetVersionString();
// Returns number of prcess attached to BPQ32
int APIENTRY GetAttachedProcesses();
// Send Session Control command (BPQHOST function 6)
// Command = 0 Connect using APPL MASK IN param
// Command = 1 Connect
// Command = 2 Disconect
// Command = 3 Return to Node
int APIENTRY SessionControl(int stream, int command, int param);
// Sets Application Flags and Mask for stream. (BPQHOST function 1)
// Top bit of flags enables monitoring
int APIENTRY SetAppl(int stream, int flags, int mask);
int APIENTRY GetApplMask(int Stream);
int APIENTRY GetApplFlags(int Stream);
BOOL APIENTRY GetAllocationState(int Stream);
// Get current Session State. Any state changed is ACK'ed
// automatically. See BPQHOST functions 4 and 5.
int APIENTRY SessionState(int stream, int * state, int * change);
// Get current Session State. Dont Ack state change
// See BPQHOST function 4.
int APIENTRY SessionStateNoAck(int stream, int * state);
// Send message to stream (BPQHOST Function 2)
int APIENTRY SendMsg(int stream, char * msg, int len);
// Send Raw (KISS mode) frame to port (BPQHOST function 10)
int APIENTRY SendRaw(int port, char * msg, int len);
// Get message from stream. Returns length, and count of frames
// still waiting to be collected. (BPQHOST function 3)
int APIENTRY GetMsg(int stream, char * msg, int * len, int * count );
// Perl Version - I couldn't get bpq32.pm to call GetMsg. Returns Lenth
int APIENTRY GetMsgPerl(int stream, char * msg);
// Get Raw (Trace) data (BPQHOST function 11)
int APIENTRY GetRaw(int stream, char * msg, int * len, int * count );
// This is not an API function. It is a utility to decode a received
// monitor frame into ascii text.
int APIENTRY DecodeFrame(char * msg, char * buffer, time_t Stamp);
// Sets the tracing options for DecodeFrame. Mask is a bit
// mask of ports to monitor (ie 101 binary will monitor ports
// 1 and 3). MTX enables monitoring on transmitted frames. MCOM
// enables monitoring of protocol control frames (eg SABM, UA, RR),
// as well as info frames.
int APIENTRY SetTraceOptions(long mask, int mtxparam, int mcomparam);
int APIENTRY SetTraceOptionsEx(uint64_t mask, int mtxparam, int mcomparam, int monUIOnly);
int APIENTRY SetTraceOptions64(uint64_t mask, int mtxparam, int mcomparam, int monUIOnly);
// Returns number of first unused BPQHOST stream. If none available,
// returns 255. See API function 13.
int APIENTRY FindFreeStream();
// Allocate stream. If stream is already allocated, return nonzero.
// Otherwise allocate stream, and return zero
int APIENTRY AllocateStream(int stream);
// Release stream.
int APIENTRY DeallocateStream(int stream);
// Get number of ports configured
int APIENTRY GetNumberofPorts();
// Get port number (ports aren't necessarily numbered 1 to n)
int APIENTRY GetPortNumber(int portslot);
UCHAR * APIENTRY GetPortDescription(int portslot, char * Desc);
// Enable async operation - new to Win32 version of API
int APIENTRY BPQSetHandle(int Stream, HWND hWnd);
int ConvFromAX25(unsigned char * incall, unsigned char * outcall);
BOOL ConvToAX25(unsigned char * callsign, unsigned char * ax25call);
char * APIENTRY GetNodeCall();
int APIENTRY ChangeSessionCallsign(int Stream, unsigned char * AXCall);
int APIENTRY ChangeSessionPaclen(int Stream, int Paclen);
int APIENTRY GetApplNum(int Stream);
char * APIENTRY GetApplCall(int Appl);
char * APIENTRY GetApplAlias(int Appl);
long APIENTRY GetApplQual(int Appl);
char * APIENTRY GetApplNabe(int Appl);
BOOL APIENTRY SetApplCall(int Appl, char * NewCall);
BOOL APIENTRY SetApplAlias(int Appl, char * NewCall);
BOOL APIENTRY SetApplQual(int Appl, int NewQual);
// Routines to support "Minimize to Tray"
BOOL APIENTRY GetMinimizetoTrayFlag();
int APIENTRY AddTrayMenuItem(HWND hWnd, char * Label);
int APIENTRY DeleteTrayMenuItem(HWND hWnd);
BOOL APIENTRY StartMinimizedFlag();
// Log a message to the bpq32 console.
int APIENTRY WritetoConsole(char * buff);
// CheckTimer should be called regularly to ensure BPQ32 detects if an application crashes
int APIENTRY CheckTimer();
// CloseBPQ32 is used if you want to close and restart BPQ32 while your application is
// running. This is only relevant of you have Dynamically linked BPQ32
int APIENTRY CloseBPQ32();
int APIENTRY GETBPQAPI();
UINT APIENTRY GETMONDECODE();
VOID APIENTRY RelBuff(VOID * Msg);
//VOID *APIENTRY GetBuff();
VOID APIENTRY CreateOneTimePassword(char * Password, char * KeyPhrase, int TimeOffset);
BOOL APIENTRY CheckOneTimePassword(char * Password, char * KeyPhrase);
VOID APIENTRY md5 (char *arg, unsigned char * checksum);
int APIENTRY SetupTrayIcon();
BOOL APIENTRY SaveReg(char * KeyIn, HANDLE hFile);
VOID APIENTRY SendChatReport(UINT_PTR ChatReportSocket, char * buff, int txlen);
int APIENTRY CountFramesQueuedOnStream(int Stream);
char * APIENTRY GetLOC();
DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqString);
#else
struct PORTCONTROL * (FAR WINAPI * GetPortTableEntryFromPortNum) (int portnum);
struct PORTCONTROL * (FAR WINAPI * GetPortTableEntryFromSlot) (int portslot);
// API Definitions for Dynamic Load of BPQ32.dll
ULONG (FAR WINAPI * GETBPQAPI)();
ULONG (FAR WINAPI * GETMONDECODE)();
UCHAR * (FAR WINAPI * GetBPQDirectory)();
UCHAR * (FAR WINAPI * GetProgramDirectory)();
UCHAR * (FAR WINAPI * GetRegistryKeyText)();
HKEY (FAR WINAPI * GetRegistryKey)();
UCHAR * (FAR WINAPI * GetSignOnMsg)();
UCHAR * (FAR WINAPI * GetVersionString)();
// Returns number of free buffers
// (BPQHOST function 7 (part)).
int (FAR WINAPI * GetFreeBuffs)();
// Returns count of packets waiting on stream
// (BPQHOST function 7 (part)).
int (FAR WINAPI * RXCount) (int Stream);
// Returns number of packets on TX queue for stream
// (BPQHOST function 7 (part)).
int (FAR WINAPI * TXCount)(int Stream);
// Returns number of monitor frames available
// (BPQHOST function 7 (part)).
int (FAR WINAPI * MONCount) (int Stream);
// Returns call connecten on stream (BPQHOST function 8 (part)).
int (FAR WINAPI * GetCallsign)(int stream, char * callsign);
// Returns connection info for stream (BPQHOST function 8).
int (FAR WINAPI * GetConnectionInfo) (int stream, char * callsign,
int * port, int * sesstype, int * paclen,
int * maxframe, int * l4window);
int (FAR WINAPI * GetStreamPID) (int Stream);
// Returns Path of BPQDirectroy
UCHAR * (FAR WINAPI * GetBPQDirectory)();
// Returns number of prcess attached to BPQ32
int (FAR WINAPI * GetAttachedProcesses) ();
// Send Session Control command (BPQHOST function 6)
// Command = 0 Connect using APPL MASK IN param
// Command = 1 Connect
// Command = 2 Disconect
// Command = 3 Return to Node
int (FAR WINAPI * SessionControl) (int stream, int command, int param);
// Sets Application Flags and Mask for stream. (BPQHOST function 1)
// Top bit of flags enables monitoring
int (FAR WINAPI * SetAppl) (int stream, int flags, int mask);
int (FAR WINAPI * GetApplMask) (int Stream);
int (FAR WINAPI * GetApplFlags)(int Stream);
BOOL (FAR WINAPI * GetAllocationState) (int Stream);
// Get current Session State. Any state changed is ACK'ed
// automatically. See BPQHOST functions 4 and 5.
int (FAR WINAPI * SessionState) (int stream, int * state, int * change);
// Get current Session State. Dont Ack state change
// See BPQHOST function 4.
int (FAR WINAPI * SessionStateNoAck) (int stream, int * state);
// Send message to stream (BPQHOST Function 2)
int (FAR WINAPI * SendMsg) (int stream, char * msg, int len);
// Send Raw (KISS mode) frame to port (BPQHOST function 10)
int (FAR WINAPI * SendRaw) (int port, char * msg, int len);
// Get message from stream. Returns length, and count of frames
// still waiting to be collected. (BPQHOST function 3)
int (FAR WINAPI * GetMsg) (int stream, char * msg, int * len, int * count );
// Perl Version - I couldn't get bpq32.pm to call GetMsg. Returns Lenth
int (FAR WINAPI * GetMsgPerl) (int stream, char * msg);
// Get Raw (Trace) data (BPQHOST function 11)
int (FAR WINAPI * GetRaw) (int stream, char * msg, int * len, int * count );
// This is not an API function. It is a utility to decode a received
// monitor frame into ascii text.
int (FAR WINAPI * DecodeFrame) (char * msg, char * buffer, int Stamp);
// Sets the tracing options for DecodeFrame. Mask is a bit
// mask of ports to monitor (ie 101 binary will monitor ports
// 1 and 3). MTX enables monitoring on transmitted frames. MCOM
// enables monitoring of protocol control frames (eg SABM, UA, RR),
// as well as info frames.
int (FAR WINAPI * SetTraceOptions) (long mask, int mtxparam, int mcomparam);
// Returns number of first unused BPQHOST stream. If none available,
// returns 255. See API function 13.
int (FAR WINAPI * FindFreeStream) ();
// Allocate stream. If stream is already allocated, return nonzero.
// Otherwise allocate stream, and return zero
int (FAR WINAPI * AllocateStream) (int stream);
// Release stream.
int (FAR WINAPI * DeallocateStream) (int stream);
// Get number of ports configured
int (FAR WINAPI * GetNumberofPorts) ();
// Get port number (ports aren't necessarily numbered 1 to n)
int (FAR WINAPI * GetPortNumber) (int portslot);
// Enable async operation - new to Win32 version of API
int (FAR WINAPI * BPQSetHandle) (int Stream, HWND hWnd);
int (FAR * ConvFromAX25) (unsigned char * incall, unsigned char * outcall);
BOOL (FAR * ConvToAX25) (unsigned char * callsign, unsigned char * ax25call);
char * (FAR WINAPI * GetNodeCall) ();
int (FAR WINAPI * ChangeSessionCallsign) (int Stream, unsigned char * AXCall);
int (FAR WINAPI * GetApplNum) (int Stream);
char * (FAR WINAPI * GetApplCall) (int Appl);
char * (FAR WINAPI * GetApplAlias) (int Appl);
char * (FAR WINAPI * GetApplName) (int Appl);
long (FAR WINAPI * GetApplQual) (int Appl);
BOOL (FAR WINAPI * SetApplCall) (int Appl, char * NewCall);
BOOL (FAR WINAPI * SetApplAlias) (int Appl, char * NewCall);
BOOL (FAR WINAPI * SetApplQual) (int Appl, int NewQual);
// Routines to support "Minimize to Tray"
BOOL (FAR WINAPI * GetMinimizetoTrayFlag)();
//int APIENTRY AddTrayMenuItem();
int (FAR WINAPI * AddTrayMenuItem)(HWND hWnd, char * Label);
//int APIENTRY DeleteTrayMenuItem();
int (FAR WINAPI * DeleteTrayMenuItem)(HWND hWnd);
int (FAR WINAPI * SetupTrayIcon)();
BOOL (FAR WINAPI * GetStartMinimizedFlag)();
// Log a message to the bpq32 console.
//int APIENTRY WritetoConsole();
int (FAR WINAPI * WritetoConsole)(char * buff);
int (FAR WINAPI * CheckTimer)();
int (FAR WINAPI * CloseBPQ32)();
char (FAR WINAPI * GetLOC)();
HMODULE ExtDriver;
BOOL GetAPI()
{
// This procedure must be called if you are using Dynamic Linking. It loads BPQ32
// if necessary, and get the addresses of the API routines
int err;
char Msg[256];
#ifdef EXTDLL
ExtDriver=GetModuleHandle("bpq32.dll");
#else
ExtDriver=LoadLibrary("bpq32.dll");
#endif
if (ExtDriver == NULL)
{
err=GetLastError();
wsprintf(Msg,"Error loading bpq32.dll - Error code %d",err);
MessageBox(NULL,Msg,"BPQDEMO",MB_ICONSTOP);
return(FALSE);
}
GetPortTableEntryFromPortNum = (struct PORTCONTROL * (__stdcall *)(int PortSlot))GetProcAddress(ExtDriver,"_GetPortTableEntryFromPortNum@4");
GetPortTableEntryFromSlot = (struct PORTCONTROL * (__stdcall *)(int PortSlot))GetProcAddress(ExtDriver,"_GetPortTableEntryFromSlot@4");
GETBPQAPI = (ULONG(__stdcall *)())GetProcAddress(ExtDriver,"_GETBPQAPI@0");
GETMONDECODE = (ULONG(__stdcall *)())GetProcAddress(ExtDriver,"_GETMONDECODE@0");
GetFreeBuffs = (int (__stdcall *)(int stream))GetProcAddress(ExtDriver,"_GetFreeBuffs@0");
TXCount = (int (__stdcall *)(int stream))GetProcAddress(ExtDriver,"_RXCount@4");
RXCount = (int (__stdcall *)(int stream))GetProcAddress(ExtDriver,"_RXCount@4");
MONCount = (int (__stdcall *)(int stream))GetProcAddress(ExtDriver,"_MONCount@4");
GetCallsign = (int (__stdcall *)(int stream, char * callsign))GetProcAddress(ExtDriver,"_GetCallsign@8");
GetBPQDirectory = (UCHAR *(__stdcall *)())GetProcAddress(ExtDriver,"_GetBPQDirectory@0");
GetProgramDirectory = (UCHAR *(__stdcall *)())GetProcAddress(ExtDriver,"_GetProgramDirectory@0");
GetRegistryKey = (HKEY(__stdcall *)())GetProcAddress(ExtDriver,"_GetRegistryKey@0");
GetRegistryKeyText = (UCHAR *(__stdcall *)())GetProcAddress(ExtDriver,"_GetRegistryKeyText@0");
GetSignOnMsg = (UCHAR *(__stdcall *)())GetProcAddress(ExtDriver,"_GetSignOnMsg@0");
GetVersionString = (UCHAR *(__stdcall *)())GetProcAddress(ExtDriver,"_GetVersionString@0");
GetConnectionInfo = (int (__stdcall *)(int, char *,int *, int *, int *,int *, int *))GetProcAddress(ExtDriver,"_GetConnectionInfo@28");
GetStreamPID = (int (__stdcall *)(int Stream))GetProcAddress(ExtDriver,"_GetStreamPID@4");
GetAttachedProcesses = (int (__stdcall *)())GetProcAddress(ExtDriver,"_GetAttachedProcesses@0");
SessionControl = (int (__stdcall *)(int stream, int command, int param))GetProcAddress(ExtDriver,"_SessionControl@12");
SetAppl = (int (__stdcall *)(int stream, int flags, int mask))GetProcAddress(ExtDriver,"_SetAppl@12");
GetApplMask = (int (__stdcall *)(int Stream))GetProcAddress(ExtDriver,"_GetApplMask@4");
GetApplFlags = (int (__stdcall *)(int Stream))GetProcAddress(ExtDriver,"_GetApplFlags@4");
GetAllocationState = (int (__stdcall *)(int Stream))GetProcAddress(ExtDriver,"_GetAllocationState@4");
SessionState = (int (__stdcall *)(int, int *, int *))GetProcAddress(ExtDriver,"_SessionState@12");
SessionStateNoAck = (int (__stdcall *)(int, int *))GetProcAddress(ExtDriver,"_SessionStateNoAck@8");
SendMsg = (int (__stdcall *)(int stream, char * msg, int len))GetProcAddress(ExtDriver,"_SendMsg@12");
SendRaw = (int (__stdcall *)(int port, char * msg, int len))GetProcAddress(ExtDriver,"_SendRaw@12");
GetMsg = (int (__stdcall *)(int stream, char * msg, int * len, int * count ))GetProcAddress(ExtDriver,"_GetMsg@16");
GetMsgPerl = (int (__stdcall *)(int stream, char * msg))GetProcAddress(ExtDriver,"_GetMsgPerl@8");
GetRaw = (int (__stdcall *)(int stream, char * msg, int * len, int * count))GetProcAddress(ExtDriver,"_GetRaw@16");
DecodeFrame = (int (__stdcall *)(char * msg, char * buffer, time_t Stamp))GetProcAddress(ExtDriver,"_DecodeFrame@12");
SetTraceOptions = (int (__stdcall *)(long mask, int mtxparam, int mcomparam))GetProcAddress(ExtDriver,"_SetTraceOptions@12");
FindFreeStream = (int (__stdcall *)())GetProcAddress(ExtDriver,"_FindFreeStream@0");
AllocateStream= (int (__stdcall *)(int Stream))GetProcAddress(ExtDriver,"_AllocateStream@4");
DeallocateStream = (int (__stdcall *)(int Stream))GetProcAddress(ExtDriver,"_DeallocateStream@4");
GetNumberofPorts = (int (__stdcall *)())GetProcAddress(ExtDriver,"_GetNumberofPorts@0");
GetPortNumber = (int (__stdcall *)(int))GetProcAddress(ExtDriver,"_GetPortNumber@4");
BPQSetHandle = (int (__stdcall *)(int Stream, HWND hWnd))GetProcAddress(ExtDriver,"_BPQSetHandle@8");
ConvFromAX25 = (int ( *)(unsigned char * incall, unsigned char * outcall))GetProcAddress(ExtDriver,"ConvFromAX25");
ConvToAX25 = (BOOL ( *)(unsigned char * callsign, unsigned char * ax25call))GetProcAddress(ExtDriver,"ConvToAX25");
GetNodeCall = (char * (__stdcall *) ())GetProcAddress(ExtDriver,"_GetNodeCall@0");
ChangeSessionCallsign = (int (__stdcall *) (int Stream, unsigned char * AXCall))GetProcAddress(ExtDriver,"_ChangeSessionCallsign@8");
GetApplNum = (int (__stdcall *)(int Stream))GetProcAddress(ExtDriver,"_GetApplNum@4");
GetApplCall = (char * (__stdcall *) (int Appl))GetProcAddress(ExtDriver,"_GetApplCall@4");
GetApplAlias = (char * (__stdcall *) (int Appl))GetProcAddress(ExtDriver,"_GetApplAlias@4");
GetApplQual = (long (__stdcall *)(int Appl))GetProcAddress(ExtDriver,"_GetApplQual@4");
GetApplName = (char * (__stdcall *) (int Appl))GetProcAddress(ExtDriver,"_GetApplName@4");
SetApplCall = (BOOL (__stdcall *)(int Appl, char * NewCall))GetProcAddress(ExtDriver,"_SetApplCall@8");
SetApplAlias = (BOOL (__stdcall *)(int Appl, char * NewCall))GetProcAddress(ExtDriver,"_SetApplAlias@8");
SetApplQual = (BOOL (__stdcall *)(int Appl, int NewQual))GetProcAddress(ExtDriver,"_SetApplQual@8");
GetMinimizetoTrayFlag = (BOOL (__stdcall *)())GetProcAddress(ExtDriver,"_GetMinimizetoTrayFlag@0");
AddTrayMenuItem = (int (__stdcall *)(HWND hWnd, char * Label))GetProcAddress(ExtDriver,"_AddTrayMenuItem@8");
DeleteTrayMenuItem = (int (__stdcall *)(HWND hWnd))GetProcAddress(ExtDriver,"_DeleteTrayMenuItem@4");
SetupTrayIcon = (BOOL (__stdcall *)())GetProcAddress(ExtDriver,"_SetupTrayIcon@0");
GetStartMinimizedFlag = (BOOL (__stdcall *)())GetProcAddress(ExtDriver,"_GetStartMinimizedFlag@0");
WritetoConsole = (int (__stdcall *)(char *))GetProcAddress(ExtDriver,"_WritetoConsole@4");
CheckTimer = (int (__stdcall *)(char *))GetProcAddress(ExtDriver,"_CheckTimer@0");
CloseBPQ32 = (int (__stdcall *)(char *))GetProcAddress(ExtDriver,"_CloseBPQ32@0");
GetLOC = (char * (__stdcall *)(char *))GetProcAddress(ExtDriver,"_GetLOC@0");
return TRUE;
}
#endif
//
// Constants and equates for async operation
//
#ifndef BPQWINMSG
#define BPQWINMSG
static char BPQWinMsg[] = "BPQWindowMessage";
extern UINT BPQMsg;
//
// Values returned in lParam of Windows Message
//
#define BPQMonitorAvail 1
#define BPQDataAvail 2
#define BPQStateChange 4
#endif

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UDPtoTCP", "UDPtoTCP\UDPtoTCP.vcproj", "{879D4FD3-82E0-429E-8A54-7AF4CA9FEF7D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{879D4FD3-82E0-429E-8A54-7AF4CA9FEF7D}.Debug|Win32.ActiveCfg = Debug|Win32
{879D4FD3-82E0-429E-8A54-7AF4CA9FEF7D}.Debug|Win32.Build.0 = Debug|Win32
{879D4FD3-82E0-429E-8A54-7AF4CA9FEF7D}.Release|Win32.ActiveCfg = Release|Win32
{879D4FD3-82E0-429E-8A54-7AF4CA9FEF7D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -0,0 +1,224 @@
/*
Copyright 2001-2018 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
*/
#include "bpqmail.h"
int LastVer[4] = {0, 0, 0, 0}; // In case we need to do somthing the first time a version is run
HWND MainWnd;
HWND hWndSess;
RECT MainRect;
HMENU hActionMenu;
static HMENU hMenu;
HMENU hDisMenu; // Disconnect Menu Handle
HMENU hFWDMenu; // Forward Menu Handle
int SessX, SessY, SessWidth; // Params for Session Window
char szBuff[80];
#define MaxSockets 64
ConnectionInfo Connections[MaxSockets+1];
struct SEM ChatSemaphore = {0, 0};
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;
struct UserInfo * BBSChain = NULL; // Chain of users that are BBSes
struct MsgInfo ** MsgHddrPtr=NULL;
int NumberofMessages=0;
int FirstMessageIndextoForward = 0; // Lowest Message with a forward bit set - limits search
BIDRec ** BIDRecPtr=NULL;
int NumberofBIDs=0;
BIDRec ** TempBIDRecPtr=NULL;
int NumberofTempBIDs=0;
WPRec ** WPRecPtr=NULL;
int NumberofWPrecs=0;
char ** BadWords=NULL;
int NumberofBadWords=0;
char * BadFile = NULL;
int LatestMsg = 0;
struct SEM MsgNoSemaphore = {0, 0}; // For locking updates to LatestMsg
int HighestBBSNumber = 0;
int MaxMsgno = 60000;
int BidLifetime = 60;
int MaxAge = 30;
int MaintInterval = 24;
int MaintTime = 0;
int UserLifetime = 0;
BOOL cfgMinToTray;
BOOL DisconnectOnClose=FALSE;
char PasswordMsg[100]="Password:";
char cfgHOSTPROMPT[100];
char cfgCTEXT[100];
char cfgLOCALECHO[100];
char AttemptsMsg[] = "Too many attempts - Disconnected\r\r";
char disMsg[] = "Disconnected by SYSOP\r\r";
char LoginMsg[]="user:";
char BlankCall[]=" ";
ULONG BBSApplMask;
ULONG ChatApplMask;
int BBSApplNum=0;
int ChatApplNum=0;
//int StartStream=0;
int NumberofStreams=0;
int MaxStreams=0;
char BBSSID[]="[%s%d.%d.%d.%d-%s%s%s%sIH%sM$]\r";
char ChatSID[]="[BPQChatServer-%d.%d.%d.%d]\r";
char NewUserPrompt[100]="Please enter your Name\r>\r";
char * WelcomeMsg = NULL;
char * NewWelcomeMsg = NULL;
char * ExpertWelcomeMsg = NULL;
char * Prompt = NULL;
char * NewPrompt = NULL;
char * ExpertPrompt = NULL;
char BBSName[100] = "NOCALL";
char SYSOPCall[50];
char MailForText[100];
char HRoute[100];
char AMPRDomain[100];
BOOL SendAMPRDirect = 0;
char SignoffMsg[120];
char AbortedMsg[100]="\rOutput aborted\r";
char UserDatabaseName[MAX_PATH] = "BPQBBSUsers.dat";
char UserDatabasePath[MAX_PATH];
char MsgDatabasePath[MAX_PATH];
char MsgDatabaseName[MAX_PATH] = "DIRMES.SYS";
char BIDDatabasePath[MAX_PATH];
char BIDDatabaseName[MAX_PATH] = "WFBID.SYS";
char WPDatabasePath[MAX_PATH];
char WPDatabaseName[MAX_PATH] = "WP.SYS";
char BadWordsPath[MAX_PATH];
char BadWordsName[MAX_PATH] = "BADWORDS.SYS";
char NTSAliasesPath[MAX_PATH];
char NTSAliasesName[MAX_PATH] = "INTRCPT.APS";
char ConfigName[250];
char ChatConfigName[250];
BOOL UsingingRegConfig = FALSE;
BOOL MulticastRX = FALSE;
char BaseDir[MAX_PATH];
char BaseDirRaw[MAX_PATH]; // As set in registry - may contain %NAME%
char ProperBaseDir[MAX_PATH]; // BPQ Directory/BPQMailChat
char MailDir[MAX_PATH];
char RlineVer[50];
BOOL KISSOnly = FALSE;
BOOL EnableUI = FALSE;
BOOL RefuseBulls = FALSE;
BOOL SendSYStoSYSOPCall = FALSE;
BOOL SendBBStoSYSOPCall = FALSE;
BOOL DontHoldNewUsers = FALSE;
BOOL DefaultNoWINLINK = FALSE;
BOOL ForwardToMe = FALSE;
BOOL OnlyKnown = FALSE;
BOOL DontNeedHomeBBS = FALSE;
BOOL DontCheckFromCall = FALSE;
// Send WP Params
BOOL SendWP;
BOOL FilterWPBulls;
BOOL NoWPGuesses;
char SendWPVIA[81];
char SendWPTO[11];
char ** SendWPAddrs; // Replaces WP To and VIA
int SendWPType;
int SMTPMsgs;
int MailForInterval = 0;
char zeros[NBMASK]; // For forward bitmask tests
time_t MaintClock; // Time to run housekeeping
time_t APIClock; // Time to sent to MOLTE's Database
struct MsgInfo * MsgnotoMsg[100000]; // Message Number to Message Slot List.
// Filter Params
char ** RejFrom; // Reject on FROM Call
char ** RejTo; // Reject on TO Call
char ** RejAt; // Reject on AT Call
char ** RejBID; // Reject on BID
char ** HoldFrom; // Hold on FROM Call
char ** HoldTo; // Hold on TO Call
char ** HoldAt; // Hold on AT Call
char ** HoldBID; // Hold on BID
struct ConsoleInfo * ConsHeader[2];

@ -0,0 +1,205 @@
/* Types.h -- Basic types
2008-11-23 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#include <stddef.h>
#ifdef WIN32
#include <windows.h>
#endif
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
extern const char *LZMA_ERRORS[];
typedef int SRes;
#ifdef _WIN32
typedef DWORD WRes;
#else
typedef int WRes;
#endif
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_LZ_UInt32_IS_ULONG
typedef long LZ_Int32;
typedef unsigned long LZ_UInt32;
#else
typedef int LZ_Int32;
typedef unsigned int LZ_UInt32;
#endif
#ifdef _SZ_NO_INT_64
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
NOTES: Some code will work incorrectly in that case! */
typedef long LZ_Int64;
typedef unsigned long LZ_UInt64;
#else
typedef long long int LZ_Int64;
typedef unsigned long long int LZ_UInt64;
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef LZ_UInt32 SizeT;
#else
typedef size_t SizeT;
#endif
//typedef int Bool;
#define True 1
#define False 0
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_CDECL __cdecl
#define MY_STD_CALL __stdcall
#define MY_FAST_CALL MY_NO_INLINE __fastcall
#else
#define MY_CDECL
#define MY_STD_CALL
#define MY_FAST_CALL
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
/* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
typedef struct
{
size_t (*Write)(void *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, LZ_Int64 *pos, ESzSeek origin);
} ISeekInStream;
typedef struct
{
SRes (*Look)(void *p, void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, LZ_Int64 *pos, ESzSeek origin);
} ILookInStream;
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStream *stream, LZ_UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct
{
ILookInStream s;
ISeekInStream *realStream;
size_t pos;
size_t size;
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead;
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream s;
ILookInStream *realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
{
SRes (*Progress)(void *p, LZ_UInt64 inSize, LZ_UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (LZ_UInt64)(LZ_Int64)-1 for size means unknown value. */
} ICompressProgress;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#endif

@ -0,0 +1,21 @@
#ifndef MINIUPNPC_DECLSPEC_H_INCLUDED
#define MINIUPNPC_DECLSPEC_H_INCLUDED
#if defined(_WIN32) && !defined(MINIUPNP_STATICLIB)
/* for windows dll */
#ifdef MINIUPNP_EXPORTS
#define MINIUPNP_LIBSPEC __declspec(dllexport)
#else
#define MINIUPNP_LIBSPEC __declspec(dllimport)
#endif
#else
#if defined(__GNUC__) && __GNUC__ >= 4
/* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */
#define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default")))
#else
#define MINIUPNP_LIBSPEC
#endif
#endif
#endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */

@ -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);

@ -0,0 +1,68 @@
// CmdLineAuth.cpp : Defines the entry point for the console application.
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#define _USE_32BIT_TIME_T
#include <stdio.h>
#include <time.h>
#include <stdio.h>
#include "MD5.c"
int LastNow;
int PassCode;
VOID CreateOneTimePassword(char * KeyPhrase)
{
// Create a time dependent One Time Password from the KeyPhrase
time_t NOW = time(NULL);
unsigned char Hash[16];
char Password[20];
char Key[1000];
int i, chr;
long long Val;
NOW = NOW/30; // Only Change every 30 secs
if (NOW == LastNow)
return;
LastNow = NOW;
sprintf(Key, "%s%x", KeyPhrase, NOW);
md5(Key, Hash);
for (i=0; i<16; i++)
{
chr = (Hash[i] & 31);
if (chr > 9) chr += 7;
Password[i] = chr + 48;
}
Password[16] = 0;
memcpy(&Val, Password, 8);
PassCode = Val %= 1000000;
printf("Passcode is %d\n", PassCode);
return;
}
int main(int argc, char * argv[])
{
if (argc < 2)
{
printf ("Need to supply KeyPhrase\n");
return 0;
}
CreateOneTimePassword(argv[1]);
return 0;
}

@ -0,0 +1,71 @@
//Microsoft Developer Studio generated resource script.
//
//#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "windows.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
#define BPQICON 400
BPQICON ICON DISCARDABLE "..\BPQIcon.ICO"
//
// Version
//
#define TEXTVER "1. 0. 3. 4\0"
#define BINVER 1, 0, 3, 4
VS_VERSION_INFO VERSIONINFO
FILEVERSION BINVER
PRODUCTVERSION BINVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "Comments", "Program to control WINMOR TNC when running remotely\0"
VALUE "CompanyName", " \0"
VALUE "FileDescription", "WinmorControl\0"
VALUE "FileVersion", TEXTVER
VALUE "InternalName", "bpq32\0"
VALUE "LegalCopyright", "Copyright © 2021 G8BPQ\0"
VALUE "OriginalFilename", "\WinmorControl.exe\0"
VALUE "ProductName", "WinmorControl\0"
VALUE "ProductVersion", TEXTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
#endif // not APSTUDIO_INVOKED

@ -0,0 +1,578 @@
//
// DLL to inteface the BPQ Virtual COM emulator to BPQ32 switch
//
// Uses BPQ EXTERNAL interface
//
// Version 1.0 November 2005
//
// Version 1.1 October 2006
// Write diagmnostics to BPQ console window instead of STDOUT
// Version 1.2 February 2008
// Changes for dynamic unload of bpq32.dll
// Version 1.2.1 May 2008
// Correct RX length (was 1 byte too long)
// Version 1.3.1 Jan 2009
// Support Win98 VirtualCOM Driver
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_DEPRECATE
//#include <process.h>
//#include <time.h>
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
typedef unsigned char byte;
#include "cheaders.h"
#include "bpqvkiss.h"
#include <stdlib.h>
//#define DYNLOADBPQ // Dynamically Load BPQ32.dll
//#define EXTDLL // Use GetMuduleHandle instead of LoadLibrary
#include "bpq32.h"
static int ASYINIT(int comport, int speed, int bpqport, BOOL Report);
int kissencode(UCHAR * inbuff, UCHAR * outbuff, int len);
int GetRXMessage(int port, PMESSAGE buff);
void CheckReceivedData(PVCOMINFO pVCOMInfo);
static int ReadCommBlock(PVCOMINFO pVCOMInfo, LPSTR lpszBlock, DWORD nMaxLength );
static BOOL WriteCommBlock(int port, UCHAR * lpByte , DWORD dwBytesToWrite);
PVCOMINFO CreateInfo( int port,int speed, int bpqport ) ;
#define FEND 0xC0 // KISS CONTROL CODES
#define FESC 0xDB
#define TFEND 0xDC
#define TFESC 0xDD
static BOOL Win98 = FALSE;
struct PORTCONTROL * PORTVEC[MaxBPQPortNo + 1];
static size_t ExtProc(int fn, int port, PMESSAGE buff)
{
int len,txlen=0;
char txbuff[1000];
if (VCOMInfo[port]->ComDev == (HANDLE) -1)
{
// Try to reopen every 30 secs
VCOMInfo[port]->ReopenTimer++;
if (VCOMInfo[port]->ReopenTimer < 300)
return 0;
VCOMInfo[port]->ReopenTimer = 0;
ASYINIT(PORTVEC[port]->IOBASE, 9600, port, FALSE);
if (VCOMInfo[port]->ComDev == (HANDLE) -1)
return 0;
}
switch (fn)
{
case 1: // poll
len = GetRXMessage(port,buff);
// if (len > 0)
// {
// // Randomly drop packets
// if ((rand() % 7) > 5)
// {
// Debugprintf("VKISS Test Drop packet");
// return 0;
// }
// }
return len;
case 2: // send
txlen = GetLengthfromBuffer((PDATAMESSAGE)buff);
txlen = kissencode(&buff->DEST[0], (char *) &txbuff, txlen - MSGHDDRLEN);
WriteCommBlock(port, txbuff, txlen);
return (0);
case 3: // CHECK IF OK TO SEND
return (0); // OK
break;
case 4: // reinit
CloseHandle(VCOMInfo[port]->ComDev);
VCOMInfo[port]->ComDev =(HANDLE) -1;
VCOMInfo[port]->ReopenTimer = 250;
return (0);
case 5: // Close
CloseHandle(VCOMInfo[port]->ComDev);
return (0);
}
return 0;
}
VOID * VCOMExtInit(struct PORTCONTROL * PortEntry)
{
char msg[80];
//
// Will be called once for each port to be mapped to a BPQ Virtual COM Port
// The VCOM port number is in IOBASE
//
sprintf(msg,"VKISS COM%d", PortEntry->IOBASE);
WritetoConsole(msg);
PORTVEC[PortEntry->PORTNUMBER] = PortEntry;
CreateInfo(PortEntry->IOBASE, 9600, PortEntry->PORTNUMBER);
// Open File
ASYINIT(PortEntry->IOBASE, 9600, PortEntry->PORTNUMBER, TRUE);
WritetoConsole("\n");
return ExtProc;
}
static int kissencode(UCHAR * inbuff, UCHAR * outbuff, int len)
{
int i, txptr = 0;
UCHAR c;
outbuff[0] = FEND;
outbuff[1] = 0;
txptr = 2;
for (i = 0; i < len; i++)
{
c = inbuff[i];
switch (c)
{
case FEND:
outbuff[txptr++] = FESC;
outbuff[txptr++] = TFEND;
break;
case FESC:
outbuff[txptr++] = FESC;
outbuff[txptr++] = TFESC;
break;
default:
outbuff[txptr++] = c;
}
}
outbuff[txptr++] = FEND;
return txptr;
}
int ASYINIT(int comport, int speed, int bpqport, BOOL Report)
{
char szPort[ 30 ];
char buf[256];
int n, Err;
#pragma warning( push )
#pragma warning( disable : 4996 )
#ifndef _winver
#define _winver 0x0600
#endif
if (HIBYTE(_winver) < 5)
Win98 = TRUE;
#pragma warning( pop )
if (Win98)
{
VCOMInfo[bpqport]->ComDev = CreateFile( "\\\\.\\BPQVCOMM.VXD", GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
}
else{
sprintf( szPort, "\\\\.\\pipe\\BPQCOM%d", comport ) ;
VCOMInfo[bpqport]->ComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
//Handle = CreateFile(Value, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
Err = GetLastError();
if (VCOMInfo[bpqport]->ComDev != (HANDLE) -1)
{
VCOMInfo[bpqport]->NewVCOM = TRUE;
Err = GetFileType(VCOMInfo[bpqport]->ComDev);
}
else
{
// Try old style
sprintf( szPort, "\\\\.\\BPQ%d", comport ) ;
VCOMInfo[bpqport]->ComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
}
}
if (VCOMInfo[bpqport]->ComDev == (HANDLE) -1 && Report)
{
n=sprintf(buf,"Virtual COM Port %d could not be opened ",comport);
WritetoConsole(buf);
return (FALSE) ;
}
return (TRUE) ;
}
static int GetRXMessage(int port, PMESSAGE buff)
{
int len;
PVCOMINFO pVCOMInfo ;
if (NULL == (pVCOMInfo = VCOMInfo[port]))
return 0;
if (!pVCOMInfo->MSGREADY)
CheckReceivedData(pVCOMInfo); // Look for data in RXBUFFER and COM port
if (pVCOMInfo->MSGREADY)
{
len = (int)(pVCOMInfo->RXMPTR- &pVCOMInfo->RXMSG[1]); // Don't need KISS Control Byte
if (pVCOMInfo->RXMSG[0] != 0 && pVCOMInfo->RXMSG[0] != 12)
{
pVCOMInfo->MSGREADY=FALSE;
pVCOMInfo->RXMPTR=(UCHAR *)&pVCOMInfo->RXMSG;
return 0; // Not KISS Data
}
//
// Remove KISS control byte
//
if (pVCOMInfo->RXMSG[0] == 12)
{
// AckMode Frame. Return the next 2 bytes, but don't pass them to Host
UCHAR AckResp[8];
AckResp[0] = FEND;
memcpy(&AckResp[1], &pVCOMInfo->RXMSG[0], 3); //Copy Opcode and Ack Bytes
AckResp[4] = FEND;
WriteCommBlock(port, AckResp, 5);
len -= 2;
memcpy(&buff->DEST[0], &pVCOMInfo->RXMSG[3], len);
// Debugprintf("VKISS Ackmode Frame");
}
else
memcpy(&buff->DEST[0], &pVCOMInfo->RXMSG[1], len);
len += MSGHDDRLEN;
PutLengthinBuffer((PDATAMESSAGE)buff, len);
//
// reset pointers
//
pVCOMInfo->MSGREADY=FALSE;
pVCOMInfo->RXMPTR=(UCHAR *)&pVCOMInfo->RXMSG;
return len;
}
else
return 0; // nothing doing
}
static void CheckReceivedData(PVCOMINFO pVCOMInfo)
{
UCHAR c;
if (pVCOMInfo->RXBCOUNT == 0)
{
//
// Check com buffer
//
pVCOMInfo->RXBCOUNT = ReadCommBlock(pVCOMInfo, (LPSTR) &pVCOMInfo->RXBUFFER, MAXBLOCK-1 );
pVCOMInfo->RXBPTR=(UCHAR *)&pVCOMInfo->RXBUFFER;
}
if (pVCOMInfo->RXBCOUNT == 0)
return;
while (pVCOMInfo->RXBCOUNT != 0)
{
pVCOMInfo->RXBCOUNT--;
c = *(pVCOMInfo->RXBPTR++);
if (pVCOMInfo->ESCFLAG)
{
//
// FESC received - next should be TFESC or TFEND
pVCOMInfo->ESCFLAG = FALSE;
if (c == TFESC)
c=FESC;
if (c == TFEND)
c=FEND;
}
else
{
switch (c)
{
case FEND:
//
// Either start of message or message complete
//
if (pVCOMInfo->RXMPTR == (UCHAR *)&pVCOMInfo->RXMSG)
continue;
pVCOMInfo->MSGREADY=TRUE;
return;
case FESC:
pVCOMInfo->ESCFLAG = TRUE;
continue;
}
}
//
// Ok, a normal char
//
*(pVCOMInfo->RXMPTR++) = c;
}
if (pVCOMInfo->RXMPTR - (UCHAR *)&pVCOMInfo->RXMSG > 500)
pVCOMInfo->RXMPTR=(UCHAR *)&pVCOMInfo->RXMSG;
return;
}
static PVCOMINFO CreateInfo( int port,int speed, int bpqport )
{
PVCOMINFO pVCOMInfo ;
if (NULL == (pVCOMInfo =
(PVCOMINFO) LocalAlloc( LPTR, sizeof( VCOMINFO ) )))
return ( (PVCOMINFO) -1 ) ;
pVCOMInfo->RXBCOUNT=0;
pVCOMInfo->MSGREADY=FALSE;
pVCOMInfo->RXBPTR=(UCHAR *)&pVCOMInfo->RXBUFFER;
pVCOMInfo->RXMPTR=(UCHAR *)&pVCOMInfo->RXMSG;
pVCOMInfo->ComDev = 0 ;
pVCOMInfo->Connected = FALSE ;
pVCOMInfo->Port = port;
VCOMInfo[bpqport]=pVCOMInfo;
return (pVCOMInfo);
}
static BOOL NEAR DestroyTTYInfo( int port )
{
PVCOMINFO pVCOMInfo ;
if (NULL == (pVCOMInfo = VCOMInfo[port]))
return ( FALSE ) ;
LocalFree( pVCOMInfo ) ;
VCOMInfo[port] = 0;
return ( TRUE ) ;
}
static int ReadCommBlock(PVCOMINFO pVCOMInfo, LPSTR lpszBlock, DWORD nMaxLength)
{
DWORD dwLength = 0;
DWORD Available = 0;
if (Win98)
DeviceIoControl(pVCOMInfo->ComDev, (pVCOMInfo->Port << 16) | W98_SERIAL_GETDATA,
NULL,0,lpszBlock,nMaxLength, &dwLength,NULL);
else if (pVCOMInfo->NewVCOM)
{
int ret = PeekNamedPipe(pVCOMInfo->ComDev, NULL, 0, NULL, &Available, NULL);
if (ret == 0)
{
ret = GetLastError();
if (ret == ERROR_BROKEN_PIPE)
{
CloseHandle(pVCOMInfo->ComDev);
pVCOMInfo->ComDev = INVALID_HANDLE_VALUE;
return 0;
}
}
if (Available > nMaxLength)
Available = nMaxLength;
if (Available)
{
UCHAR * ptr1 = lpszBlock;
UCHAR * ptr2 = lpszBlock;
UCHAR c;
int Length;
ReadFile(pVCOMInfo->ComDev, lpszBlock, Available, &dwLength, NULL);
// Have to look foro FF escape chars
Length = dwLength;
while (Length != 0)
{
c = *(ptr1++);
Length--;
if (c == 0xff)
{
c = c = *(ptr1++);
Length--;
if (c == 0xff) // ff ff means ff
{
dwLength--;
}
else
{
// This is connection statua from other end
dwLength -= 2;
pVCOMInfo->NewVCOMConnected = c;
continue;
}
}
*(ptr2++) = c;
}
}
}
else
DeviceIoControl(
pVCOMInfo->ComDev,IOCTL_SERIAL_GETDATA,NULL,0,lpszBlock,nMaxLength, &dwLength,NULL);
return (dwLength);
}
static BOOL WriteCommBlock(int port, UCHAR * Message, DWORD MsgLen)
{
ULONG bytesReturned;
// if ((rand() % 100) > 80)
// return 0;
if (Win98)
return DeviceIoControl(
VCOMInfo[port]->ComDev,(VCOMInfo[port]->Port << 16) | W98_SERIAL_SETDATA,Message,MsgLen,NULL,0, &bytesReturned,NULL);
else if (VCOMInfo[port]->NewVCOM)
{
// Have to escape all oxff chars, as these are used to get status info
UCHAR NewMessage[1000];
UCHAR * ptr1 = Message;
UCHAR * ptr2 = NewMessage;
UCHAR c;
int Length = MsgLen;
while (Length != 0)
{
c = *(ptr1++);
*(ptr2++) = c;
if (c == 0xff)
{
*(ptr2++) = c;
MsgLen++;
}
Length--;
}
return WriteFile(VCOMInfo[port]->ComDev, NewMessage, MsgLen, &bytesReturned, NULL);
}
else
return DeviceIoControl(
VCOMInfo[port]->ComDev,IOCTL_SERIAL_SETDATA,Message,MsgLen,NULL,0, &bytesReturned,NULL);
}

@ -0,0 +1,654 @@
/*
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
*/
// Monitor Code - from moncode.asm
// Modified for AGW form monitor
#pragma data_seg("_BPQDATA")
#define _CRT_SECURE_NO_DEPRECATE
#include <stdlib.h>
#include <string.h>
#include <time.h>
#pragma data_seg("_BPQDATA")
#include "cheaders.h"
#include "tncinfo.h"
// MSGFLAG contains CMD/RESPONSE BITS
#define CMDBIT 4 // CURRENT MESSAGE IS A COMMAND
#define RESP 2 // CURRENT MSG IS RESPONSE
#define VER1 1 // CURRENT MSG IS VERSION 1
#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
#define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE
#define NETROM_PID 0xCF
#define IP_PID 0xCC
#define ARP_PID 0xCD
#define NODES_SIG 0xFF
UCHAR * DisplayINP3RIF(UCHAR * ptr1, UCHAR * ptr2, int msglen);
static UCHAR * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen, int DoNodes);
static UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen);
static UCHAR * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output);
int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int DoNodes)
{
UCHAR * ptr;
int n;
MESSAGE * ADJBUFFER;
ptrdiff_t Work;
UCHAR CTL;
BOOL PF = 0;
char CRCHAR[3] = " ";
char PFCHAR[3] = " ";
int MSGFLAG = 0; //CR and V1 flags
char * Output = buffer;
char From[10], To[10];
BOOL Info = 0;
BOOL FRMRFLAG = 0;
BOOL XIDFLAG = 0;
BOOL TESTFLAG = 0;
size_t MsgLen = msg->LENGTH;
struct tm * TM;
if (useLocalTime)
TM = localtime(&Stamp);
else
TM = gmtime(&Stamp);
// GET THE CONTROL BYTE, TO SEE IF THIS FRAME IS TO BE DISPLAYED
n = 8; // MAX DIGIS
ptr = &msg->ORIGIN[6]; // End of Address bit
while ((*ptr & 1) == 0)
{
// MORE TO COME
ptr += 7;
n--;
if (n == 0)
{
return 0; // Corrupt - no end of address bit
}
}
// Reached End of digis
Work = ptr - &msg->ORIGIN[6]; // Work is length of digis
MsgLen -= Work;
ADJBUFFER = (MESSAGE *)((UCHAR *)msg + Work); // ADJBUFFER points to CTL, etc. allowing for digis
CTL = ADJBUFFER->CTL;
if (CTL & PFBIT)
PF = TRUE;
CTL &= ~PFBIT;
*FrameType = CTL;
Output += sprintf((char *)Output, " %d:Fm ", msg->PORT & 0x7f); // Mask TX bit
From[ConvFromAX25(msg->ORIGIN, From)] = 0;
To[ConvFromAX25(msg->DEST, To)] = 0;
Output += sprintf((char *)Output, "%s To %s", From, To);
// Display any Digi-Peaters
n = 8; // Max number of digi-peaters
ptr = &msg->ORIGIN[6]; // End of Address bit
while ((*ptr & 1) == 0)
{
// MORE TO COME
From[ConvFromAX25(ptr + 1, From)] = 0;
if (n == 8)
Output += sprintf((char *)Output, " Via %s", From); // Send via on first
else
Output += sprintf((char *)Output, ",%s", From);
ptr += 7;
n--;
if (n == 0)
break;
// See if digi actioned - put a * on last actioned
if (*ptr & 0x80)
{
if (*ptr & 1) // if last address, must need *
*(Output++) = '*';
else
if ((ptr[7] & 0x80) == 0) // Repeased by next?
*(Output++) = '*'; // No, so need *
}
}
*(Output++) = ' ';
// Set up CR and PF
CRCHAR[0] = 0;
PFCHAR[0] = 0;
if (msg->DEST[6] & 0x80)
{
if (msg->ORIGIN[6] & 0x80) // Both set, assume V1
MSGFLAG |= VER1;
else
{
MSGFLAG |= CMDBIT;
CRCHAR[0] = ' ';
CRCHAR[1] = 'C';
if (PF) // If FP set
{
PFCHAR[0] = ' ';
PFCHAR[1] = 'P';
}
}
}
else
{
if (msg->ORIGIN[6] & 0x80) // Only Origin Set
{
MSGFLAG |= RESP;
CRCHAR[0] = ' ';
CRCHAR[1] = 'R';
if (PF) // If FP set
{
PFCHAR[0] = ' ';
PFCHAR[1] = 'F';
}
}
else
MSGFLAG |= VER1; // Neither, assume V1
}
if ((CTL & 1) == 0) // I frame
{
int NS = (CTL >> 1) & 7; // ISOLATE RECEIVED N(S)
int NR = (CTL >> 5) & 7;
Info = 1;
Output += sprintf((char *)Output, "<I%s%s S%d R%d>", CRCHAR, PFCHAR, NS, NR);
}
else if (CTL == 3)
{
// Un-numbered Information Frame
//UI pid=F0 Len=20 >
Output += sprintf((char *)Output, "<UI pid=%02X Len=%d>", ADJBUFFER->PID, (int)MsgLen - 23);
Info = 1;
}
else if (CTL & 2)
{
// UN Numbered
char SUP[5] = "??";
switch (CTL)
{
case SABM:
strcpy(SUP, "C");
break;
case DISC:
strcpy(SUP, "D");
break;
case DM:
strcpy(SUP, "DM");
break;
case UA:
strcpy(SUP, "UA");
break;
case FRMR:
strcpy(SUP, "FRMR");
FRMRFLAG = 1;
break;
}
Output += sprintf((char *)Output, "<%s%s%s>", SUP, CRCHAR, PFCHAR);
}
else
{
// Super
int NR = (CTL >> 5) & 7;
char SUP[4] = "??";
switch (CTL & 0x0F)
{
case RR:
strcpy(SUP, "RR");
break;
case RNR:
strcpy(SUP, "RNR");
break;
case REJ:
strcpy(SUP, "REJ");
break;
}
Output += sprintf((char *)Output, "<%s%s%s R%d>", SUP, CRCHAR, PFCHAR, NR);
}
Output += sprintf((char *)Output, "[%02d:%02d:%02d]", TM->tm_hour, TM->tm_min, TM->tm_sec);
if (FRMRFLAG)
Output += sprintf((char *)Output, "%02X %02X %02X", ADJBUFFER->PID, ADJBUFFER->L2DATA[0], ADJBUFFER->L2DATA[1]);
if (Info)
{
// We have an info frame
switch (ADJBUFFER->PID)
{
case 0xF0: // Normal Data
{
char Infofield[257];
char * ptr1 = Infofield;
char * ptr2 = ADJBUFFER->L2DATA;
UCHAR C;
size_t len;
MsgLen = MsgLen - 23;
if (MsgLen < 0 || MsgLen > 257)
return 0; // Duff
while (MsgLen--)
{
C = *(ptr2++);
// Convert to printable
C &= 0x7F;
if (C == 13 || C == 10 || C > 31)
*(ptr1++) = C;
}
len = ptr1 - Infofield;
// Output[0] = ':';
Output[0] = 13;
memcpy(&Output[1], Infofield, len);
Output += (len + 1);
break;
}
case NETROM_PID:
Output = DISPLAY_NETROM(ADJBUFFER, Output,(int) MsgLen, DoNodes);
break;
case IP_PID:
Output += sprintf((char *)Output, " <IP>\r");
Output = DISPLAYIPDATAGRAM((IPMSG *)&ADJBUFFER->L2DATA[0], Output, (int)MsgLen);
break;
case ARP_PID:
Output = DISPLAYARPDATAGRAM(&ADJBUFFER->L2DATA[0], Output);
break;
case 8: // Fragmented IP
Output += sprintf((char *)Output, "<Fragmented IP>");
break;
}
}
if (Output == NULL)
return 0;
if (Output[-1] != 13)
Output += sprintf((char *)Output, "\r");
return (int)(Output - buffer);
}
// Display NET/ROM data
UCHAR * DISPLAY_NETROM(MESSAGE * ADJBUFFER, UCHAR * Output, int MsgLen, int DoNodes)
{
char Alias[7]= "";
char Dest[10];
char Node[10];
UCHAR TTL, Index, ID, TXNO, RXNO, OpCode, Flags, Window;
UCHAR * ptr = &ADJBUFFER->L2DATA[0];
if (ADJBUFFER->L2DATA[0] == NODES_SIG)
{
// Display NODES
if (DoNodes == 0)
return NULL;
// If an INP3 RIF (type <> UI) decode as such
if (ADJBUFFER->CTL != 3) // UI
return DisplayINP3RIF(&ADJBUFFER->L2DATA[1], Output, MsgLen - 24);
memcpy(Alias, ++ptr, 6);
ptr += 6;
Output += sprintf((char *)Output, "\rFF %s (NetRom Routing)\r", Alias);
MsgLen -= 30; //Header, mnemonic and signature length
while(MsgLen > 20) // Entries are 21 bytes
{
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
memcpy(Alias, ptr, 6);
ptr +=6;
strlop(Alias, ' ');
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
Output += sprintf((char *)Output, " %s:%s via %s qlty=%d\r", Alias, Dest, Node, ptr[0]);
ptr++;
MsgLen -= 21;
}
return Output;
}
// Display normal NET/ROM transmissions
Output += sprintf((char *)Output, " NET/ROM\r ");
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
TTL = *(ptr++);
Index = *(ptr++);
ID = *(ptr++);
TXNO = *(ptr++);
RXNO = *(ptr++);
OpCode = Flags = *(ptr++);
OpCode &= 15; // Remove Flags
Output += sprintf((char *)Output, "%s to %s ttl %d cct=%02X%02X ", Dest, Node, TTL, Index, ID );
MsgLen -= 20;
switch (OpCode)
{
case L4CREQ:
Window = *(ptr++);
Dest[ConvFromAX25(ptr, Dest)] = 0;
ptr +=7;
Node[ConvFromAX25(ptr, Node)] = 0;
ptr +=7;
Output += sprintf((char *)Output, "<CON REQ> w=%d %s at %s", Window, Dest, Node);
if (MsgLen > 38) // BPQ Extended Params
{
short Timeout = (SHORT)*ptr;
Output += sprintf((char *)Output, " t/o %d", Timeout);
}
return Output;
case L4CACK:
if (Flags & L4BUSY) // BUSY RETURNED
return Output + sprintf((char *)Output, " <CON NAK> - BUSY");
return Output + sprintf((char *)Output, " <CON ACK> w=%d my cct=%02X%02X", ptr[1], TXNO, RXNO);
case L4DREQ:
return Output + sprintf((char *)Output, " <DISC REQ>");
case L4DACK:
return Output + sprintf((char *)Output, " <DISC ACK>");
case L4INFO:
{
char Infofield[257];
char * ptr1 = Infofield;
UCHAR C;
size_t len;
Output += sprintf((char *)Output, " <INFO S%d R%d>", TXNO, RXNO);
if (Flags & L4BUSY)
*(Output++) = 'B';
if (Flags & L4NAK)
*(Output++) = 'N';
if (Flags & L4MORE)
*(Output++) = 'M';
MsgLen = MsgLen - 23;
if (MsgLen < 0 || MsgLen > 257)
return Output; // Duff
while (MsgLen--)
{
C = *(ptr++);
// Convert to printable
C &= 0x7F;
if (C == 13 || C == 10 || C > 31)
*(ptr1++) = C;
}
len = ptr1 - Infofield;
Output[0] = ':';
Output[1] = 13;
memcpy(&Output[2], Infofield, len);
Output += (len + 2);
}
return Output;
case L4IACK:
Output += sprintf((char *)Output, " <INFO ACK R%d> ", RXNO);
if (Flags & L4BUSY)
*(Output++) = 'B';
if (Flags & L4NAK)
*(Output++) = 'N';
if (Flags & L4MORE)
*(Output++) = 'M';
return Output;
case 0:
// OPcode zero is used for several things
if (Index == 0x0c && ID == 0x0c) // IP
{
// Output = L3IP(Output);
return Output;
}
if (Index == 0 && ID == 1) // NRR
{
Output += sprintf((char *)Output, " <Record Route>\r");
MsgLen -= 23;
while (MsgLen > 6)
{
Dest[ConvFromAX25(ptr, Dest)] = 0;
if (ptr[7] & 0x80)
Output += sprintf((char *)Output, "%s* ", Dest);
else
Output += sprintf((char *)Output, "%s ", Dest);
ptr +=8;
MsgLen -= 8;
}
return Output;
}
}
Output += sprintf((char *)Output, " <???\?>");
return Output;
}
/*
PUBLIC L3IP
L3IP:
;
; TCP/IP DATAGRAM
;
mov EBX,OFFSET IP_MSG
call NORMSTR
;
INC ESI ; NOW POINTING TO IP HEADER
*/
UCHAR * DISPLAYIPDATAGRAM(IPMSG * IP, UCHAR * Output, int MsgLen)
{
UCHAR * ptr;
ptr = (UCHAR *)&IP->IPSOURCE;
Output += sprintf((char *)Output, "%d.%d.%d.%d>", ptr[0], ptr[1], ptr[2], ptr[3]);
ptr = (UCHAR *)&IP->IPDEST;
Output += sprintf((char *)Output, "%d.%d.%d.%d LEN:%d ", ptr[0], ptr[1], ptr[2], ptr[3], htons(IP->IPLENGTH));
/*
MOV AL,IPPROTOCOL[ESI]
CMP AL,6
JNE @F
MOV EBX, OFFSET TCP
CALL NORMSTR
JMP ADD_CR
@@:
CMP AL,1
JNE @F
MOV EBX, OFFSET ICMP
CALL NORMSTR
JMP ADD_CR
@@:
CALL DISPLAY_BYTE_1 ; DISPLAY PROTOCOL TYPE
; mov AL,CR
; call PUTCHAR
;
; MOV ECX,39 ; TESTING
;IPLOOP:
; lodsb
; CALL BYTE_TO_HEX
;
; LOOP IPLOOP
JMP ADD_CR
*/
return Output;
}
UCHAR * DISPLAYARPDATAGRAM(UCHAR * Datagram, UCHAR * Output)
{
UCHAR * ptr = Datagram;
UCHAR Dest[10];
if (ptr[7] == 1) // Request
return Output + sprintf((char *)Output, " < ARP Request who has %d.%d.%d.%d? Tell %d.%d.%d.%d",
ptr[26], ptr[27], ptr[28], ptr[29], ptr[15], ptr[16], ptr[17], ptr[18]);
// Response
Dest[ConvFromAX25(&ptr[8], Dest)] = 0;
return Output + sprintf((char *)Output, " < ARP Rreply %d.%d.%d.%d? is at %s",
ptr[15], ptr[16], ptr[17], ptr[18], "??");
}

@ -0,0 +1,572 @@
EXCLUDEBITS EQU 0 ; INCLUDE ExcludeList SUPPORT
TNCBUFFLEN EQU 400h
BPQHOSTSTREAMS EQU 64
;BUFFLEN EQU 400 ; ??
MAXAPPLS EQU 32 ; Max Application Commands
ApplOffset EQU 80000 ; Applications string in buffer
C_INFOMSG EQU 85000 ; Info Msg in buffer
ApplStringLen EQU 48 ; Length of each config entry
ALIASLEN EQU 32 ; Max chars in command alias
MHENTRIES EQU 30 ; Entries in MH List
;
; BUFFLEN-4 = L2 POINTER (FOR CLEARING TIMEOUT WHEN ACKMODE USED)
; BUFFLEN-8 = TIMESTAMP
; BUFFLEN-12 = BUFFER ALLOCATED FLAG (ADDR OF ALLOCATING ROUTINE)
;MAXDATA EQU BUFFLEN-16
MAXDIGIS EQU 8
;
; BPQHOST MODE VECTOR STRUC
;
BPQVECSTRUC STRUC
HOSTSESSION DD 0
HOSTFLAGS DB 0 ; ALLOCATED AND STATE CHANGE FLAGS
HOSTAPPLMASK DD 0
HOSTAPPLFLAGS DB 0
HOSTSTREAM DB 0 ; STREAM NUMBER
HOSTTRACEQ DD 0
HOSTHANDLE DD 0 ; HANDLE FOR POSTING MSGS TO
HOSTAPPLNUM DD 0 ; Application Number
STREAMOWNER DD 0 ; PID of Process owning stream
HOSTPGMNAME DB 32 dup (0);
BPQVECSTRUC ENDS
; HOSTFLAGS = Bit 80 = Allocated
; Bit 40 = Disc Request
; Bit 20 = Stay Flag
; Bit 02 and 01 State Change Bits
VECTORLENGTH EQU TYPE BPQVECSTRUC
;
; BASIC LINK LEVEL MESSAGE BUFFER LAYOUT
;
MESSAGE STRUC
MSGCHAIN DD ? ; CHAIN WORD
MSGPORT DB ? ; PORT
MSGLENGTH DW ? ; LENGTH
MSGDEST DB 7 DUP (?) ; DESTINATION
MSGORIGIN DB 7 DUP (?) ; ORIGIN
;
; MAY BE UP TO 56 BYTES OF DIGIS
;
MSGCONTROL DB ? ; CONTROL BYTE
MSGPID DB ? ; PROTOCOL IDENTIFIER
MSGDATA DB ? ; START OF LEVEL 2 MESSAGE
;
MESSAGE ENDS
;
L3MESSAGE STRUC
;
; NETROM LEVEL 3 MESSAGE - WITHOUT L2 INFO
;
L3HEADER DB 7 DUP (?) ; CHAIN, PORT, LENGTH
L3PID DB ? ; PID
L3SRCE DB 7 DUP (?) ; ORIGIN NODE
L3DEST DB 7 DUP (?) ; DEST NODE
L3MONR DB ? ; TX MONITOR FIELD - TO PREVENT MESSAGE GOING
; ROUND THE NETWORK FOR EVER DUE TO ROUTING LOOP
;
; NETROM LEVEL 4 DATA
;
L4INDEX DB ? ; TRANSPORT SESSION INDEX
L4ID DB ? ; TRANSPORT SESSION ID
L4TXNO DB ? ; TRANSMIT SEQUENCE NUMBER
L4RXNO DB ? ; RECEIVE (ACK) SEQ NUMBER
L4FLAGS DB ? ; FRAGMENTATION, ACK/NAK, FLOW CONTROL AND MSG TYPE BITS
L4DATA DB ? ; DATA
L4CALLS DB 14 DUP (?) ; CALLS IN CONNECT REQUEST
L4_BPQ DB ? ; THENODE EXTENDED CONNECT PARAMS
L3MESSAGE ENDS
;
; L4FLAGS DEFINITION
;
L4BUSY EQU 80H ; BNA - DONT SEND ANY MORE
L4NAK EQU 40H ; NEGATIVE RESPONSE FLAG
L4MORE EQU 20H ; MORE DATA FOLLOWS - FRAGMENTATION FLAG
L4CREQ EQU 1 ; CONNECT REQUEST
L4CACK EQU 2 ; CONNECT ACK
L4DREQ EQU 3 ; DISCONNECT REQUEST
L4DACK EQU 4 ; DISCONNECT ACK
L4INFO EQU 5 ; INFORMATION
L4IACK EQU 6 ; INFORMATION ACK
;
; PORT CONTROL TABLE
;
PORTCONTROL STRUC
PORTCALL DB 7 DUP (0)
PORTALIAS DB 7 DUP (0) ; USED FOR UPLINKS ONLY
PORTNUMBER DB ?
PORTPOINTER DD ? ; NEXT IN CHAIN
PORTQUALITY DB ? ; 'STANDARD' QUALITY FOR THIS PORT
PORTRX_Q DD ? ; FRAMES RECEIVED ON THIS PORT
PORTTX_Q DD ? ; FRAMES TO BE SENT ON THIS PORT
PORTTXROUTINE DD ? ; POINTER TO TRANSMIT ROUTINE FOR THIS PORT
PORTRXROUTINE DD ? ; POINTER TO RECEIVE ROUTINE FOR THIS PORT
PORTINITCODE DD ? ; INITIALISATION ROUTINE
PORTTIMERCODE DD ?
PORTCLOSECODE DD ?
PORTTXCHECK DD ? ; OK to Send Check
PORTDESCRIPTION DB 30 DUP (0) ; TEXT DESCRIPTION OF FREQ/SPEED ETC
PORTBBSFLAG DB ? ; NZ MEANS PORT CALL/ALIAS ARE FOR BBS
PORTL3FLAG DB ? ; NZ RESTRICTS OUTGOING L2 CONNECTS
;
; CWID FIELDS
;
CWID DW 9 DUP (0) ; 8 ELEMENTS + FLAG
ELEMENT DW ? ; REMAINING BITS OF CURRENT CHAR
CWPOINTER DD ? ; POINTER TO NEXT CHAR
CWIDTIMER DW ? ; TIME TO NEXT ID
CWSTATE DB ? ; STATE MACHINE FOR CWID
CWTYPE DB ? ; SET TO USE ON/OFF KEYING INSTEAD OF
; FSK (FOR RUH MODEMS)
PORTMINQUAL DB ? ; MIN QUAL TO BRAOCAST ON THIS PORT
; STATS COUNTERS
;
L2DIGIED DD ?
L2FRAMES DD ?
L2FRAMESFORUS DD ?
L2FRAMESSENT DD ?
L2TIMEOUTS DD ?
L2ORUNC DD ? ; OVERRUNS
L2URUNC DD ? ; UNDERRUNS
L1DISCARD DD ? ; FRAMES DISCARDED (UNABLE TO TX DUE TO DCD)
L2FRMRRX DD ?
L2FRMRTX DD ?
RXERRORS DD ? ; RECEIVE ERRORS
L2REJCOUNT DD ? ; REJ FRAMES RECEIVED
L2OUTOFSEQ DD ? ; FRAMES RECEIVED OUT OF SEQUENCE
L2RESEQ DD ? ; FRAMES RESEQUENCED
SENDING DW 0 ; LINK STATUS BITS
ACTIVE DW 0
AVSENDING DB 0 ; LAST MINUTE
AVACTIVE DB 0
PORTTYPE DB 0 ; H/W TYPE
; 0 = ASYNC, 2 = PC120, 4 = DRSI
; 6 = TOSH, 8 = QUAD, 10 = RLC100
; 12 = RLC400 14 = INTERNAL 16 = EXTERNAL ; 18 = i2c
PROTOCOL DB 0 ; PORT PROTOCOL
; 0 = KISS, 2 = NETROM, 4 = BPQKISS
; 6 = HDLC, 8 = L2, 10 = PACTOR
IOBASE DW ? ; CONFIG PARAMS FOR HARDWARE DRIVERS
INTLEVEL DB ? ; FIRST 4 SAME FOR ALL H/W TYPES
BAUDRATE DD ? ; SPEED
CHANNELNUM DB ? ; ON MULTICHANNEL H/W
INTCHAIN DD ? ; POINTER TO NEXT PORT USING THIS LEVEL
PORTWINDOW DB ? ; L2 WINDOW FOR THIS PORT
PORTTXDELAY DW ? ; TX DELAY FOR THIS PORT
PORTPERSISTANCE DB ? ; PERSISTANCE VALUE FOR THIS PORT
FULLDUPLEX DB ? ; FULL DUPLEX IF SET
SOFTDCDFLAG DB ? ; IF SET USE 'SOFT DCD' - IF MODEM CANT GIVE A REAL ONE
PORTSLOTTIME DB ? ; SLOT TIME
PORTTAILTIME DB ? ; TAIL TIME
BBSBANNED DB ? ; SET IF PORT CAN'T ACCEPT L2 CALLS TO BBS CALLSIGN
PORTT1 DB ? ; L2 TIMEOUT
PORTT2 DB ? ; L2 DELAYED ACK TIMER
PORTN2 DB ? ; RETRIES
PORTPACLEN DB ? ; DEFAULT PACLEN FOR INCOMING SESSIONS
PORTINTERRUPT DD ? ; ADDRESS OF INTERRUPT HANDLER
QUAL_ADJUST DB ? ; % REDUCTION IN QUALITY IF ON SAME PORT
PERMITTEDCALLS DD ? ; POINTER TO PERMITED CALLS LIST
PORTUNPROTO DD ? ; POINTER TO UI DEST AND DIGI LIST
PORTDISABLED DB 0 ; PORT TX DISABLE FLAG
DIGIFLAG DB 0 ; ENABLE/DISABLE/UI ONLY
DIGIPORT DB 0 ; CROSSBAND DIGI PORT
DIGIMASK DW 0 ; CROSSBAND DIGI MASK
USERS DB 0 ; MAX USERS ON PORT
KISSFLAGS DB 0 ; KISS SPECIAL MODE BITS
PORTINTERLOCK DB 0 ; TO DEFINE PORTS WHICH CANT TX AT SAME TIME
NODESPACLEN DB 0 ; MAX LENGTH OF 'NODES' MSG
TXPORT DB 0 ; PORT FOR SHARED TX OPERATION
PORTMHEARD DD 0 ; POINTER TO MH DATA
PARAMTIMER DW 0 ; MOVED FROM HW DATA FOR SYSOPH
PORTMAXDIGIS DB 0 ; DIGIS ALLOWED ON THIS PORT
PORTALIAS2 DB 7 DUP (0) ; 2ND ALIAS FOR DIGIPEATING FOR APRS
PORTBCALL DB 7 DUP (0) ; Source for Beacons
PortNoKeepAlive DB 0; ; Default to No Keepalives
PortUIOnly DB 0;
UICAPABLE DB 0; ; Pactor-style port that can do UI
WL2K DB 189 DUP (0) ; WL2K Report Data
PORTIPADDR DD 0;
SerialPortName DD 0 ; Serial Port Name for Unix
XDIGIS DD 0; ; Cross Port Digi Definitions
NormalizeQuality DD 0 ; Normalise Node Qualities
IgnoreUnlocked DD 0 ; Ignore Unlocked Routes
HARDWAREDATA DB 200 DUP (?) ; WORK AREA FOR HARDWARE DRIVERS
PORTCONTROL ENDS
;
; DEFINE MAPPING FOR EXTERNAL DRIVER
;
EXTDATA STRUC
DB HARDWAREDATA DUP (0) ; REMAP HARDWARE INFO
PORT_EXT_ADDR DD ? ; ADDR OF RESIDENT ROUTINE
PORT_DLL_NAME DB 16 DUP (0);
EXTRESTART DB ? ; FLAG FOR DRIVER REINIT
DLLHANDLE DD ?
MAXHOSTMODESESSIONS DD ? ; Max Host Sessions supported (Used for KAM Pactor + ax.25 support)
ATTACHEDSESSIONS DD 27 DUP (0); Owning Sessions for PACTOR, etc
PERMITGATEWAY DD 0 ; Set if ax.25 ports can change callsign (ie SCS, not KAM
SCANCAPABILITIES DD 0 ; Type of scan control Controller supports (None, Simple, Connect Lock)
UI_Q DD 0 ; Unproto Frames for Session Mode Drivers (TRK, etc)
EXTDATA ENDS
IF TYPE EXTDATA GT TYPE PORTCONTROL
.ERR2 TOO MUCH PORT DATA
ENDIF
EXTERNAL EQU 16
L2 EQU 8
;
; CW STATE MACHINE EQUATES
;
dot equ 1b
dash equ 10b
dotspace equ 100b
letterspace equ 1000b
IDPENDING EQU 10000B
;
; LEVEL 2 LINK CONTROL TABLE
;
LINKTABLE STRUC
LINKCALL DB 7 DUP (?) ; CALLSIGN OF STATION
OURCALL DB 7 DUP (?) ; CALLSIGN OF OUR END
DIGIS DB MAXDIGIS*7 DUP (?) ; LEVEL 2 DIGIS IN PATH
LINKPORT DD ? ; PORT POINTER
LINKTYPE DB ? ; 1 = UP, 2= DOWN, 3 = INTERNODE
LINKNR DB ?
LINKNS DB ? ; LEV 2 SEQUENCE COUNTS
LINKWS DB ? ; WINDOW START
LINKOWS DB ? ; OLD (LAST ACKED) WINDOW START
LINKWINDOW DB ? ; LEVEL 2 WINDOW SIZE
L2FLAGS DB ? ; CONTROL BITS
VER1FLAG DB ? ; SET IF OTHER END RUNNING VERSION 1
RX_Q DD ? ; PACKETS RECEIVED ON THIS LINK
TX_Q DD ? ; PACKETS TO SEND
FRAMES DD 8 DUP (?) ; FRAMES WAITING ACK
RXFRAMES DD 8 DUP (?) ; Frames received out of sequence
L2STATE DB ? ; PROCESSING STATE
L2TIMER DW ? ; FRAME RETRY TIMER
L2TIME DB ? ; RETRY TIMER INITIAL VALUE
L2SLOTIM DW ? ; DELAY FOR LINK VALIDATION POLL
L2ACKREQ DB ? ; DELAYED TEXT ACK TIMER
REJTIMER DB ? ; TO TIME OUT REJ IN VERSION 1
LAST_F_TIME DW ? ; TIME LAST R(F) SENT
SDREJF DB ? ; FLAGS FOR FRMR
SDRBYTE DB ? ; SAVED CONTROL BYTE FOR FRMR
SDTSLOT DB ? ; POINTER TO NEXT TXSLOT TO USE
L2RETRIES DB ? ; RETRY COUNTER
SESSACTIVE DB ? ; SET WHEN WE ARE SURE SESSION IS UP
KILLTIMER DW ? ; TIME TO KILL IDLE LINK
CIRCUITPOINTER DD ? ; POINTER TO L4 CIRCUIT TABLE ENTRY
; (IF UP/DOWN)
NEIGHBOUR DD ? ; POINTER TO NEIGHBOUR (IF CROSSLINK)
L2FRAG_Q DD ? ; DEFRAGMENTATION QUEUE
LINKTABLE ENDS
;
; L2FLAGS EQUATES
;
REJSENT EQU 1B ; SET WHEN FIRST REJ IS SENT IN REPLY
; TO AN I(P)
RNRSET EQU 10B ; RNR RECEIVED FROM OTHER END
;DISCPENDING EQU 1000B ; SEND DISC WHEN ALL DATA ACK'ED
RNRSENT EQU 10000B ; WE HAVE SEND RNR
POLLSENT EQU 100000B ; POLL BIT OUTSTANDING
;
; FRMR REJECT FLAGS
;
SDINVC EQU 1B ; INVALID COMMAND
SDNRER EQU 1000B ; INVALID N(R)
TRANSPORTENTRY STRUC
L4USER DB 7 DUP (?) ; CALL OF ORIGINATING USER
L4TARGET DD ? ; POINTER TO TARGET LINK/DEST
L4MYCALL DB 7 DUP (0) ; CALL WE ARE USING
CIRCUITINDEX DB ? ; OUR CIRCUIT INFO
CIRCUITID DB ?
FARINDEX DB ?
FARID DB ? ; OTHER END'S INFO
L4WINDOW DB ? ; WINDOW SIZE
L4WS DB ? ; WINDOW START - NEXT FRAME TO ACK
TXSEQNO DB ?
RXSEQNO DB ? ; TRANSPORT LEVEL SEQUENCE INFO
L4LASTACKED DB ? ; LAST SEQUENCE ACKED
FLAGS DB ? ; TRANSPORT LEVEL FLAGS
NAKBITS DB ? ; NAK & CHOKE BITS TO BE SENT
L4CROSSLINK DD ? ; POINTER TO LINKED L4 SESSION ENTRY
L4CIRCUITTYPE DB ? ; BIT SIGNIFICANT - SEE BELOW
KAMSESSION DB ? ; Session Number on KAM Host Mode TNC
L4TX_Q DD ?
L4RX_Q DD ?
L4HOLD_Q DD ? ; FRAMES WAITING TO BE ACKED
L4RESEQ_Q DD ? ; FRAMES RECEIVED OUT OF SEQUENCE
L4STATE DB ?
L4TIMER DW ?
L4ACKREQ DB ? ; DATA ACK NEEDED
L4RETRIES DB ? ; RETRY COUNTER
L4KILLTIMER DW 0 ; IDLE CIRCUIT TIMER
SESSIONT1 DW 0 ; TIMEOUT FOR SESSIONS FROM HERE
SESSPACLEN DB 0 ; PACLEN FOR THIS SESSION
BADCOMMANDS DB 0 ; SUCCESSIVE BAD COMMANDS
STAYFLAG DB 0 ; STAY CONNECTED FLAG
SPYFLAG DB 0 ; SPY - CONNECT TO NODE VIA BBS CALLSIGN
RTT_SEQ DB 0 ; SEQUENCE NUMBER BEING TIMED
RTT_TIMER DD 0 ; TIME ABOVE SEQUENCE WAS SENT
PASSWORD DW 0 ; AUTHORISATION CODE FOR REMOTE SYSOP
;
SESS_APPLFLAGS DB 0 ; APPL FLAGS FOR THIS SESSION
Authorised_Session DB 0; // Set if Host session from BPQTerminal or BPQMailChat
DUMPPTR DD 0 ; POINTER FOR REMOTE DUMP MODE
PARTCMDBUFFER DD 0 ; Save area for incomplete commmand
Frequency DD 0 ; If known - for CMS Reporting Hz
RMSCall DB 10 DUP (0);
Mode DB 0 ; ditto
UNPROTO DD 0 ; Unproto Mode flag - port number if in unproto mode
UAddrLen DD 0 ;
UADDRESS DB 64 DUP (0); Unproto Address String - Dest + Digis
LISTEN DD 0 ; Listen Mode flag - port number of Listen Mode
APPL DB 16 DUP (0); Set if session initiated by an APPL
L4LIMIT dd 0 ; Idle Timout for this session
TRANSPORTENTRY ENDS
;
; CIRCUITTYPE EQUATES
;
L2LINK EQU 1
SESSION EQU 10B
UPLINK EQU 100B
DOWNLINK EQU 1000B
BPQHOST EQU 100000B
PACTOR EQU 1000000B
;
; FLAGS EQUATES
;
DISCPENDING EQU 1000B ; SEND DISC WHEN ALL DATA ACK'ED
;
; TOP 4 BITS MATCH L4FLAGS BITS - ALSO USED FOR NAKBITS
;
;L4BUSY EQU 80H ; BNA - DONT SEND ANY MORE
;L4NAK EQU 40H ; NEGATIVE RESPONSE FLAG
;L4MORE EQU 20H ; MORE DATA FOLLOWS - FRAGMENTATION FLAG
DEST_LIST STRUC
DEST_CHAIN DD ? ; SORTED LIST CHAIN
DEST_CALL DB 7 DUP (?) ; DESTINATION CALLSIGN (AX25 FORMAT)
DEST_ALIAS DB 6 DUP (?)
DEST_STATE DB ? ; CONTROL BITS - SETTING UP, ACTIVE ETC
DEST_ROUTE DB ? ; CURRENTY ACTIVE DESTINATION
INP3FLAGS DB ?
ROUT1_NEIGHBOUR DD ? ; POINTER TO NEXT NODE IN PATH
ROUT1_QUALITY DB ? ; QUALITY
ROUT1_OBSCOUNT DB ?
db 5 dup (?); Padding
ROUT2_NEIGHBOUR DD ?
ROUT2_QUALITY DB ?
ROUT2_OBSCOUNT DB ?
db 5 dup (?); Padding
ROUT3_NEIGHBOUR DD ?
ROUT3_QUALITY DB ?
ROUT3_OBSCOUNT DB ?
db 5 dup (?); Padding
INPROUT1_NEIGHBOUR DD ?
LastRTT1 DW ?; // Last Value Reported
RTT1 DW ?; // Current
SRTT1 DW ?; // Smoothed RTT
Hops1 DB ?;
INPROUT2_NEIGHBOUR DD ?
LastRTT2 DW ?; // Last Value Reported
RTT2 DW ?; // Current
SRTT2 DW ?; // Smoothed RTT
Hops2 DB ?;
INPROUT3_NEIGHBOUR DD ?
LastRTT3 DW ?; // Last Value Reported
RTT3 DW ?; // Current
SRTT3 DW ?; // Smoothed RTT
Hops3 DB ?;
DEST_Q DD ? ; QUEUE OF FRAMES FOR THIS DESTINATION
DEST_RTT DD ? ; SMOOTHED ROUND TRIP TIMER
DEST_COUNT DD ? ; FRAMES SENT
DEST_LIST ENDS
;
; MODEFLAG DEFINITIONS
;
COMMAND EQU 1B
TRANS EQU 10B
CONV EQU 100B
;
; APPL DEFINITIONS
;
BBSAPPL EQU 1B
HOSTAPPL EQU 10B
SYSOPAPPL EQU 100B
;
; HOSTFLAG DEFINITIONS
;
;HOSTMODE EQU 1B ; PK232 HOSTMODE ENABLED
;HOSTESCBIT EQU 10B ; IN ESCAPE SEQUENCE
;UFQ EQU 100B ; UFQ MODE (IE NOT AA4RE)
;POLLED EQU 1000B ; POLL RECEIVED
;KISSMODE EQU 10000B ; KISS MODE
;KISSESC EQU 100000B ; IN ESCAPE SEQUENCE
;
; APPLFLAGS BITS
;
CMD_TO_APPL EQU 1B ; PASS COMMAND TO APPLICATION
MSG_TO_USER EQU 10B ; SEND 'CONNECTED' TO USER
MSG_TO_APPL EQU 100B ; SEND 'CONECTED' TO APPL
;
; HDLC COMMANDS (WITHOUT P/F)
;
UI EQU 3
SABM EQU 2FH
DISC EQU 43H
DM EQU 0FH
UA EQU 63H
FRMR EQU 87H
RR EQU 1
RNR EQU 5
REJ EQU 9
;
PFBIT EQU 10H ; POLL/FINAL BIT IN CONTROL BYTE
;
; MH DATA AREA
;
;MHSTRUC STRUC
;MHCALL DB 7 DUP (0)
;MHTIME DD 0 ; ? FROM BIOS
;MHDIGI DB 0
;MHFreq DB 12 DUP (0)
;MHLocator DB 6 DUP (0)
;MHSTRUC ENDS
; Application Calls/Alias Supports multiple L4 application calls
APPLCALLS STRUC
APPLCALL DB 7 DUP (0) ; ax.25
APPLALIAS_TEXT DB 10 DUP (0) ; TEXT, WITH APPENDED SPACE
APPLCALL_TEXT DB 10 DUP (0)
APPLALIAS DB 6 DUP (0)
APFiller DB 0
APPLQUAL DW 0
APPNODEPOINTER DD 0 ; Pointer to "NODES" entry for this App (if L4)
APPLCMDNAME DB 13 DUP (0) ; Command to invoke this APPL
APPLHASALIAS DD 0
APPLPORT DD 0 ; Port if Appl has an alias
APPLALIASPTR DD 0 ; Pointer to Alias if defined
APPLCALLS ENDS
; New Style APPL configuration
APPLCONFIG STRUC
ACCommand DB 12 DUP (0);
ACCommandAlias DB 48 DUP (0);
ACApplCall DB 10 DUP (0);
ACApplAlias DB 10 DUP (0);
ACApplQual DD 0
APPLCONFIG ENDS
;
; HARDWARE TYPE EQUATES
;
KISS EQU 0
PC120 EQU 2
DRSI EQU 4
TOSH EQU 6
QUADRAM EQU 8
RLC100 EQU 0AH
RLC400 EQU 0CH
INTERNAL EQU 0EH
EXTERNAL EQU 10H
BAYCOM EQU 12H
PA0HZP EQU 14H

@ -0,0 +1,840 @@
// Program to start or stop a Software TNC on a remote host
// Should work with ARDOP, WINMOR or VARA
// Version 1. 0. 0. 1 June 2013
// Version 1. 0. 2. 1 April 2018
// Updated to support running programs with command line parameters
// Add option to KILL by program name
// Version 1. 0. 3. 1 April 2019
// Add remote rigcontrol feature
// Version 1. 0. 3. 2 Feb 2020
// Fix Rigcontol
// Version 1. 0. 3. 3 Dec 2020
// Set working directory when starting TNC
// Version 1. 0. 3. 4 Jan 2021
// Add trace window
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <Psapi.h>
#define BPQICON 400
#define WSA_READ WM_USER + 1
HINSTANCE hInst;
char AppName[] = "WinmorControl";
char Title[80] = "WinmorControl";
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(CONST WNDCLASS*);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap);
VOID WINAPI txCompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap);
VOID CATThread();
int TimerHandle = 0;
LOGFONT LFTTYFONT ;
HFONT hFont;
struct sockaddr_in sinx;
struct sockaddr rx;
SOCKET sock;
int udpport = 8500;
int addrlen = sizeof(struct sockaddr_in);
BOOL MinimizetoTray=FALSE;
VOID __cdecl Debugprintf(const char * format, ...)
{
char Mess[10000];
va_list(arglist);
va_start(arglist, format);
vsprintf(Mess, format, arglist);
strcat(Mess, "\r\n");
OutputDebugString(Mess);
return;
}
char * strlop(char * buf, char delim)
{
// Terminate buf at delim, and return rest of string
char * ptr;
if (buf == NULL) return NULL; // Protect
ptr = strchr(buf, delim);
if (ptr == NULL) return NULL;
*(ptr)++ = 0;
return ptr;
}
BOOL KillOldTNC(char * Path)
{
HANDLE hProc;
char ExeName[256] = "";
DWORD Pid = 0;
DWORD Processes[1024], Needed, Count;
unsigned int i;
if (!EnumProcesses(Processes, sizeof(Processes), &Needed))
return FALSE;
// Calculate how many process identifiers were returned.
Count = Needed / sizeof(DWORD);
for (i = 0; i < Count; i++)
{
if (Processes[i] != 0)
{
hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Processes[i]);
if (hProc)
{
GetModuleFileNameEx(hProc, 0, ExeName, 255);
if (_memicmp(ExeName, Path, strlen(ExeName)) == 0)
{
Debugprintf("Killing Pid %d %s", Processes[i], ExeName);
TerminateProcess(hProc, 0);
CloseHandle(hProc);
return TRUE;
}
CloseHandle(hProc);
}
}
}
return FALSE;
}
KillTNC(int PID)
{
HANDLE hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
Debugprintf("KillTNC Called Pid %d", PID);
if (hProc)
{
TerminateProcess(hProc, 0);
CloseHandle(hProc);
}
return 0;
}
RestartTNC(char * Path)
{
STARTUPINFO SInfo; // pointer to STARTUPINFO
PROCESS_INFORMATION PInfo; // pointer to PROCESS_INFORMATION
int i, n = 0;
char workingDirectory[256];
SInfo.cb=sizeof(SInfo);
SInfo.lpReserved=NULL;
SInfo.lpDesktop=NULL;
SInfo.lpTitle=NULL;
SInfo.dwFlags=0;
SInfo.cbReserved2=0;
SInfo.lpReserved2=NULL;
Debugprintf("RestartTNC Called for %s", Path);
strcpy(workingDirectory, Path);
i = strlen(Path);
while (i--)
{
if (workingDirectory[i] == '\\' || workingDirectory[i] == '/')
{
workingDirectory[i] = 0;
break;
}
}
while (KillOldTNC(Path) && n++ < 100)
{
Sleep(100);
}
if (CreateProcess(NULL, Path, NULL, NULL, FALSE,0 ,NULL ,workingDirectory, &SInfo, &PInfo))
Debugprintf("Restart TNC OK");
else
Debugprintf("Restart TNC Failed %d ", GetLastError());
}
char * RigPort = NULL;
char * RigSpeed = NULL;
HANDLE RigHandle = 0;
int RigType = 0; // Flag for possible RTS/DTR
#define RTS 1
#define DTR 2
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
if (lpCmdLine[0])
{
// Port Name and Speed for Remote CAT
RigPort = _strdup(lpCmdLine);
RigSpeed = strlop(RigPort, ':');
}
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
KillTimer(NULL, TimerHandle);
return (msg.wParam);
}
//
//
// FUNCTION: InitApplication(HANDLE)
//
// PURPOSE: Initializes window data and registers window class
//
// COMMENTS:
//
// In this function, we initialize a window class by filling out a data
// structure of type WNDCLASS and calling either RegisterClass or
// the internal MyRegisterClass.
//
BOOL InitApplication(HINSTANCE hInstance)
{
WNDCLASS wc;
// Fill in window class structure with parameters that describe
// the main window.
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(BPQICON));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
// wc.lpszMenuName = MAKEINTRESOURCE(BPQMENU) ;
wc.lpszClassName = AppName;
// Register the window class and return success/failure code.
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
HFONT FAR PASCAL MyCreateFont( void )
{
CHOOSEFONT cf;
LOGFONT lf;
HFONT hfont;
// Initialize members of the CHOOSEFONT structure.
cf.lStructSize = sizeof(CHOOSEFONT);
cf.hwndOwner = (HWND)NULL;
cf.hDC = (HDC)NULL;
cf.lpLogFont = &lf;
cf.iPointSize = 0;
cf.Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY;
cf.rgbColors = RGB(0,0,0);
cf.lCustData = 0L;
cf.lpfnHook = (LPCFHOOKPROC)NULL;
cf.lpTemplateName = (LPSTR)NULL;
cf.hInstance = (HINSTANCE) NULL;
cf.lpszStyle = (LPSTR)NULL;
cf.nFontType = SCREEN_FONTTYPE;
cf.nSizeMin = 0;
cf.nSizeMax = 0;
// Display the CHOOSEFONT common-dialog box.
ChooseFont(&cf);
// Create a logical font based on the user's
// selection and return a handle identifying
// that font.
hfont = CreateFontIndirect(cf.lpLogFont);
return (hfont);
}
VOID COMSetDTR(HANDLE fd)
{
EscapeCommFunction(fd, SETDTR);
}
VOID COMClearDTR(HANDLE fd)
{
EscapeCommFunction(fd, CLRDTR);
}
VOID COMSetRTS(HANDLE fd)
{
EscapeCommFunction(fd, SETRTS);
}
VOID COMClearRTS(HANDLE fd)
{
EscapeCommFunction(fd, CLRRTS);
}
OVERLAPPED txOverlapped;
HANDLE txEvent;
char RXBuffer[1024];
int RXLen;
int ReadCOMBlock(HANDLE fd, char * Block, int MaxLength)
{
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLength;
BOOL ret;
// only try to read number of bytes in queue
ret = ClearCommError(fd, &dwErrorFlags, &ComStat);
if (ret == 0)
{
int Err = GetLastError();
return 0;
}
dwLength = min((DWORD) MaxLength, ComStat.cbInQue);
if (dwLength > 0)
{
fReadStat = ReadFile(fd, Block, dwLength, &dwLength, NULL) ;
if (!fReadStat)
{
dwLength = 0 ;
ClearCommError(fd, &dwErrorFlags, &ComStat ) ;
}
}
return dwLength;
}
BOOL WriteCOMBlock(HANDLE fd, char * Block, int BytesToWrite)
{
BOOL fWriteStat;
DWORD BytesWritten;
DWORD ErrorFlags;
COMSTAT ComStat;
int Err, txLength;
Err = WaitForSingleObject(txEvent, 1000);
if (Err == WAIT_TIMEOUT)
{
Debugprintf("TX Event Wait Timout");
}
else
{
ResetEvent(txEvent);
Err = GetOverlappedResult(RigHandle, &txOverlapped, &txLength, FALSE);
}
memset(&txOverlapped, 0, sizeof(OVERLAPPED));
txOverlapped.hEvent = txEvent;
fWriteStat = WriteFile(fd, Block, BytesToWrite,
&BytesWritten, &txOverlapped);
if (!fWriteStat)
{
Err = GetLastError();
if (Err != ERROR_IO_PENDING)
{
ClearCommError(fd, &ErrorFlags, &ComStat);
return FALSE;
}
}
return TRUE;
}
HANDLE OpenCOMPort(char * pPort, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet, int Stopbits)
{
char szPort[80];
BOOL fRetVal ;
COMMTIMEOUTS CommTimeOuts ;
char buf[100];
HANDLE fd;
DCB dcb;
sprintf( szPort, "\\\\.\\%s", pPort);
// open COMM device
fd = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL );
if (fd == (HANDLE) -1)
{
char Msg[80];
sprintf(Msg, "%s could not be opened - Error %d", pPort, GetLastError());
MessageBox(NULL, Msg, "WinmorControl", MB_OK);
return FALSE;
}
// setup device buffers
SetupComm(fd, 4096, 4096);
// purge any information in the buffer
PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
// set up for overlapped I/O
CommTimeOuts.ReadIntervalTimeout = 20;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 0 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
// CommTimeOuts.WriteTotalTimeoutConstant = 0 ;
CommTimeOuts.WriteTotalTimeoutConstant = 500 ;
SetCommTimeouts(fd, &CommTimeOuts);
dcb.DCBlength = sizeof(DCB);
GetCommState(fd, &dcb);
dcb.BaudRate = speed;
dcb.ByteSize = 8;
dcb.Parity = 0;
dcb.StopBits = TWOSTOPBITS;
dcb.StopBits = Stopbits;
// setup hardware flow control
dcb.fOutxDsrFlow = 0;
dcb.fDtrControl = DTR_CONTROL_DISABLE ;
dcb.fOutxCtsFlow = 0;
dcb.fRtsControl = RTS_CONTROL_DISABLE ;
// setup software flow control
dcb.fInX = dcb.fOutX = 0;
dcb.XonChar = 0;
dcb.XoffChar = 0;
dcb.XonLim = 100 ;
dcb.XoffLim = 100 ;
// other various settings
dcb.fBinary = TRUE ;
dcb.fParity = FALSE;
fRetVal = SetCommState(fd, &dcb);
if (fRetVal)
{
if (SetDTR)
EscapeCommFunction(fd, SETDTR);
else
EscapeCommFunction(fd, CLRDTR);
if (SetRTS)
EscapeCommFunction(fd, SETRTS);
else
EscapeCommFunction(fd, CLRRTS);
}
else
{
sprintf(buf,"%s Setup Failed %d ", pPort, GetLastError());
OutputDebugString(buf);
CloseHandle(fd);
return 0;
}
txEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// Start Read Thread
_beginthread(CATThread, 0, 0);
return fd;
}
VOID CloseCOMPort(HANDLE fd)
{
SetCommMask(fd, 0);
// drop DTR
COMClearDTR(fd);
// purge any outstanding reads/writes and close device handle
PurgeComm(fd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CloseHandle(fd);
}
HWND hMonitor;
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
u_long param=1;
BOOL bcopt=TRUE;
char Msg[255];
int ret, err;
WSADATA WsaData; // receives data from WSAStartup
hInst = hInstance; // Store instance handle in our global variable
WSAStartup(MAKEWORD(2, 0), &WsaData);
hWnd = CreateWindow(AppName, Title, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, 420,275,
NULL, NULL, hInstance, NULL);
if (!hWnd) {
return (FALSE);
}
// setup default font information
LFTTYFONT.lfHeight = 12;
LFTTYFONT.lfWidth = 8 ;
LFTTYFONT.lfEscapement = 0 ;
LFTTYFONT.lfOrientation = 0 ;
LFTTYFONT.lfWeight = 0 ;
LFTTYFONT.lfItalic = 0 ;
LFTTYFONT.lfUnderline = 0 ;
LFTTYFONT.lfStrikeOut = 0 ;
LFTTYFONT.lfCharSet = OEM_CHARSET ;
LFTTYFONT.lfOutPrecision = OUT_DEFAULT_PRECIS ;
LFTTYFONT.lfClipPrecision = CLIP_DEFAULT_PRECIS ;
LFTTYFONT.lfQuality = DEFAULT_QUALITY ;
LFTTYFONT.lfPitchAndFamily = FIXED_PITCH | FF_MODERN ;
lstrcpy( LFTTYFONT.lfFaceName, "Fixedsys" ) ;
hFont = CreateFontIndirect(&LFTTYFONT) ;
// hFont = MyCreateFont();
SetWindowText(hWnd,Title);
hMonitor = CreateWindowEx(0, "LISTBOX", "", WS_CHILD | WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
LBS_DISABLENOSCROLL | WS_HSCROLL | WS_VSCROLL,
2,2,400,230, hWnd, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
sock = socket(AF_INET,SOCK_DGRAM,0);
if (sock == INVALID_SOCKET)
{
err = WSAGetLastError();
sprintf(Msg, "Failed to create UDP socket - error code = %d", err);
MessageBox(NULL, Msg, "WinmorControl", MB_OK);
return FALSE;
}
if (WSAAsyncSelect(sock, hWnd, WSA_READ, FD_READ) > 0)
{
wsprintf(Msg, TEXT("WSAAsyncSelect failed Error %d"), WSAGetLastError());
MessageBox(hWnd, Msg, TEXT("WinmorControl"), MB_OK);
closesocket(sock);
return FALSE;
}
// ioctlsocket (sock, FIONBIO, &param);
setsockopt (sock,SOL_SOCKET,SO_BROADCAST,(const char FAR *)&bcopt,4);
sinx.sin_family = AF_INET;
sinx.sin_addr.s_addr = INADDR_ANY;
sinx.sin_port = htons(udpport);
ret = bind(sock, (struct sockaddr *) &sinx, sizeof(sinx));
if (ret != 0)
{
// Bind Failed
err = WSAGetLastError();
sprintf(Msg, "Bind Failed for UDP socket - error code = %d", err);
MessageBox(NULL, Msg, "WinmorControl", MB_OK);
return FALSE;
}
if (RigPort)
{
int Speed = 9600;
if (RigSpeed)
Speed = atoi(RigSpeed);
RigHandle = OpenCOMPort(RigPort, Speed, FALSE, FALSE, FALSE, TWOSTOPBITS);
if (RigHandle)
{
if (RigType == RTS)
COMClearRTS(RigHandle);
else
COMSetRTS(RigHandle);
if (RigType == DTR)
COMClearDTR(RigHandle);
else
COMSetDTR(RigHandle);
}
else
return FALSE; // Open Failed
}
TimerHandle = SetTimer(hWnd, 1, 100, NULL);
return TRUE;
}
void Trace(char * Msg)
{
int index = SendMessage(hMonitor, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) Msg);
if (index > 1200)
do
index=index=SendMessage(hMonitor, LB_DELETESTRING, 0, 0);
while (index > 1000);
if (index > -1)
index=SendMessage(hMonitor, LB_SETCARETINDEX,(WPARAM) index, MAKELPARAM(FALSE, 0));
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
char Msg[256];
int len;
switch (message)
{
case WSA_READ: // Notification on data socket
len = recvfrom(sock, Msg, 256, 0, &rx, &addrlen);
if (len <= 0)
return 0;
Msg[len] = 0;
if (_memicmp(Msg, "REMOTE:", 7) == 0)
{
Trace(Msg);
RestartTNC(&Msg[7]);
}
else
if (_memicmp(Msg, "KILL ", 5) == 0)
{
Trace(Msg);
KillTNC(atoi(&Msg[5]));
}
else
if (_memicmp(Msg, "KILLBYNAME ", 11) == 0)
{
Trace(Msg);
KillOldTNC(&Msg[11]);
}
else
{
// Anything else is Rig Control
len = WriteCOMBlock(RigHandle, Msg, len);
}
break;
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case SC_MINIMIZE:
if (MinimizetoTray)
return ShowWindow(hWnd, SW_HIDE);
else
return (DefWindowProc(hWnd, message, wParam, lParam));
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
BOOL EndCATThread = FALSE;
VOID CATThread()
{
DWORD dwLength = 0;
int Length, ret;
HANDLE Event;
OVERLAPPED Overlapped;
EndCATThread = FALSE;
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
memset(&Overlapped, 0, sizeof(OVERLAPPED));
Overlapped.hEvent = Event;
ReadFile(RigHandle, RXBuffer, 1024, &RXLen, &Overlapped);
while (EndCATThread == FALSE)
{
ret = WaitForSingleObject(Event, 10000);
if (ret == WAIT_TIMEOUT)
{
if (EndCATThread)
{
CancelIo(RigHandle);
CloseHandle(RigHandle);
RigHandle = INVALID_HANDLE_VALUE;
CloseHandle(Event);
EndCATThread = FALSE;
return;
}
continue;
}
ResetEvent(Event);
ret = GetOverlappedResult(RigHandle, &Overlapped, &Length, FALSE);
if (ret && Length)
{
// got something so send to BPQ
sendto(sock, RXBuffer, Length, 0, &rx, sizeof(struct sockaddr));
}
memset(&Overlapped, 0, sizeof(OVERLAPPED));
Overlapped.hEvent = Event;
ReadFile(RigHandle, RXBuffer, 1024, &RXLen, &Overlapped);
}
}

@ -0,0 +1,62 @@
// CmdLineAuth.cpp : Defines the entry point for the console application.
//
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE
#define _USE_32BIT_TIME_T
#include <stdio.h>
#include <time.h>
#include <stdio.h>
#include "md5.c"
VOID CreateOneTimePassword(char * KeyPhrase)
{
// Create a time dependent One Time Password from the KeyPhrase
time_t NOW = time(NULL);
unsigned char Hash[16];
char Password[20];
char Key[1000];
int i, chr;
long long Val;
int PassCode;
NOW = NOW/30; // Only Change every 30 secs
sprintf(Key, "%s%x", KeyPhrase, NOW);
md5(Key, Hash);
for (i=0; i<16; i++)
{
chr = (Hash[i] & 31);
if (chr > 9) chr += 7;
Password[i] = chr + 48;
}
Password[16] = 0;
memcpy(&Val, Password, 8);
PassCode = Val % 1000000;
printf("Passcode is %06d\n", PassCode);
return;
}
int main(int argc, char * argv[])
{
if (argc < 2)
{
printf ("Need to supply KeyPhrase\n");
return 0;
}
CreateOneTimePassword(argv[1]);
return 0;
}

@ -0,0 +1,41 @@
/*
Copyright 2001-2015 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
*/
#include "cheaders.h"
#include "tncinfo.h"
//int SENDNODES() {return 0;}
//int BYECMD() {return 0;}
//int CMDR00() {return 0;}
//int DoNetromConnect() {return 0;}
//int CMDC00() {return 0;}
//int CheckReceivedData() {return 0;}
//int GetLastError() {return 0;}

@ -0,0 +1,434 @@
#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;
}
// Message Database Entry. Designed to be compatible with FBB
#define NBBBS 160 // Max BBSes we can forward to. Must be Multiple of 8, and must be 80 for FBB compatibliliy
#define NBMASK NBBBS/8 // Number of bytes in Forward bitlists.
#pragma pack(1)
struct MsgInfo
{
char type;
char status;
int number;
int length;
int xdatereceived;
char bbsfrom[7]; // ? BBS we got it from ?
char via[41];
char from[7];
char to[7];
char bid[13];
char title[61];
int nntpnum; // Number within topic (ie Bull TO Addr) - used for nntp
UCHAR B2Flags; // Not all flags specific to B2
#define B2Msg 1 // Set if Message File is a formatted B2 message
#define Attachments 2 // Set if B2 message has attachments
#define FromPaclink 4
#define FromCMS 8
#define FromRMSExpress 16
#define RadioOnlyMsg 32 // Received using call-T
#define RadioOnlyFwd 64 // Received using call-R
#define WarnNotForwardedSent 128
int xdatecreated;
int xdatechanged;
UCHAR fbbs[NBMASK];
UCHAR forw[NBMASK];
char emailfrom[41];
char Locked; // Set if selected for sending (NTS Pickup)
char Defered; // FBB response '=' received
UCHAR UTF8; // Set if Message is in UTF8 (ie from POP/SMTP)
// For 64 bit time_t compatibility define as long long
// (so struct is same with 32 or 64 bit time_t)
int64_t datereceived;
int64_t datecreated;
int64_t datechanged;
char Spare[61 - 24]; // For future use
} ;
#pragma pack()
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

@ -0,0 +1,229 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="WinmorControl"
ProjectGUID="{005A91EA-3A00-4FB4-ADD9-EB78DBFA2B82}"
RootNamespace="WinmorControl"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="C:\Dev\Msdev2005\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
IntermediateDirectory="C:\Dev\Msdev2005\Intermed\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/WinmorControl.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
RuntimeLibrary="1"
PrecompiledHeaderFile=".\Debug/WinmorControl.pch"
AssemblerListingLocation="$(IntDir)\"
ObjectFile="$(IntDir)\"
ProgramDataBaseFileName="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="WS2_32.Lib Psapi.lib"
OutputFile="c:\DevProgs\bpq32\WinmorControl.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/bpq32.pdb"
GenerateMapFile="true"
MapFileName="c:\devprogs\bpq32\bpqpp.map"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/WinmorControl.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="C:\Dev\Msdev2005\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
IntermediateDirectory="C:\Dev\Msdev2005\Intermed\$(SolutionName)\$(ProjectName)\$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/WinmorControl.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\cinclude"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile="C:\msdev2005\Intermed\Release/WinmorControl.pch"
AssemblerListingLocation="$(IntDir)\"
ObjectFile="$(IntDir)\"
ProgramDataBaseFileName="$(IntDir)\"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="WS2_32.Lib Psapi.lib"
OutputFile="c:\DevProgs\bpq32\WinmorControl.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/WinmorControl.pdb"
GenerateMapFile="true"
MapFileName="c:\devprogs\bpq32\WinmorControl.map"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/WinmorControl.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
>
<File
RelativePath=".\WinmorControl.c"
>
</File>
<File
RelativePath=".\WinmorControl.rc"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

@ -0,0 +1,193 @@
/*
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
*/
//
// Netrom Record ROute Suport Code for BPQ32 Switch
//
// All code runs from the BPQ32 Received or Timer Routines under Semaphore.
// As most data areas are dynamically allocated, they will not survive a Timer Process Swap.
// Shared data can be used for Config Info.
#define _CRT_SECURE_NO_DEPRECATE
#pragma data_seg("_BPQDATA")
#include "time.h"
#include "stdio.h"
#include <fcntl.h>
//#include "vmm.h"
#include "cheaders.h"
extern int SENDNETFRAME();
extern VOID Q_ADD();
VOID __cdecl Debugprintf(const char * format, ...);
TRANSPORTENTRY * NRRSession;
/*
datagrams (and other things) to be transported in Netrom L3 frames.
When the frametype is 0x00, the "circuit index" and "circuit id" (first 2
bytes of the transport header) take on a different meaning, something like
"protocol family" and "protocol id". IP over netrom uses 0x0C for both
bytes, TheNet uses 0x00 for both bytes when making L3RTT measurements, and
Xnet uses family 0x00, protocol id 0x01 for Netrom Record Route. I believe
there are authors using other values too. Unfortunately there is no
co-ordinating authority for these numbers, so authors just pick an unused
one.
*/
VOID NRRecordRoute(UCHAR * Buff, int Len)
{
// NRR frame for us. If We originated it, report outcome, else put our call on end, and send back
L3MESSAGEBUFFER * Msg = (L3MESSAGEBUFFER *)Buff;
struct DEST_LIST * DEST;
char Temp[7];
int NRRLen = Len - (21 + MSGHDDRLEN);
UCHAR Flags;
char call[10];
int calllen;
char * Save = Buff;
if (memcmp(&Msg->L4DATA, MYCALL, 7) == 0)
{
UCHAR * BUFFER = GetBuff();
UCHAR * ptr1;
struct _MESSAGE * Msg;
if (BUFFER == NULL)
return;
ptr1 = &BUFFER[MSGHDDRLEN];
*ptr1++ = 0xf0; // PID
ptr1 += sprintf(ptr1, "NRR Response:");
Buff += 21 + MSGHDDRLEN;
Len -= (21 + MSGHDDRLEN);
while (Len > 0)
{
calllen = ConvFromAX25(Buff, call);
call[calllen] = 0;
ptr1 += sprintf(ptr1, " %s", call);
if ((Buff[7] & 0x80) == 0x80) // Check turnround bit
*ptr1++ = '*';
Buff+=8;
Len -= 8;
}
// Add ours on end for neatness
calllen = ConvFromAX25(MYCALL, call);
call[calllen] = 0;
ptr1 += sprintf(ptr1, " %s", call);
*ptr1++ = 0x0d; // CR
Len = (int)(ptr1 - BUFFER);
Msg = (struct _MESSAGE *)BUFFER;
Msg->LENGTH = Len;
Msg->CHAIN = NULL;
C_Q_ADD(&NRRSession->L4TX_Q, (UINT *)BUFFER);
PostDataAvailable(NRRSession);
ReleaseBuffer(Save);
return;
}
// Add our call on end, and increase count
Flags = Buff[Len - 1];
Flags--;
if (Flags && NRRLen < 228) // Dont update if full
{
Flags |= 0x80; // Set End of route bit
Msg->L3PID = NRPID;
memcpy(&Msg->L4DATA[NRRLen], MYCALL, 7);
Msg->L4DATA[NRRLen+7] = Flags;
NRRLen += 8;
}
// We should send it back via our bast route, or recorded route could be wrong
memcpy(Temp, Msg->L3DEST, 7);
memcpy(Msg->L3DEST, Msg->L3SRCE, 7);
memcpy(Msg->L3SRCE, Temp, 7);
if (FindDestination(Msg->L3DEST, &DEST) == 0)
{
ReleaseBuffer(Msg); // CANT FIND DESTINATION
return;
}
Msg->LENGTH = NRRLen + 21 + MSGHDDRLEN;
Debugprintf("NRR TX Len %d Flags %d NRRLen %d", Msg->LENGTH, Flags, NRRLen);
C_Q_ADD(&DEST->DEST_Q, Msg);
}
VOID SendNRRecordRoute(struct DEST_LIST * DEST, TRANSPORTENTRY * Session)
{
L3MESSAGEBUFFER * Msg = GetBuff();
int Stream = 1;
if (Msg == NULL)
return;
NRRSession = Session; // Save Session Pointer for reply
Msg->Port = 0;
Msg->L3PID = NRPID;
memcpy(Msg->L3DEST, DEST->DEST_CALL, 7);
memcpy(Msg->L3SRCE, MYCALL, 7);
Msg->L3TTL = L3LIVES;
Msg->L4ID = 1;
Msg->L4INDEX = 0;
Msg->L4FLAGS = 0;
memcpy(Msg->L4DATA, MYCALL, 7);
Msg->L4DATA[7] = Stream + 28;
Msg->LENGTH = 8 + 21 + MSGHDDRLEN;
C_Q_ADD(&DEST->DEST_Q, Msg);
}

@ -0,0 +1,297 @@
/* pngerror.c - stub functions for i/o and memory allocation
*
* libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*
* This file provides a location for all error handling. Users who
* need special error handling are expected to write replacement functions
* and use png_set_error_fn() to use those functions. See the instructions
* at each function.
*/
#define PNG_INTERNAL
#include "png.h"
void Myabort();
static void /* PRIVATE */
png_default_error PNGARG((png_structp png_ptr,
png_const_charp error_message));
static void /* PRIVATE */
png_default_warning PNGARG((png_structp png_ptr,
png_const_charp warning_message));
/* This function is called whenever there is a fatal error. This function
* should not be changed. If there is a need to handle errors differently,
* you should supply a replacement error function and use png_set_error_fn()
* to replace the error function at run-time.
*/
void PNGAPI
png_error(png_structp png_ptr, png_const_charp error_message)
{
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
char msg[16];
if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
{
if (*error_message == '#')
{
int offset;
for (offset=1; offset<15; offset++)
if (*(error_message+offset) == ' ')
break;
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
int i;
for (i=0; i<offset-1; i++)
msg[i]=error_message[i+1];
msg[i]='\0';
error_message=msg;
}
else
error_message+=offset;
}
else
{
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
{
msg[0]='0';
msg[1]='\0';
error_message=msg;
}
}
}
#endif
if (png_ptr != NULL && png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, error_message);
/* If the custom handler doesn't exist, or if it returns,
use the default handler, which will not return. */
png_default_error(png_ptr, error_message);
}
/* This function is called whenever there is a non-fatal error. This function
* should not be changed. If there is a need to handle warnings differently,
* you should supply a replacement warning function and use
* png_set_error_fn() to replace the warning function at run-time.
*/
void PNGAPI
png_warning(png_structp png_ptr, png_const_charp warning_message)
{
int offset = 0;
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
#endif
{
if (*warning_message == '#')
{
for (offset=1; offset<15; offset++)
if (*(warning_message+offset) == ' ')
break;
}
}
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
else
png_default_warning(png_ptr, warning_message+offset);
}
/* These utilities are used internally to build an error message that relates
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
* this is used to prefix the message. The message is limited in length
* to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid.
*/
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'
};
static void /* PRIVATE */
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
error_message)
{
int iout = 0, iin = 0;
while (iin < 4)
{
int c = png_ptr->chunk_name[iin++];
if (isnonalpha(c))
{
buffer[iout++] = '[';
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
buffer[iout++] = png_digit[c & 0x0f];
buffer[iout++] = ']';
}
else
{
buffer[iout++] = (png_byte)c;
}
}
if (error_message == NULL)
buffer[iout] = 0;
else
{
buffer[iout++] = ':';
buffer[iout++] = ' ';
png_strncpy(buffer+iout, error_message, 63);
buffer[iout+63] = 0;
}
}
void PNGAPI
png_chunk_error(png_structp png_ptr, png_const_charp error_message)
{
char msg[18+64];
png_format_buffer(png_ptr, msg, error_message);
png_error(png_ptr, msg);
}
void PNGAPI
png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
{
char msg[18+64];
png_format_buffer(png_ptr, msg, warning_message);
png_warning(png_ptr, msg);
}
/* This is the default error handling function. Note that replacements for
* this function MUST NOT RETURN, or the program will likely crash. This
* function is used by default, or if the program supplies NULL for the
* error function pointer in png_set_error_fn().
*/
static void /* PRIVATE */
png_default_error(png_structp png_ptr, png_const_charp error_message)
{
#ifndef PNG_NO_CONSOLE_IO
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*error_message == '#')
{
int offset;
char error_number[16];
for (offset=0; offset<15; offset++)
{
error_number[offset] = *(error_message+offset+1);
if (*(error_message+offset) == ' ')
break;
}
if((offset > 1) && (offset < 15))
{
error_number[offset-1]='\0';
fprintf(stderr, "libpng error no. %s: %s\n", error_number,
error_message+offset);
}
else
fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
}
else
#endif
fprintf(stderr, "libpng error: %s\n", error_message);
#endif
#ifdef PNG_SETJMP_SUPPORTED
# ifdef USE_FAR_KEYWORD
{
jmp_buf jmpbuf;
png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf));
longjmp(jmpbuf, 1);
}
# else
longjmp(png_ptr->jmpbuf, 1);
# endif
#else
/* make compiler happy */ ;
if (png_ptr)
PNG_ABORT();
#endif
#ifdef PNG_NO_CONSOLE_IO
/* make compiler happy */ ;
// if (&error_message != NULL)
return;
#endif
}
/* This function is called when there is a warning, but the library thinks
* it can continue anyway. Replacement functions don't have to do anything
* here if you don't want them to. In the default configuration, png_ptr is
* not used, but it is passed in case it may be useful.
*/
static void /* PRIVATE */
png_default_warning(png_structp png_ptr, png_const_charp warning_message)
{
#ifndef PNG_NO_CONSOLE_IO
# ifdef PNG_ERROR_NUMBERS_SUPPORTED
if (*warning_message == '#')
{
int offset;
char warning_number[16];
for (offset=0; offset<15; offset++)
{
warning_number[offset]=*(warning_message+offset+1);
if (*(warning_message+offset) == ' ')
break;
}
if((offset > 1) && (offset < 15))
{
warning_number[offset-1]='\0';
fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
warning_message+offset);
}
else
fprintf(stderr, "libpng warning: %s\n", warning_message);
}
else
# endif
fprintf(stderr, "libpng warning: %s\n", warning_message);
#else
/* make compiler happy */ ;
if (warning_message)
return;
#endif
/* make compiler happy */ ;
if (png_ptr)
return;
}
/* This function is called when the application wants to use another method
* of handling errors and warnings. Note that the error function MUST NOT
* return to the calling routine or serious problems will occur. The return
* method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
*/
void PNGAPI
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warning_fn)
{
png_ptr->error_ptr = error_ptr;
png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn;
}
/* This function returns a pointer to the error_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp PNGAPI
png_get_error_ptr(png_structp png_ptr)
{
return ((png_voidp)png_ptr->error_ptr);
}
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
void PNGAPI
png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
{
if(png_ptr != NULL)
{
png_ptr->flags &=
((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
}
}
#endif

@ -0,0 +1,673 @@
/*
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
*/
// DRATS support code
#define _CRT_SECURE_NO_DEPRECATE
#include "cheaders.h"
#include "bpq32.h"
#include "telnetserver.h"
/*
The header is the first 23 bytes of of the frame. The payload is the rest of the frame.
Byte 1 is a "magic" number. It is 0xDD if the payload is zlib compressed before being yencoded.
Bytes 2 and 3 is a 16 bit sequence number.
Byte 4 is a session number.
Byte 5 is a type. Still don't know the types.
Bytes 6 and 7, 16 bits, is the checksum of the data after any compression.
Bytes 8 and 9, 16 bits, is the length of the data.
bytes 10-18, 8 bits, are the source call sign.
bytes 19-25, 8 bits, are the destination call sign.
If a call sign is less than 8 characters, it is padded to fill the space with the "~" tilde character.
Frame types: (Some from sessions/chat.py)
0 - T_DEF
1 - T_PING_REQ - Ping request (Used in Test frame)
2 - T_PING_RSP - Ping response
3 - T_PING_ERS - Ping error status?
4 - T_STATUS - Status frame
5 - File Transfer
8 - Used in Test frame
254 - Apparently a warm up frame.
T_DEF = 0
T_PNG_REQ = 1
T_PNG_RSP = 2
T_PNG_ERQ = 3
T_PNG_ERS = 4
T_STATUS = 5
For a station status frame, the first byte of the message is an ASCII station status value.
'0' - Unknown
'1' - Online
'2' - Unattended
'9' - Offline
*/
#define T_DEF 0
#define T_PNG_REQ 1
#define T_PNG_RSP 2
#define T_PNG_ERQ 3
#define T_PNG_ERS 4
#define T_STATUS 5
#pragma pack(1)
// shorts are big-endian
struct DRATSHeader
{
unsigned char Magic;
unsigned short Seq;
unsigned char Sessno;
unsigned char Type;
unsigned short CheckSum;
unsigned short Length;
char CallFrom[8];
char CallTo[8];
unsigned char Message[2048];
};
#pragma pack()
struct DRATSSession
{
struct ConnectionInfo * sockptr;
unsigned int Seq;
unsigned int Sessno;
char CallFrom[8];
char CallTo[8];
int Stream; // BPQ Stream
int StreamState;
struct DRATSQueue * Queue;
struct DRATSSession * Next;
};
struct DRATSQueue
{
// Queue of messages to be sent to node from background (ie not under semaphore)
int Stream;
int Len;
unsigned char * Msg;
struct DRATSQueue * Next;
};
struct DRATSSession * DRATSSessions = NULL;
char peer0_2[] = { /* Packet 17 */
0x5b, 0x53, 0x4f, 0x42, 0x5d, 0xdd, 0x3d, 0x40,
0x3d, 0x40, 0x01, 0x05, 0x45, 0x78, 0x3d, 0x40,
0x18, 0x47, 0x38, 0x42, 0x50, 0x51, 0x7e, 0x7e,
0x7e, 0x43, 0x51, 0x43, 0x51, 0x43, 0x51, 0x7e,
0x7e, 0x78, 0xda, 0x33, 0xf4, 0xcf, 0xcb, 0xc9,
0xcc, 0x4b, 0x55, 0xd0, 0x70, 0xd1, 0x0d, 0x72,
0x0c, 0x09, 0xd6, 0x04, 0x3d, 0x40, 0x2a, 0x8c,
0x04, 0xb3, 0x5b, 0x45, 0x4f, 0x42, 0x5d };
void processDRATSFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr);
int testDRATS()
{
// processDRATSFrame(peer0_1, sizeof(peer0_1), 0);
// processDRATSFrame(peer0_2, sizeof(peer0_2), 0);
// processDRATSFrame(peer1_1, sizeof(peer1_1), 0);
// processDRATSFrame(peer1_20, sizeof(peer1_20));
// processDRATSFrame(peer0_20, sizeof(peer0_20));
// processDRATSFrame(peer1_21, sizeof(peer1_21));
return 0;
}
extern char pgm[256];
extern char TextVerstring[50];
int HeaderLen = offsetof(struct DRATSHeader, Message);
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen);
int dratscrc(unsigned char *ptr, int count);
int FindFreeStreamNoSem();
void sendDRATSFrame(struct ConnectionInfo * sockptr, struct DRATSHeader * Header);
int yEncode(unsigned char * in, unsigned char * out, int len, unsigned char * Banned);
int AllocateDRATSStream(struct DRATSSession * Sess)
{
int Stream;
strcpy(pgm, "DRATS");
Stream = FindFreeStreamNoSem();
strcpy(pgm, "bpq32.exe");
if (Stream == 255) return 0;
if (memcmp(Sess->CallTo, "NODE", 4) == 0)
{
// Just connect to command level on switch
}
return Stream;
}
void ProcessDRATSPayload(struct DRATSHeader * Header, struct DRATSSession * Sess)
{
struct DRATSQueue * QEntry;
BPQVECSTRUC * HOST;
if (Sess->Stream == 0)
{
Sess->Stream = AllocateDRATSStream(Sess);
}
if (Sess->StreamState == 0)
{
unsigned char AXCall[10];
Connect(Sess->Stream); // Connect
ConvToAX25(Sess->CallFrom, AXCall);
ChangeSessionCallsign(Sess->Stream, AXCall); // Prevent triggering incoming connect code
// Clear State Changed bits (cant use SessionState under semaphore)
HOST = &BPQHOSTVECTOR[Sess->Stream -1]; // API counts from 1
HOST->HOSTFLAGS &= 0xFC; // Clear Change Bits
Sess->StreamState = 1;
}
strcat(Header->Message, "\r");
// Need to Queue to Background as we can't use SendMsg under semaphore
QEntry = zalloc(sizeof(struct DRATSQueue));
QEntry->Len = strlen(Header->Message);
QEntry->Msg = malloc(QEntry->Len);
memcpy(QEntry->Msg, Header->Message, QEntry->Len);
// Add to queue
if (Sess->Queue)
{
struct DRATSQueue * End = Sess->Queue;
// Add on end
while (End->Next)
End = End->Next;
End->Next = QEntry;
}
else
Sess->Queue = QEntry;
}
// Called under semaphore
void processDRATSFrame(unsigned char * Message, int Len, struct ConnectionInfo * sockptr)
{
unsigned char * Payload;
unsigned char * ptr;
unsigned char dest[2048];
struct DRATSHeader * Header;
int outLen;
struct DRATSSession * Sess = DRATSSessions;
unsigned short crc, savecrc;
char CallFrom[10] = "";
char CallTo[10] = "";
Message[Len] = 0;
Debugprintf(Message);
Payload = strstr(Message, "[SOB]");
if (Payload == 0)
return;
ptr = strstr(Message, "[EOB]");
if (ptr == 0)
return;
ptr[0] = 0;
Payload += 5;
Header = (struct DRATSHeader *)Payload;
// Undo = transparency
ptr = Payload;
while (ptr = strchr(ptr, '='))
{
memmove(ptr, ptr + 1, Len);
ptr[0] -= 64;
ptr++;
}
// Check CRC
savecrc = htons(Header->CheckSum);
Header->CheckSum = 0;
crc = dratscrc(Payload, htons(Header->Length) + HeaderLen);
if (crc != savecrc)
{
Debugprintf(" DRARS CRC Error %x %x", crc, savecrc); // Good CRC
return;
}
Header->Length = htons(Header->Length); // convert to machine order
if (Header->Magic == 0xdd) // Zlib compressed
{
doinflate(Header->Message, dest, Header->Length, 2048, &outLen);
memcpy(Header->Message, dest, outLen + 1);
Header->Length = outLen;
}
Debugprintf(Header->Message);
// Look for a matching From/To/Session
memcpy(CallFrom, Header->CallFrom, 8);
memcpy(CallTo, Header->CallTo, 8);
strlop(CallFrom, '~');
strlop(CallTo, '~');
if (Header->Type == T_STATUS)
{
// Status frame ?? What to do with it ??
return;
}
if (Header->Type == T_PNG_REQ)
{
// "Ping Request"
// if to "NODE" reply to it
if (strcmp(CallTo, "NODE") == 0)
{
// Reuse incoming message
strcpy(Header->CallFrom, CallTo);
strcpy(Header->CallTo, CallFrom);
Header->Type = T_PNG_RSP;
Header->Length = sprintf(Header->Message, "Running BPQ32 Version %s", TextVerstring);
sendDRATSFrame(sockptr, Header);
return;
}
// Not to us - do we route it ??
return;
}
if (Header->Type == T_PNG_RSP)
{
// Reponse is PNG_RSP then Status - 1Online (D-RATS)
// "Running D-RATS 0.3.9 (Windows 8->10 (6, 2, 9200, 2, ''))"
// "Running D-RATS 0.3.10 beta 4 (Linux - Raspbian GNU/Linux 9)"
return;
}
if (Header->Type != T_DEF)
{
return;
}
// ?? Normal Data
if (strcmp(CallTo, "NODE") != 0)
{
// Not not Node - should we route it ??
return;
}
while (Sess)
{
if (Sess->Sessno == Header->Sessno && memcmp(Sess->CallFrom, CallFrom, 8) == 0
&& memcmp(Sess->CallTo, CallTo, 8) == 0 && Sess->sockptr == sockptr)
{
ProcessDRATSPayload(Header, Sess);
return;
}
Sess = Sess->Next;
}
// Allocate a new one
Sess = zalloc(sizeof(struct DRATSSession));
Sess->Sessno = Header->Sessno;
memcpy(Sess->CallFrom, CallFrom, 8);
memcpy(Sess->CallTo, CallTo, 8);
Sess->sockptr = sockptr;
if (DRATSSessions)
{
// Add to front of Chain
Sess->Next = DRATSSessions;
}
DRATSSessions = Sess;
ProcessDRATSPayload(Header, Sess);
return;
}
void DRATSPoll()
{
struct DRATSSession * Sess = DRATSSessions;
int Stream, state, change;
int count;
struct DRATSHeader Header;
struct DRATSQueue * QEntry;
struct DRATSQueue * Save;
while (Sess)
{
Stream = Sess->Stream;
SessionState(Stream, &state, &change);
if (change == 1)
{
if (state == 1)
{
// Connected - do we need anything ??
}
else
{
// Send a disconnected message
char From[10] = "~~~~~~~~~";
char To[10] = "~~~~~~~~~";
Sess->StreamState = 0;
Header.Length = sprintf(Header.Message, "*** Disconnected from Node");
memcpy(To, Sess->CallFrom, strlen(Sess->CallFrom));
memcpy(From, Sess->CallTo, strlen(Sess->CallTo));
memcpy(Header.CallFrom, From, 8);
memcpy(Header.CallTo, To, 8);
Header.Magic = 0x22;
Header.Type = 0;
Header.Seq = 0;
Header.Sessno = Sess->Sessno;
sendDRATSFrame(Sess->sockptr, &Header);
}
}
do
{
int Len;
GetMsg(Stream, (char *)Header.Message, &Len, &count);
Header.Length = Len;
if (Header.Length)
{
char From[10] = "~~~~~~~~~";
char To[10] = "~~~~~~~~~";
memcpy(To, Sess->CallFrom, strlen(Sess->CallFrom));
memcpy(From, Sess->CallTo, strlen(Sess->CallTo));
memcpy(Header.CallFrom, From, 8);
memcpy(Header.CallTo, To, 8);
Header.Magic = 0x22;
Header.Type = 0;
Header.Seq = 0;
Header.Sessno = Sess->Sessno;
sendDRATSFrame(Sess->sockptr, &Header);
}
}
while (count > 0);
// See if anything to send to node
QEntry = Sess->Queue;
while (QEntry)
{
SendMsg(Sess->Stream, QEntry->Msg, QEntry->Len);
Save = QEntry;
QEntry = QEntry->Next;
free(Save->Msg);
free(Save);
}
Sess->Queue = 0;
Sess = Sess->Next;
}
}
unsigned char BANNED[] = {'=', 0x11, 0x13, 0x1A, 0xFD, 0xFE, 0xFF, 0};
void sendDRATSFrame(struct ConnectionInfo * sockptr, struct DRATSHeader * Header)
{
unsigned short crc;
int len;
unsigned char out[2048] = "[SOB]";
int packetLen = Header->Length + HeaderLen;
// Length is in host order
Header->Length = htons(Header->Length);
Header->CheckSum = 0;
crc = dratscrc((unsigned char *)Header, packetLen);
Header->CheckSum = htons(crc);
len = yEncode((unsigned char *)Header, out + 5, packetLen, BANNED);
memcpy(&out[len + 5], "[EOB]", 5);
Debugprintf(out);
send(sockptr->socket, out, len + 10, 0);
}
void DRATSConnectionLost(struct ConnectionInfo * sockptr)
{
// Disconnect any sessions, then free Stream and Sess record
struct DRATSSession * Sess = DRATSSessions;
struct DRATSSession * Save = 0;
BPQVECSTRUC * HOST;
while (Sess)
{
if (Sess->sockptr == sockptr)
{
if (Sess->StreamState == 1) // COnnected
{
Disconnect(Sess->Stream);
HOST = &BPQHOSTVECTOR[Sess->Stream -1]; // API counts from 1
HOST->HOSTFLAGS &= 0xFC; // Clear Change Bits
}
DeallocateStream(Sess->Stream);
// We must unhook from chain
if (Save)
Save->Next = Sess->Next;
else
DRATSSessions = Sess->Next;
// Should really Free any Queue, but unlikely to be any
free(Sess);
if (Save)
Sess = Save->Next;
else
Sess = DRATSSessions;
}
else
{
Save = Sess;
Sess = Sess->Next;
}
}
}
#ifdef WIN32
#define ZEXPORT __stdcall
#endif
#include <zlib.h>
int doinflate(unsigned char * source, unsigned char * dest, int Len, int destlen, int * outLen)
{
int ret;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
strm.avail_in = Len;
strm.next_in = source;
strm.avail_out = destlen;
strm.next_out = dest;
ret = inflate(&strm, Z_NO_FLUSH);
inflateEnd(&strm);
dest[strm.total_out] = 0;
*outLen = strm.total_out;
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
// No idea what this CRC is, but it works! (converted from DRATS python code)
int update_crc(int c, int crc)
{
int i;
int v;
for (i = 0; i < 8; i++)
{
if ((c & 0x80))
v = 1;
else
v = 0;
if (crc & 0x8000)
{
crc <<= 1;
crc += v;
crc ^= 0x1021;
}
else
{
crc <<= 1;
crc += v;
}
c <<= 1;
}
crc &= 0xFFFF;
return crc;
}
int dratscrc(unsigned char *ptr, int count)
{
int i;
int checksum = 0;
for (i = 0; i < count; i++)
checksum = update_crc(ptr[i], checksum);
checksum = update_crc(0, checksum);
checksum = update_crc(0, checksum);
return checksum;
}
#define OFFSET 64
int yEncode(unsigned char * in, unsigned char * out, int len, unsigned char * Banned)
{
unsigned char * ptr = out;
unsigned char c;
while (len--)
{
c = *(in++);
if (strchr(&Banned[0], c))
{
*(out++) = '=';
*(out++) = (c + OFFSET) & 0xFF;
}
else
*(out++) = c;
}
return (out - ptr);
}

@ -0,0 +1,750 @@
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#ifndef __AFXRES_H__
#define __AFXRES_H__
#ifdef REZ // Mac resource compiler (mrc) defines REZ
#define RC_INVOKED
#endif
#ifdef RC_INVOKED
#ifndef _INC_WINDOWS
#define _INC_WINDOWS
#include "..\include\winres.h" // extract from windows header
#endif
#endif
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, off)
#endif
#ifdef APSTUDIO_INVOKED
#define APSTUDIO_HIDDEN_SYMBOLS
#endif
/////////////////////////////////////////////////////////////////////////////
// MFC resource types (see Technical note TN024 for implementation details)
#ifndef RC_INVOKED
#define RT_DLGINIT MAKEINTRESOURCE(240)
#define RT_TOOLBAR MAKEINTRESOURCE(241)
#endif
/////////////////////////////////////////////////////////////////////////////
#ifdef APSTUDIO_INVOKED
#undef APSTUDIO_HIDDEN_SYMBOLS
#endif
/////////////////////////////////////////////////////////////////////////////
// General style bits etc
// Tab Control styles
#ifndef TCS_MULTILINE // new in later versions of Win32
#define TCS_MULTILINE 0x0200
#endif
// ControlBar styles
#define CBRS_ALIGN_LEFT 0x1000L
#define CBRS_ALIGN_TOP 0x2000L
#define CBRS_ALIGN_RIGHT 0x4000L
#define CBRS_ALIGN_BOTTOM 0x8000L
#define CBRS_ALIGN_ANY 0xF000L
#define CBRS_BORDER_LEFT 0x0100L
#define CBRS_BORDER_TOP 0x0200L
#define CBRS_BORDER_RIGHT 0x0400L
#define CBRS_BORDER_BOTTOM 0x0800L
#define CBRS_BORDER_ANY 0x0F00L
#define CBRS_TOOLTIPS 0x0010L
#define CBRS_FLYBY 0x0020L
#define CBRS_FLOAT_MULTI 0x0040L
#define CBRS_BORDER_3D 0x0080L
#define CBRS_HIDE_INPLACE 0x0008L
#define CBRS_SIZE_DYNAMIC 0x0004L
#define CBRS_SIZE_FIXED 0x0002L
#define CBRS_FLOATING 0x0001L
#define CBRS_ORIENT_HORZ (CBRS_ALIGN_TOP|CBRS_ALIGN_BOTTOM)
#define CBRS_ORIENT_VERT (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT)
#define CBRS_ORIENT_ANY (CBRS_ORIENT_HORZ|CBRS_ORIENT_VERT)
#define CBRS_ALL 0xFFFFL
// the CBRS_ style is made up of an alignment style and a draw border style
// the alignment styles are mutually exclusive
// the draw border styles may be combined
#define CBRS_NOALIGN 0x00000000L
#define CBRS_LEFT (CBRS_ALIGN_LEFT|CBRS_BORDER_RIGHT)
#define CBRS_TOP (CBRS_ALIGN_TOP|CBRS_BORDER_BOTTOM)
#define CBRS_RIGHT (CBRS_ALIGN_RIGHT|CBRS_BORDER_LEFT)
#define CBRS_BOTTOM (CBRS_ALIGN_BOTTOM|CBRS_BORDER_TOP)
/////////////////////////////////////////////////////////////////////////////
// Standard window components
// Mode indicators in status bar - these are routed like commands
#define ID_INDICATOR_EXT 0xE700 // extended selection indicator
#define ID_INDICATOR_CAPS 0xE701 // cap lock indicator
#define ID_INDICATOR_NUM 0xE702 // num lock indicator
#define ID_INDICATOR_SCRL 0xE703 // scroll lock indicator
#define ID_INDICATOR_OVR 0xE704 // overtype mode indicator
#define ID_INDICATOR_REC 0xE705 // record mode indicator
#define ID_INDICATOR_KANA 0xE706 // kana lock indicator
#define ID_SEPARATOR 0 // special separator value
#ifndef RC_INVOKED // code only
// Standard control bars (IDW = window ID)
#define AFX_IDW_CONTROLBAR_FIRST 0xE800
#define AFX_IDW_CONTROLBAR_LAST 0xE8FF
#define AFX_IDW_TOOLBAR 0xE800 // main Toolbar for window
#define AFX_IDW_STATUS_BAR 0xE801 // Status bar window
#define AFX_IDW_PREVIEW_BAR 0xE802 // PrintPreview Dialog Bar
#define AFX_IDW_RESIZE_BAR 0xE803 // OLE in-place resize bar
// Note: If your application supports docking toolbars, you should
// not use the following IDs for your own toolbars. The IDs chosen
// are at the top of the first 32 such that the bars will be hidden
// while in print preview mode, and are not likely to conflict with
// IDs your application may have used succesfully in the past.
#define AFX_IDW_DOCKBAR_TOP 0xE81B
#define AFX_IDW_DOCKBAR_LEFT 0xE81C
#define AFX_IDW_DOCKBAR_RIGHT 0xE81D
#define AFX_IDW_DOCKBAR_BOTTOM 0xE81E
#define AFX_IDW_DOCKBAR_FLOAT 0xE81F
// Macro for mapping standard control bars to bitmask (limit of 32)
#define AFX_CONTROLBAR_MASK(nIDC) (1L << (nIDC - AFX_IDW_CONTROLBAR_FIRST))
// parts of Main Frame
#define AFX_IDW_PANE_FIRST 0xE900 // first pane (256 max)
#define AFX_IDW_PANE_LAST 0xE9ff
#define AFX_IDW_HSCROLL_FIRST 0xEA00 // first Horz scrollbar (16 max)
#define AFX_IDW_VSCROLL_FIRST 0xEA10 // first Vert scrollbar (16 max)
#define AFX_IDW_SIZE_BOX 0xEA20 // size box for splitters
#define AFX_IDW_PANE_SAVE 0xEA21 // to shift AFX_IDW_PANE_FIRST
#endif //!RC_INVOKED
#ifndef APSTUDIO_INVOKED
// common style for form views
#define AFX_WS_DEFAULT_VIEW (WS_CHILD | WS_VISIBLE | WS_BORDER)
#endif //!APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Standard app configurable strings
// for application title (defaults to EXE name or name in constructor)
#define AFX_IDS_APP_TITLE 0xE000
// idle message bar line
#define AFX_IDS_IDLEMESSAGE 0xE001
// message bar line when in shift-F1 help mode
#define AFX_IDS_HELPMODEMESSAGE 0xE002
// document title when editing OLE embedding
#define AFX_IDS_APP_TITLE_EMBEDDING 0xE003
// company name
#define AFX_IDS_COMPANY_NAME 0xE004
// object name when server is inplace
#define AFX_IDS_OBJ_TITLE_INPLACE 0xE005
/////////////////////////////////////////////////////////////////////////////
// Standard Commands
// File commands
#define ID_FILE_NEW 0xE100
#define ID_FILE_OPEN 0xE101
#define ID_FILE_CLOSE 0xE102
#define ID_FILE_SAVE 0xE103
#define ID_FILE_SAVE_AS 0xE104
#define ID_FILE_PAGE_SETUP 0xE105
#define ID_FILE_PRINT_SETUP 0xE106
#define ID_FILE_PRINT 0xE107
#define ID_FILE_PRINT_DIRECT 0xE108
#define ID_FILE_PRINT_PREVIEW 0xE109
#define ID_FILE_UPDATE 0xE10A
#define ID_FILE_SAVE_COPY_AS 0xE10B
#define ID_FILE_SEND_MAIL 0xE10C
#define ID_FILE_MRU_FIRST 0xE110
#define ID_FILE_MRU_FILE1 0xE110 // range - 16 max
#define ID_FILE_MRU_FILE2 0xE111
#define ID_FILE_MRU_FILE3 0xE112
#define ID_FILE_MRU_FILE4 0xE113
#define ID_FILE_MRU_FILE5 0xE114
#define ID_FILE_MRU_FILE6 0xE115
#define ID_FILE_MRU_FILE7 0xE116
#define ID_FILE_MRU_FILE8 0xE117
#define ID_FILE_MRU_FILE9 0xE118
#define ID_FILE_MRU_FILE10 0xE119
#define ID_FILE_MRU_FILE11 0xE11A
#define ID_FILE_MRU_FILE12 0xE11B
#define ID_FILE_MRU_FILE13 0xE11C
#define ID_FILE_MRU_FILE14 0xE11D
#define ID_FILE_MRU_FILE15 0xE11E
#define ID_FILE_MRU_FILE16 0xE11F
#define ID_FILE_MRU_LAST 0xE11F
// Edit commands
#define ID_EDIT_CLEAR 0xE120
#define ID_EDIT_CLEAR_ALL 0xE121
#define ID_EDIT_COPY 0xE122
#define ID_EDIT_CUT 0xE123
#define ID_EDIT_FIND 0xE124
#define ID_EDIT_PASTE 0xE125
#define ID_EDIT_PASTE_LINK 0xE126
#define ID_EDIT_PASTE_SPECIAL 0xE127
#define ID_EDIT_REPEAT 0xE128
#define ID_EDIT_REPLACE 0xE129
#define ID_EDIT_SELECT_ALL 0xE12A
#define ID_EDIT_UNDO 0xE12B
#define ID_EDIT_REDO 0xE12C
// Window commands
#define ID_WINDOW_NEW 0xE130
#define ID_WINDOW_ARRANGE 0xE131
#define ID_WINDOW_CASCADE 0xE132
#define ID_WINDOW_TILE_HORZ 0xE133
#define ID_WINDOW_TILE_VERT 0xE134
#define ID_WINDOW_SPLIT 0xE135
#ifndef RC_INVOKED // code only
#define AFX_IDM_WINDOW_FIRST 0xE130
#define AFX_IDM_WINDOW_LAST 0xE13F
#define AFX_IDM_FIRST_MDICHILD 0xFF00 // window list starts here
#endif //!RC_INVOKED
// Help and App commands
#define ID_APP_ABOUT 0xE140
#define ID_APP_EXIT 0xE141
#define ID_HELP_INDEX 0xE142
#define ID_HELP_FINDER 0xE143
#define ID_HELP_USING 0xE144
#define ID_CONTEXT_HELP 0xE145 // shift-F1
// special commands for processing help
#define ID_HELP 0xE146 // first attempt for F1
#define ID_DEFAULT_HELP 0xE147 // last attempt
// Misc
#define ID_NEXT_PANE 0xE150
#define ID_PREV_PANE 0xE151
// Format
#define ID_FORMAT_FONT 0xE160
// OLE commands
#define ID_OLE_INSERT_NEW 0xE200
#define ID_OLE_EDIT_LINKS 0xE201
#define ID_OLE_EDIT_CONVERT 0xE202
#define ID_OLE_EDIT_CHANGE_ICON 0xE203
#define ID_OLE_EDIT_PROPERTIES 0xE204
#define ID_OLE_VERB_FIRST 0xE210 // range - 16 max
#ifndef RC_INVOKED // code only
#define ID_OLE_VERB_LAST 0xE21F
#endif //!RC_INVOKED
// for print preview dialog bar
#define AFX_ID_PREVIEW_CLOSE 0xE300
#define AFX_ID_PREVIEW_NUMPAGE 0xE301 // One/Two Page button
#define AFX_ID_PREVIEW_NEXT 0xE302
#define AFX_ID_PREVIEW_PREV 0xE303
#define AFX_ID_PREVIEW_PRINT 0xE304
#define AFX_ID_PREVIEW_ZOOMIN 0xE305
#define AFX_ID_PREVIEW_ZOOMOUT 0xE306
// View commands (same number used as IDW used for control bar)
#define ID_VIEW_TOOLBAR 0xE800
#define ID_VIEW_STATUS_BAR 0xE801
// -> E8FF reserved for other control bar commands
// RecordForm commands
#define ID_RECORD_FIRST 0xE900
#define ID_RECORD_LAST 0xE901
#define ID_RECORD_NEXT 0xE902
#define ID_RECORD_PREV 0xE903
/////////////////////////////////////////////////////////////////////////////
// Standard control IDs
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1) // all static controls
/////////////////////////////////////////////////////////////////////////////
// Standard string error/warnings
#ifndef RC_INVOKED // code only
#define AFX_IDS_SCFIRST 0xEF00
#endif //!RC_INVOKED
#define AFX_IDS_SCSIZE 0xEF00
#define AFX_IDS_SCMOVE 0xEF01
#define AFX_IDS_SCMINIMIZE 0xEF02
#define AFX_IDS_SCMAXIMIZE 0xEF03
#define AFX_IDS_SCNEXTWINDOW 0xEF04
#define AFX_IDS_SCPREVWINDOW 0xEF05
#define AFX_IDS_SCCLOSE 0xEF06
#define AFX_IDS_SCRESTORE 0xEF12
#define AFX_IDS_SCTASKLIST 0xEF13
#define AFX_IDS_MDICHILD 0xEF1F
#define AFX_IDS_DESKACCESSORY 0xEFDA
// General strings
#define AFX_IDS_OPENFILE 0xF000
#define AFX_IDS_SAVEFILE 0xF001
#define AFX_IDS_ALLFILTER 0xF002
#define AFX_IDS_UNTITLED 0xF003
#define AFX_IDS_SAVEFILECOPY 0xF004
#define AFX_IDS_PREVIEW_CLOSE 0xF005
#define AFX_IDS_UNNAMED_FILE 0xF006
#ifdef _MAC
#define AFX_IDS_ABOUT 0xF010
#endif
#define AFX_IDS_HIDE 0xF011
// MFC Standard Exception Error messages
#define AFX_IDP_NO_ERROR_AVAILABLE 0xF020
#define AFX_IDS_NOT_SUPPORTED_EXCEPTION 0xF021
#define AFX_IDS_RESOURCE_EXCEPTION 0xF022
#define AFX_IDS_MEMORY_EXCEPTION 0xF023
#define AFX_IDS_USER_EXCEPTION 0xF024
// Printing and print preview strings
#define AFX_IDS_PRINTONPORT 0xF040
#define AFX_IDS_ONEPAGE 0xF041
#define AFX_IDS_TWOPAGE 0xF042
#define AFX_IDS_PRINTPAGENUM 0xF043
#define AFX_IDS_PREVIEWPAGEDESC 0xF044
#define AFX_IDS_PRINTDEFAULTEXT 0xF045
#define AFX_IDS_PRINTDEFAULT 0xF046
#define AFX_IDS_PRINTFILTER 0xF047
#define AFX_IDS_PRINTCAPTION 0xF048
#define AFX_IDS_PRINTTOFILE 0xF049
// OLE strings
#define AFX_IDS_OBJECT_MENUITEM 0xF080
#define AFX_IDS_EDIT_VERB 0xF081
#define AFX_IDS_ACTIVATE_VERB 0xF082
#define AFX_IDS_CHANGE_LINK 0xF083
#define AFX_IDS_AUTO 0xF084
#define AFX_IDS_MANUAL 0xF085
#define AFX_IDS_FROZEN 0xF086
#define AFX_IDS_ALL_FILES 0xF087
// dynamically changing menu items
#define AFX_IDS_SAVE_MENU 0xF088
#define AFX_IDS_UPDATE_MENU 0xF089
#define AFX_IDS_SAVE_AS_MENU 0xF08A
#define AFX_IDS_SAVE_COPY_AS_MENU 0xF08B
#define AFX_IDS_EXIT_MENU 0xF08C
#define AFX_IDS_UPDATING_ITEMS 0xF08D
// COlePasteSpecialDialog defines
#define AFX_IDS_METAFILE_FORMAT 0xF08E
#define AFX_IDS_DIB_FORMAT 0xF08F
#define AFX_IDS_BITMAP_FORMAT 0xF090
#define AFX_IDS_LINKSOURCE_FORMAT 0xF091
#define AFX_IDS_EMBED_FORMAT 0xF092
// other OLE utility strings
#define AFX_IDS_PASTELINKEDTYPE 0xF094
#define AFX_IDS_UNKNOWNTYPE 0xF095
#define AFX_IDS_RTF_FORMAT 0xF096
#define AFX_IDS_TEXT_FORMAT 0xF097
// OLE datatype format error strings
#define AFX_IDS_INVALID_CURRENCY 0xF098
#define AFX_IDS_INVALID_DATETIME 0xF099
#define AFX_IDS_INVALID_DATETIMESPAN 0xF09A
// General error / prompt strings
#define AFX_IDP_INVALID_FILENAME 0xF100
#define AFX_IDP_FAILED_TO_OPEN_DOC 0xF101
#define AFX_IDP_FAILED_TO_SAVE_DOC 0xF102
#define AFX_IDP_ASK_TO_SAVE 0xF103
#define AFX_IDP_FAILED_TO_CREATE_DOC 0xF104
#define AFX_IDP_FILE_TOO_LARGE 0xF105
#define AFX_IDP_FAILED_TO_START_PRINT 0xF106
#define AFX_IDP_FAILED_TO_LAUNCH_HELP 0xF107
#define AFX_IDP_INTERNAL_FAILURE 0xF108 // general failure
#define AFX_IDP_COMMAND_FAILURE 0xF109 // command failure
#define AFX_IDP_FAILED_MEMORY_ALLOC 0xF10A
// DDV parse errors
#define AFX_IDP_PARSE_INT 0xF110
#define AFX_IDP_PARSE_REAL 0xF111
#define AFX_IDP_PARSE_INT_RANGE 0xF112
#define AFX_IDP_PARSE_REAL_RANGE 0xF113
#define AFX_IDP_PARSE_STRING_SIZE 0xF114
#define AFX_IDP_PARSE_RADIO_BUTTON 0xF115
#define AFX_IDP_PARSE_BYTE 0xF116
#define AFX_IDP_PARSE_UINT 0xF117
#define AFX_IDP_PARSE_DATETIME 0xF118
#define AFX_IDP_PARSE_CURRENCY 0xF119
// CFile/CArchive error strings for user failure
#define AFX_IDP_FAILED_INVALID_FORMAT 0xF120
#define AFX_IDP_FAILED_INVALID_PATH 0xF121
#define AFX_IDP_FAILED_DISK_FULL 0xF122
#define AFX_IDP_FAILED_ACCESS_READ 0xF123
#define AFX_IDP_FAILED_ACCESS_WRITE 0xF124
#define AFX_IDP_FAILED_IO_ERROR_READ 0xF125
#define AFX_IDP_FAILED_IO_ERROR_WRITE 0xF126
// OLE errors / prompt strings
#define AFX_IDP_STATIC_OBJECT 0xF180
#define AFX_IDP_FAILED_TO_CONNECT 0xF181
#define AFX_IDP_SERVER_BUSY 0xF182
#define AFX_IDP_BAD_VERB 0xF183
#define AFX_IDP_FAILED_TO_NOTIFY 0xF185
#define AFX_IDP_FAILED_TO_LAUNCH 0xF186
#define AFX_IDP_ASK_TO_UPDATE 0xF187
#define AFX_IDP_FAILED_TO_UPDATE 0xF188
#define AFX_IDP_FAILED_TO_REGISTER 0xF189
#define AFX_IDP_FAILED_TO_AUTO_REGISTER 0xF18A
#define AFX_IDP_FAILED_TO_CONVERT 0xF18B
#define AFX_IDP_GET_NOT_SUPPORTED 0xF18C
#define AFX_IDP_SET_NOT_SUPPORTED 0xF18D
#define AFX_IDP_ASK_TO_DISCARD 0xF18E
#define AFX_IDP_FAILED_TO_CREATE 0xF18F
// MAPI errors / prompt strings
#define AFX_IDP_FAILED_MAPI_LOAD 0xF190
#define AFX_IDP_INVALID_MAPI_DLL 0xF191
#define AFX_IDP_FAILED_MAPI_SEND 0xF192
#define AFX_IDP_FILE_NONE 0xF1A0
#define AFX_IDP_FILE_GENERIC 0xF1A1
#define AFX_IDP_FILE_NOT_FOUND 0xF1A2
#define AFX_IDP_FILE_BAD_PATH 0xF1A3
#define AFX_IDP_FILE_TOO_MANY_OPEN 0xF1A4
#define AFX_IDP_FILE_ACCESS_DENIED 0xF1A5
#define AFX_IDP_FILE_INVALID_FILE 0xF1A6
#define AFX_IDP_FILE_REMOVE_CURRENT 0xF1A7
#define AFX_IDP_FILE_DIR_FULL 0xF1A8
#define AFX_IDP_FILE_BAD_SEEK 0xF1A9
#define AFX_IDP_FILE_HARD_IO 0xF1AA
#define AFX_IDP_FILE_SHARING 0xF1AB
#define AFX_IDP_FILE_LOCKING 0xF1AC
#define AFX_IDP_FILE_DISKFULL 0xF1AD
#define AFX_IDP_FILE_EOF 0xF1AE
#define AFX_IDP_ARCH_NONE 0xF1B0
#define AFX_IDP_ARCH_GENERIC 0xF1B1
#define AFX_IDP_ARCH_READONLY 0xF1B2
#define AFX_IDP_ARCH_ENDOFFILE 0xF1B3
#define AFX_IDP_ARCH_WRITEONLY 0xF1B4
#define AFX_IDP_ARCH_BADINDEX 0xF1B5
#define AFX_IDP_ARCH_BADCLASS 0xF1B6
#define AFX_IDP_ARCH_BADSCHEMA 0xF1B7
#define AFX_IDS_OCC_SCALEUNITS_PIXELS 0xF1C0
// 0xf200-0xf20f reserved
// font names and point sizes
#define AFX_IDS_STATUS_FONT 0xF230
#define AFX_IDS_TOOLTIP_FONT 0xF231
#define AFX_IDS_UNICODE_FONT 0xF232
#define AFX_IDS_MINI_FONT 0xF233
// ODBC Database errors / prompt strings
#ifndef RC_INVOKED // code only
#define AFX_IDP_SQL_FIRST 0xF280
#endif //!RC_INVOKED
#define AFX_IDP_SQL_CONNECT_FAIL 0xF281
#define AFX_IDP_SQL_RECORDSET_FORWARD_ONLY 0xF282
#define AFX_IDP_SQL_EMPTY_COLUMN_LIST 0xF283
#define AFX_IDP_SQL_FIELD_SCHEMA_MISMATCH 0xF284
#define AFX_IDP_SQL_ILLEGAL_MODE 0xF285
#define AFX_IDP_SQL_MULTIPLE_ROWS_AFFECTED 0xF286
#define AFX_IDP_SQL_NO_CURRENT_RECORD 0xF287
#define AFX_IDP_SQL_NO_ROWS_AFFECTED 0xF288
#define AFX_IDP_SQL_RECORDSET_READONLY 0xF289
#define AFX_IDP_SQL_SQL_NO_TOTAL 0xF28A
#define AFX_IDP_SQL_ODBC_LOAD_FAILED 0xF28B
#define AFX_IDP_SQL_DYNASET_NOT_SUPPORTED 0xF28C
#define AFX_IDP_SQL_SNAPSHOT_NOT_SUPPORTED 0xF28D
#define AFX_IDP_SQL_API_CONFORMANCE 0xF28E
#define AFX_IDP_SQL_SQL_CONFORMANCE 0xF28F
#define AFX_IDP_SQL_NO_DATA_FOUND 0xF290
#define AFX_IDP_SQL_ROW_UPDATE_NOT_SUPPORTED 0xF291
#define AFX_IDP_SQL_ODBC_V2_REQUIRED 0xF292
#define AFX_IDP_SQL_NO_POSITIONED_UPDATES 0xF293
#define AFX_IDP_SQL_LOCK_MODE_NOT_SUPPORTED 0xF294
#define AFX_IDP_SQL_DATA_TRUNCATED 0xF295
#define AFX_IDP_SQL_ROW_FETCH 0xF296
#define AFX_IDP_SQL_INCORRECT_ODBC 0xF297
#define AFX_IDP_SQL_UPDATE_DELETE_FAILED 0xF298
#define AFX_IDP_SQL_DYNAMIC_CURSOR_NOT_SUPPORTED 0xF299
// DAO Database errors / prompt strings
#ifndef RC_INVOKED // code only
#define AFX_IDP_DAO_FIRST 0xF2A0
#endif //!RC_INVOKED
#define AFX_IDP_DAO_ENGINE_INITIALIZATION 0xF2A0
#define AFX_IDP_DAO_DFX_BIND 0xF2A1
#define AFX_IDP_DAO_OBJECT_NOT_OPEN 0xF2A2
// ICDAORecordset::GetRows Errors
// These are not placed in DAO Errors collection
// and must be handled directly by MFC.
#define AFX_IDP_DAO_ROWTOOSHORT 0xF2A3
#define AFX_IDP_DAO_BADBINDINFO 0xF2A4
#define AFX_IDP_DAO_COLUMNUNAVAILABLE 0xF2A5
/////////////////////////////////////////////////////////////////////////////
// AFX implementation - control IDs (AFX_IDC)
// Parts of dialogs
#define AFX_IDC_LISTBOX 100
#define AFX_IDC_CHANGE 101
// for print dialog
#define AFX_IDC_PRINT_DOCNAME 201
#define AFX_IDC_PRINT_PRINTERNAME 202
#define AFX_IDC_PRINT_PORTNAME 203
#define AFX_IDC_PRINT_PAGENUM 204
// Property Sheet control id's (determined with Spy++)
#define ID_APPLY_NOW 0x3021
#define ID_WIZBACK 0x3023
#define ID_WIZNEXT 0x3024
#define ID_WIZFINISH 0x3025
#define AFX_IDC_TAB_CONTROL 0x3020
/////////////////////////////////////////////////////////////////////////////
// IDRs for standard components
#ifndef RC_INVOKED // code only
// These are really COMMDLG dialogs, so there usually isn't a resource
// for them, but these IDs are used as help IDs.
#define AFX_IDD_FILEOPEN 28676
#define AFX_IDD_FILESAVE 28677
#define AFX_IDD_FONT 28678
#define AFX_IDD_COLOR 28679
#define AFX_IDD_PRINT 28680
#define AFX_IDD_PRINTSETUP 28681
#define AFX_IDD_FIND 28682
#define AFX_IDD_REPLACE 28683
#endif //!RC_INVOKED
// Standard dialogs app should leave alone (0x7801->)
#define AFX_IDD_NEWTYPEDLG 30721
#define AFX_IDD_PRINTDLG 30722
#define AFX_IDD_PREVIEW_TOOLBAR 30723
#ifdef _MAC
#define AFX_IDD_PREVIEW_SHORTTOOLBAR 30731
#endif
// Dialogs defined for OLE2UI library
#define AFX_IDD_INSERTOBJECT 30724
#define AFX_IDD_CHANGEICON 30725
#define AFX_IDD_CONVERT 30726
#define AFX_IDD_PASTESPECIAL 30727
#define AFX_IDD_EDITLINKS 30728
#define AFX_IDD_FILEBROWSE 30729
#define AFX_IDD_BUSY 30730
#define AFX_IDD_OBJECTPROPERTIES 30732
#define AFX_IDD_CHANGESOURCE 30733
// Standard cursors (0x7901->)
// AFX_IDC = Cursor resources
#define AFX_IDC_CONTEXTHELP 30977 // context sensitive help
#define AFX_IDC_MAGNIFY 30978 // print preview zoom
#define AFX_IDC_SMALLARROWS 30979 // splitter
#define AFX_IDC_HSPLITBAR 30980 // splitter
#define AFX_IDC_VSPLITBAR 30981 // splitter
#define AFX_IDC_NODROPCRSR 30982 // No Drop Cursor
#define AFX_IDC_TRACKNWSE 30983 // tracker
#define AFX_IDC_TRACKNESW 30984 // tracker
#define AFX_IDC_TRACKNS 30985 // tracker
#define AFX_IDC_TRACKWE 30986 // tracker
#define AFX_IDC_TRACK4WAY 30987 // tracker
#define AFX_IDC_MOVE4WAY 30988 // resize bar (server only)
// Mini frame window bitmap ID
#define AFX_IDB_MINIFRAME_MENU 30994
// CheckListBox checks bitmap ID
#define AFX_IDB_CHECKLISTBOX_NT 30995
#define AFX_IDB_CHECKLISTBOX_95 30996
// AFX standard accelerator resources
#define AFX_IDR_PREVIEW_ACCEL 30997
// AFX standard ICON IDs (for MFC V1 apps) (0x7A01->)
#define AFX_IDI_STD_MDIFRAME 31233
#define AFX_IDI_STD_FRAME 31234
/////////////////////////////////////////////////////////////////////////////
// AFX OLE control implementation - control IDs (AFX_IDC)
// Font property page
#define AFX_IDC_FONTPROP 1000
#define AFX_IDC_FONTNAMES 1001
#define AFX_IDC_FONTSTYLES 1002
#define AFX_IDC_FONTSIZES 1003
#define AFX_IDC_STRIKEOUT 1004
#define AFX_IDC_UNDERLINE 1005
#define AFX_IDC_SAMPLEBOX 1006
// Color property page
#define AFX_IDC_COLOR_BLACK 1100
#define AFX_IDC_COLOR_WHITE 1101
#define AFX_IDC_COLOR_RED 1102
#define AFX_IDC_COLOR_GREEN 1103
#define AFX_IDC_COLOR_BLUE 1104
#define AFX_IDC_COLOR_YELLOW 1105
#define AFX_IDC_COLOR_MAGENTA 1106
#define AFX_IDC_COLOR_CYAN 1107
#define AFX_IDC_COLOR_GRAY 1108
#define AFX_IDC_COLOR_LIGHTGRAY 1109
#define AFX_IDC_COLOR_DARKRED 1110
#define AFX_IDC_COLOR_DARKGREEN 1111
#define AFX_IDC_COLOR_DARKBLUE 1112
#define AFX_IDC_COLOR_LIGHTBROWN 1113
#define AFX_IDC_COLOR_DARKMAGENTA 1114
#define AFX_IDC_COLOR_DARKCYAN 1115
#define AFX_IDC_COLORPROP 1116
#define AFX_IDC_SYSTEMCOLORS 1117
// Picture porperty page
#define AFX_IDC_PROPNAME 1201
#define AFX_IDC_PICTURE 1202
#define AFX_IDC_BROWSE 1203
#define AFX_IDC_CLEAR 1204
/////////////////////////////////////////////////////////////////////////////
// IDRs for OLE control standard components
// Standard propery page dialogs app should leave alone (0x7E01->)
#define AFX_IDD_PROPPAGE_COLOR 32257
#define AFX_IDD_PROPPAGE_FONT 32258
#define AFX_IDD_PROPPAGE_PICTURE 32259
#define AFX_IDB_TRUETYPE 32384
/////////////////////////////////////////////////////////////////////////////
// Standard OLE control strings
// OLE Control page strings
#define AFX_IDS_PROPPAGE_UNKNOWN 0xFE01
#define AFX_IDS_COLOR_DESKTOP 0xFE04
#define AFX_IDS_COLOR_APPWORKSPACE 0xFE05
#define AFX_IDS_COLOR_WNDBACKGND 0xFE06
#define AFX_IDS_COLOR_WNDTEXT 0xFE07
#define AFX_IDS_COLOR_MENUBAR 0xFE08
#define AFX_IDS_COLOR_MENUTEXT 0xFE09
#define AFX_IDS_COLOR_ACTIVEBAR 0xFE0A
#define AFX_IDS_COLOR_INACTIVEBAR 0xFE0B
#define AFX_IDS_COLOR_ACTIVETEXT 0xFE0C
#define AFX_IDS_COLOR_INACTIVETEXT 0xFE0D
#define AFX_IDS_COLOR_ACTIVEBORDER 0xFE0E
#define AFX_IDS_COLOR_INACTIVEBORDER 0xFE0F
#define AFX_IDS_COLOR_WNDFRAME 0xFE10
#define AFX_IDS_COLOR_SCROLLBARS 0xFE11
#define AFX_IDS_COLOR_BTNFACE 0xFE12
#define AFX_IDS_COLOR_BTNSHADOW 0xFE13
#define AFX_IDS_COLOR_BTNTEXT 0xFE14
#define AFX_IDS_COLOR_BTNHIGHLIGHT 0xFE15
#define AFX_IDS_COLOR_DISABLEDTEXT 0xFE16
#define AFX_IDS_COLOR_HIGHLIGHT 0xFE17
#define AFX_IDS_COLOR_HIGHLIGHTTEXT 0xFE18
#define AFX_IDS_REGULAR 0xFE19
#define AFX_IDS_BOLD 0xFE1A
#define AFX_IDS_ITALIC 0xFE1B
#define AFX_IDS_BOLDITALIC 0xFE1C
#define AFX_IDS_SAMPLETEXT 0xFE1D
#define AFX_IDS_DISPLAYSTRING_FONT 0xFE1E
#define AFX_IDS_DISPLAYSTRING_COLOR 0xFE1F
#define AFX_IDS_DISPLAYSTRING_PICTURE 0xFE20
#define AFX_IDS_PICTUREFILTER 0xFE21
#define AFX_IDS_PICTYPE_UNKNOWN 0xFE22
#define AFX_IDS_PICTYPE_NONE 0xFE23
#define AFX_IDS_PICTYPE_BITMAP 0xFE24
#define AFX_IDS_PICTYPE_METAFILE 0xFE25
#define AFX_IDS_PICTYPE_ICON 0xFE26
#define AFX_IDS_COLOR_PPG 0xFE28
#define AFX_IDS_COLOR_PPG_CAPTION 0xFE29
#define AFX_IDS_FONT_PPG 0xFE2A
#define AFX_IDS_FONT_PPG_CAPTION 0xFE2B
#define AFX_IDS_PICTURE_PPG 0xFE2C
#define AFX_IDS_PICTURE_PPG_CAPTION 0xFE2D
#define AFX_IDS_PICTUREBROWSETITLE 0xFE30
#define AFX_IDS_BORDERSTYLE_0 0xFE31
#define AFX_IDS_BORDERSTYLE_1 0xFE32
// OLE Control verb names
#define AFX_IDS_VERB_EDIT 0xFE40
#define AFX_IDS_VERB_PROPERTIES 0xFE41
// OLE Control internal error messages
#define AFX_IDP_PICTURECANTOPEN 0xFE83
#define AFX_IDP_PICTURECANTLOAD 0xFE84
#define AFX_IDP_PICTURETOOLARGE 0xFE85
#define AFX_IDP_PICTUREREADFAILED 0xFE86
// Standard OLE Control error strings
#define AFX_IDP_E_ILLEGALFUNCTIONCALL 0xFEA0
#define AFX_IDP_E_OVERFLOW 0xFEA1
#define AFX_IDP_E_OUTOFMEMORY 0xFEA2
#define AFX_IDP_E_DIVISIONBYZERO 0xFEA3
#define AFX_IDP_E_OUTOFSTRINGSPACE 0xFEA4
#define AFX_IDP_E_OUTOFSTACKSPACE 0xFEA5
#define AFX_IDP_E_BADFILENAMEORNUMBER 0xFEA6
#define AFX_IDP_E_FILENOTFOUND 0xFEA7
#define AFX_IDP_E_BADFILEMODE 0xFEA8
#define AFX_IDP_E_FILEALREADYOPEN 0xFEA9
#define AFX_IDP_E_DEVICEIOERROR 0xFEAA
#define AFX_IDP_E_FILEALREADYEXISTS 0xFEAB
#define AFX_IDP_E_BADRECORDLENGTH 0xFEAC
#define AFX_IDP_E_DISKFULL 0xFEAD
#define AFX_IDP_E_BADRECORDNUMBER 0xFEAE
#define AFX_IDP_E_BADFILENAME 0xFEAF
#define AFX_IDP_E_TOOMANYFILES 0xFEB0
#define AFX_IDP_E_DEVICEUNAVAILABLE 0xFEB1
#define AFX_IDP_E_PERMISSIONDENIED 0xFEB2
#define AFX_IDP_E_DISKNOTREADY 0xFEB3
#define AFX_IDP_E_PATHFILEACCESSERROR 0xFEB4
#define AFX_IDP_E_PATHNOTFOUND 0xFEB5
#define AFX_IDP_E_INVALIDPATTERNSTRING 0xFEB6
#define AFX_IDP_E_INVALIDUSEOFNULL 0xFEB7
#define AFX_IDP_E_INVALIDFILEFORMAT 0xFEB8
#define AFX_IDP_E_INVALIDPROPERTYVALUE 0xFEB9
#define AFX_IDP_E_INVALIDPROPERTYARRAYINDEX 0xFEBA
#define AFX_IDP_E_SETNOTSUPPORTEDATRUNTIME 0xFEBB
#define AFX_IDP_E_SETNOTSUPPORTED 0xFEBC
#define AFX_IDP_E_NEEDPROPERTYARRAYINDEX 0xFEBD
#define AFX_IDP_E_SETNOTPERMITTED 0xFEBE
#define AFX_IDP_E_GETNOTSUPPORTEDATRUNTIME 0xFEBF
#define AFX_IDP_E_GETNOTSUPPORTED 0xFEC0
#define AFX_IDP_E_PROPERTYNOTFOUND 0xFEC1
#define AFX_IDP_E_INVALIDCLIPBOARDFORMAT 0xFEC2
#define AFX_IDP_E_INVALIDPICTURE 0xFEC3
#define AFX_IDP_E_PRINTERERROR 0xFEC4
#define AFX_IDP_E_CANTSAVEFILETOTEMP 0xFEC5
#define AFX_IDP_E_SEARCHTEXTNOTFOUND 0xFEC6
#define AFX_IDP_E_REPLACEMENTSTOOLONG 0xFEC7
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, on)
#endif
#endif //__AFXRES_H__
/////////////////////////////////////////////////////////////////////////////

@ -0,0 +1,432 @@
// Mail and Chat Server for BPQ32 Packet Switch
//
// Debug Window(s) Module
#include "BPQChat.h"
static char ClassName[]="BPQDEBUGWINDOW";
static WNDPROC wpOrigInputProc;
static WNDPROC wpOrigOutputProc;
HWND hDebug;
static HWND hwndInput;
static HWND hwndOutput;
static HMENU hMenu; // handle of menu
#define InputBoxHeight 25
RECT DebugRect;
int Height, Width, LastY;
static char readbuff[1024];
static BOOL Bells = TRUE;
static BOOL StripLF = TRUE;
static BOOL MonBBS = TRUE;
static BOOL MonCHAT = TRUE;
static BOOL MonTCP = TRUE;
static int PartLinePtr=0;
static int PartLineIndex=0; // Listbox index of (last) incomplete line
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY MonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY SplitProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static void MoveWindows();
#define BGCOLOUR RGB(236,233,216)
extern char DebugSize[32];
BOOL CreateDebugWindow()
{
WNDCLASS wc;
HBRUSH bgBrush;
char Text[80];
if (hDebug)
{
ShowWindow(hDebug, SW_SHOWNORMAL);
SetForegroundWindow(hDebug);
return FALSE; // Alreaqy open
}
bgBrush = CreateSolidBrush(BGCOLOUR);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MonWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
RegisterClass(&wc);
hDebug=CreateDialog(hInst,ClassName,0,NULL);
if (!hDebug)
return (FALSE);
wsprintf(Text, "Chat %s Debug", Session);
SetWindowText(hDebug, Text);
hMenu=GetMenu(hDebug);
if (Bells & 1)
CheckMenuItem(hMenu,BPQBELLS, MF_CHECKED);
else
CheckMenuItem(hMenu,BPQBELLS, MF_UNCHECKED);
if (StripLF & 1)
CheckMenuItem(hMenu,BPQStripLF, MF_CHECKED);
else
CheckMenuItem(hMenu,BPQStripLF, MF_UNCHECKED);
CheckMenuItem(hMenu,MONBBS, MonBBS ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONCHAT, MonCHAT ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONTCP, MonTCP ? MF_CHECKED : MF_UNCHECKED);
DrawMenuBar(hWnd);
// Retrieve the handlse to the edit controls.
hwndOutput = GetDlgItem(hDebug, 122);
// Set our own WndProcs for the controls.
wpOrigOutputProc = (WNDPROC)SetWindowLong(hwndOutput, GWL_WNDPROC, (LONG)OutputProc);
if (cfgMinToTray)
{
AddTrayMenuItem(hDebug, Text);
}
ShowWindow(hDebug, SW_SHOWNORMAL);
if (DebugRect.right < 100 || DebugRect.bottom < 100)
{
GetWindowRect(hDebug, &DebugRect);
}
MoveWindow(hDebug,DebugRect.left,DebugRect.top, DebugRect.right-DebugRect.left, DebugRect.bottom-DebugRect.top, TRUE);
MoveWindows();
return TRUE;
}
static void MoveWindows()
{
RECT rcMain, rcClient;
int ClientHeight, ClientWidth;
GetWindowRect(hDebug, &rcMain);
GetClientRect(hDebug, &rcClient);
ClientHeight = rcClient.bottom;
ClientWidth = rcClient.right;
// MoveWindow(hwndMon,2, 0, ClientWidth-4, SplitPos, TRUE);
MoveWindow(hwndOutput,2, 2, ClientWidth-4, ClientHeight-4, TRUE);
// MoveWindow(hwndSplit,0, SplitPos, ClientWidth, SplitBarHeight, TRUE);
}
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
LPRECT lprc;
switch (message) {
case WM_ACTIVATE:
SetFocus(hwndInput);
break;
case WM_COMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case MONBBS:
ToggleParam(hMenu, hWnd, &MonBBS, MONBBS);
break;
case MONCHAT:
ToggleParam(hMenu, hWnd, &MonCHAT, MONCHAT);
break;
case MONTCP:
ToggleParam(hMenu, hWnd, &MonTCP, MONTCP);
break;
case BPQCLEAROUT:
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
break;
case BPQCOPYOUT:
CopyToClipboard(hwndOutput);
break;
//case BPQHELP:
// HtmlHelp(hWnd,"BPQTerminal.chm",HH_HELP_FINDER,0);
// break;
default:
return 0;
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case SC_MINIMIZE:
if (cfgMinToTray)
return ShowWindow(hWnd, SW_HIDE);
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SIZING:
lprc = (LPRECT) lParam;
Height = lprc->bottom-lprc->top;
Width = lprc->right-lprc->left;
MoveWindows();
return TRUE;
case WM_DESTROY:
// Remove the subclass from the edit control.
GetWindowRect(hWnd, &DebugRect); // For save soutine
SetWindowLong(hwndInput, GWL_WNDPROC,
(LONG) wpOrigInputProc);
if (cfgMinToTray)
DeleteTrayMenuItem(hWnd);
hDebug = NULL;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Trap mouse messages, so we cant select stuff in output and mon windows,
// otherwise scrolling doesnt work.
if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST)
return TRUE;
return CallWindowProc(wpOrigOutputProc, hwnd, uMsg, wParam, lParam);
}
VOID ClearDebugWindow()
{
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
}
VOID WritetoDebugWindow(char * Msg, int len)
{
char * ptr1, * ptr2;
int index;
if (len ==0)
return;
if (PartLinePtr != 0)
SendMessage(hwndOutput,LB_DELETESTRING,PartLineIndex,(LPARAM)(LPCTSTR) 0 );
memcpy(&readbuff[PartLinePtr], Msg, len);
len=len+PartLinePtr;
ptr1=&readbuff[0];
readbuff[len]=0;
if (Bells)
{
do {
ptr2=memchr(ptr1,7,len);
if (ptr2)
{
*(ptr2)=32;
Beep(440,250);
}
} while (ptr2);
}
lineloop:
if (PartLinePtr > 300)
PartLinePtr = 0;
if (len > 0)
{
// copy text to control a line at a time
ptr2=memchr(ptr1,13,len);
if (ptr2 == 0)
{
// no newline. Move data to start of buffer and Save pointer
PartLinePtr=len;
memmove(readbuff,ptr1,len);
PartLineIndex=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) PartLineIndex, MAKELPARAM(FALSE, 0));
return;
}
*(ptr2++)=0;
index=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
// if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1);
PartLinePtr=0;
len-=(ptr2-ptr1);
ptr1=ptr2;
if ((len > 0) && StripLF)
{
if (*ptr1 == 0x0a) // Line Feed
{
ptr1++;
len--;
}
}
if (index > 1200)
do{
index=SendMessage(hwndOutput,LB_DELETESTRING, 0, 0);
} while (index > 1000);
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) index, MAKELPARAM(FALSE, 0));
goto lineloop;
}
return;
}
/*static int ToggleParam(HMENU hMenu, HWND hWnd, BOOL * Param, int Item)
{
*Param = !(*Param);
CheckMenuItem(hMenu,Item, (*Param) ? MF_CHECKED : MF_UNCHECKED);
return (0);
}
*/
static void CopyToClipboard(HWND hWnd)
{
int i,n, len=0;
HGLOBAL hMem;
char * ptr;
//
// Copy List Box to clipboard
//
n = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
for (i=0; i<n; i++)
{
len+=SendMessage(hWnd, LB_GETTEXTLEN, i, 0);
}
hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len+n+n+1);
if (hMem != 0)
{
ptr=GlobalLock(hMem);
if (OpenClipboard(MainWnd))
{
// CopyScreentoBuffer(GlobalLock(hMem));
for (i=0; i<n; i++)
{
ptr+=SendMessage(hWnd, LB_GETTEXT, i, (LPARAM) ptr);
*(ptr++)=13;
*(ptr++)=10;
}
*(ptr)=0; // end of data
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(CF_TEXT,hMem);
CloseClipboard();
}
else
GlobalFree(hMem);
}
}

@ -0,0 +1,26 @@
/* $Id: upnperrors.h,v 1.6 2015/07/21 13:16:55 nanard Exp $ */
/* (c) 2007-2015 Thomas Bernard
* All rights reserved.
* MiniUPnP Project.
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* This software is subjet to the conditions detailed in the
* provided LICENCE file. */
#ifndef UPNPERRORS_H_INCLUDED
#define UPNPERRORS_H_INCLUDED
#include "miniupnpc_declspec.h"
#ifdef __cplusplus
extern "C" {
#endif
/* strupnperror()
* Return a string description of the UPnP error code
* or NULL for undefinded errors */
MINIUPNP_LIBSPEC const char * strupnperror(int err);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,563 @@
/* pngwtran.c - transforms the data in a row for PNG writers
*
* libpng version 1.2.8 - December 3, 2004
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
*/
#define PNG_INTERNAL
#include "png.h"
#ifdef PNG_WRITE_SUPPORTED
/* Transform the data according to the user's wishes. The order of
* transformations is significant.
*/
void /* PRIVATE */
png_do_write_transformations(png_structp png_ptr)
{
png_debug(1, "in png_do_write_transformations\n");
if (png_ptr == NULL)
return;
#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
if (png_ptr->transformations & PNG_USER_TRANSFORM)
if(png_ptr->write_user_transform_fn != NULL)
(*(png_ptr->write_user_transform_fn)) /* user write transform function */
(png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */
/* png_uint_32 width; width of row */
/* png_uint_32 rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */
/* png_byte bit_depth; bit depth of samples */
/* png_byte channels; number of channels (1-4) */
/* png_byte pixel_depth; bits per pixel (depth*channels) */
png_ptr->row_buf + 1); /* start of pixel data for row */
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->flags);
#endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
if (png_ptr->transformations & PNG_PACKSWAP)
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED)
if (png_ptr->transformations & PNG_PACK)
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
(png_uint_32)png_ptr->bit_depth);
#endif
#if defined(PNG_WRITE_SWAP_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
if (png_ptr->transformations & PNG_SHIFT)
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
&(png_ptr->shift));
#endif
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
if (png_ptr->transformations & PNG_INVERT_ALPHA)
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED)
if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_WRITE_INVERT_SUPPORTED)
if (png_ptr->transformations & PNG_INVERT_MONO)
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
}
#if defined(PNG_WRITE_PACK_SUPPORTED)
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
* row_info bit depth should be 8 (one pixel per byte). The channels
* should be 1 (this only happens on grayscale and paletted images).
*/
void /* PRIVATE */
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
png_debug(1, "in png_do_pack\n");
if (row_info->bit_depth == 8 &&
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
row_info->channels == 1)
{
switch ((int)bit_depth)
{
case 1:
{
png_bytep sp, dp;
int mask, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
mask = 0x80;
v = 0;
for (i = 0; i < row_width; i++)
{
if (*sp != 0)
v |= mask;
sp++;
if (mask > 1)
mask >>= 1;
else
{
mask = 0x80;
*dp = (png_byte)v;
dp++;
v = 0;
}
}
if (mask != 0x80)
*dp = (png_byte)v;
break;
}
case 2:
{
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 6;
v = 0;
for (i = 0; i < row_width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0x03);
v |= (value << shift);
if (shift == 0)
{
shift = 6;
*dp = (png_byte)v;
dp++;
v = 0;
}
else
shift -= 2;
sp++;
}
if (shift != 6)
*dp = (png_byte)v;
break;
}
case 4:
{
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 4;
v = 0;
for (i = 0; i < row_width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0x0f);
v |= (value << shift);
if (shift == 0)
{
shift = 4;
*dp = (png_byte)v;
dp++;
v = 0;
}
else
shift -= 4;
sp++;
}
if (shift != 4)
*dp = (png_byte)v;
break;
}
}
row_info->bit_depth = (png_byte)bit_depth;
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
row_info->width);
}
}
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
/* Shift pixel values to take advantage of whole range. Pass the
* true number of bits in bit_depth. The row should be packed
* according to row_info->bit_depth. Thus, if you had a row of
* bit depth 4, but the pixels only had values from 0 to 7, you
* would pass 3 as bit_depth, and this routine would translate the
* data to 0 to 15.
*/
void /* PRIVATE */
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
png_debug(1, "in png_do_shift\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL &&
#else
if (
#endif
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift_start[4], shift_dec[4];
int channels = 0;
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
{
shift_start[channels] = row_info->bit_depth - bit_depth->red;
shift_dec[channels] = bit_depth->red;
channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->green;
shift_dec[channels] = bit_depth->green;
channels++;
shift_start[channels] = row_info->bit_depth - bit_depth->blue;
shift_dec[channels] = bit_depth->blue;
channels++;
}
else
{
shift_start[channels] = row_info->bit_depth - bit_depth->gray;
shift_dec[channels] = bit_depth->gray;
channels++;
}
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
{
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
shift_dec[channels] = bit_depth->alpha;
channels++;
}
/* with low row depths, could only be grayscale, so one channel */
if (row_info->bit_depth < 8)
{
png_bytep bp = row;
png_uint_32 i;
png_byte mask;
png_uint_32 row_bytes = row_info->rowbytes;
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
mask = 0x55;
else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
mask = 0x11;
else
mask = 0xff;
for (i = 0; i < row_bytes; i++, bp++)
{
png_uint_16 v;
int j;
v = *bp;
*bp = 0;
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
{
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & mask);
}
}
}
else if (row_info->bit_depth == 8)
{
png_bytep bp = row;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (i = 0; i < istop; i++, bp++)
{
png_uint_16 v;
int j;
int c = (int)(i%channels);
v = *bp;
*bp = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & 0xff);
}
}
}
else
{
png_bytep bp;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (bp = row, i = 0; i < istop; i++)
{
int c = (int)(i%channels);
png_uint_16 value, v;
int j;
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
value = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
else
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
}
*bp++ = (png_byte)(value >> 8);
*bp++ = (png_byte)(value & 0xff);
}
}
}
}
#endif
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void /* PRIVATE */
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_swap_alpha\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL)
#endif
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
/* This converts from ARGB to RGBA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
}
/* This converts from AARRGGBB to RRGGBBAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
/* This converts from AG to GA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
}
/* This converts from AAGG to GGAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
}
}
}
#endif
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void /* PRIVATE */
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_invert_alpha\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL)
#endif
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
/* This inverts the alpha channel in RGBA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = (png_byte)(255 - *(sp++));
}
}
/* This inverts the alpha channel in RRGGBBAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = (png_byte)(255 - *(sp++));
*(dp++) = (png_byte)(255 - *(sp++));
}
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
/* This inverts the alpha channel in GA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = (png_byte)(255 - *(sp++));
}
}
/* This inverts the alpha channel in GGAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = (png_byte)(255 - *(sp++));
*(dp++) = (png_byte)(255 - *(sp++));
}
}
}
}
}
#endif
#if defined(PNG_MNG_FEATURES_SUPPORTED)
/* undoes intrapixel differencing */
void /* PRIVATE */
png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_intrapixel\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{
int bytes_per_pixel;
png_uint_32 row_width = row_info->width;
if (row_info->bit_depth == 8)
{
png_bytep rp;
png_uint_32 i;
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 3;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 4;
else
return;
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
*(rp) = (png_byte)((*rp - *(rp+1))&0xff);
*(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
}
}
else if (row_info->bit_depth == 16)
{
png_bytep rp;
png_uint_32 i;
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
bytes_per_pixel = 6;
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
bytes_per_pixel = 8;
else
return;
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
{
png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL);
png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
*(rp ) = (png_byte)((red >> 8) & 0xff);
*(rp+1) = (png_byte)(red & 0xff);
*(rp+4) = (png_byte)((blue >> 8) & 0xff);
*(rp+5) = (png_byte)(blue & 0xff);
}
}
}
}
#endif /* PNG_MNG_FEATURES_SUPPORTED */
#endif /* PNG_WRITE_SUPPORTED */

@ -0,0 +1,455 @@
// Mail and Chat Server for BPQ32 Packet Switch
//
// Monitor Window(s) Module
#include "BPQChat.h"
static char ClassName[]="BPQMONWINDOW";
static WNDPROC wpOrigInputProc;
static WNDPROC wpOrigOutputProc;
HWND hMonitor;
static HWND hwndInput;
static HWND hwndOutput;
static HMENU hMenu; // handle of menu
#define InputBoxHeight 25
RECT MonitorRect;
RECT OutputRect;
int Height, Width, LastY;
static char kbbuf[160];
static int kbptr=0;
static char * readbuff;
static int readbufflen;
static BOOL StripLF = TRUE;
static BOOL MonBBS = TRUE;
static BOOL MonCHAT = TRUE;
static BOOL MonTCP = TRUE;
BOOL LogBBS = TRUE;
BOOL LogCHAT = TRUE;
BOOL LogTCP = TRUE;
static int PartLinePtr=0;
static int PartLineIndex=0; // Listbox index of (last) incomplete line
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT APIENTRY InputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static LRESULT APIENTRY MonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) ;
static void MoveWindows();
#define BGCOLOUR RGB(236,233,216)
extern char MonitorSize[32];
BOOL CreateMonitor()
{
WNDCLASS wc;
HBRUSH bgBrush;
char Text[80];
if (hMonitor)
{
ShowWindow(hMonitor, SW_SHOWNORMAL);
SetForegroundWindow(hMonitor);
return FALSE; // Alreaqy open
}
bgBrush = CreateSolidBrush(BGCOLOUR);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MonWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = hInst;
wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(BPQICON) );
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = bgBrush;
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
RegisterClass(&wc);
hMonitor=CreateDialog(hInst,ClassName,0,NULL);
if (!hMonitor)
return (FALSE);
wsprintf(Text, "Chat %s Monitor", Session);
SetWindowText(hMonitor, Text);
readbuff = zalloc(1000);
readbufflen = 1000;
hMenu=GetMenu(hMonitor);
CheckMenuItem(hMenu,MONBBS, MonBBS ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONCHAT, MonCHAT ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hMenu,MONTCP, MonTCP ? MF_CHECKED : MF_UNCHECKED);
DrawMenuBar(hWnd);
// Retrieve the handlse to the edit controls.
hwndOutput = GetDlgItem(hMonitor, 121);
// Set our own WndProcs for the controls.
wpOrigOutputProc = (WNDPROC)SetWindowLong(hwndOutput, GWL_WNDPROC, (LONG)OutputProc);
if (cfgMinToTray)
{
AddTrayMenuItem(hMonitor, Text);
}
ShowWindow(hMonitor, SW_SHOWNORMAL);
if (MonitorRect.right < 100 || MonitorRect.bottom < 100)
{
GetWindowRect(hMonitor, &MonitorRect);
}
MoveWindow(hMonitor,MonitorRect.left,MonitorRect.top, MonitorRect.right-MonitorRect.left, MonitorRect.bottom-MonitorRect.top, TRUE);
MoveWindows();
return TRUE;
}
static void MoveWindows()
{
RECT rcMain, rcClient;
int ClientHeight, ClientWidth;
GetWindowRect(hMonitor, &rcMain);
GetClientRect(hMonitor, &rcClient);
ClientHeight = rcClient.bottom;
ClientWidth = rcClient.right;
// MoveWindow(hwndMon,2, 0, ClientWidth-4, SplitPos, TRUE);
MoveWindow(hwndOutput,2, 2, ClientWidth-4, ClientHeight-4, TRUE);
// MoveWindow(hwndSplit,0, SplitPos, ClientWidth, SplitBarHeight, TRUE);
}
static LRESULT CALLBACK MonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
LPRECT lprc;
switch (message) {
case WM_ACTIVATE:
SetFocus(hwndInput);
break;
case WM_COMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case MONBBS:
ToggleParam(hMenu, hWnd, &MonBBS, MONBBS);
break;
case MONCHAT:
ToggleParam(hMenu, hWnd, &MonCHAT, MONCHAT);
break;
case MONTCP:
ToggleParam(hMenu, hWnd, &MonTCP, MONTCP);
break;
case BPQCLEAROUT:
SendMessage(hwndOutput,LB_RESETCONTENT, 0, 0);
break;
case BPQCOPYOUT:
CopyToClipboard(hwndOutput);
break;
//case BPQHELP:
// HtmlHelp(hWnd,"BPQTerminal.chm",HH_HELP_FINDER,0);
// break;
default:
return 0;
}
case WM_SYSCOMMAND:
wmId = LOWORD(wParam); // Remember, these are...
wmEvent = HIWORD(wParam); // ...different for Win32!
switch (wmId) {
case SC_MINIMIZE:
if (cfgMinToTray)
return ShowWindow(hWnd, SW_HIDE);
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
case WM_SIZING:
lprc = (LPRECT) lParam;
Height = lprc->bottom-lprc->top;
Width = lprc->right-lprc->left;
MoveWindows();
return TRUE;
case WM_DESTROY:
// Remove the subclass from the edit control.
GetWindowRect(hWnd, &MonitorRect); // For save soutine
SetWindowLong(hwndInput, GWL_WNDPROC,
(LONG) wpOrigInputProc);
if (cfgMinToTray)
DeleteTrayMenuItem(hWnd);
hMonitor = NULL;
free(readbuff);
readbufflen = 0;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
LRESULT APIENTRY OutputProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// Trap mouse messages, so we cant select stuff in output and mon windows,
// otherwise scrolling doesnt work.
if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_LBUTTONDBLCLK)
return TRUE;
return CallWindowProc(wpOrigOutputProc, hwnd, uMsg, wParam, lParam);
}
int WritetoMonitorWindow(char * Msg, int len)
{
char * ptr1, * ptr2;
int index;
if (len+PartLinePtr > readbufflen)
{
readbufflen += len+PartLinePtr;
readbuff = realloc(readbuff, readbufflen);
}
if (PartLinePtr != 0)
SendMessage(hwndOutput,LB_DELETESTRING,PartLineIndex,(LPARAM)(LPCTSTR) 0 );
memcpy(&readbuff[PartLinePtr], Msg, len);
len=len+PartLinePtr;
ptr1=&readbuff[0];
readbuff[len]=0;
do {
ptr2=memchr(ptr1,7,len);
if (ptr2)
*(ptr2)=32;
} while (ptr2);
lineloop:
// if (PartLinePtr > 300)
// PartLinePtr = 0;
if (len > 0)
{
// copy text to control a line at a time
ptr2=memchr(ptr1,13,len);
if (ptr2 == 0)
{
// no newline. Move data to start of buffer and Save pointer
PartLinePtr=len;
memmove(readbuff,ptr1,len);
PartLineIndex=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) PartLineIndex, MAKELPARAM(FALSE, 0));
return (0);
}
*(ptr2++)=0;
index=SendMessage(hwndOutput,LB_ADDSTRING,0,(LPARAM)(LPCTSTR) ptr1 );
// if (LogOutput) WriteMonitorLine(ptr1, ptr2 - ptr1);
PartLinePtr=0;
len-=(ptr2-ptr1);
ptr1=ptr2;
if ((len > 0) && StripLF)
{
if (*ptr1 == 0x0a) // Line Feed
{
ptr1++;
len--;
}
}
if (index > 1200)
do{
index=SendMessage(hwndOutput,LB_DELETESTRING, 0, 0);
} while (index > 1000);
SendMessage(hwndOutput,LB_SETCARETINDEX,(WPARAM) index, MAKELPARAM(FALSE, 0));
goto lineloop;
}
return (0);
}
static int ToggleParam(HMENU hMenu, HWND hWnd, BOOL * Param, int Item)
{
*Param = !(*Param);
CheckMenuItem(hMenu,Item, (*Param) ? MF_CHECKED : MF_UNCHECKED);
return (0);
}
static void CopyToClipboard(HWND hWnd)
{
int i,n, len=0;
HGLOBAL hMem;
char * ptr;
//
// Copy List Box to clipboard
//
n = SendMessage(hWnd, LB_GETCOUNT, 0, 0);
for (i=0; i<n; i++)
{
len+=SendMessage(hWnd, LB_GETTEXTLEN, i, 0);
}
hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, len+n+n+1);
if (hMem != 0)
{
ptr=GlobalLock(hMem);
if (OpenClipboard(MainWnd))
{
// CopyScreentoBuffer(GlobalLock(hMem));
for (i=0; i<n; i++)
{
ptr+=SendMessage(hWnd, LB_GETTEXT, i, (LPARAM) ptr);
*(ptr++)=13;
*(ptr++)=10;
}
*(ptr)=0; // end of data
GlobalUnlock(hMem);
EmptyClipboard();
SetClipboardData(CF_TEXT,hMem);
CloseClipboard();
}
else
GlobalFree(hMem);
}
}
HANDLE LogHandle[4] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
char * Logs[4] = {"BBS", "CHAT", "TCP", "DEBUG"};
BOOL OpenLogfile(int Flags)
{
UCHAR FN[MAX_PATH];
time_t T;
struct tm * tm;
T = time(NULL);
tm = gmtime(&T);
sprintf(FN,"%s/logs/log_%02d%02d%02d_%s.txt", GetLogDirectory(), tm->tm_year-100, tm->tm_mon+1, tm->tm_mday, Logs[Flags]);
LogHandle[Flags] = CreateFile(FN,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
SetFilePointer(LogHandle[Flags], 0, 0, FILE_END);
return (LogHandle[Flags] != INVALID_HANDLE_VALUE);
}

@ -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

@ -0,0 +1,913 @@
/*******************************************************
HIDAPI - Multi-Platform library for
communication with HID devices.
Alan Ott
Signal 11 Software
8/22/2009
Copyright 2009, All Rights Reserved.
At the discretion of the user of this library,
this software may be licensed under the terms of the
GNU Public License v3, a BSD-Style license, or the
original HIDAPI license as outlined in the LICENSE.txt,
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
files located at the root of the source distribution.
These files may also be found in the public source
code repository located at:
http://github.com/signal11/hidapi .
********************************************************/
// Hacked about a bit for BPQ32. John Wiseman G8BPQ April 2018
#include <windows.h>
#ifndef _NTDEF_
typedef LONG NTSTATUS;
#endif
#ifdef __MINGW32__
#include <ntdef.h>
#include <winbase.h>
#endif
#ifdef __CYGWIN__
#include <ntdef.h>
#define _wcsdup wcsdup
#endif
//#define HIDAPI_USE_DDK
#ifdef __cplusplus
extern "C" {
#endif
#include <setupapi.h>
#include <winioctl.h>
#ifdef HIDAPI_USE_DDK
#include <hidsdi.h>
#endif
// Copied from inc/ddk/hidclass.h, part of the Windows DDK.
#define HID_OUT_CTL_CODE(id) \
CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
#ifdef __cplusplus
} // extern "C"
#endif
#include <stdio.h>
#include <stdlib.h>
#include "hidapi.h"
#ifdef _MSC_VER
// Thanks Microsoft, but I know how to use strncpy().
#pragma warning(disable:4996)
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef HIDAPI_USE_DDK
// Since we're not building with the DDK, and the HID header
// files aren't part of the SDK, we have to define all this
// stuff here. In lookup_functions(), the function pointers
// defined below are set.
typedef struct _HIDD_ATTRIBUTES{
ULONG Size;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
typedef USHORT USAGE;
typedef struct _HIDP_CAPS {
USAGE Usage;
USAGE UsagePage;
USHORT InputReportByteLength;
USHORT OutputReportByteLength;
USHORT FeatureReportByteLength;
USHORT Reserved[17];
USHORT fields_not_used_by_hidapi[10];
} HIDP_CAPS, *PHIDP_CAPS;
typedef char* HIDP_PREPARSED_DATA;
#define HIDP_STATUS_SUCCESS 0x0
typedef BOOLEAN (__stdcall *HidD_GetAttributes_)(HANDLE device, PHIDD_ATTRIBUTES attrib);
typedef BOOLEAN (__stdcall *HidD_GetSerialNumberString_)(HANDLE device, PVOID buffer, ULONG buffer_len);
typedef BOOLEAN (__stdcall *HidD_GetManufacturerString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
typedef BOOLEAN (__stdcall *HidD_GetProductString_)(HANDLE handle, PVOID buffer, ULONG buffer_len);
typedef BOOLEAN (__stdcall *HidD_SetFeature_)(HANDLE handle, PVOID data, ULONG length);
typedef BOOLEAN (__stdcall *HidD_GetFeature_)(HANDLE handle, PVOID data, ULONG length);
typedef BOOLEAN (__stdcall *HidD_GetIndexedString_)(HANDLE handle, ULONG string_index, PVOID buffer, ULONG buffer_len);
typedef BOOLEAN (__stdcall *HidD_GetPreparsedData_)(HANDLE handle, HIDP_PREPARSED_DATA **preparsed_data);
typedef BOOLEAN (__stdcall *HidD_FreePreparsedData_)(HIDP_PREPARSED_DATA *preparsed_data);
typedef BOOLEAN (__stdcall *HidP_GetCaps_)(HIDP_PREPARSED_DATA *preparsed_data, HIDP_CAPS *caps);
static HidD_GetAttributes_ HidD_GetAttributes;
static HidD_GetSerialNumberString_ HidD_GetSerialNumberString;
static HidD_GetManufacturerString_ HidD_GetManufacturerString;
static HidD_GetProductString_ HidD_GetProductString;
static HidD_SetFeature_ HidD_SetFeature;
static HidD_GetFeature_ HidD_GetFeature;
static HidD_GetIndexedString_ HidD_GetIndexedString;
static HidD_GetPreparsedData_ HidD_GetPreparsedData;
static HidD_FreePreparsedData_ HidD_FreePreparsedData;
static HidP_GetCaps_ HidP_GetCaps;
static HMODULE lib_handle = NULL;
static BOOLEAN initialized = FALSE;
#endif // HIDAPI_USE_DDK
struct hid_device_ {
HANDLE device_handle;
BOOL blocking;
int input_report_length;
void *last_error_str;
DWORD last_error_num;
BOOL read_pending;
char *read_buf;
OVERLAPPED ol;
};
static hid_device *new_hid_device()
{
hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
dev->device_handle = INVALID_HANDLE_VALUE;
dev->blocking = TRUE;
dev->input_report_length = 0;
dev->last_error_str = NULL;
dev->last_error_num = 0;
dev->read_pending = FALSE;
dev->read_buf = NULL;
memset(&dev->ol, 0, sizeof(dev->ol));
dev->ol.hEvent = CreateEvent(NULL, FALSE, FALSE /*inital state f=nonsignaled*/, NULL);
return dev;
}
static void register_error(hid_device *device, const char *op)
{
WCHAR *ptr, *msg;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&msg, 0/*sz*/,
NULL);
// Get rid of the CR and LF that FormatMessage() sticks at the
// end of the message. Thanks Microsoft!
ptr = msg;
while (*ptr) {
if (*ptr == '\r') {
*ptr = 0x0000;
break;
}
ptr++;
}
// Store the message off in the Device entry so that
// the hid_error() function can pick it up.
LocalFree(device->last_error_str);
device->last_error_str = msg;
}
#ifndef HIDAPI_USE_DDK
static int lookup_functions()
{
lib_handle = LoadLibraryA("hid.dll");
if (lib_handle) {
#define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1;
RESOLVE(HidD_GetAttributes);
RESOLVE(HidD_GetSerialNumberString);
RESOLVE(HidD_GetManufacturerString);
RESOLVE(HidD_GetProductString);
RESOLVE(HidD_SetFeature);
RESOLVE(HidD_GetFeature);
RESOLVE(HidD_GetIndexedString);
RESOLVE(HidD_GetPreparsedData);
RESOLVE(HidD_FreePreparsedData);
RESOLVE(HidP_GetCaps);
#undef RESOLVE
}
else
return -1;
return 0;
}
#endif
static HANDLE open_device(const char *path)
{
HANDLE handle;
/* First, try to open with sharing mode turned off. This will make it so
that a HID device can only be opened once. This is to be consistent
with the behavior on the other platforms. */
handle = CreateFileA(path,
GENERIC_WRITE |GENERIC_READ,
0, /*share mode*/
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
0);
if (handle == INVALID_HANDLE_VALUE) {
/* Couldn't open the device. Some devices must be opened
with sharing enabled (even though they are only opened once),
so try it here. */
handle = CreateFileA(path,
GENERIC_WRITE |GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, /*share mode*/
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL,
0);
}
return handle;
}
int HID_API_EXPORT hid_init(void)
{
#ifndef HIDAPI_USE_DDK
if (!initialized) {
if (lookup_functions() < 0) {
hid_exit();
return -1;
}
initialized = TRUE;
}
#endif
return 0;
}
int HID_API_EXPORT hid_exit(void)
{
#ifndef HIDAPI_USE_DDK
if (lib_handle)
FreeLibrary(lib_handle);
lib_handle = NULL;
initialized = FALSE;
#endif
return 0;
}
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
BOOL res;
struct hid_device_info *root = NULL; // return object
struct hid_device_info *cur_dev = NULL;
// Windows objects for interacting with the driver.
GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} };
SP_DEVINFO_DATA devinfo_data;
SP_DEVICE_INTERFACE_DATA device_interface_data;
SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL;
HDEVINFO device_info_set = INVALID_HANDLE_VALUE;
int device_index = 0;
if (hid_init() < 0)
return NULL;
// Initialize the Windows objects.
devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA);
device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
// Get information for all the devices belonging to the HID class.
device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
// Iterate over each device in the HID class, looking for the right one.
for (;;) {
HANDLE write_handle = INVALID_HANDLE_VALUE;
DWORD required_size = 0;
HIDD_ATTRIBUTES attrib;
res = SetupDiEnumDeviceInterfaces(device_info_set,
NULL,
&InterfaceClassGuid,
device_index,
&device_interface_data);
if (!res) {
// A return of FALSE from this function means that
// there are no more devices.
break;
}
// Call with 0-sized detail size, and let the function
// tell us how long the detail struct needs to be. The
// size is put in &required_size.
res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
&device_interface_data,
NULL,
0,
&required_size,
NULL);
// Allocate a long enough structure for device_interface_detail_data.
device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size);
device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
// Get the detailed data for this device. The detail data gives us
// the device path for this device, which is then passed into
// CreateFile() to get a handle to the device.
res = SetupDiGetDeviceInterfaceDetailA(device_info_set,
&device_interface_data,
device_interface_detail_data,
required_size,
NULL,
NULL);
if (!res) {
//register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail");
// Continue to the next device.
goto cont;
}
//wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath);
// Open a handle to the device
write_handle = open_device(device_interface_detail_data->DevicePath);
// Check validity of write_handle.
if (write_handle == INVALID_HANDLE_VALUE) {
// Unable to open the device.
//register_error(dev, "CreateFile");
goto cont_close;
}
// Get the Vendor ID and Product ID for this device.
attrib.Size = sizeof(HIDD_ATTRIBUTES);
HidD_GetAttributes(write_handle, &attrib);
//wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID);
// Check the VID/PID to see if we should add this
// device to the enumeration list.
if ((vendor_id == 0x0 && product_id == 0x0) ||
(attrib.VendorID == vendor_id && attrib.ProductID == product_id)) {
#define WSTR_LEN 512
const char *str;
struct hid_device_info *tmp;
HIDP_PREPARSED_DATA *pp_data = NULL;
HIDP_CAPS caps;
BOOLEAN res;
NTSTATUS nt_res;
wchar_t wstr[WSTR_LEN]; // TODO: Determine Size
int len;
/* VID/PID match. Create the record. */
tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info));
if (cur_dev) {
cur_dev->next = tmp;
}
else {
root = tmp;
}
cur_dev = tmp;
// Get the Usage Page and Usage for this device.
res = HidD_GetPreparsedData(write_handle, &pp_data);
if (res) {
nt_res = HidP_GetCaps(pp_data, &caps);
if (nt_res == HIDP_STATUS_SUCCESS) {
cur_dev->usage_page = caps.UsagePage;
cur_dev->usage = caps.Usage;
}
HidD_FreePreparsedData(pp_data);
}
/* Fill out the record */
cur_dev->next = NULL;
str = device_interface_detail_data->DevicePath;
if (str) {
len = (int)strlen(str);
cur_dev->path = (char*) calloc(len+1, sizeof(char));
strncpy(cur_dev->path, str, len+1);
cur_dev->path[len] = '\0';
}
else
cur_dev->path = NULL;
/* Serial Number */
res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr));
wstr[WSTR_LEN-1] = 0x0000;
if (res) {
cur_dev->serial_number = _wcsdup(wstr);
}
/* Manufacturer String */
res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr));
wstr[WSTR_LEN-1] = 0x0000;
if (res) {
cur_dev->manufacturer_string = _wcsdup(wstr);
}
/* Product String */
res = HidD_GetProductString(write_handle, wstr, sizeof(wstr));
wstr[WSTR_LEN-1] = 0x0000;
if (res) {
cur_dev->product_string = _wcsdup(wstr);
}
/* VID/PID */
cur_dev->vendor_id = attrib.VendorID;
cur_dev->product_id = attrib.ProductID;
/* Release Number */
cur_dev->release_number = attrib.VersionNumber;
/* Interface Number. It can sometimes be parsed out of the path
on Windows if a device has multiple interfaces. See
http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or
search for "Hardware IDs for HID Devices" at MSDN. If it's not
in the path, it's set to -1. */
cur_dev->interface_number = -1;
if (cur_dev->path) {
char *interface_component = strstr(cur_dev->path, "&mi_");
if (interface_component) {
char *hex_str = interface_component + 4;
char *endptr = NULL;
cur_dev->interface_number = strtol(hex_str, &endptr, 16);
if (endptr == hex_str) {
/* The parsing failed. Set interface_number to -1. */
cur_dev->interface_number = -1;
}
}
}
}
cont_close:
CloseHandle(write_handle);
cont:
// We no longer need the detail data. It can be freed
free(device_interface_detail_data);
device_index++;
}
// Close the device information handle.
SetupDiDestroyDeviceInfoList(device_info_set);
return root;
}
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
{
// TODO: Merge this with the Linux version. This function is platform-independent.
struct hid_device_info *d = devs;
while (d) {
struct hid_device_info *next = d->next;
free(d->path);
free(d->serial_number);
free(d->manufacturer_string);
free(d->product_string);
free(d);
d = next;
}
}
HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number)
{
// TODO: Merge this functions with the Linux version. This function should be platform independent.
struct hid_device_info *devs, *cur_dev;
const char *path_to_open = NULL;
hid_device *handle = NULL;
devs = hid_enumerate(vendor_id, product_id);
cur_dev = devs;
while (cur_dev) {
if (cur_dev->vendor_id == vendor_id &&
cur_dev->product_id == product_id) {
if (serial_number) {
if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
path_to_open = cur_dev->path;
break;
}
}
else {
path_to_open = cur_dev->path;
break;
}
}
cur_dev = cur_dev->next;
}
if (path_to_open) {
/* Open the device */
handle = hid_open_path(path_to_open);
}
hid_free_enumeration(devs);
return handle;
}
HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path)
{
hid_device *dev;
HIDP_CAPS caps;
HIDP_PREPARSED_DATA *pp_data = NULL;
BOOLEAN res;
NTSTATUS nt_res;
if (hid_init() < 0) {
return NULL;
}
dev = new_hid_device();
// Open a handle to the device
dev->device_handle = open_device(path);
// Check validity of write_handle.
if (dev->device_handle == INVALID_HANDLE_VALUE) {
// Unable to open the device.
register_error(dev, "CreateFile");
goto err;
}
// Get the Input Report length for the device.
res = HidD_GetPreparsedData(dev->device_handle, &pp_data);
if (!res) {
register_error(dev, "HidD_GetPreparsedData");
goto err;
}
nt_res = HidP_GetCaps(pp_data, &caps);
if (nt_res != HIDP_STATUS_SUCCESS) {
register_error(dev, "HidP_GetCaps");
goto err_pp_data;
}
dev->input_report_length = caps.InputReportByteLength;
HidD_FreePreparsedData(pp_data);
dev->read_buf = (char*) malloc(dev->input_report_length);
return dev;
err_pp_data:
HidD_FreePreparsedData(pp_data);
err:
CloseHandle(dev->device_handle);
free(dev);
return NULL;
}
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
{
DWORD bytes_written;
BOOL res;
OVERLAPPED ol;
memset(&ol, 0, sizeof(ol));
res = WriteFile(dev->device_handle, data, (int)length, NULL, &ol);
if (!res)
{
int err = GetLastError();
if (GetLastError() != ERROR_IO_PENDING) {
// WriteFile() failed. Return error.
register_error(dev, "WriteFile");
return -1;
}
}
// Wait here until the write is done. This makes
// hid_write() synchronous.
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE/*wait*/);
if (!res) {
// The Write operation failed.
register_error(dev, "WriteFile");
return -1;
}
return bytes_written;
}
int HID_API_EXPORT HID_API_CALL hid_set_ptt(int state)
{
int res;
hid_device *handle;
unsigned char buf[16];
handle = hid_open(0xd8c, 0x8, NULL);
if (!handle) {
printf("unable to open device\n");
return 1;
}
// Toggle PTT
buf[0] = 0;
buf[1] = 0;
buf[2]= 1 << (3 - 1);
buf[3] = state << (3 - 1);
buf[4] = 0;
res = hid_write(handle, buf, 5);
if (res < 0)
{
printf("Unable to write()\n");
printf("Error: %ls\n", hid_error(handle));
}
hid_close(handle);
return res;
}
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
{
DWORD bytes_read = 0;
BOOL res;
// Copy the handle for convenience.
HANDLE ev = dev->ol.hEvent;
if (!dev->read_pending) {
// Start an Overlapped I/O read.
dev->read_pending = TRUE;
ResetEvent(ev);
res = ReadFile(dev->device_handle, dev->read_buf, dev->input_report_length, &bytes_read, &dev->ol);
if (!res) {
if (GetLastError() != ERROR_IO_PENDING) {
// ReadFile() has failed.
// Clean up and return error.
CancelIo(dev->device_handle);
dev->read_pending = FALSE;
goto end_of_function;
}
}
}
if (milliseconds >= 0) {
// See if there is any data yet.
res = WaitForSingleObject(ev, milliseconds);
if (res != WAIT_OBJECT_0) {
// There was no data this time. Return zero bytes available,
// but leave the Overlapped I/O running.
return 0;
}
}
// Either WaitForSingleObject() told us that ReadFile has completed, or
// we are in non-blocking mode. Get the number of bytes read. The actual
// data has been copied to the data[] array which was passed to ReadFile().
res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/);
// Set pending back to false, even if GetOverlappedResult() returned error.
dev->read_pending = FALSE;
if (res && bytes_read > 0) {
if (dev->read_buf[0] == 0x0) {
/* If report numbers aren't being used, but Windows sticks a report
number (0x0) on the beginning of the report anyway. To make this
work like the other platforms, and to make it work more like the
HID spec, we'll skip over this byte. */
bytes_read--;
memcpy(data, dev->read_buf+1, length);
}
else {
/* Copy the whole buffer, report number and all. */
memcpy(data, dev->read_buf, length);
}
}
end_of_function:
if (!res) {
register_error(dev, "GetOverlappedResult");
return -1;
}
return bytes_read;
}
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length)
{
return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
}
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock)
{
dev->blocking = !nonblock;
return 0; /* Success */
}
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
BOOL res = HidD_SetFeature(dev->device_handle, (PVOID)data, (int)length);
if (!res) {
register_error(dev, "HidD_SetFeature");
return -1;
}
return (int)length;
}
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
{
BOOL res;
#if 0
res = HidD_GetFeature(dev->device_handle, data, length);
if (!res) {
register_error(dev, "HidD_GetFeature");
return -1;
}
return 0; /* HidD_GetFeature() doesn't give us an actual length, unfortunately */
#else
DWORD bytes_returned;
OVERLAPPED ol;
memset(&ol, 0, sizeof(ol));
res = DeviceIoControl(dev->device_handle,
IOCTL_HID_GET_FEATURE,
data, (int)length,
data, (int)length,
&bytes_returned, &ol);
if (!res) {
if (GetLastError() != ERROR_IO_PENDING) {
// DeviceIoControl() failed. Return error.
register_error(dev, "Send Feature Report DeviceIoControl");
return -1;
}
}
// Wait here until the write is done. This makes
// hid_get_feature_report() synchronous.
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_returned, TRUE/*wait*/);
if (!res) {
// The operation failed.
register_error(dev, "Send Feature Report GetOverLappedResult");
return -1;
}
return bytes_returned;
#endif
}
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev)
{
if (!dev)
return;
CancelIo(dev->device_handle);
CloseHandle(dev->ol.hEvent);
CloseHandle(dev->device_handle);
LocalFree(dev->last_error_str);
free(dev->read_buf);
free(dev);
}
int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
BOOL res;
res = HidD_GetManufacturerString(dev->device_handle, string, 2 * (int)maxlen);
if (!res) {
register_error(dev, "HidD_GetManufacturerString");
return -1;
}
return 0;
}
int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
BOOL res;
res = HidD_GetProductString(dev->device_handle, string, 2 * (int)maxlen);
if (!res) {
register_error(dev, "HidD_GetProductString");
return -1;
}
return 0;
}
int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
BOOL res;
res = HidD_GetSerialNumberString(dev->device_handle, string, 2 * (int)maxlen);
if (!res) {
register_error(dev, "HidD_GetSerialNumberString");
return -1;
}
return 0;
}
int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
{
BOOL res;
res = HidD_GetIndexedString(dev->device_handle, string_index, string, 2 * (int)maxlen);
if (!res) {
register_error(dev, "HidD_GetIndexedString");
return -1;
}
return 0;
}
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
{
return (wchar_t*)dev->last_error_str;
}
//#define PICPGM
//#define S11
#define P32
#ifdef S11
unsigned short VendorID = 0xa0a0;
unsigned short ProductID = 0x0001;
#endif
#ifdef P32
unsigned short VendorID = 0x04d8;
unsigned short ProductID = 0x3f;
#endif
#ifdef PICPGM
unsigned short VendorID = 0x04d8;
unsigned short ProductID = 0x0033;
#endif
#if 0
int __cdecl main(int argc, char* argv[])
{
int res;
unsigned char buf[65];
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
// Set up the command buffer.
memset(buf,0x00,sizeof(buf));
buf[0] = 0;
buf[1] = 0x81;
// Open the device.
int handle = open(VendorID, ProductID, L"12345");
if (handle < 0)
printf("unable to open device\n");
// Toggle LED (cmd 0x80)
buf[1] = 0x80;
res = write(handle, buf, 65);
if (res < 0)
printf("Unable to write()\n");
// Request state (cmd 0x81)
buf[1] = 0x81;
write(handle, buf, 65);
if (res < 0)
printf("Unable to write() (2)\n");
// Read requested state
read(handle, buf, 65);
if (res < 0)
printf("Unable to read()\n");
// Print out the returned buffer.
for (int i = 0; i < 4; i++)
printf("buf[%d]: %d\n", i, buf[i]);
return 0;
}
#endif
#ifdef __cplusplus
} // extern "C"
#endif

@ -0,0 +1,386 @@
/*******************************************************
HIDAPI - Multi-Platform library for
communication with HID devices.
Alan Ott
Signal 11 Software
8/22/2009
Copyright 2009, All Rights Reserved.
At the discretion of the user of this library,
this software may be licensed under the terms of the
GNU Public License v3, a BSD-Style license, or the
original HIDAPI license as outlined in the LICENSE.txt,
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
files located at the root of the source distribution.
These files may also be found in the public source
code repository located at:
http://github.com/signal11/hidapi .
********************************************************/
/** @file
* @defgroup API hidapi API
*/
#ifndef HIDAPI_H__
#define HIDAPI_H__
#include <wchar.h>
#ifdef _WIN32
// #define HID_API_EXPORT __declspec(dllexport) // BPQ
#define HID_API_EXPORT
#define HID_API_CALL
#else
#define HID_API_EXPORT /**< API export macro */
#define HID_API_CALL /**< API call macro */
#endif
#define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/
#ifdef __cplusplus
extern "C" {
#endif
struct hid_device_;
typedef struct hid_device_ hid_device; /**< opaque hidapi structure */
/** hidapi info structure */
struct hid_device_info {
/** Platform-specific device path */
char *path;
/** Device Vendor ID */
unsigned short vendor_id;
/** Device Product ID */
unsigned short product_id;
/** Serial Number */
wchar_t *serial_number;
/** Device Release Number in binary-coded decimal,
also known as Device Version Number */
unsigned short release_number;
/** Manufacturer String */
wchar_t *manufacturer_string;
/** Product string */
wchar_t *product_string;
/** Usage Page for this Device/Interface
(Windows/Mac only). */
unsigned short usage_page;
/** Usage for this Device/Interface
(Windows/Mac only).*/
unsigned short usage;
/** The USB interface which this logical device
represents. Valid on both Linux implementations
in all cases, and valid on the Windows implementation
only if the device contains more than one interface. */
int interface_number;
/** Pointer to the next device */
struct hid_device_info *next;
};
/** @brief Initialize the HIDAPI library.
This function initializes the HIDAPI library. Calling it is not
strictly necessary, as it will be called automatically by
hid_enumerate() and any of the hid_open_*() functions if it is
needed. This function should be called at the beginning of
execution however, if there is a chance of HIDAPI handles
being opened by different threads simultaneously.
@ingroup API
@returns
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_init(void);
/** @brief Finalize the HIDAPI library.
This function frees all of the static data associated with
HIDAPI. It should be called at the end of execution to avoid
memory leaks.
@ingroup API
@returns
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_exit(void);
/** @brief Enumerate the HID Devices.
This function returns a linked list of all the HID devices
attached to the system which match vendor_id and product_id.
If @p vendor_id and @p product_id are both set to 0, then
all HID devices will be returned.
@ingroup API
@param vendor_id The Vendor ID (VID) of the types of device
to open.
@param product_id The Product ID (PID) of the types of
device to open.
@returns
This function returns a pointer to a linked list of type
struct #hid_device, containing information about the HID devices
attached to the system, or NULL in the case of failure. Free
this linked list by calling hid_free_enumeration().
*/
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id);
/** @brief Free an enumeration Linked List
This function frees a linked list created by hid_enumerate().
@ingroup API
@param devs Pointer to a list of struct_device returned from
hid_enumerate().
*/
void HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs);
/** @brief Open a HID device using a Vendor ID (VID), Product ID
(PID) and optionally a serial number.
If @p serial_number is NULL, the first device with the
specified VID and PID is opened.
@ingroup API
@param vendor_id The Vendor ID (VID) of the device to open.
@param product_id The Product ID (PID) of the device to open.
@param serial_number The Serial Number of the device to open
(Optionally NULL).
@returns
This function returns a pointer to a #hid_device object on
success or NULL on failure.
*/
HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, wchar_t *serial_number);
/** @brief Open a HID device by its path name.
The path name be determined by calling hid_enumerate(), or a
platform-specific path name can be used (eg: /dev/hidraw0 on
Linux).
@ingroup API
@param path The path name of the device to open
@returns
This function returns a pointer to a #hid_device object on
success or NULL on failure.
*/
HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path);
/** @brief Write an Output report to a HID device.
The first byte of @p data[] must contain the Report ID. For
devices which only support a single report, this must be set
to 0x0. The remaining bytes contain the report data. Since
the Report ID is mandatory, calls to hid_write() will always
contain one more byte than the report contains. For example,
if a hid report is 16 bytes long, 17 bytes must be passed to
hid_write(), the Report ID (or 0x0, for devices with a
single report), followed by the report data (16 bytes). In
this example, the length passed in would be 17.
hid_write() will send the data on the first OUT endpoint, if
one exists. If it does not, it will send the data through
the Control Endpoint (Endpoint 0).
@ingroup API
@param device A device handle returned from hid_open().
@param data The data to send, including the report number as
the first byte.
@param length The length in bytes of the data to send.
@returns
This function returns the actual number of bytes written and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length);
/** @brief Read an Input report from a HID device with timeout.
Input reports are returned
to the host through the INTERRUPT IN endpoint. The first byte will
contain the Report number if the device uses numbered reports.
@ingroup API
@param device A device handle returned from hid_open().
@param data A buffer to put the read data into.
@param length The number of bytes to read. For devices with
multiple reports, make sure to read an extra byte for
the report number.
@param milliseconds timeout in milliseconds or -1 for blocking wait.
@returns
This function returns the actual number of bytes read and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds);
/** @brief Read an Input report from a HID device.
Input reports are returned
to the host through the INTERRUPT IN endpoint. The first byte will
contain the Report number if the device uses numbered reports.
@ingroup API
@param device A device handle returned from hid_open().
@param data A buffer to put the read data into.
@param length The number of bytes to read. For devices with
multiple reports, make sure to read an extra byte for
the report number.
@returns
This function returns the actual number of bytes read and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length);
/** @brief Set the device handle to be non-blocking.
In non-blocking mode calls to hid_read() will return
immediately with a value of 0 if there is no data to be
read. In blocking mode, hid_read() will wait (block) until
there is data to read before returning.
Nonblocking can be turned on and off at any time.
@ingroup API
@param device A device handle returned from hid_open().
@param nonblock enable or not the nonblocking reads
- 1 to enable nonblocking
- 0 to disable nonblocking.
@returns
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock);
/** @brief Send a Feature report to the device.
Feature reports are sent over the Control endpoint as a
Set_Report transfer. The first byte of @p data[] must
contain the Report ID. For devices which only support a
single report, this must be set to 0x0. The remaining bytes
contain the report data. Since the Report ID is mandatory,
calls to hid_send_feature_report() will always contain one
more byte than the report contains. For example, if a hid
report is 16 bytes long, 17 bytes must be passed to
hid_send_feature_report(): the Report ID (or 0x0, for
devices which do not use numbered reports), followed by the
report data (16 bytes). In this example, the length passed
in would be 17.
@ingroup API
@param device A device handle returned from hid_open().
@param data The data to send, including the report number as
the first byte.
@param length The length in bytes of the data to send, including
the report number.
@returns
This function returns the actual number of bytes written and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length);
/** @brief Get a feature report from a HID device.
Make sure to set the first byte of @p data[] to the Report
ID of the report to be read. Make sure to allow space for
this extra byte in @p data[].
@ingroup API
@param device A device handle returned from hid_open().
@param data A buffer to put the read data into, including
the Report ID. Set the first byte of @p data[] to the
Report ID of the report to be read.
@param length The number of bytes to read, including an
extra byte for the report ID. The buffer can be longer
than the actual report.
@returns
This function returns the number of bytes read and
-1 on error.
*/
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length);
/** @brief Close a HID device.
@ingroup API
@param device A device handle returned from hid_open().
*/
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device);
/** @brief Get The Manufacturer String from a HID device.
@ingroup API
@param device A device handle returned from hid_open().
@param string A wide string buffer to put the data into.
@param maxlen The length of the buffer in multiples of wchar_t.
@returns
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen);
/** @brief Get The Product String from a HID device.
@ingroup API
@param device A device handle returned from hid_open().
@param string A wide string buffer to put the data into.
@param maxlen The length of the buffer in multiples of wchar_t.
@returns
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen);
/** @brief Get The Serial Number String from a HID device.
@ingroup API
@param device A device handle returned from hid_open().
@param string A wide string buffer to put the data into.
@param maxlen The length of the buffer in multiples of wchar_t.
@returns
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen);
/** @brief Get a string from a HID device, based on its string index.
@ingroup API
@param device A device handle returned from hid_open().
@param string_index The index of the string to get.
@param string A wide string buffer to put the data into.
@param maxlen The length of the buffer in multiples of wchar_t.
@returns
This function returns 0 on success and -1 on error.
*/
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen);
/** @brief Get a string describing the last error which occurred.
@ingroup API
@param device A device handle returned from hid_open().
@returns
This function returns a string containing the last error
which occurred or NULL if none has occurred.
*/
HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device);
int HID_API_EXPORT HID_API_CALL hid_set_ptt(int state);
#ifdef __cplusplus
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save

Powered by TurnKey Linux.