diff --git a/.rej b/.rej
deleted file mode 100644
index 1137117..0000000
--- a/.rej
+++ /dev/null
@@ -1,139 +0,0 @@
---- APRSCode.c
-+++ APRSCode.c
-@@ -3674,7 +3674,7 @@
- if (ptr1)
- *ptr1 = 0;
-
--// Debugprintf("Duplicate Message supressed %s", Msg);
-+// Debugprintf("Duplicate Message suppressed %s", Msg);
- return TRUE; // Duplicate
- }
- }
---- BPQChat.rc
-+++ BPQChat.rc
-@@ -162,7 +162,7 @@
- WS_VSCROLL
- DEFPUSHBUTTON "Save Welcome Message",SAVEWELCOME,140,296,91,14,
- BS_CENTER | BS_VCENTER
-- LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
-+ LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
- IDC_STATIC,9,52,355,24
- END
-
---- BPQMail.rc
-+++ BPQMail.rc
-@@ -1045,7 +1045,7 @@
- CONTROL "Delete Log and Message Files to Recycle Bin",
- IDC_DELETETORECYCLE,"Button",BS_AUTOCHECKBOX |
- BS_LEFTTEXT | BS_MULTILINE | WS_TABSTOP,5,142,115,20
-- CONTROL "Supress Mailing of Housekeeping Results",
-+ CONTROL "Suppress Mailing of Housekeeping Results",
- IDC_MAINTNOMAIL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
- BS_MULTILINE | WS_TABSTOP,5,182,115,20
- CONTROL "Generate Traffic Report",IDC_MAINTTRAFFIC,"Button",
---- HanksRT.c
-+++ HanksRT.c
-@@ -1186,7 +1186,7 @@
- // Duplicate, so discard, but save time
-
- DupInfo[i].DupTime = Now;
-- Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s supressed", Call, Msg);
-+ Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s suppressed", Call, Msg);
-
- return TRUE; // Duplicate
- }
---- RigControl.c
-+++ RigControl.c
-@@ -8385,7 +8385,7 @@
-
- switch (Msg[0])
- {
-- case 'f': // Get Freqency
-+ case 'f': // Get Frequency
-
- HLGetFreq(Sock, RIG, sep);
- return 0;
---- UZ7HODrv.c
-+++ UZ7HODrv.c
-@@ -374,7 +374,7 @@
- {
- // Read Freq
-
-- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Freqency %d\r", AGW->CenterFreq);
-+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Frequency %d\r", AGW->CenterFreq);
- return 1;
- }
-
-@@ -382,7 +382,7 @@
-
- if (AGW->CenterFreq == 0)
- {
-- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Freqency\r");
-+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Frequency\r");
- return 1;
- }
-
---- WinRPRHelper.c
-+++ WinRPRHelper.c
-@@ -111,7 +111,7 @@
-
- if (argc < 3)
- {
-- printf ("Missing paramters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
-+ printf ("Missing parameters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
- " WinRPRHelper com10 192.168.1.64:4532\r\n\r\n"
- "Press any key to exit\r\n");
-
---- config.c
-+++ config.c
-@@ -649,7 +649,7 @@
- if (LOCATOR[0] == 0 && LocSpecified == 0 && RFOnly == 0)
- {
- Consoleprintf("");
-- Consoleprintf("Please enter a LOCATOR statment in your BPQ32.cfg");
-+ Consoleprintf("Please enter a LOCATOR statement in your BPQ32.cfg");
- Consoleprintf("If you really don't want to be on the Node Map you can enter LOCATOR=NONE");
- Consoleprintf("");
-
---- kiss.c
-+++ kiss.c
-@@ -1485,7 +1485,7 @@
- }
- }
- else
-- Debugprintf("Polled KISS - response from wrong address - Polled %d Reponse %d",
-+ Debugprintf("Polled KISS - response from wrong address - Polled %d Response %d",
- KISS->POLLPOINTER->OURCTRL, (Port->RXMSG[0] & 0xf0));
-
- goto SeeifMore; // SEE IF ANYTHING ELSE
---- templatedefs.c
-+++ templatedefs.c
-@@ -1165,7 +1165,7 @@
- "Send Non-delivery Notifications \r\n"
- "for P and T messages \r\n"
- " \r\n"
-- "Supress Mailing of \r\n"
-+ "Suppress Mailing of \r\n"
- "Housekeeping Result
\r\n"
- "Generate Traffic Report
\r\n"
- "
\r\n"
-@@ -1454,7 +1454,7 @@
- "
The Nodes to link to box defines which other Chat Nodes should be connected to, or from which "
- "connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4. If the node is not directly "
- "connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands "
-- "seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
-+ "separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
-
- "
The Callsign of the Chat Node is not defined here - it is obtained from the bpq32.cfg APPLICATION line corresponding to the Chat Appl Number. \r\n"
- "
\n"
---- WebMail.c
-+++ WebMail.c
-@@ -2020,7 +2020,7 @@
- "document.getElementById('myform').action = '/WebMail/QuoteOriginal' + '?%s';"
- " document.getElementById('myform').submit();}"
- "";
-+ "value='Include Original Msg'>";
-
- char Temp[1024];
- char ReplyAddr[128];
diff --git a/6pack.c b/6pack.c
index 8f954d8..5557827 100644
--- a/6pack.c
+++ b/6pack.c
@@ -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);
diff --git a/AEAPactor.c b/AEAPactor.c
index 2d5af4b..bb7a8d4 100644
--- a/AEAPactor.c
+++ b/AEAPactor.c
@@ -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);
diff --git a/APRSCode.c.orig b/APRSCode.c.orig
deleted file mode 100644
index b4ed594..0000000
--- a/APRSCode.c.orig
+++ /dev/null
@@ -1,9223 +0,0 @@
-/*
-Copyright 2001-2022 John Wiseman G8BPQ
-
-This file is part of LinBPQ/BPQ32.
-
-LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-LinBPQ/BPQ32 is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
-*/
-
-// Module to implement APRS "New Paradigm" Digipeater and APRS-IS Gateway
-
-// First Version, November 2011
-
-#pragma data_seg("_BPQDATA")
-
-#define _CRT_SECURE_NO_DEPRECATE
-
-#include
-#include "CHeaders.h"
-#include "bpq32.h"
-#include
-#include "kernelresource.h"
-
-#include "tncinfo.h"
-
-#include "bpqaprs.h"
-
-#ifndef WIN32
-
-#include
-#include
-#include
-
-int sfd;
-struct sockaddr_un my_addr, peer_addr;
-socklen_t peer_addr_size;
-
-
-#endif
-
-
-#define MAXAGE 3600 * 12 // 12 Hours
-#define MAXCALLS 20 // Max Flood, Trace and Digi
-#define GATETIMELIMIT 40 * 60 // Don't gate to RF if station not heard for this time (40 mins)
-
-static BOOL APIENTRY GETSENDNETFRAMEADDR();
-static VOID DoSecTimer();
-static VOID DoMinTimer();
-static int APRSProcessLine(char * buf);
-static BOOL APRSReadConfigFile();
-VOID APRSISThread(void * Report);
-VOID __cdecl Debugprintf(const char * format, ...);
-VOID __cdecl Consoleprintf(const char * format, ...);
-BOOL APIENTRY Send_AX(PMESSAGE Block, DWORD Len, UCHAR Port);
-VOID Send_AX_Datagram(PDIGIMESSAGE Block, DWORD Len, UCHAR Port);
-int APRSDecodeFrame(char * msg, char * buffer, time_t Stamp, uint64_t Mask); // Unsemaphored DecodeFrame
-APRSHEARDRECORD * UpdateHeard(UCHAR * Call, int Port);
-BOOL CheckforDups(char * Call, char * Msg, int Len);
-VOID ProcessQuery(char * Query);
-VOID ProcessSpecificQuery(char * Query, int Port, char * Origin, char * DestPlusDigis);
-VOID CheckandDigi(DIGIMESSAGE * Msg, int Port, int FirstUnused, int Digis, int Len);
-VOID SendBeacon(int toPort, char * Msg, BOOL SendISStatus, BOOL SendSOGCOG);
-Dll BOOL APIENTRY PutAPRSMessage(char * Frame, int Len);
-VOID ProcessAPRSISMsg(char * APRSMsg);
-static VOID SendtoDigiPorts(PDIGIMESSAGE Block, DWORD Len, UCHAR Port);
-APRSHEARDRECORD * FindStationInMH(char * call);
-BOOL OpenGPSPort();
-void PollGPSIn();
-int CountLocalStations();
-BOOL SendAPPLAPRSMessage(char * Frame);
-VOID SendAPRSMessage(char * Message, int toPort);
-static VOID TCPConnect(void * unuxed);
-struct STATIONRECORD * DecodeAPRSISMsg(char * msg);
-struct STATIONRECORD * ProcessRFFrame(char * buffer, int len, int * ourMessage);
-VOID APRSSecTimer();
-double myDistance(double laa, double loa, BOOL KM);
-struct STATIONRECORD * FindStation(char * Call, BOOL AddIfNotFound);
-int DecodeAPRSPayload(char * Payload, struct STATIONRECORD * Station);
-BOOL KillOldTNC(char * Path);
-
-BOOL ToLOC(double Lat, double Lon , char * Locator);
-BOOL InternalSendAPRSMessage(char * Text, char * Call);
-void UndoTransparency(char * input);
-char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char * format, ...);
-char * GetStandardPage(char * FN, int * Len);
-VOID WriteMiniDump();
-BOOL ProcessConfig();
-int ProcessAISMessage(char * msg, int len);
-int read_png(unsigned char *bytes);
-VOID sendandcheck(SOCKET sock, const char * Buffer, int Len);
-void SaveAPRSMessage(struct APRSMESSAGE * ptr);
-void ClearSavedMessages();
-void GetSavedAPRSMessages();
-static VOID GPSDConnect(void * unused);
-int CanPortDigi(int Port);
-int FromLOC(char * Locator, double * pLat, double * pLon);
-
-extern int SemHeldByAPI;
-extern int APRSMONDECODE();
-extern struct ConsoleInfo MonWindow;
-extern char VersionString[];
-
-BOOL SaveAPRSMsgs = 0;
-
-BOOL LogAPRSIS = FALSE;
-
-// All data should be initialised to force into shared segment
-
-static char ConfigClassName[]="CONFIG";
-
-extern BPQVECSTRUC * APRSMONVECPTR;
-
-extern int MONDECODE();
-extern VOID * zalloc(int len);
-extern BOOL StartMinimized;
-
-extern char TextVerstring[];
-
-extern HWND hConsWnd;
-extern HKEY REGTREE;
-
-extern char LOCATOR[80];
-extern char LOC[7];
-
-static int SecTimer = 10;
-static int MinTimer = 60;
-
-BOOL APRSApplConnected = FALSE;
-BOOL APRSWeb = FALSE;
-
-void * APPL_Q = 0; // Queue of frames for APRS Appl
-void * APPLTX_Q = 0; // Queue of frames from APRS Appl
-uint64_t APRSPortMask = 0;
-
-char APRSCall[10] = "";
-char APRSDest[10] = "APBPQ1";
-
-char WXCall[10];
-
-UCHAR AXCall[7] = "";
-
-char CallPadded[10] = " ";
-
-char GPSPort[80] = "";
-int GPSSpeed = 0;
-char GPSRelay[80] = "";
-
-BOOL GateLocal = FALSE;
-double GateLocalDistance = 0.0;
-
-int MaxDigisforIS = 7; // Dont send to IS if more digis uued to reach us
-
-char WXFileName[MAX_PATH];
-char WXComment[80];
-BOOL SendWX = FALSE;
-int WXInterval = 30;
-int WXCounter = 29 * 60;
-
-char APRSCall[10];
-char LoppedAPRSCall[10];
-
-BOOL WXPort[MaxBPQPortNo + 1]; // Ports to send WX to
-
-BOOL GPSOK = 0;
-
-char LAT[] = "0000.00N"; // in standard APRS Format
-char LON[] = "00000.00W"; //in standard APRS Format
-
-char HostName[80]; // for BlueNMEA
-int HostPort = 4352;
-
-char GPSDHost[80];
-int GPSDPort = 2947;
-
-
-extern int ADSBPort;
-extern char ADSBHost[];
-
-BOOL BlueNMEAOK = FALSE;
-int BlueNMEATimer = 0;
-
-BOOL GPSDOK = FALSE;
-int GPSDTimer = 0;
-
-
-BOOL GPSSetsLocator = 0; // Update Map Location from GPS
-
-double SOG, COG; // From GPS
-
-double Lat = 0.0;
-double Lon = 0.0;
-
-BOOL PosnSet = FALSE;
-/*
-The null position should be include the \. symbol (unknown/indeterminate
-position). For example, a Position Report for a station with unknown position
-will contain the coordinates …0000.00N\00000.00W.…
-*/
-char * FloodCalls = 0; // Calls to relay using N-n without tracing
-char * TraceCalls = 0; // Calls to relay using N-n with tracing
-char * DigiCalls = 0; // Calls for normal relaying
-
-UCHAR FloodAX[MAXCALLS][7] = {0};
-UCHAR TraceAX[MAXCALLS][7] = {0};
-UCHAR DigiAX[MAXCALLS][7] = {0};
-
-int FloodLen[MAXCALLS];
-int TraceLen[MAXCALLS];
-int DigiLen[MAXCALLS];
-
-int ISPort = 0;
-char ISHost[256] = "";
-int ISPasscode = 0;
-char NodeFilter[1000] = "m/50"; // Filter when the isn't an application
-char ISFilter[1000] = "m/50"; // Current Filter
-char APPLFilter[1000] = ""; // Filter when an Applcation is running
-
-extern BOOL IGateEnabled;
-
-char StatusMsg[256] = ""; // Must be in shared segment
-int StatusMsgLen = 0;
-
-char * BeaconPath[65] = {0};
-
-char CrossPortMap[65][65] = {0};
-char APRSBridgeMap[65][65] = {0};
-
-UCHAR BeaconHeader[65][10][7] = {""}; // Dest, Source and up to 8 digis
-int BeaconHddrLen[65] = {0}; // Actual Length used
-
-UCHAR GatedHeader[65][10][7] = {""}; // Dest, Source and up to 8 digis for messages gated from IS
-int GatedHddrLen[65] = {0}; // Actual Length used
-
-
-char CFGSYMBOL = 'a';
-char CFGSYMSET = 'B';
-
-char SYMBOL = '='; // Unknown Locaton
-char SYMSET = '/';
-
-char * PHG = 0; // Optional PHG (Power-Height-Gain) string for beacon
-
-BOOL TraceDigi = FALSE; // Add Trace to packets relayed on Digi Calls
-BOOL SATGate = FALSE; // Delay Gating to IS directly heard packets
-BOOL RXOnly = FALSE; // Run as RX only IGATE, ie don't gate anything to RF
-
-BOOL DefaultLocalTime = FALSE;
-BOOL DefaultDistKM = FALSE;
-
-int multiple = 0; // Allows multiple copies of LinBPQ/APRS on one machine
-
-extern BOOL needAIS;
-
-extern unsigned long long IconData[]; // Symbols as a png image.
-
-typedef struct _ISDELAY
-{
- struct _ISDELAY * Next;
- char * ISMSG;
- time_t SendTIme;
-} ISDELAY;
-
-ISDELAY * SatISQueue = NULL;
-
-int MaxTraceHops = 2;
-int MaxFloodHops = 2;
-
-int BeaconInterval = 0;
-int MobileBeaconInterval = 0;
-time_t LastMobileBeacon = 0;
-int BeaconCounter = 0;
-int IStatusCounter = 3600; // Used to send ?ISTATUS? Responses
-//int StatusCounter = 0; // Used to send Status Messages
-
-char RunProgram[128] = ""; // Program to start
-
-BOOL APRSISOpen = FALSE;
-BOOL BeacontoIS = TRUE;
-
-int ISDelayTimer = 0; // Time before trying to reopen APRS-IS link
-
-char APRSDESTS[][7] = {"AIR*", "ALL*", "AP*", "BEACON", "CQ*", "GPS*", "DF*", "DGPS*", "DRILL*",
- "DX*", "ID*", "JAVA*", "MAIL*", "MICE*", "QST*", "QTH*", "RTCM*", "SKY*",
- "SPACE*", "SPC*", "SYM*", "TEL*", "TEST*", "TLM*", "WX*", "ZIP"};
-
-UCHAR AXDESTS[30][7] = {""};
-int AXDESTLEN[30] = {0};
-
-UCHAR axTCPIP[7];
-UCHAR axRFONLY[7];
-UCHAR axNOGATE[7];
-
-int MessageCount = 0;
-
-struct PortInfo
-{
- int Index;
- int ComPort;
- char PortType[2];
- BOOL NewVCOM; // Using User Mode Virtual COM Driver
- int ReopenTimer; // Retry if open failed delay
- int RTS;
- int CTS;
- int DCD;
- int DTR;
- int DSR;
- char Params[20]; // Init Params (eg 9600,n,8)
- char PortLabel[20];
- HANDLE hDevice;
- BOOL Created;
- BOOL PortEnabled;
- int FLOWCTRL;
- int gpsinptr;
-#ifdef WIN32
- OVERLAPPED Overlapped;
- OVERLAPPED OverlappedRead;
-#endif
- char GPSinMsg[160];
- int GPSTypeFlag; // GPS Source flags
- BOOL RMCOnly; // Only send RMC msgs to this port
-};
-
-
-
-struct PortInfo InPorts[1] = {0};
-
-// Heard Station info
-
-#define MAXHEARD 1000
-
-int HEARDENTRIES = 0;
-int MAXHEARDENTRIES = 0;
-int MHLEN = sizeof(APRSHEARDRECORD);
-
-// Area is allocated as needed
-
-APRSHEARDRECORD MHTABLE[MAXHEARD] = {0};
-
-APRSHEARDRECORD * MHDATA = &MHTABLE[0];
-
-static SOCKET sock = (SOCKET)0;
-
-//Duplicate suppression Code
-
-#define MAXDUPS 100 // Number to keep
-#define DUPSECONDS 28 // Time to Keep
-
-struct DUPINFO
-{
- time_t DupTime;
- int DupLen;
- char DupUser[8]; // Call in ax.35 format
- char DupText[100];
-};
-
-struct DUPINFO DupInfo[MAXDUPS];
-
-struct OBJECT
-{
- struct OBJECT * Next;
- UCHAR Path[10][7]; // Dest, Source and up to 8 digis
- int PathLen; // Actual Length used
- char Message[81];
- char PortMap[MaxBPQPortNo + 1];
- int Interval;
- int Timer;
-};
-
-struct OBJECT * ObjectList; // List of objects to send;
-
-int ObjectCount = 0;
-
-#include
-
-#define M_PI 3.14159265358979323846
-
-int RetryCount = 4;
-int RetryTimer = 45;
-int ExpireTime = 120;
-int TrackExpireTime = 1440;
-BOOL SuppressNullPosn = FALSE;
-BOOL DefaultNoTracks = FALSE;
-
-int MaxStations = 1000;
-
-int SharedMemorySize = 0;
-
-
-RECT Rect, MsgRect, StnRect;
-
-char Key[80];
-
-// function prototypes
-
-VOID RefreshMessages();
-
-// a few global variables
-
-char APRSDir[MAX_PATH] = "BPQAPRS";
-char DF[MAX_PATH];
-
-#define FEND 0xC0 // KISS CONTROL CODES
-#define FESC 0xDB
-#define TFEND 0xDC
-#define TFESC 0xDD
-
-int StationCount = 0;
-
-UCHAR NextSeq = 1;
-
-// Stationrecords are stored in a shared memory segment. based at APRSStationMemory (normally 0x43000000)
-
-// A pointer to the first is placed at the start of this
-
-struct STATIONRECORD ** StationRecords = NULL;
-struct STATIONRECORD * StationRecordPool = NULL;
-struct APRSMESSAGE * MessageRecordPool = NULL;
-
-struct SharedMem * SMEM;
-
-UCHAR * Shared;
-UCHAR * StnRecordBase;
-
-VOID SendObject(struct OBJECT * Object);
-VOID MonitorAPRSIS(char * Msg, int MsgLen, BOOL TX);
-
-#ifndef WIN32
-#define WSAEWOULDBLOCK 11
-#endif
-
-HANDLE hMapFile;
-
-// Logging
-
-static int LogAge = 14;
-
-#ifdef WIN32
-
-int DeleteAPRSLogFiles()
-{
- WIN32_FIND_DATA ffd;
-
- char szDir[MAX_PATH];
- char File[MAX_PATH];
- HANDLE hFind = INVALID_HANDLE_VALUE;
- DWORD dwError=0;
- LARGE_INTEGER ft;
- time_t now = time(NULL);
- int Age;
-
- // Prepare string for use with FindFile functions. First, copy the
- // string to a buffer, then append '\*' to the directory name.
-
- strcpy(szDir, GetLogDirectory());
- strcat(szDir, "/logs/APRS*.log");
-
- // Find the first file in the directory.
-
- hFind = FindFirstFile(szDir, &ffd);
-
- if (INVALID_HANDLE_VALUE == hFind)
- return dwError;
-
- // Walk directory
-
- do
- {
- if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- OutputDebugString(ffd.cFileName);
- }
- else
- {
- ft.HighPart = ffd.ftCreationTime.dwHighDateTime;
- ft.LowPart = ffd.ftCreationTime.dwLowDateTime;
-
- ft.QuadPart -= 116444736000000000;
- ft.QuadPart /= 10000000;
-
- Age = (int)((now - ft.LowPart) / 86400);
-
- if (Age > LogAge)
- {
- sprintf(File, "%s/logs/%s%c", GetLogDirectory(), ffd.cFileName, 0);
- Debugprintf("Deleting %s", File);
- DeleteFile(File);
- }
- }
- }
- while (FindNextFile(hFind, &ffd) != 0);
-
- FindClose(hFind);
- return dwError;
-}
-
-#else
-
-#include
-
-int APRSFilter(const struct dirent * dir)
-{
- return (memcmp(dir->d_name, "APRS", 4) == 0 && strstr(dir->d_name, ".log"));
-}
-
-int DeleteAPRSLogFiles()
-{
- struct dirent **namelist;
- int n;
- struct stat STAT;
- time_t now = time(NULL);
- int Age = 0, res;
- char FN[256];
-
- n = scandir("logs", &namelist, APRSFilter, alphasort);
-
- if (n < 0)
- perror("scandir");
- else
- {
- while(n--)
- {
- sprintf(FN, "logs/%s", namelist[n]->d_name);
- if (stat(FN, &STAT) == 0)
- {
- Age = (now - STAT.st_mtime) / 86400;
-
- if (Age > LogAge)
- {
- Debugprintf("Deleting %s\n", FN);
- unlink(FN);
- }
- }
- free(namelist[n]);
- }
- free(namelist);
- }
- return 0;
-}
-#endif
-
-int APRSWriteLog(char * msg)
-{
- FILE *file;
- UCHAR Value[MAX_PATH];
- time_t T;
- struct tm * tm;
-
- if (LogAPRSIS == 0)
- return 0;
-
- if (strchr(msg, '\n') == 0)
- strcat(msg, "\r\n");
-
- T = time(NULL);
- tm = gmtime(&T);
-
- if (GetLogDirectory()[0] == 0)
- {
- strcpy(Value, "logs/APRS_");
- }
- else
- {
- strcpy(Value, GetLogDirectory());
- strcat(Value, "/");
- strcat(Value, "logs/APRS_");
- }
-
- sprintf(Value, "%s%02d%02d%02d.log", Value,
- tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday);
-
- if ((file = fopen(Value, "ab")) == NULL)
- return FALSE;
-
- fputs(msg, file);
- fclose(file);
- return 0;
-}
-
-
-int ISSend(SOCKET sock, char * Msg, int Len, int flags)
-{
- int Loops = 0;
- int Sent;
-
- MonitorAPRSIS(Msg, Len, TRUE);
-
- Sent = send(sock, Msg, Len, flags);
-
- while (Sent != Len && Loops++ < 300) // 10 secs max
- {
- if ((Sent == SOCKET_ERROR) && (WSAGetLastError() != WSAEWOULDBLOCK))
- return SOCKET_ERROR;
-
- if (Sent > 0) // something sent
- {
- Len -= Sent;
- memmove(Msg, &Msg[Sent], Len);
- }
-
- Sleep(30);
- Sent = send(sock, Msg, Len, flags);
- }
-
- return Sent;
-}
-
-void * endofStations;
-
-Dll BOOL APIENTRY Init_APRS()
-{
- int i;
- char * DCall;
-
-#ifdef WIN32
- HKEY hKey=0;
- int retCode, Vallen, Type;
-#else
- int fd;
- char RX_SOCK_PATH[] = "BPQAPRSrxsock";
- char TX_SOCK_PATH[] = "BPQAPRStxsock";
- char SharedName[256];
- char * ptr1;
-#endif
- struct STATIONRECORD * Stn1, * Stn2;
- struct APRSMESSAGE * Msg1, * Msg2;
-
- // Clear tables in case a restart
-
- StationRecords = NULL;
-
- StationCount = 0;
- HEARDENTRIES = 0;
- MAXHEARDENTRIES = 0;
- MobileBeaconInterval = 0;
- BeaconInterval = 0;
-
- DeleteAPRSLogFiles();
-
- memset(MHTABLE, 0, sizeof(MHTABLE));
-
- ConvToAX25(MYNODECALL, MYCALL);
-
- ConvToAX25("TCPIP", axTCPIP);
- ConvToAX25("RFONLY", axRFONLY);
- ConvToAX25("NOGATE", axNOGATE);
-
- memset(&FloodAX[0][0], 0, sizeof(FloodAX));
- memset(&TraceAX[0][0], 0, sizeof(TraceAX));
- memset(&DigiAX[0][0], 0, sizeof(DigiAX));
-
- APRSPortMask = 0;
-
- memset(BeaconPath, sizeof(BeaconPath), 0);
-
- memset(&CrossPortMap[0][0], 0, sizeof(CrossPortMap));
- memset(&APRSBridgeMap[0][0], 0, sizeof(APRSBridgeMap));
-
- for (i = 1; i <= MaxBPQPortNo; i++)
- {
- if (CanPortDigi(i))
- CrossPortMap[i][i] = TRUE; // Set Defaults - Same Port
- CrossPortMap[i][0] = TRUE; // and APRS-IS
- }
-
- PosnSet = 0;
- ObjectList = NULL;
- ObjectCount = 0;
-
- ISPort = ISHost[0] = ISPasscode = 0;
-
- if (APRSReadConfigFile() == 0)
- return FALSE;
-
- if (APRSCall[0] == 0)
- {
- strcpy(APRSCall, MYNODECALL);
- strlop(APRSCall, ' ');
- strcpy(LoppedAPRSCall, APRSCall);
- memcpy(CallPadded, APRSCall, (int)strlen(APRSCall)); // Call Padded to 9 chars for APRS Messaging
- ConvToAX25(APRSCall, AXCall);
- }
-
- if (WXCall[0] == 0)
- strcpy(WXCall, APRSCall);
-
- // Caluclate size of Shared Segment
-
- SharedMemorySize = sizeof(struct STATIONRECORD) * (MaxStations + 4) +
- sizeof(struct APRSMESSAGE) * (MAXMESSAGES + 4) + 32; // 32 for header
-
-
-#ifndef WIN32
-
- // Create a Shared Memory Object
-
- Shared = NULL;
-
- // Append last bit of current directory to shared name
-
- ptr1 = BPQDirectory;
-
- while (strchr(ptr1, '/'))
- {
- ptr1 = strchr(ptr1, '/');
- ptr1++;
- }
-
- if (multiple)
- sprintf(SharedName, "/BPQAPRSSharedMem%s", ptr1);
- else
- strcpy(SharedName, "/BPQAPRSSharedMem");
-
- printf("Using Shared Memory %s\n", SharedName);
-
-#ifndef WIN32
-
- fd = shm_open(SharedName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
- if (fd == -1)
- {
- perror("Create Shared Memory");
- printf("Create APRS Shared Memory Failed\n");
- }
- else
- {
- if (ftruncate(fd, SharedMemorySize))
- {
- perror("Extend Shared Memory");
- printf("Extend APRS Shared Memory Failed\n");
- }
- else
- {
- // Map shared memory object
-
- Shared = mmap((void *)APRSSHAREDMEMORYBASE,
- SharedMemorySize,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-
- if (Shared == MAP_FAILED)
- {
- perror("Map Shared Memory");
- printf("Map APRS Shared Memory Failed\n");
- Shared = NULL;
- }
-
- if (Shared != (void *)APRSSHAREDMEMORYBASE)
- {
- printf("Map APRS Shared Memory Allocated at %x\n", Shared);
- Shared = NULL;
- }
-
- }
- }
-
-#endif
-
- printf("Map APRS Shared Memory Allocated at %p\n", Shared);
-
- if (Shared == NULL)
- {
- printf("APRS not using shared memory\n");
- Shared = malloc(SharedMemorySize);
- printf("APRS Non-Shared Memory Allocated at %x\n", Shared);
- }
-
-#else
-
-#ifndef LINBPQ
-
- retCode = RegOpenKeyEx (REGTREE,
- "SOFTWARE\\G8BPQ\\BPQ32",
- 0,
- KEY_QUERY_VALUE,
- &hKey);
-
- if (retCode == ERROR_SUCCESS)
- {
- Vallen = 4;
- retCode = RegQueryValueEx(hKey, "IGateEnabled", 0, &Type, (UCHAR *)&IGateEnabled, &Vallen);
- }
-
-#endif
-
- // Create Memory Mapping for Station List
-
- hMapFile = CreateFileMapping(
- INVALID_HANDLE_VALUE, // use paging file
- NULL, // default security
- PAGE_READWRITE, // read/write access
- 0, // maximum object size (high-order DWORD)
- SharedMemorySize, // maximum object size (low-order DWORD)
- "BPQAPRSStationsMappingObject");// name of mapping object
-
- if (hMapFile == NULL)
- {
- Consoleprintf("Could not create file mapping object (%d).\n", GetLastError());
- return 0;
- }
-
- UnmapViewOfFile((void *)APRSSHAREDMEMORYBASE);
-
-
- Shared = (LPTSTR) MapViewOfFileEx(hMapFile, // handle to map object
- FILE_MAP_ALL_ACCESS, // read/write permission
- 0,
- 0,
- SharedMemorySize,
- (void *)APRSSHAREDMEMORYBASE);
-
- if (Shared == NULL)
- {
- Consoleprintf("Could not map view of file (%d).\n", GetLastError());
- CloseHandle(hMapFile);
- return 0;
- }
-
-#endif
-
- // First record has pointer to table
-
- memset(Shared, 0, SharedMemorySize);
-
- StnRecordBase = Shared + 32;
- SMEM = (struct SharedMem *)Shared;
-
- SMEM->Version = 1;
- SMEM->SharedMemLen = SharedMemorySize;
- SMEM->NeedRefresh = TRUE;
- SMEM->Arch = sizeof(void *);
- SMEM->SubVersion = 1;
-
- Stn1 = (struct STATIONRECORD *)StnRecordBase;
-
- StationRecords = (struct STATIONRECORD **)Stn1;
-
- Stn1++;
-
- StationRecordPool = Stn1;
-
- for (i = 1; i < MaxStations; i++) // Already have first
- {
- Stn2 = Stn1;
- Stn2++;
- Stn1->Next = Stn2;
-
- Stn1 = Stn2;
- }
-
- Debugprintf("End of Stations %p", Stn1);
- endofStations = Stn1;
-
- Stn1 += 2; // Try to fix corruption of messages.
-
- // Build Message Record Pool
-
- Msg1 = (struct APRSMESSAGE *)Stn1;
-
- MessageRecordPool = Msg1;
-
- for (i = 1; i < MAXMESSAGES; i++) // Already have first
- {
- Msg2 = Msg1;
- Msg2++;
- Msg1->Next = Msg2;
-
- Msg1 = Msg2;
- }
-
- if (PosnSet == 0)
- {
- SYMBOL = '.';
- SYMSET = '\\'; // Undefined Posn Symbol
- }
- else
- {
- // Convert posn to floating degrees
-
- char LatDeg[3], LonDeg[4];
- memcpy(LatDeg, LAT, 2);
- LatDeg[2]=0;
- Lat=atof(LatDeg) + (atof(LAT+2)/60);
-
- if (LAT[7] == 'S') Lat=-Lat;
-
- memcpy(LonDeg, LON, 3);
- LonDeg[3]=0;
- Lon=atof(LonDeg) + (atof(LON+3)/60);
-
- if (LON[8]== 'W') Lon=-Lon;
-
- SYMBOL = CFGSYMBOL;
- SYMSET = CFGSYMSET;
- }
-
- // First record has control info for APRS Mapping App
-
- Stn1 = (struct STATIONRECORD *)StnRecordBase;
- memcpy(Stn1->Callsign, APRSCall, 10);
- Stn1->Lat = Lat;
- Stn1->Lon = Lon;
- Stn1->LastPort = MaxStations;
-
-#ifndef WIN32
-
- // Open unix socket for messaging app
-
- sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
-
- if (sfd == -1)
- {
- perror("Socket");
- }
- else
- {
- u_long param=1;
- ioctl(sfd, FIONBIO, ¶m); // Set non-blocking
-
- memset(&my_addr, 0, sizeof(struct sockaddr_un));
- my_addr.sun_family = AF_UNIX;
- strncpy(my_addr.sun_path, TX_SOCK_PATH, sizeof(my_addr.sun_path) - 1);
-
- memset(&peer_addr, 0, sizeof(struct sockaddr_un));
- peer_addr.sun_family = AF_UNIX;
- strncpy(peer_addr.sun_path, RX_SOCK_PATH, sizeof(peer_addr.sun_path) - 1);
-
- unlink(TX_SOCK_PATH);
-
- if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1)
- perror("bind");
- }
-#endif
-
- // Convert Dest ADDRS to AX.25
-
- for (i = 0; i < 26; i++)
- {
- DCall = &APRSDESTS[i][0];
- if (strchr(DCall, '*'))
- AXDESTLEN[i] = (int)strlen(DCall) - 1;
- else
- AXDESTLEN[i] = 6;
-
- ConvToAX25(DCall, &AXDESTS[i][0]);
- }
-
- // Process any Object Definitions
-
- // Setup Heard Data Area
-
- HEARDENTRIES = 0;
- MAXHEARDENTRIES = MAXHEARD;
-
- APRSMONVECPTR->HOSTAPPLFLAGS = 0x80; // Request Monitoring
-
- if (ISPort && IGateEnabled)
- {
- _beginthread(APRSISThread, 0, (VOID *) TRUE);
- }
-
- if (GPSPort[0])
- OpenGPSPort();
-
- WritetoConsole("APRS Digi/Gateway Enabled\n");
-
- APRSWeb = TRUE;
-
- read_png((unsigned char *)IconData);
-
- // Reload saved messages
-
- if (SaveAPRSMsgs)
- GetSavedAPRSMessages();
-
- // If a Run parameter was supplied, run the program
-
- if (RunProgram[0] == 0)
- return TRUE;
-
- #ifndef WIN32
- {
- char * arg_list[] = {NULL, NULL};
- pid_t child_pid;
-
- signal(SIGCHLD, SIG_IGN); // Silently (and portably) reap children.
-
- // Fork and Exec program
-
- printf("Trying to start %s\n", RunProgram);
-
- arg_list[0] = RunProgram;
-
- // Duplicate this process.
-
- child_pid = fork ();
-
- if (child_pid == -1)
- {
- printf ("APRS fork() Failed\n");
- return 0;
- }
-
- 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", RunProgram);
- exit(0); // Kill the new process
- }
- }
-#else
- {
- int n = 0;
-
- STARTUPINFO SInfo; // pointer to STARTUPINFO
- PROCESS_INFORMATION PInfo; // pointer to PROCESS_INFORMATION
-
- SInfo.cb=sizeof(SInfo);
- SInfo.lpReserved=NULL;
- SInfo.lpDesktop=NULL;
- SInfo.lpTitle=NULL;
- SInfo.dwFlags=0;
- SInfo.cbReserved2=0;
- SInfo.lpReserved2=NULL;
-
- while (KillOldTNC(RunProgram) && n++ < 100)
- {
- Sleep(100);
- }
-
- if (!CreateProcess(RunProgram, NULL, NULL, NULL, FALSE,0 ,NULL ,NULL, &SInfo, &PInfo))
- Debugprintf("Failed to Start %s Error %d ", RunProgram, GetLastError());
- }
-#endif
-
- return TRUE;
-}
-
-#define SD_RECEIVE 0x00
-#define SD_SEND 0x01
-#define SD_BOTH 0x02
-
-BOOL APRSActive;
-
-VOID APRSClose()
-{
- APRSActive = FALSE;
-
- if (sock)
- {
- shutdown(sock, SD_BOTH);
- Sleep(50);
-
- closesocket(sock);
- }
-#ifdef WIN32
- if (InPorts[0].hDevice)
- CloseHandle(InPorts[0].hDevice);
-#endif
-}
-
-time_t lastSecTimer = 0;
-
-
-Dll VOID APIENTRY Poll_APRS()
-{
- time_t Now = time(NULL);
-
- if (lastSecTimer != Now)
- {
- lastSecTimer = Now;
-
- DoSecTimer();
-
- MinTimer--;
-
- if (MinTimer == 0)
- {
- MinTimer = 60;
- DoMinTimer();
- }
- }
-
- if (SMEM->ClearRX)
- {
- // Clear Received Messages request from GUI
-
- struct APRSMESSAGE * ptr = SMEM->Messages;
-
- // Move Message Queue to Free Queue
-
- if (ptr)
- {
- while (ptr->Next) // Find end of chain
- {
- ptr = ptr->Next;
- }
-
- // ptr is end of chain - chain free pool to it
-
- ptr->Next = MessageRecordPool;
-
- MessageRecordPool = SMEM->Messages;
- MessageCount = 0;
- }
-
- SMEM->Messages = NULL;
- SMEM->ClearRX = 0;
- SMEM->NeedRefresh = TRUE;
-
- ClearSavedMessages();
- }
-
- if (SMEM->ClearTX)
- {
- // Clear Sent Messages )request from GUI
-
- struct APRSMESSAGE * ptr = SMEM->OutstandingMsgs;
-
- // Move Message Queue to Free Queue
-
- if (ptr)
- {
- while (ptr->Next) // Find end of chain
- {
- ptr = ptr->Next;
- }
-
- // ptr is end of chain - chain free pool to it
-
- ptr->Next = MessageRecordPool;
-
- MessageRecordPool = SMEM->OutstandingMsgs;
- MessageCount = 0;
- }
-
- SMEM->OutstandingMsgs = NULL;
- SMEM->ClearTX = 0;
- SMEM->NeedRefresh = TRUE;
- }
-#ifdef LINBPQ
-#ifndef WIN32
- {
- char Msg[256];
- int numBytes;
-
- // Look for messages from App
-
- numBytes = recvfrom(sfd, Msg, 256, 0, NULL, NULL);
-
- if (numBytes > 0)
- {
- InternalSendAPRSMessage(&Msg[10], &Msg[0]);
- }
- }
-#endif
-#endif
-
- if (GPSPort[0])
- PollGPSIn();
-
- if (APPLTX_Q)
- {
- PMSGWITHLEN buffptr = Q_REM(&APPLTX_Q);
-
- InternalSendAPRSMessage(&buffptr->Data[10], &buffptr->Data[0]);
- ReleaseBuffer(buffptr);
- }
-
- while (APRSMONVECPTR->HOSTTRACEQ)
- {
- time_t stamp;
- int len;
- BOOL MonitorNODES = FALSE;
- PMESSAGE monbuff;
- UCHAR * monchars;
- MESSAGE * Orig;
- int Digis = 0;
- MESSAGE * AdjBuff; // Adjusted for digis
- BOOL FirstUnused = FALSE;
- int DigisUsed = 0; // Digis used to reach us
- DIGIMESSAGE Msg = {0};
- int Port;
- unsigned char buffer[1024];
- char ISMsg[500];
- char * ptr1;
- char * Payload;
- char * ptr3;
- char * ptr4;
- BOOL ThirdParty = FALSE;
- BOOL NoGate = FALSE;
- APRSHEARDRECORD * MH;
- char MsgCopy[500];
- int toPort;
- struct STATIONRECORD * Station;
- int ourMessage = 0;
-
-#ifdef WIN32
- struct _EXCEPTION_POINTERS exinfo;
- char EXCEPTMSG[80] = "";
-#endif
- monbuff = Q_REM((VOID **)&APRSMONVECPTR->HOSTTRACEQ);
-
- monchars = (UCHAR *)monbuff;
- AdjBuff = Orig = (MESSAGE *)monchars; // Adjusted for digis
-
- Port = Orig->PORT;
-
- if (Port & 0x80) // TX
- {
- ReleaseBuffer(monbuff);
- continue;
- }
-
- if ((APRSPortMask & ((uint64_t)1 << (Port - 1))) == 0)// Port in use for APRS?
- {
- ReleaseBuffer(monbuff);
- continue;
- }
-
- stamp = monbuff->Timestamp;
-
- if ((UCHAR)monchars[4] & 0x80) // TX
- {
- ReleaseBuffer(monbuff);
- continue;
- }
-
- // See if digipeaters present.
-
- while ((AdjBuff->ORIGIN[6] & 1) == 0 && Digis < 9)
- {
- UCHAR * temp = (UCHAR *)AdjBuff;
- temp += 7;
- AdjBuff = (MESSAGE *)temp;
-
- // If we have already digi'ed it or if we sent it,
- // ignore (Dup Check my fail on slow links)
-
- if (AdjBuff->ORIGIN[6] & 0x80)
- {
- // Used Digi
-
- if (memcmp(AdjBuff->ORIGIN, AXCall, 7) == 0)
- {
- ReleaseBuffer(monbuff);
- return;
- }
- DigisUsed++;
- }
-
- if (memcmp(AdjBuff->ORIGIN, axTCPIP, 6) == 0)
- ThirdParty = TRUE;
-
- Digis ++;
-
- if (FirstUnused == FALSE && (AdjBuff->ORIGIN[6] & 0x80) == 0)
- {
- // Unused Digi - see if we should digi it
-
- FirstUnused = Digis;
- // CheckDigi(buff, AdjBuff->ORIGIN);
- }
- }
-
- if (Digis > 8)
- {
- ReleaseBuffer(monbuff);
- continue; // Corrupt
- }
-
- if (Digis)
- {
- if (memcmp(AdjBuff->ORIGIN, axNOGATE, 6) == 0
- || memcmp(AdjBuff->ORIGIN, axRFONLY, 6) == 0
- || DigisUsed > MaxDigisforIS)
-
- // Too many digis or Last digis is NOGATE or RFONLY - dont send to IS
-
- NoGate = TRUE;
- }
- if (AdjBuff->CTL != 3 || AdjBuff->PID != 0xf0) // Only UI
- {
- ReleaseBuffer(monbuff);
- continue;
- }
-
- // Bridge if requested
-
- for (toPort = 1; toPort <= MaxBPQPortNo; toPort++)
- {
- if (APRSBridgeMap[Port][toPort])
- {
- MESSAGE * Buffer = GetBuff();
- struct PORTCONTROL * PORT;
-
- if (Buffer)
- {
- memcpy(Buffer, Orig, Orig->LENGTH);
- Buffer->PORT = toPort;
- PORT = GetPortTableEntryFromPortNum(toPort);
-
- if (PORT)
- {
- if (PORT->SmartIDInterval && PORT->SmartIDNeeded == 0)
- {
- // Using Smart ID, but none scheduled
-
- PORT->SmartIDNeeded = time(NULL) + PORT->SmartIDInterval;
- }
- PUT_ON_PORT_Q(PORT, Buffer);
- }
- else
- ReleaseBuffer(Buffer);
- }
- }
- }
-
- // Used to check for dups here but according to "Notes to iGate developers" IS should be sent dups, and dup
- // check only applied to digi'ing
-
-// if (SATGate == 0)
-// {
-// if (CheckforDups(Orig->ORIGIN, AdjBuff->L2DATA, Orig->LENGTH - Digis * 7 - (19 + sizeof(void *)))
-// {
-// ReleaseBuffer(monbuff);
-// continue;
-// }
-// }
- // Decode Frame to TNC2 Monitor Format
-
- len = APRSDecodeFrame((char *)monchars, buffer, stamp, APRSPortMask);
-
- if (len == 0)
- {
- // Couldn't Decode
-
- ReleaseBuffer(monbuff);
- Debugprintf("APRS discarded frame - decode failed\n");
- continue;
- }
-
- buffer[len] = 0;
-
- memcpy(MsgCopy, buffer, len);
- MsgCopy[len] = 0;
-
- // Do internal Decode
-
-#ifdef WIN32
-
- strcpy(EXCEPTMSG, "ProcessRFFrame");
-
- __try
- {
-
- Station = ProcessRFFrame(MsgCopy, len, &ourMessage);
- }
- #include "StdExcept.c"
-
- }
-#else
- Station = ProcessRFFrame(MsgCopy, len, &ourMessage);
-#endif
-
- if (Station == NULL)
- {
- ReleaseBuffer(monbuff);
- continue;
- }
-
- memcpy(MsgCopy, buffer, len); // Process RF Frame may have changed it
- MsgCopy[len] = 0;
-
- buffer[len++] = 10;
- buffer[len] = 0;
- ptr1 = &buffer[10]; // Skip Timestamp
- Payload = strchr(ptr1, ':') + 2; // Start of Payload
- ptr3 = strchr(ptr1, ' '); // End of addresses
- *ptr3 = 0;
-
- // We should send path to IS unchanged, so create IS
- // message before chopping path. We won't decide if
- // we will actually send it to IS till later
-
- len = sprintf(ISMsg, "%s,qAR,%s:%s", ptr1, APRSCall, Payload);
-
-
- // if digis, remove any unactioned ones
-
- if (Digis)
- {
- ptr4 = strchr(ptr1, '*'); // Last Used Digi
-
- if (ptr4)
- {
- // We need header up to ptr4
-
- *(ptr4) = 0;
- }
- else
- {
- // No digis actioned - remove them all
-
- ptr4 = strchr(ptr1, ','); // End of Dest
- if (ptr4)
- *ptr4 = 0;
- }
- }
-
- ptr4 = strchr(ptr1, '>'); // End of Source
- *ptr4++ = 0;
-
- MH = UpdateHeard(ptr1, Port);
-
- MH->Station = Station;
-
- if (ThirdParty)
- {
-// Debugprintf("Setting Igate Flag - %s", MsgCopy);
- MH->IGate = TRUE; // if we've seen msgs to TCPIP, it must be an Igate
- }
-
- if (NoGate || RXOnly)
- goto NoIS;
-
- // I think all PID F0 UI frames go to APRS-IS,
- // Except General Queries, Frames Gated from IS to RF, and Messages Addressed to us
-
- // or should we process Query frames locally ??
-
- if (Payload[0] == '}')
- goto NoIS;
-
- if (Payload[0] == '?')
- {
- // General Query
-
- ProcessQuery(&Payload[1]);
-
- // ?? Should we pass addressed Queries to IS ??
-
- goto NoIS;
- }
-
- if (Payload[0] == ':' && memcmp(&Payload[1], CallPadded, 9) == 0)
- {
- // Message for us
-
- if (Payload[11] == '?') // Only queries - the node doesnt do messaging
- ProcessSpecificQuery(&Payload[12], Port, ptr1, ptr4);
-
- goto NoIS;
- }
-
- if (APRSISOpen && CrossPortMap[Port][0]) // No point if not open
- {
- // was done above len = sprintf(ISMsg, "%s>%s,qAR,%s:%s", ptr1, ptr4, APRSCall, Payload);
-
- if (BeacontoIS == 0)
- {
- // Don't send anything we've received as an echo
-
- char SaveCall[7];
- memcpy(SaveCall, &monbuff->ORIGIN, 7);
- SaveCall[6] &= 0x7e; // Mask End of address bit
-
- if (memcmp(SaveCall, AXCall, 7) == 0) // We sent it
- {
- // Should we check for being received via digi? - not for now
-
- goto NoIS;
- }
- }
-
- if (SATGate && (DigisUsed == 0))
- {
- // If in Satgate mode delay directly heard to IGate
-
- ISDELAY * SatISEntry = malloc(sizeof(ISDELAY));
- SatISEntry->Next = NULL;
- SatISEntry->ISMSG = _strdup(ISMsg);
- SatISEntry->SendTIme = time(NULL) + 10; // Delay 10 seconds
-
- if (SatISQueue)
- SatISEntry->Next = SatISQueue; // Chain
-
- SatISQueue = SatISEntry;
- goto NoIS;
- }
-
- ISSend(sock, ISMsg, len, 0);
-
- ptr1 = strchr(ISMsg, 13);
- if (ptr1) *ptr1 = 0;
-// Debugprintf(">%s", ISMsg);
- }
-
- NoIS:
-
- // We skipped DUP check for SATGate Mode, so apply it here
-
- // Now we don't dup check earlier so always check here
-
-// if (SATGate)
-// {
- if (CheckforDups(Orig->ORIGIN, AdjBuff->L2DATA, Orig->LENGTH - Digis * 7 - (19 + sizeof(void *))))
- {
- ReleaseBuffer(monbuff);
- continue;
- }
-// }
-
- // See if it is an APRS frame
-
- // If MIC-E, we need to process, whatever the destination
-
- // Now process any dest
-
-/*
- DEST = &Orig->DEST[0];
-
- for (i = 0; i < 26; i++)
- {
- if (memcmp(DEST, &AXDESTS[i][0], AXDESTLEN[i]) == 0)
- goto OK;
- }
-
- switch(AdjBuff->L2DATA[0])
- {
- case '`':
- case 0x27: // '
- case 0x1c:
- case 0x1d: // MIC-E
-
- break;
- // default:
-
- // Not to an APRS Destination
-
-// ReleaseBuffer(monbuff);
-// continue;
- }
-
-OK:
-*/
-
- // If there are unused digis, we may need to digi it.
-
- if (ourMessage)
- {
- // A message addressed to us, so no point in digi'ing it
-
- ReleaseBuffer(monbuff);
- continue;
- }
-
- if (Digis == 0 || FirstUnused == 0)
- {
- // No Digis, so finished
-
- ReleaseBuffer(monbuff);
- continue;
- }
-
- if (memcmp(monbuff->ORIGIN, AXCall, 7) == 0) // We sent it
- {
- ReleaseBuffer(monbuff);
- continue;
- }
-
- // Copy frame to a DIGIMessage Struct
-
- memcpy(&Msg, monbuff, MSGHDDRLEN + 14 + (7 * Digis)); // Header, Dest, Source, Addresses and Digis
-
- len = Msg.LENGTH - (MSGHDDRLEN + 14) - (7 * Digis); // Payload Length (including CTL and PID
-
- memcpy(&Msg.CTL, &AdjBuff->CTL, len);
-
- // Pass to Digi Code
-
- CheckandDigi(&Msg, Port, FirstUnused, Digis, len); // Digi if necessary
-
- ReleaseBuffer(monbuff);
- }
-
- return;
-}
-
-VOID CheckandDigi(DIGIMESSAGE * Msg, int Port, int FirstUnused, int Digis, int Len)
-{
- UCHAR * Digi = &Msg->DIGIS[--FirstUnused][0];
- UCHAR * Call;
- int Index = 0;
- int SSID;
-
- // Check ordinary digi first
-
- Call = &DigiAX[0][0];
- SSID = Digi[6] & 0x1e;
-
- while (*Call)
- {
- if ((memcmp(Digi, Call, 6) == 0) && ((Call[6] & 0x1e) == SSID))
- {
- // Trace Call if enabled
-
- if (TraceDigi)
- memcpy(Digi, AXCall, 7);
-
- // mark as used;
-
- Digi[6] |= 0x80; // Used bit
-
- SendtoDigiPorts(Msg, Len, Port);
- return;
- }
- Call += 7;
- Index++;
- }
-
- Call = &TraceAX[0][0];
- Index = 0;
-
- while (*Call)
- {
- if (memcmp(Digi, Call, TraceLen[Index]) == 0)
- {
- // if possible move calls along
- // insert our call, set used
- // decrement ssid, and if zero, mark as used;
-
- SSID = (Digi[6] & 0x1E) >> 1;
-
- if (SSID == 0)
- return; // Shouldn't have SSID 0 for Rrace/Flood
-
- if (SSID > MaxTraceHops)
- SSID = MaxTraceHops; // Enforce our limit
-
- SSID--;
-
- if (SSID ==0) // Finihed with it ?
- Digi[6] = (SSID << 1) | 0xe0; // Used and Fixed bits
- else
- Digi[6] = (SSID << 1) | 0x60; // Fixed bits
-
- if (Digis < 8)
- {
- memmove(Digi + 7, Digi, (Digis - FirstUnused) * 7);
- }
-
- memcpy(Digi, AXCall, 7);
- Digi[6] |= 0x80;
-
- SendtoDigiPorts(Msg, Len, Port);
-
- return;
- }
- Call += 7;
- Index++;
- }
-
- Index = 0;
- Call = &FloodAX[0][0];
-
- while (*Call)
- {
- if (memcmp(Digi, Call, FloodLen[Index]) == 0)
- {
- // decrement ssid, and if zero, mark as used;
-
- SSID = (Digi[6] & 0x1E) >> 1;
-
- if (SSID == 0)
- return; // Shouldn't have SSID 0 for Trace/Flood
-
- if (SSID > MaxFloodHops)
- SSID = MaxFloodHops; // Enforce our limit
-
- SSID--;
-
- if (SSID ==0) // Finihed with it ?
- Digi[6] = (SSID << 1) | 0xe0; // Used and Fixed bits
- else
- Digi[6] = (SSID << 1) | 0x60; // Fixed bits
-
- SendtoDigiPorts(Msg, Len, Port);
-
- return;
- }
- Call += 7;
- Index++;
- }
-}
-
-
-
-static VOID SendtoDigiPorts(PDIGIMESSAGE Block, DWORD Len, UCHAR Port)
-{
- // Can't use API SENDRAW, as that tries to get the semaphore, which we already have
- // Len is the Payload Length (from CTL onwards)
- // The message can contain DIGIS - The payload must be copied forwards if there are less than 8
-
- // We send to all ports enabled in CrossPortMap
-
- UCHAR * EndofDigis = &Block->CTL;
- int i = 0;
- int toPort;
-
- while (Block->DIGIS[i][0] && i < 8)
- {
- i++;
- }
-
- EndofDigis = &Block->DIGIS[i][0];
- *(EndofDigis -1) |= 1; // Set End of Address Bit
-
- if (i != 8)
- memmove(EndofDigis, &Block->CTL, Len);
-
- Len = Len + (i * 7) + 14; // Include Source, Dest and Digis
-
-// Block->DEST[6] &= 0x7e; // Clear End of Call
-// Block->ORIGIN[6] |= 1; // Set End of Call
-
-// Block->CTL = 3; //UI
-
- for (toPort = 1; toPort <= MaxBPQPortNo; toPort++)
- {
- if (CrossPortMap[Port][toPort])
- Send_AX((PMESSAGE)Block, Len, toPort);
- }
- return;
-
-}
-
-VOID Send_AX_Datagram(PDIGIMESSAGE Block, DWORD Len, UCHAR Port)
-{
- // Can't use API SENDRAW, as that tries to get the semaphore, which we already have
-
- // Len is the Payload Length (CTL, PID, Data)
-
- // The message can contain DIGIS - The payload must be copied forwards if there are less than 8
-
- UCHAR * EndofDigis = &Block->CTL;
-
- int i = 0;
-
- while (Block->DIGIS[i][0] && i < 8)
- {
- i++;
- }
-
- EndofDigis = &Block->DIGIS[i][0];
- *(EndofDigis -1) |= 1; // Set End of Address Bit
-
- if (i != 8)
- memmove(EndofDigis, &Block->CTL, Len); // Include PID
-
- Len = Len + (i * 7) + 14; // Include Source, Dest and Digis
-
- Send_AX((PMESSAGE)Block, Len, Port);
-
- return;
-
-}
-
-static BOOL APRSReadConfigFile()
-{
- char * Config;
- char * ptr1, * ptr2;
-
- char buf[256],errbuf[256];
-
- Config = PortConfig[APRSConfigSlot]; // Config from bpq32.cfg
-
- sprintf(StatusMsg, "BPQ32 Igate V %s", VersionString); // Set Default Status Message
-
- if (Config)
- {
- // Using config from bpq32.cfg
-
- ptr1 = Config;
-
- 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 (!APRSProcessLine(buf))
- {
- WritetoConsole("APRS Bad config record ");
- strcat(errbuf, "\r\n");
- WritetoConsole(errbuf);
- }
- }
- return TRUE;
- }
- return FALSE;
-}
-
-BOOL ConvertCalls(char * DigiCalls, UCHAR * AX, int * Lens)
-{
- int Index = 0;
- char * ptr;
- char * Context;
- UCHAR Work[MAXCALLS][7] = {0};
- int Len[MAXCALLS] = {0};
-
- ptr = strtok_s(DigiCalls, ", ", &Context);
-
- while(ptr)
- {
- if (Index == MAXCALLS) return FALSE;
-
- ConvToAX25(ptr, &Work[Index][0]);
- Len[Index++] = (int)strlen(ptr);
- ptr = strtok_s(NULL, ", ", &Context);
- }
-
- memcpy(AX, Work, sizeof(Work));
- memcpy(Lens, Len, sizeof(Len));
- return TRUE;
-}
-
-
-
-static int APRSProcessLine(char * buf)
-{
- char * ptr, * p_value;
-
- ptr = strtok(buf, "= \t\n\r");
-
- if(ptr == NULL) return (TRUE);
-
- if(*ptr =='#') return (TRUE); // comment
-
- if(*ptr ==';') return (TRUE); // comment
-
-
-// OBJECT PATH=APRS,WIDE1-1 PORT=1,IS INTERVAL=30 TEXT=;444.80TRF*111111z4807.60N/09610.63Wr%156 R15m
-
- if (_stricmp(ptr, "OBJECT") == 0)
- {
- char * p_Path, * p_Port, * p_Text;
- int Interval;
- struct OBJECT * Object;
- int Digi = 2;
- char * Context;
- int SendTo;
-
- p_value = strtok(NULL, "=");
- if (p_value == NULL) return FALSE;
- if (_stricmp(p_value, "PATH"))
- return FALSE;
-
- p_Path = strtok(NULL, "\t\n\r ");
- if (p_Path == NULL) return FALSE;
-
- p_value = strtok(NULL, "=");
- if (p_value == NULL) return FALSE;
- if (_stricmp(p_value, "PORT"))
- return FALSE;
-
- p_Port = strtok(NULL, "\t\n\r ");
- if (p_Port == NULL) return FALSE;
-
- p_value = strtok(NULL, "=");
- if (p_value == NULL) return FALSE;
- if (_stricmp(p_value, "INTERVAL"))
- return FALSE;
-
- p_value = strtok(NULL, " \t");
- if (p_value == NULL) return FALSE;
-
- Interval = atoi(p_value);
-
- if (Interval == 0)
- return FALSE;
-
- p_value = strtok(NULL, "=");
- if (p_value == NULL) return FALSE;
- if (_stricmp(p_value, "TEXT"))
- return FALSE;
-
- p_Text = strtok(NULL, "\n\r");
- if (p_Text == NULL) return FALSE;
-
- Object = zalloc(sizeof(struct OBJECT));
-
- if (Object == NULL)
- return FALSE;
-
- Object->Next = ObjectList;
- ObjectList = Object;
-
- if (Interval < 10)
- Interval = 10;
-
- Object->Interval = Interval;
- Object->Timer = (ObjectCount++) * 10 + 30; // Spread them out;
-
- // Convert Path to AX.25
-
- ConvToAX25(APRSCall, &Object->Path[1][0]);
-
- ptr = strtok_s(p_Path, ",\t\n\r", &Context);
-
- if (_stricmp(ptr, "APRS") == 0) // First is Dest
- ConvToAX25(APRSDest, &Object->Path[0][0]);
- else if (_stricmp(ptr, "APRS-0") == 0)
- ConvToAX25("APRS", &Object->Path[0][0]);
- else
- ConvToAX25(ptr, &Object->Path[0][0]);
-
- ptr = strtok_s(NULL, ",\t\n\r", &Context);
-
- while (ptr)
- {
- ConvToAX25(ptr, &Object->Path[Digi++][0]);
- ptr = strtok_s(NULL, " ,\t\n\r", &Context);
- }
-
- Object->PathLen = Digi * 7;
-
- // Process Port List
-
- ptr = strtok_s(p_Port, ",", &Context);
-
- while (ptr)
- {
- SendTo = atoi(ptr); // this gives zero for IS
-
- if (SendTo > MaxBPQPortNo)
- return FALSE;
-
- Object->PortMap[SendTo] = TRUE;
- ptr = strtok_s(NULL, " ,\t\n\r", &Context);
- }
-
- if (strlen(p_Text) > 80)
- p_Text[80] = 0;
-
- strcpy(Object->Message, p_Text);
- return TRUE;
- }
-
- if (_stricmp(ptr, "STATUSMSG") == 0)
- {
- p_value = strtok(NULL, ";\t\n\r");
- memcpy(StatusMsg, p_value, 128); // Just in case too long
- StatusMsgLen = (int)strlen(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "WXFileName") == 0)
- {
- p_value = strtok(NULL, ";\t\n\r");
- strcpy(WXFileName, p_value);
- SendWX = TRUE;
- return TRUE;
- }
- if (_stricmp(ptr, "WXComment") == 0)
- {
- p_value = strtok(NULL, ";\t\n\r");
-
- if (p_value == NULL)
- return TRUE;
-
- if (strlen(p_value) > 79)
- p_value[80] = 0;
-
- strcpy(WXComment, p_value);
- return TRUE;
- }
-
-
- if (_stricmp(ptr, "ISFILTER") == 0)
- {
- p_value = strtok(NULL, ";\t\n\r");
- strcpy(ISFilter, p_value);
- strcpy(NodeFilter, ISFilter);
- return TRUE;
- }
-
- if (_stricmp(ptr, "ReplaceDigiCalls") == 0)
- {
- TraceDigi = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "Multiple") == 0)
- {
- multiple = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "SATGate") == 0)
- {
- SATGate = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "RXOnly") == 0)
- {
- RXOnly = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "DISTKM") == 0)
- {
- DefaultDistKM = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "LOCALTIME") == 0)
- {
- DefaultLocalTime = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "LOGAPRSIS") == 0)
- {
- LogAPRSIS = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "SaveAPRSMsgs") == 0)
- {
- SaveAPRSMsgs = TRUE;
- return TRUE;
- }
-
- p_value = strtok(NULL, " \t\n\r");
-
- if (p_value == NULL)
- return FALSE;
-
- if (_stricmp(ptr, "APRSCALL") == 0)
- {
- strcpy(APRSCall, p_value);
- strcpy(LoppedAPRSCall, p_value);
- memcpy(CallPadded, APRSCall, (int)strlen(APRSCall)); // Call Padded to 9 chars for APRS Messaging
-
- // Convert to ax.25
-
- return ConvToAX25(APRSCall, AXCall);
- }
-
- if (_stricmp(ptr, "WXCALL") == 0)
- {
- strcpy(WXCall, p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "APRSPATH") == 0)
- {
- int Digi = 2;
- int Port;
- char * Context;
-
- p_value = strtok_s(p_value, "=\t\n\r", &Context);
-
- Port = atoi(p_value);
-
- if (GetPortTableEntryFromPortNum(Port) == NULL)
- return FALSE;
-
- APRSPortMask |= (uint64_t)1 << (Port - 1);
-
- if (Context == NULL || Context[0] == 0)
- return TRUE; // No dest - a receive-only port
-
- BeaconPath[Port] = _strdup(_strupr(Context));
-
- ptr = strtok_s(NULL, ",\t\n\r", &Context);
-
- if (ptr == NULL)
- return FALSE;
-
- ConvToAX25(APRSCall, &BeaconHeader[Port][1][0]);
-
- if (_stricmp(ptr, "APRS") == 0) // First is Dest
- ConvToAX25(APRSDest, &BeaconHeader[Port][0][0]);
- else if (_stricmp(ptr, "APRS-0") == 0)
- ConvToAX25("APRS", &BeaconHeader[Port][0][0]);
- else
- ConvToAX25(ptr, &BeaconHeader[Port][0][0]);
-
- ptr = strtok_s(NULL, ",\t\n\r", &Context);
-
- while (ptr)
- {
- ConvToAX25(ptr, &BeaconHeader[Port][Digi++][0]);
- ptr = strtok_s(NULL, " ,\t\n\r", &Context);
- }
-
- BeaconHddrLen[Port] = Digi * 7;
-
- return TRUE;
- }
-
- if (_stricmp(ptr, "GATEDPATH") == 0)
- {
- int Digi = 2;
- int Port;
- char * Context;
-
- p_value = strtok_s(p_value, "=\t\n\r", &Context);
-
- Port = atoi(p_value);
-
- if (GetPortTableEntryFromPortNum(Port) == NULL)
- return FALSE;
-
-// APRSPortMask |= 1 << (Port - 1);
-
- if (Context == NULL || Context[0] == 0)
- return TRUE; // No dest - a receive-only port
-
- BeaconPath[Port] = _strdup(_strupr(Context));
-
- ptr = strtok_s(NULL, ",\t\n\r", &Context);
-
- if (ptr == NULL)
- return FALSE;
-
- ConvToAX25(APRSCall, &GatedHeader[Port][1][0]);
-
- if (_stricmp(ptr, "APRS") == 0) // First is Dest
- ConvToAX25(APRSDest, &GatedHeader[Port][0][0]);
- else if (_stricmp(ptr, "APRS-0") == 0)
- ConvToAX25("APRS", &GatedHeader[Port][0][0]);
- else
- ConvToAX25(ptr, &GatedHeader[Port][0][0]);
-
- ptr = strtok_s(NULL, ",\t\n\r", &Context);
-
- while (ptr)
- {
- ConvToAX25(ptr, &GatedHeader[Port][Digi++][0]);
- ptr = strtok_s(NULL, " ,\t\n\r", &Context);
- }
-
- GatedHddrLen[Port] = Digi * 7;
-
- return TRUE;
- }
-
-
- if (_stricmp(ptr, "DIGIMAP") == 0)
- {
- int DigiTo;
- int Port;
- char * Context;
-
- p_value = strtok_s(p_value, "=\t\n\r", &Context);
-
- Port = atoi(p_value);
-
- if (GetPortTableEntryFromPortNum(Port) == NULL)
- return FALSE;
-
- // Check that port can digi (SCS Pactor can't set digi'd bit in calls)
-
- if (CanPortDigi(Port) == 0)
- return FALSE;
-
-
- CrossPortMap[Port][Port] = FALSE; // Cancel Default mapping
- CrossPortMap[Port][0] = FALSE; // Cancel Default APRSIS
-
- if (Context == NULL || Context[0] == 0)
- return TRUE;
-
- ptr = strtok_s(NULL, ",\t\n\r", &Context);
-
- while (ptr)
- {
- DigiTo = atoi(ptr); // this gives zero for IS
-
- if (DigiTo && GetPortTableEntryFromPortNum(DigiTo) == NULL)
- return FALSE;
-
- CrossPortMap[Port][DigiTo] = TRUE;
- ptr = strtok_s(NULL, " ,\t\n\r", &Context);
- }
-
- return TRUE;
- }
- if (_stricmp(ptr, "BRIDGE") == 0)
- {
- int DigiTo;
- int Port;
- char * Context;
-
- p_value = strtok_s(p_value, "=\t\n\r", &Context);
-
- Port = atoi(p_value);
-
- if (GetPortTableEntryFromPortNum(Port) == NULL)
- return FALSE;
-
- if (Context == NULL)
- return FALSE;
-
- ptr = strtok_s(NULL, ",\t\n\r", &Context);
-
- while (ptr)
- {
- DigiTo = atoi(ptr); // this gives zero for IS
-
- if (DigiTo > MaxBPQPortNo)
- return FALSE;
-
- APRSBridgeMap[Port][DigiTo] = TRUE;
- ptr = strtok_s(NULL, " ,\t\n\r", &Context);
- }
-
- return TRUE;
- }
-
-
- if (_stricmp(ptr, "BeaconInterval") == 0)
- {
- BeaconInterval = atoi(p_value);
-
- if (BeaconInterval < 5)
- BeaconInterval = 5;
-
- if (BeaconInterval)
- BeaconCounter = 30; // Send first after 30 secs
-
- return TRUE;
- }
-
- if (_stricmp(ptr, "MobileBeaconInterval") == 0)
- {
- MobileBeaconInterval = atoi(p_value) * 60;
- return TRUE;
- }
- if (_stricmp(ptr, "MobileBeaconIntervalSecs") == 0)
- {
- MobileBeaconInterval = atoi(p_value);
- if (MobileBeaconInterval < 10)
- MobileBeaconInterval = 10;
-
- return TRUE;
- }
-
- if (_stricmp(ptr, "BeacontoIS") == 0)
- {
- BeacontoIS = atoi(p_value);
- return TRUE;
- }
-
-
- if (_stricmp(ptr, "TRACECALLS") == 0)
- {
- TraceCalls = _strdup(_strupr(p_value));
- ConvertCalls(TraceCalls, &TraceAX[0][0], &TraceLen[0]);
- return TRUE;
- }
-
- if (_stricmp(ptr, "FLOODCALLS") == 0)
- {
- FloodCalls = _strdup(_strupr(p_value));
- ConvertCalls(FloodCalls, &FloodAX[0][0], &FloodLen[0]);
- return TRUE;
- }
-
- if (_stricmp(ptr, "DIGICALLS") == 0)
- {
- char AllCalls[1024];
-
- DigiCalls = _strdup(_strupr(p_value));
- strcpy(AllCalls, APRSCall);
- strcat(AllCalls, ",");
- strcat(AllCalls, DigiCalls);
- ConvertCalls(AllCalls, &DigiAX[0][0], &DigiLen[0]);
- return TRUE;
- }
-
- if (_stricmp(ptr, "MaxStations") == 0)
- {
- MaxStations = atoi(p_value);
-
- if (MaxStations > 10000)
- MaxStations = 10000;
-
- return TRUE;
- }
-
- if (_stricmp(ptr, "MaxAge") == 0)
- {
- ExpireTime = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "GPSPort") == 0)
- {
- if (strcmp(p_value, "0") != 0)
- strcpy(GPSPort, p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "GPSSpeed") == 0)
- {
- GPSSpeed = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "GPSRelay") == 0)
- {
- if (strlen(p_value) > 79)
- return FALSE;
-
- strcpy(GPSRelay, p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "BlueNMEA") == 0 || _stricmp(ptr, "TCPHost") == 0 || _stricmp(ptr, "AISHost") == 0)
- {
- if (strlen(p_value) > 70)
- return FALSE;
-
- strcpy(HostName, p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "TCPPort") == 0 || _stricmp(ptr, "AISPort") == 0)
- {
- HostPort = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "GPSDHost") == 0)
- {
- if (strlen(p_value) > 70)
- return FALSE;
-
- strcpy(GPSDHost, p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "GPSDPort") == 0)
- {
- GPSDPort = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "ADSBHost") == 0)
- {
- if (strlen(p_value) > 70)
- return FALSE;
-
- strcpy(ADSBHost, p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "ADSBPort") == 0)
- {
- ADSBPort = atoi(p_value);
- return TRUE;
- }
-
-
-
- if (_stricmp(ptr, "GPSSetsLocator") == 0)
- {
- GPSSetsLocator = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "LAT") == 0)
- {
- if (strlen(p_value) != 8)
- return FALSE;
-
- memcpy(LAT, _strupr(p_value), 8);
- PosnSet = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "LON") == 0)
- {
- if (strlen(p_value) != 9)
- return FALSE;
-
- memcpy(LON, _strupr(p_value), 9);
- PosnSet = TRUE;
- return TRUE;
- }
-
- if (_stricmp(ptr, "SYMBOL") == 0)
- {
- if (p_value[0] > ' ' && p_value[0] < 0x7f)
- CFGSYMBOL = p_value[0];
-
- return TRUE;
- }
-
- if (_stricmp(ptr, "SYMSET") == 0)
- {
- CFGSYMSET = p_value[0];
- return TRUE;
- }
-
- if (_stricmp(ptr, "PHG") == 0)
- {
- PHG = _strdup(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "MaxTraceHops") == 0)
- {
- MaxTraceHops = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "MaxFloodHops") == 0)
- {
- MaxFloodHops = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "ISHOST") == 0)
- {
- strncpy(ISHost, p_value, 250);
- return TRUE;
- }
-
- if (_stricmp(ptr, "ISPORT") == 0)
- {
- ISPort = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "ISPASSCODE") == 0)
- {
- ISPasscode = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "MaxDigisforIS") == 0)
- {
- MaxDigisforIS = atoi(p_value);
- return TRUE;
- }
-
- if (_stricmp(ptr, "GateLocalDistance") == 0)
- {
- GateLocalDistance = atoi(p_value);
- if (GateLocalDistance > 0.0)
- GateLocal = TRUE;
-
- return TRUE;
- }
-
- if (_stricmp(ptr, "WXInterval") == 0)
- {
- WXInterval = atoi(p_value);
- WXCounter = (WXInterval - 1) * 60;
- return TRUE;
- }
-
- if (_stricmp(ptr, "WXPortList") == 0)
- {
- char ParamCopy[80];
- char * Context;
- int Port;
- char * ptr;
- int index = 0;
-
- for (index = 0; index < MaxBPQPortNo; index++)
- WXPort[index] = FALSE;
-
- if (strlen(p_value) > 79)
- p_value[80] = 0;
-
- strcpy(ParamCopy, p_value);
-
- ptr = strtok_s(ParamCopy, " ,\t\n\r", &Context);
-
- while (ptr)
- {
- Port = atoi(ptr); // this gives zero for IS
-
- WXPort[Port] = TRUE;
-
- ptr = strtok_s(NULL, " ,\t\n\r", &Context);
- }
- return TRUE;
- }
-
- if (_stricmp(ptr, "Run") == 0)
- {
- strcpy(RunProgram, p_value);
- return TRUE;
- }
-
- //
- // Bad line
- //
- return (FALSE);
-}
-
-VOID SendAPRSMessageEx(char * Message, int toPort, char * FromCall, int Gated);
-
-
-VOID SendAPRSMessage(char * Message, int toPort)
-{
- SendAPRSMessageEx(Message, toPort, APRSCall, 0);
-}
-
-// Ex allows setting source call (For WX Messages)
-
-
-VOID SendAPRSMessageEx(char * Message, int toPort, char * FromCall, int Gated)
-{
- int Port;
- DIGIMESSAGE Msg;
-
- int Len;
-
- // toPort = -1 means all tadio ports. 0 = IS
-
- if (toPort == -1)
- {
- for (Port = 1; Port <= MaxBPQPortNo; Port++)
- {
- if (Gated && GatedHddrLen[Port])
- memcpy(Msg.DEST, &GatedHeader[Port][0][0], 10 * 7);
- else if (BeaconHddrLen[Port]) // Only send to ports with a DEST defined
- memcpy(Msg.DEST, &BeaconHeader[Port][0][0], 10 * 7);
- else
- continue;
-
- Msg.DEST[6] |= 0x80; // set Command Bit
-
- ConvToAX25(FromCall, Msg.ORIGIN);
- Msg.PID = 0xf0;
- Msg.CTL = 3;
- Len = sprintf(Msg.L2DATA, "%s", Message);
- Send_AX_Datagram(&Msg, Len + 2, Port);
- }
-
- return;
- }
-
- if (toPort == 0 && APRSISOpen)
- {
- char ISMsg[300];
-
- Len = sprintf(ISMsg, "%s>%s,TCPIP*:%s\r\n", FromCall, APRSDest, Message);
- ISSend(sock, ISMsg, Len, 0);
- }
-
- if (toPort == 0)
- return;
-
- if (Gated && GatedHddrLen[toPort])
- memcpy(Msg.DEST, &GatedHeader[toPort][0][0], 10 * 7);
- else if (BeaconHddrLen[toPort]) // Only send to ports with a DEST defined
- memcpy(Msg.DEST, &BeaconHeader[toPort][0][0], 10 * 7);
- else
- return;
-
- Msg.DEST[6] |= 0x80; // set Command Bit
-
- ConvToAX25(FromCall, Msg.ORIGIN);
- Msg.PID = 0xf0;
- Msg.CTL = 3;
- Len = sprintf(Msg.L2DATA, "%s", Message);
- Send_AX_Datagram(&Msg, Len + 2, toPort);
-
- return;
-}
-
-
-VOID ProcessSpecificQuery(char * Query, int Port, char * Origin, char * DestPlusDigis)
-{
- if (_memicmp(Query, "APRSS", 5) == 0)
- {
- char Message[255];
-
- sprintf(Message, ":%-9s:%s", Origin, StatusMsg);
- SendAPRSMessage(Message, Port);
-
- return;
- }
-
- if (_memicmp(Query, "APRST", 5) == 0 || _memicmp(Query, "PING?", 5) == 0)
- {
- // Trace Route
- //:KH2ZV :?APRST :N8UR :KH2Z>APRS,DIGI1,WIDE*:
- //:G8BPQ-14 :Path - G8BPQ-14>APU25N
-
- char Message[255];
-
- sprintf(Message, ":%-9s:Path - %s>%s", Origin, Origin, DestPlusDigis);
- SendAPRSMessage(Message, Port);
-
- return;
- }
-}
-
-VOID ProcessQuery(char * Query)
-{
- if (memcmp(Query, "IGATE?", 6) == 0)
- {
- IStatusCounter = (rand() & 31) + 5; // 5 - 36 secs delay
- return;
- }
-
- if (memcmp(Query, "APRS?", 5) == 0)
- {
- BeaconCounter = (rand() & 31) + 5; // 5 - 36 secs delay
- return;
- }
-}
-Dll VOID APIENTRY APISendBeacon()
-{
- BeaconCounter = 2;
-}
-
-typedef struct _BeaconParams
-{
- int toPort;
- char * BeaconText;
- BOOL SendStatus;
- BOOL SendSOGCOG;
-} Params;
-
-
-Params BeaconParams;
-
-void SendBeaconThread(void * Params);
-
-VOID SendBeacon(int toPort, char * BeaconText, BOOL SendStatus, BOOL SendSOGCOG)
-{
- // Send to IS if needed then start a thread to send to radio ports
-
- if (PosnSet == FALSE)
- return;
-
- if (APRSISOpen && toPort == 0 && BeacontoIS)
- {
- char SOGCOG[10] = "";
- char ISMsg[300];
- int Len;
-
- Debugprintf("Sending APRS Beacon to APRS-IS");
-
- if (SendSOGCOG | (COG != 0.0))
- sprintf(SOGCOG, "%03.0f/%03.0f", COG, SOG);
-
- if (PHG) // Send PHG instead of SOG COG
- Len = sprintf(ISMsg, "%s>%s,TCPIP*:%c%s%c%s%c%s%s\r\n", APRSCall, APRSDest,
- (APRSApplConnected) ? '=' : '!', LAT, SYMSET, LON, SYMBOL, PHG, BeaconText);
- else
- Len = sprintf(ISMsg, "%s>%s,TCPIP*:%c%s%c%s%c%s%s\r\n", APRSCall, APRSDest,
- (APRSApplConnected) ? '=' : '!', LAT, SYMSET, LON, SYMBOL, SOGCOG, BeaconText);
-
- ISSend(sock, ISMsg, Len, 0);
- Debugprintf(">%s", ISMsg);
- }
-
- BeaconParams.toPort = toPort;
- BeaconParams.BeaconText = BeaconText;
- BeaconParams.SendStatus = SendStatus;
- BeaconParams.SendSOGCOG = SendSOGCOG;
-
- _beginthread(SendBeaconThread, 0, (VOID *) &BeaconParams);
-}
-
-void SendBeaconThread(void * Param)
-{
- // runs as a thread so we can sleep() between calls
-
- // Params are passed via a param block
-
- Params * BeaconParams = (Params *)Param;
-
- int toPort = BeaconParams->toPort;
- char * BeaconText = BeaconParams->BeaconText;
- BOOL SendStatus = BeaconParams->SendStatus;
- BOOL SendSOGCOG = BeaconParams->SendSOGCOG;
-
- int Port;
- DIGIMESSAGE Msg;
- int Len;
- char SOGCOG[256] = "";
- struct STATIONRECORD * Station;
- struct PORTCONTROL * PORT;
-
- if (PosnSet == FALSE)
- return;
-
- if (PHG) // Send PHG instead of SOG COG
- strcpy(SOGCOG, PHG);
- else
- if (SendSOGCOG | (COG != 0.0))
- sprintf(SOGCOG, "%03.0f/%03.0f", COG, SOG);
-
- BeaconCounter = BeaconInterval * 60;
-
- if (ISPort && IGateEnabled)
- Len = sprintf(Msg.L2DATA, "%c%s%c%s%c%s%s", (APRSApplConnected) ? '=' : '!',
- LAT, SYMSET, LON, SYMBOL, SOGCOG, BeaconText);
- else
- Len = sprintf(Msg.L2DATA, "%c%s%c%s%c%s%s", (APRSApplConnected) ? '=' : '!',
- LAT, SYMSET, LON, SYMBOL, SOGCOG, BeaconText);
-
- Msg.PID = 0xf0;
- Msg.CTL = 3;
-
- // Add to dup check list, so we won't digi it if we hear it back
- // Should we drop it if we've sent it recently ??
-
- if (CheckforDups(APRSCall, Msg.L2DATA, Len - (19 + sizeof(void *))))
- return;
-
- // Add to our station list
-
- Station = FindStation(APRSCall, TRUE);
-
- if (Station == NULL)
- return;
-
-
- strcpy(Station->Path, "APBPQ1");
- strcpy(Station->LastPacket, Msg.L2DATA);
-// Station->LastPort = Port;
-
- DecodeAPRSPayload(Msg.L2DATA, Station);
- Station->TimeLastUpdated = time(NULL);
-
- if (toPort)
- {
- if (BeaconHddrLen[toPort] == 0)
- return;
-
- Debugprintf("Sending APRS Beacon to port %d", toPort);
-
- memcpy(Msg.DEST, &BeaconHeader[toPort][0][0], 10 * 7); // Clear unused digis
- Msg.DEST[6] |= 0x80; // set Command Bit
-
- GetSemaphore(&Semaphore, 12);
- Send_AX_Datagram(&Msg, Len + 2, toPort);
- FreeSemaphore(&Semaphore);
-
- return;
- }
-
- for (Port = 1; Port <= MaxBPQPortNo; Port++) // Check all ports
- {
- if (BeaconHddrLen[Port]) // Only send to ports with a DEST defined
- {
- Debugprintf("Sending APRS Beacon to port %d", Port);
-
- if (ISPort && IGateEnabled)
- Len = sprintf(Msg.L2DATA, "%c%s%c%s%c%s%s", (APRSApplConnected) ? '=' : '!',
- LAT, SYMSET, LON, SYMBOL, SOGCOG, BeaconText);
- else
- Len = sprintf(Msg.L2DATA, "%c%s%c%s%c%s%s", (APRSApplConnected) ? '=' : '!',
- LAT, SYMSET, LON, SYMBOL, SOGCOG, BeaconText);
- Msg.PID = 0xf0;
- Msg.CTL = 3;
-
- memcpy(Msg.DEST, &BeaconHeader[Port][0][0], 10 * 7);
- Msg.DEST[6] |= 0x80; // set Command Bit
-
- GetSemaphore(&Semaphore, 12);
- Send_AX_Datagram(&Msg, Len + 2, Port);
- FreeSemaphore(&Semaphore);
-
- // if Port has interlock set pause before next
-
- PORT = GetPortTableEntryFromPortNum(Port);
-
- // Just pause for all ports
-
-// if (PORT && PORT->PORTINTERLOCK)
- Sleep(20000);
- }
- }
- return ;
-}
-
-VOID SendObject(struct OBJECT * Object)
-{
- int Port;
- DIGIMESSAGE Msg;
- int Len;
-
- // Add to dup list in case we get it back
-
- CheckforDups(APRSCall, Object->Message, (int)strlen(Object->Message));
-
- for (Port = 1; Port <= MaxBPQPortNo; Port++)
- {
- if (Object->PortMap[Port])
- {
- Msg.PID = 0xf0;
- Msg.CTL = 3;
- Len = sprintf(Msg.L2DATA, "%s", Object->Message);
- memcpy(Msg.DEST, &Object->Path[0][0], Object->PathLen + 1);
- Msg.DEST[6] |= 0x80; // set Command Bit
-
- Send_AX_Datagram(&Msg, Len + 2, Port);
- }
- }
-
- // Also send to APRS-IS if connected
-
- if (APRSISOpen && Object->PortMap[0])
- {
- char ISMsg[300];
- Len = sprintf(ISMsg, "%s>%s,TCPIP*:%s\r\n", APRSCall, APRSDest, Object->Message);
- ISSend(sock, ISMsg, Len, 0);
- }
-}
-
-
-/*
-VOID SendStatus(char * StatusText)
-{
- int Port;
- DIGIMESSAGE Msg;
- int Len;
-
- if (APRSISOpen)
- {
- Msg.PID = 0xf0;
- Msg.CTL = 3;
-
- Len = sprintf(Msg.L2DATA, ">%s", StatusText);
-
- for (Port = 1; Port <= NUMBEROFPORTS; Port++)
- {
- if (BeaconHddrLen[Port]) // Only send to ports with a DEST defined
- {
- memcpy(Msg.DEST, &BeaconHeader[Port][0][0], 10 * 7);
- Send_AX_Datagram(&Msg, Len + 2, Port);
- }
- }
-
- Len = sprintf(Msg.L2DATA, "%s>%s,TCPIP*:>%s\r\n", APRSCall, APRSDest, StatusText);
- ISSend(sock, Msg.L2DATA, Len, 0);
-// Debugprintf(">%s", Msg.L2DATA);
- }
-}
-
-
-*/
-VOID SendIStatus()
-{
- int Port;
- DIGIMESSAGE Msg;
- int Len;
-
- IStatusCounter = 3600; // One per hour
-
- if (APRSISOpen && BeacontoIS && RXOnly == 0)
- {
- Msg.PID = 0xf0;
- Msg.CTL = 3;
-
- Len = sprintf(Msg.L2DATA, "%s,TCPIP*:%s", Msg.L2DATA);
- }
-
-}
-
-
-VOID DoSecTimer()
-{
- struct OBJECT * Object = ObjectList;
-
- while (Object)
- {
- Object->Timer--;
-
- if (Object->Timer == 0)
- {
- Object->Timer = 60 * Object->Interval;
- SendObject(Object);
- }
- Object = Object->Next;
- }
-
- // Check SatGate Mode delay Q
-
- if (SatISQueue)
- {
- time_t NOW = time(NULL);
- ISDELAY * SatISEntry = SatISQueue;
- ISDELAY * Prev = NULL;
-
- while (SatISEntry)
- {
- if (SatISEntry->SendTIme < NOW)
- {
- // Send it
-
- ISSend(sock, SatISEntry->ISMSG, (int)strlen(SatISEntry->ISMSG), 0);
- free(SatISEntry->ISMSG);
-
- if (Prev)
- Prev->Next = SatISEntry->Next;
- else
- SatISQueue = SatISEntry->Next;
-
- free(SatISEntry);
- return; // unlinkely to get 2 in sam esecond and doesn;t matter if we delay a bit more
- }
-
- Prev = SatISEntry;
- SatISEntry = SatISEntry->Next;
- }
- }
-
- if (ISPort && APRSISOpen == 0 && IGateEnabled)
- {
- ISDelayTimer++;
-
- if (ISDelayTimer > 60)
- {
- ISDelayTimer = 0;
- _beginthread(APRSISThread, 0, (VOID *) TRUE);
- }
- }
-
- if (HostName[0])
- {
- if (BlueNMEAOK == 0)
- {
- BlueNMEATimer++;
- if (BlueNMEATimer > 15)
- {
- BlueNMEATimer = 0;
- _beginthread(TCPConnect, 0, 0);
- }
- }
- }
-
- if (GPSDHost[0])
- {
- if (GPSDOK == 0)
- {
- GPSDTimer++;
- if (GPSDTimer > 15)
- {
- GPSDTimer = 0;
- _beginthread(GPSDConnect, 0, 0);
- }
- }
- }
-
- if (BeaconCounter)
- {
- BeaconCounter--;
-
- if (BeaconCounter == 0)
- {
- BeaconCounter = BeaconInterval * 60;
- SendBeacon(0, StatusMsg, TRUE, FALSE);
- }
- }
-
- if (IStatusCounter)
- {
- IStatusCounter--;
-
- if (IStatusCounter == 0)
- {
- SendIStatus();
- }
- }
-
- if (GPSOK)
- {
- GPSOK--;
-
- if (GPSOK == 0)
-#ifdef LINBPQ
- Debugprintf("GPS Lost");
-#else
- SetDlgItemText(hConsWnd, IDC_GPS, "No GPS");
-#endif
- }
-
- APRSSecTimer(); // Code from APRS APPL
-}
-
-int CountPool()
-{
- struct STATIONRECORD * ptr = StationRecordPool;
- int n = 0;
-
- while (ptr)
- {
- n++;
- ptr = ptr->Next;
- }
- return n;
-}
-
-static VOID DoMinTimer()
-{
- struct STATIONRECORD * ptr = *StationRecords;
- struct STATIONRECORD * last = NULL;
- time_t AgeLimit = time(NULL ) - (ExpireTime * 60);
- int i = 0;
-
- // Remove old records
-
- while (ptr)
- {
- if (ptr->TimeLastUpdated < AgeLimit)
- {
- StationCount--;
-
- if (last)
- {
- last->Next = ptr->Next;
-
- // Put on front of free chain
-
- ptr->Next = StationRecordPool;
- StationRecordPool = ptr;
-
- ptr = last->Next;
- }
- else
- {
- // First in list
-
- *StationRecords = ptr->Next;
-
- // Put on front of free chain
-
- ptr->Next = StationRecordPool;
- StationRecordPool = ptr;
-
- if (*StationRecords)
- {
- ptr = *StationRecords;
- }
- else
- {
- ptr = NULL;
- }
- }
- }
- else
- {
- last = ptr;
- ptr = ptr->Next;
- }
- }
-}
-
-char APRSMsg[300];
-
-int ISHostIndex = 0;
-char RealISHost[256];
-
-VOID APRSISThread(void * Report)
-{
- // Receive from core server
-
- char Signon[500];
- unsigned char work[4];
-
- struct sockaddr_in sinx;
- int addrlen=sizeof(sinx);
- struct addrinfo hints, *res = 0, *saveres;
- size_t len;
- int err;
- u_long param=1;
- BOOL bcopt=TRUE;
- char Buffer[1000];
- int InputLen = 1; // Non-zero
- char errmsg[100];
- char * ptr;
- size_t inptr = 0;
- char APRSinMsg[1000];
- char PortString[20];
- char serv[256];
-
- Debugprintf("BPQ32 APRS IS Thread");
-#ifndef LINBPQ
- SetDlgItemText(hConsWnd, IGATESTATE, "IGate State: Connecting");
-#endif
-
- if (ISFilter[0])
- sprintf(Signon, "user %s pass %d vers BPQ32 %s filter %s\r\n",
- APRSCall, ISPasscode, TextVerstring, ISFilter);
- else
- sprintf(Signon, "user %s pass %d vers BPQ32 %s\r\n",
- APRSCall, ISPasscode, TextVerstring);
-
-
- sprintf(PortString, "%d", ISPort);
-
- // get host info, make socket, and connect it
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
- hints.ai_socktype = SOCK_STREAM;
- getaddrinfo(ISHost, PortString, &hints, &res);
-
- InputLen = sprintf(errmsg, "Connecting to APRS Host %s\r\n", ISHost);
- MonitorAPRSIS(errmsg, InputLen, FALSE);
-
- if (!res)
- {
- err = WSAGetLastError();
- InputLen = sprintf(errmsg, "APRS IS Resolve %s Failed Error %d\r\n", ISHost, err);
- MonitorAPRSIS(errmsg, InputLen, FALSE);
-
- return; // Resolve failed
-
- }
-
- // Step thorough the list of hosts
-
- saveres = res; // Save for free
-
- if (res->ai_next) // More than one
- {
- int n = ISHostIndex;
-
- while (n && res->ai_next)
- {
- res = res->ai_next;
- n--;
- }
-
- if (n)
- {
- // We have run off the end of the list
-
- ISHostIndex = 0; // Back to start
- res = saveres;
- }
- else
- ISHostIndex++;
-
- }
-
- getnameinfo(res->ai_addr, (int)res->ai_addrlen, RealISHost, 256, serv, 256, 0);
-
- sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-
- if (sock == INVALID_SOCKET)
- return;
-
- setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4);
-
- memcpy(work, res->ai_addr->sa_data, 4);
-
- Debugprintf("Trying APRSIS Host %d.%d.%d.%d (%d) %s", work[0], work[1], work[2], work[3], ISHostIndex, RealISHost);
-
- if (connect(sock, res->ai_addr, (int)res->ai_addrlen))
- {
- err=WSAGetLastError();
-
- //
- // Connect failed
- //
-
-#ifndef LINBPQ
- MySetWindowText(GetDlgItem(hConsWnd, IGATESTATE), "IGate State: Connect Failed");
-#else
- printf("APRS Igate connect failed\n");
-#endif
- err=WSAGetLastError();
- InputLen = sprintf(errmsg, "Connect Failed %s af %d Error %d \r\n", RealISHost, res->ai_family, err);
- MonitorAPRSIS(errmsg, InputLen, FALSE);
-
- freeaddrinfo(res);
- return;
- }
-
- freeaddrinfo(saveres);
-
- APRSISOpen = TRUE;
-
-#ifndef LINBPQ
- MySetWindowText(GetDlgItem(hConsWnd, IGATESTATE), "IGate State: Connected");
-#endif
-
- InputLen=recv(sock, Buffer, 500, 0);
-
- if (InputLen > 0)
- {
- Buffer[InputLen] = 0;
- Debugprintf(Buffer);
- MonitorAPRSIS(Buffer, InputLen, FALSE);
- }
-
- ISSend(sock, Signon, (int)strlen(Signon), 0);
-/*
- InputLen=recv(sock, Buffer, 500, 0);
-
- if (InputLen > 0)
- {
- Buffer[InputLen] = 0;
- Debugprintf(Buffer);
- MonitorAPRSIS(Buffer, InputLen, FALSE);
- }
-
- InputLen=recv(sock, Buffer, 500, 0);
-
- if (InputLen > 0)
- {
- Buffer[InputLen] = 0;
- Debugprintf(Buffer);
- MonitorAPRSIS(Buffer, InputLen, FALSE);
- }
-*/
- while (InputLen > 0 && IGateEnabled)
- {
- InputLen = recv(sock, &APRSinMsg[inptr], (int)(500 - inptr), 0);
-
- if (InputLen > 0)
- {
- inptr += InputLen;
-
- ptr = memchr(APRSinMsg, 0x0a, inptr);
-
- while (ptr != NULL)
- {
- ptr++; // include lf
- len = ptr-(char *)APRSinMsg;
-
- inptr -= len; // bytes left
-
- // UIView server has a null before crlf
-
- if (*(ptr - 3) == 0)
- {
- *(ptr - 3) = 13;
- *(ptr - 2) = 10;
- *(ptr - 1) = 0;
-
- len --;
- }
-
- if (len > 10 && len < 300) // Ignore if way too long or too short
- {
- memcpy(&APRSMsg, APRSinMsg, len);
- MonitorAPRSIS(APRSMsg, (int)len, FALSE);
- if (APRSMsg[len - 2] == 13)
- APRSMsg[len - 2] = 0;
- else
- APRSMsg[len - 1] = 0;
-
-// Debugprintf("%s", APRSMsg);
-
- ProcessAPRSISMsg(APRSMsg);
- }
-
- if (inptr > 0)
- {
- memmove(APRSinMsg, ptr, inptr);
- ptr = memchr(APRSinMsg, 0x0a, inptr);
- }
- else
- ptr = 0;
-
- if (inptr < 0)
- break;
- }
- }
- }
-
- closesocket(sock);
-
- APRSISOpen = FALSE;
-
- Debugprintf("BPQ32 APRS IS Thread Exited");
-
-#ifndef LINBPQ
- if (IGateEnabled)
- SetDlgItemText(hConsWnd, IGATESTATE, "IGate State: Disconnected");
- else
- SetDlgItemText(hConsWnd, IGATESTATE, "IGate State: Disabled");
-#endif
- ISDelayTimer = 30; // Retry pretty quickly
- return;
-}
-
-VOID ProcessAPRSISMsg(char * APRSMsg)
-{
- char * Payload;
- char * Source;
- char * Dest;
- char IGateCall[10] = " ";
- char * ptr;
- char Message[255];
- PAPRSHEARDRECORD MH;
- time_t NOW = time(NULL);
- char ISCopy[1024];
- struct STATIONRECORD * Station = NULL;
-#ifdef WIN32
- struct _EXCEPTION_POINTERS exinfo;
- char EXCEPTMSG[80] = "";
-#endif
-
- if (APRSMsg[0] == '#') // Comment
- return;
-
- // if APRS Appl is atttached, queue message to it
-
- strcpy(ISCopy, APRSMsg);
-
- GetSemaphore(&Semaphore, 12);
-
-#ifdef WIN32
-
- strcpy(EXCEPTMSG, "ProcessAPRSISMsg");
-
- __try
- {
-
- Station = DecodeAPRSISMsg(ISCopy);
-
- }
- #include "StdExcept.c"
- Debugprintf(APRSMsg);
- }
-#else
- Station = DecodeAPRSISMsg(ISCopy);
-#endif
-
- FreeSemaphore(&Semaphore);
-
-//}WB4APR-14>APRS,RELAY,TCPIP,G9RXG*::G3NRWVVVV:Hi Ian{001
-//KE7XO-2>hg,TCPIP*,qAC,T2USASW::G8BPQ-14 :Path - G8BPQ-14>APU25N
-//IGATECALL>APRS,GATEPATH}FROMCALL>TOCALL,TCPIP,IGATECALL*:original packet data
-
- Payload = strchr(APRSMsg, ':');
-
- // Get call of originating Igate
-
- ptr = Payload;
-
- if (Payload == NULL)
- return;
-
- *(Payload++) = 0;
-
- while (ptr[0] != ',')
- ptr--;
-
- ptr++;
-
- if (strlen(ptr) > 9)
- return;
-
- memcpy(IGateCall, ptr, (int)strlen(ptr));
-
- if (strstr(APRSMsg, ",qAS,") == 0) // Findu generates invalid q construct
- {
- MH = FindStationInMH(IGateCall);
- if (MH)
- {
-// Debugprintf("Setting Igate Flag - %s:%s", APRSMsg, Payload);
- MH->IGate = TRUE; // If we have seen this station on RF, set it as an Igate
- }
- }
- Source = APRSMsg;
- Dest = strchr(APRSMsg, '>');
-
- if (Dest == NULL)
- return;
-
- *(Dest++) = 0; // Termainate Source
- ptr = strchr(Dest, ',');
-
- if (ptr)
- *ptr = 0;
-
- MH = UpdateHeard(Source, 0);
-
- MH->Station = Station;
-
- // See if we should gate to RF.
-
- // Have we heard dest recently? (use the message dest (not ax.25 dest) - does this mean we only gate Messages?
- // Not if it is an Igate (it will get a copy direct)
- // Have we recently sent a message from this call - if so, we gate the next Position
-
-/*
-
- From http://www.aprs-is.net/IGateDetails.aspx
-
- Gate message packets and associated posits to RF if all of the following are true:
-
- the receiving station has been heard within range within a predefined time period (range defined
- as digi hops, distance, or both).
-
- the sending station has not been heard via RF within a predefined time period (packets gated
- from the Internet by other stations are excluded from this test).
-
- the sending station does not have TCPXX, NOGATE, or RFONLY in the header.
-
- the receiving station has not been heard via the Internet within a predefined time period.
-
- A station is said to be heard via the Internet if packets from the station contain TCPIP* or
- TCPXX* in the header or if gated (3rd-party) packets are seen on RF gated by the station
- and containing TCPIP or TCPXX in the 3rd-party header (in other words, the station is seen on RF
- as being an IGate).
-
-*/
-
- if (Payload[0] == ':') // Message
- {
- char MsgDest[10];
- APRSHEARDRECORD * STN;
-
- if (strlen(Payload) > 100) // I don't think any valid APRS msgs are more than this
- return;
-
- memcpy(MsgDest, &Payload[1], 9);
- MsgDest[9] = 0;
-
- if (strcmp(MsgDest, CallPadded) == 0) // to us
- return;
-
- // Check that the sending station has not been heard via RF recently
-
- if (MH->rfPort && (NOW - MH->MHTIME) < GATETIMELIMIT)
- return;
-
- STN = FindStationInMH(MsgDest);
-
- // Shouldn't we check DUP list, in case we have digi'ed this message directly?
-
- if (CheckforDups(Source, Payload, (int)strlen(Payload)))
- return;
-
- // has the receiving station has been heard on RF and is not an IGate
-
- if (STN && STN->rfPort && !STN->IGate && (NOW - STN->MHTIME) < GATETIMELIMIT)
- {
- sprintf(Message, "}%s>%s,TCPIP,%s*:%s", Source, Dest, APRSCall, Payload);
-
- GetSemaphore(&Semaphore, 12);
- SendAPRSMessageEx(Message, STN->rfPort, APRSCall, 1); // Set gated to IS flag
- FreeSemaphore(&Semaphore);
-
- MessageCount++;
- MH->LASTMSG = NOW;
-
- return;
- }
- }
-
- // Not a message. If it is a position report gate if have sent a message recently
-
- if (Payload[0] == '!' || Payload[0] == '/' || Payload[0] == '=' || Payload[0] == '@') // Posn Reports
- {
- if ((NOW - MH->LASTMSG) < 900 && MH->rfPort)
- {
- sprintf(Message, "}%s>%s,TCPIP,%s*:%s", Source, Dest, APRSCall, Payload);
-
- GetSemaphore(&Semaphore, 12);
- SendAPRSMessageEx(Message, MH->rfPort, APRSCall, 1); // Set gated to IS flag
- FreeSemaphore(&Semaphore);
-
- return;
- }
- }
-
- // If Gate Local to RF is defined, and station is in range, Gate it
-
- if (GateLocal && Station)
- {
- if (Station->Object)
- Station = Station->Object; // If Object Report, base distance on Object, not station
-
- if (Station->Lat != 0.0 && Station->Lon != 0.0 && myDistance(Station->Lat, Station->Lon, 0) < GateLocalDistance)
- {
- sprintf(Message, "}%s>%s,TCPIP,%s*:%s", Source, Dest, APRSCall, Payload);
- GetSemaphore(&Semaphore, 12);
- SendAPRSMessage(Message, -1); // Send to all APRS Ports
- FreeSemaphore(&Semaphore);
-
- return;
- }
- }
-}
-
-APRSHEARDRECORD * FindStationInMH(char * Call)
-{
- APRSHEARDRECORD * MH = MHDATA;
- int i;
-
- // We keep call in ascii format, as that is what we get from APRS-IS, and we have it in that form
-
- for (i = 0; i < HEARDENTRIES; i++)
- {
- if (memcmp(Call, MH->MHCALL, 9) == 0)
- return MH;
-
- MH++;
- }
-
- return NULL;
-}
-
-APRSHEARDRECORD * UpdateHeard(UCHAR * Call, int Port)
-{
- APRSHEARDRECORD * MH = MHDATA;
- APRSHEARDRECORD * MHBASE = MH;
- int i;
- time_t NOW = time(NULL);
- time_t OLDEST = NOW - MAXAGE;
- char CallPadded[10] = " ";
- BOOL SaveIGate = FALSE;
- time_t SaveLastMsg = 0;
- int SaveheardViaIS = 0;
-
- // We keep call in ascii format, space padded, as that is what we get from APRS-IS, and we have it in that form
-
- // Make Sure Space Padded
-
- memcpy(CallPadded, Call, (int)strlen(Call));
-
- for (i = 0; i < MAXHEARDENTRIES; i++)
- {
- if (memcmp(CallPadded, MH->MHCALL, 10) == 0)
- {
- // if from APRS-IS, only update if record hasn't been heard via RF
-
- if (Port == 0)
- MH->heardViaIS = 1; // Flag heard via IS
-
- if (Port == 0 && MH->rfPort)
- return MH; // Don't update RF with IS
-
- if (Port == MH->rfPort)
- {
- SaveIGate = MH->IGate;
- SaveLastMsg = MH->LASTMSG;
- SaveheardViaIS = MH->heardViaIS;
- goto DoMove;
- }
- }
-
- if (MH->MHCALL[0] == 0 || MH->MHTIME < OLDEST) // Spare entry
- goto DoMove;
-
- MH++;
- }
-
- // TABLE FULL AND ENTRY NOT FOUND - MOVE DOWN ONE, AND ADD TO TOP
-
- i = MAXHEARDENTRIES - 1;
-
- // Move others down and add at front
-DoMove:
- if (i != 0) // First
- memmove(MHBASE + 1, MHBASE, i * sizeof(APRSHEARDRECORD));
-
- if (i >= HEARDENTRIES)
- {
- char Status[80];
-
- HEARDENTRIES = i + 1;
-
- sprintf(Status, "IGATE Stats: Msgs %d Local Stns %d", MessageCount , CountLocalStations());
-#ifndef LINBPQ
- SetDlgItemText(hConsWnd, IGATESTATS, Status);
-#endif
- }
-
- memcpy (MHBASE->MHCALL, CallPadded, 10);
- MHBASE->rfPort = Port;
- MHBASE->MHTIME = NOW;
- MHBASE->IGate = SaveIGate;
- MHBASE->LASTMSG = SaveLastMsg;
- MHBASE->heardViaIS = SaveheardViaIS;
-
- return MHBASE;
-}
-
-int CountLocalStations()
-{
- APRSHEARDRECORD * MH = MHDATA;
- int i, n = 0;
-
- for (i = 0; i < HEARDENTRIES; i++)
- {
- if (MH->rfPort) // DOn't count IS Stations
- n++;
-
- MH++;
- }
- return n;
-}
-
-
-BOOL CheckforDups(char * Call, char * Msg, int Len)
-{
- // Primitive duplicate suppression - see if same call and text reeived in last few seconds
-
- time_t Now = time(NULL);
- time_t DupCheck = Now - DUPSECONDS;
- int i, saveindex = -1;
- char * ptr1;
-
- if (Len < 1)
- return TRUE;
-
- for (i = 0; i < MAXDUPS; i++)
- {
- if (DupInfo[i].DupTime < DupCheck)
- {
- // too old - use first if we need to save it
-
- if (saveindex == -1)
- {
- saveindex = i;
- }
-
- if (DupInfo[i].DupTime == 0) // Off end of used area
- break;
-
- continue;
- }
-
- if ((Len == DupInfo[i].DupLen || (DupInfo[i].DupLen == 99 && Len > 99)) && memcmp(Call, DupInfo[i].DupUser, 7) == 0 && (memcmp(Msg, DupInfo[i].DupText, DupInfo[i].DupLen) == 0))
- {
- // Duplicate, so discard
-
- Msg[Len] = 0;
- ptr1 = strchr(Msg, 13);
- if (ptr1)
- *ptr1 = 0;
-
-// Debugprintf("Duplicate Message supressed %s", Msg);
- return TRUE; // Duplicate
- }
- }
-
- // Not in list
-
- if (saveindex == -1) // List is full
- saveindex = MAXDUPS - 1; // Stick on end
-
- DupInfo[saveindex].DupTime = Now;
- memcpy(DupInfo[saveindex].DupUser, Call, 7);
-
- if (Len > 99) Len = 99;
-
- DupInfo[saveindex].DupLen = Len;
- memcpy(DupInfo[saveindex].DupText, Msg, Len);
-
- return FALSE;
-}
-
-char * FormatAPRSMH(APRSHEARDRECORD * MH)
- {
- // Called from CMD.ASM
-
- struct tm * TM;
- static char MHLine[50];
- time_t szClock = MH->MHTIME;
-
- szClock = (time(NULL) - szClock);
- TM = gmtime(&szClock);
-
- sprintf(MHLine, "%-10s %d %.2d:%.2d:%.2d:%.2d %s\r",
- MH->MHCALL, MH->rfPort, TM->tm_yday, TM->tm_hour, TM->tm_min, TM->tm_sec, (MH->IGate) ? "IGATE" : "");
-
- return MHLine;
- }
-
-// GPS Handling Code
-
-void SelectSource(BOOL Recovering);
-void DecodeRMC(char * msg, size_t len);
-
-void PollGPSIn();
-
-
-UINT GPSType = 0xffff; // Source of Postion info - 1 = Phillips 2 = AIT1000. ffff = not posn message
-
-int RecoveryTimer; // Serial Port recovery
-
-double PI = 3.1415926535;
-double P2 = 3.1415926535 / 180;
-
-double Latitude, Longtitude, SOG, COG, LatIncrement, LongIncrement;
-double LastSOG = -1.0;
-
-BOOL Check0183CheckSum(char * msg, size_t len)
-{
- BOOL retcode=TRUE;
- char * ptr;
- UCHAR sum,xsum1,xsum2;
-
- sum=0;
- ptr=++msg; // Skip $
-
-loop:
-
- if (*(ptr)=='*') goto eom;
-
- sum ^=*(ptr++);
-
- len--;
-
- if (len > 0) goto loop;
-
- return TRUE; // No Checksum
-
-eom:
- _strupr(ptr);
-
- xsum1=*(++ptr);
- xsum1-=0x30;
- if (xsum1 > 9) xsum1-=7;
-
- xsum2=*(++ptr);
- xsum2-=0x30;
- if (xsum2 > 9) xsum2-=7;
-
- xsum1=xsum1<<4;
- xsum1+=xsum2;
-
- return (xsum1==sum);
-}
-
-BOOL OpenGPSPort()
-{
- struct PortInfo * portptr = &InPorts[0];
-
- // open COMM device
-
- if (strlen(GPSPort) < 4)
- {
- int port = atoi(GPSPort);
-#ifdef WIN32
- sprintf(GPSPort, "COM%d", port);
-#else
- sprintf(GPSPort, "com%d", port);
-#endif
- }
-
- portptr->hDevice = OpenCOMPort(GPSPort, GPSSpeed, TRUE, TRUE, FALSE, 0);
-
- if (portptr->hDevice == 0)
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-void PollGPSIn()
-{
- size_t len;
- char GPSMsg[2000] = "$GPRMC,061213.000,A,5151.5021,N,00056.8388,E,0.15,324.11,190414,,,A*6F";
- char * ptr;
- struct PortInfo * portptr;
-
- portptr = &InPorts[0];
-
- if (!portptr->hDevice)
- return;
-
- getgpsin:
-
-// Comm Error - probably lost USB Port. Try closing and reopening after a delay
-
-// if (RecoveryTimer == 0)
-// {
-// RecoveryTimer = 100; // 10 Secs
-// return;
-// }
-// }
-
- if (portptr->gpsinptr == 160)
- portptr->gpsinptr = 0;
-
- len = ReadCOMBlock(portptr->hDevice, &portptr->GPSinMsg[portptr->gpsinptr],
- 160 - portptr->gpsinptr);
-
- if (len > 0)
- {
- portptr->gpsinptr += (int)len;
-
- ptr = memchr(portptr->GPSinMsg, 0x0a, portptr->gpsinptr);
-
- while (ptr != NULL)
- {
- ptr++; // include lf
- len=ptr-(char *)&portptr->GPSinMsg;
- memcpy(&GPSMsg,portptr->GPSinMsg,len);
-
- GPSMsg[len] = 0;
-
- if (Check0183CheckSum(GPSMsg, len))
- if (memcmp(&GPSMsg[3], "RMC", 3) == 0)
- DecodeRMC(GPSMsg, len);
-
- portptr->gpsinptr -= (int)len; // bytes left
-
- if (portptr->gpsinptr > 0 && *ptr == 0)
- {
- *ptr++;
- portptr->gpsinptr--;
- }
-
- if (portptr->gpsinptr > 0)
- {
- memmove(portptr->GPSinMsg,ptr, portptr->gpsinptr);
- ptr = memchr(portptr->GPSinMsg, 0x0a, portptr->gpsinptr);
- }
- else
- ptr=0;
- }
-
- goto getgpsin;
- }
- return;
-}
-
-
-void ClosePorts()
-{
- if (InPorts[0].hDevice)
- {
- CloseCOMPort(InPorts[0].hDevice);
- InPorts[0].hDevice=0;
- }
-
- return;
-}
-
-void DecodeRMC(char * msg, size_t len)
-{
- char * ptr1;
- char * ptr2;
- char TimHH[3], TimMM[3], TimSS[3];
- char OurSog[5], OurCog[4];
- char LatDeg[3], LonDeg[4];
- char NewLat[10] = "", NewLon[10] = "";
- struct STATIONRECORD * Stn1;
-
- char Day[3];
-
- ptr1 = &msg[7];
-
- len-=7;
-
- ptr2=(char *)memchr(ptr1,',',15);
-
- if (ptr2 == 0) return; // Duff
-
- *(ptr2++)=0;
-
- memcpy(TimHH,ptr1,2);
- memcpy(TimMM,ptr1+2,2);
- memcpy(TimSS,ptr1+4,2);
- TimHH[2]=0;
- TimMM[2]=0;
- TimSS[2]=0;
-
- ptr1=ptr2;
-
- if (*(ptr1) != 'A') // ' Data Not Valid
- {
-#ifndef LINBPQ
- SetDlgItemText(hConsWnd, IDC_GPS, "No GPS Fix");
-#endif
- return;
- }
-
- ptr1+=2;
-
- ptr2=(char *)memchr(ptr1,',',15);
-
- if (ptr2 == 0) return; // Duff
-
- *(ptr2++)=0;
-
- memcpy(NewLat, ptr1, 7);
- memcpy(LatDeg, ptr1, 2);
- LatDeg[2]=0;
- Lat=atof(LatDeg) + (atof(ptr1+2)/60);
-
- if (*(ptr1+7) > '4') if (NewLat[6] < '9') NewLat[6]++;
-
- ptr1=ptr2;
-
- NewLat[7] = (*ptr1);
- if ((*ptr1) == 'S') Lat=-Lat;
-
- ptr1+=2;
-
- ptr2=(char *)memchr(ptr1,',',15);
-
- if (ptr2 == 0) return; // Duff
- *(ptr2++)=0;
-
- memcpy(NewLon, ptr1, 8);
-
- memcpy(LonDeg,ptr1,3);
- LonDeg[3]=0;
- Lon=atof(LonDeg) + (atof(ptr1+3)/60);
-
- if (*(ptr1+8) > '4') if (NewLon[7] < '9') NewLon[7]++;
-
- ptr1=ptr2;
-
- NewLon[8] = (*ptr1);
- if ((*ptr1) == 'W') Lon=-Lon;
-
- // Now have a valid posn, so stop sending Undefined LOC Sysbol
-
- SYMBOL = CFGSYMBOL;
- SYMSET = CFGSYMSET;
-
- PosnSet = TRUE;
-
- Stn1 = (struct STATIONRECORD *)StnRecordBase; // Pass to App
- Stn1->Lat = Lat;
- Stn1->Lon = Lon;
-
- if (GPSOK == 0)
- {
-#ifdef LINBPQ
- Debugprintf("GPS OK");
- printf("GPS OK\n");
-#else
- SetDlgItemText(hConsWnd, IDC_GPS, "GPS OK");
-#endif
- }
-
- GPSOK = 30;
-
- ptr1+=2;
-
- ptr2 = (char *)memchr(ptr1,',',30);
-
- if (ptr2 == 0) return; // Duff
-
- *(ptr2++)=0;
-
- memcpy(OurSog, ptr1, 4);
- OurSog[4] = 0;
-
- ptr1=ptr2;
-
- ptr2 = (char *)memchr(ptr1,',',15);
-
- if (ptr2 == 0) return; // Duff
-
- *(ptr2++)=0;
-
- memcpy(OurCog, ptr1, 3);
- OurCog[3] = 0;
-
- memcpy(Day,ptr2,2);
- Day[2]=0;
-
- SOG = atof(OurSog);
- COG = atof(OurCog);
-
- if (strcmp(NewLat, LAT) || strcmp(NewLon, LON))
- {
- if (MobileBeaconInterval)
- {
- time_t NOW = time(NULL);
-
- if ((NOW - LastMobileBeacon) > MobileBeaconInterval)
- {
- LastMobileBeacon = NOW;
- SendBeacon(0, StatusMsg, FALSE, TRUE);
- }
- }
- if (GPSSetsLocator)
- {
- ToLOC(Lat, Lon, LOC);
- sprintf(LOCATOR, "%f:%f", Lat, Lon);
- }
- }
-
- strcpy(LAT, NewLat);
- strcpy(LON, NewLon);
-}
-
-Dll VOID APIENTRY APRSConnect(char * Call, char * Filter)
-{
- // Request APRS Data from Switch (called by APRS Applications)
-
- APRSApplConnected = TRUE;
- APRSWeb = TRUE;
-
- strcpy(APPLFilter, Filter);
-
- if (APPLFilter[0])
- {
- // This is called in APPL context so must queue the message
-
- char Msg[2000];
- PMSGWITHLEN buffptr;
-
- sprintf(Msg, "filter %s", Filter);
-
- if (strlen(Msg) > 240)
- Msg[240] = 0;
-
-
- GetSemaphore(&Semaphore, 11);
-
- buffptr = GetBuff();
-
- if (buffptr)
- {
- buffptr->Len = 0;
- strcpy(&buffptr->Data[0], "SERVER");
- strcpy(&buffptr->Data[10], Msg);
- C_Q_ADD(&APPLTX_Q, buffptr);
- }
-
- buffptr = GetBuff();
-
- if (buffptr)
- {
- buffptr->Len = 0;
- strcpy(&buffptr->Data[0], "SERVER");
- strcpy(&buffptr->Data[10], "filter?");
- C_Q_ADD(&APPLTX_Q, buffptr);
- }
- FreeSemaphore(&Semaphore);
- }
- strcpy(Call, CallPadded);
-}
-
-Dll VOID APIENTRY APRSDisconnect()
-{
- // Stop requesting APRS Data from Switch (called by APRS Applications)
-
- char Msg[2000];
- PMSGWITHLEN buffptr;
-
- strcpy(ISFilter, NodeFilter);
- sprintf(Msg, "filter %s", NodeFilter);
-
- APRSApplConnected = FALSE;
- APRSWeb = FALSE;
-
- GetSemaphore(&Semaphore, 11);
-
- buffptr = GetBuff();
-
- if (buffptr)
- {
- buffptr->Len = 0;
- strcpy(&buffptr->Data[0], "SERVER");
- strcpy(&buffptr->Data[10], Msg);
- C_Q_ADD(&APPLTX_Q, buffptr);
- }
-
- buffptr = GetBuff();
-
- if (buffptr)
- {
- buffptr->Len = 0;
- strcpy(&buffptr->Data[0], "SERVER");
- strcpy(&buffptr->Data[10], "filter?");
- C_Q_ADD(&APPLTX_Q, buffptr);
- }
-
- while (APPL_Q)
- {
- buffptr = Q_REM(&APPL_Q);
- ReleaseBuffer(buffptr);
- }
-
- FreeSemaphore(&Semaphore);
-}
-
-
-Dll char * APIENTRY APRSGetStatusMsgPtr()
-{
- return StatusMsg;
-}
-
-
-
-Dll BOOL APIENTRY GetAPRSFrame(char * Frame, char * Call)
-{
- // Request APRS Data from Switch (called by APRS Applications)
-
- void ** buffptr;
-#ifdef bpq32
- struct _EXCEPTION_POINTERS exinfo;
-#endif
-
- GetSemaphore(&Semaphore, 10);
- {
- if (APPL_Q)
- {
- buffptr = Q_REM(&APPL_Q);
-
- memcpy(Call, (char *)&buffptr[2], 12);
- strcpy(Frame, (char *)&buffptr[5]);
-
- ReleaseBuffer(buffptr);
- FreeSemaphore(&Semaphore);
- return TRUE;
- }
- }
-
- FreeSemaphore(&Semaphore);
-
- return FALSE;
-}
-
-Dll BOOL APIENTRY PutAPRSFrame(char * Frame, int Len, int Port)
-{
- // Called from BPQAPRS App
- // Message has to be queued so it can be sent by Timer Process (IS sock is not valid in this context)
-
- PMSGWITHLEN buffptr;
-
- GetSemaphore(&Semaphore, 11);
-
- buffptr = GetBuff();
-
- if (buffptr)
- {
- buffptr->Len = ++Len; // Len doesn't include Null
- memcpy(&buffptr->Data[0], Frame, Len);
- C_Q_ADD(&APPLTX_Q, buffptr);
- }
-
-// buffptr-> = Port; // Pass to SendAPRSMessage();
-
- FreeSemaphore(&Semaphore);
-
- return TRUE;
-}
-
-Dll BOOL APIENTRY APISendAPRSMessage(char * Text, char * ToCall)
-{
- // Called from BPQAPRS App or BPQMail
- // Message has to be queued so it can be sent by Timer Process (IS sock is not valid in this context)
-
- PMSGWITHLEN buffptr;
-
- if (APRSActive == 0)
- return FALSE;
-
- GetSemaphore(&Semaphore, 11);
-
- buffptr = GetBuff();
-
- if (buffptr)
- {
- buffptr->Len = 0;
- memcpy(&buffptr->Data[0], ToCall, 9);
- buffptr->Data[9] = 0;
- strcpy(&buffptr->Data[10], Text);
- C_Q_ADD(&APPLTX_Q, buffptr);
- }
-
- FreeSemaphore(&Semaphore);
-
- return TRUE;
-}
-
-Dll BOOL APIENTRY GetAPRSLatLon(double * PLat, double * PLon)
-{
- *PLat = Lat;
- *PLon = Lon;
-
- return GPSOK;
-}
-
-Dll BOOL APIENTRY GetAPRSLatLonString(char * PLat, char * PLon)
-{
- strcpy(PLat, LAT);
- strcpy(PLon, LON);
-
- return GPSOK;
-}
-
-// Code to support getting GPS from Andriod Device running BlueNMEA
-
-
-#define SD_BOTH 0x02
-
-static VOID ProcessReceivedData(SOCKET TCPSock)
-{
- char UDPMsg[8192];
- char Buffer[65536];
-
- int len = recv(TCPSock, Buffer, 65500, 0);
-
- char * ptr;
- char * Lastptr;
-
- if (len <= 0)
- {
- closesocket(TCPSock);
- BlueNMEAOK = FALSE;
- return;
- }
-
- ptr = Lastptr = Buffer;
- Buffer[len] = 0;
-
- while (len > 0)
- {
- ptr = strchr(Lastptr, 10);
-
- if (ptr)
- {
- size_t Len = ptr - Lastptr -1;
-
- if (Len > 8100)
- return;
-
- memcpy(UDPMsg, Lastptr, Len);
- UDPMsg[Len++] = 13;
- UDPMsg[Len++] = 10;
- UDPMsg[Len] = 0;
-
- if (!Check0183CheckSum(UDPMsg, Len))
- {
- Debugprintf("Checksum Error %s", UDPMsg);
- }
- else
- {
- if (memcmp(&UDPMsg[3], "RMC", 3) == 0)
- DecodeRMC(UDPMsg, Len);
-
- else if (memcmp(UDPMsg, "!AIVDM", 6) == 0)
- ProcessAISMessage(UDPMsg, Len);
-
- }
- Lastptr = ptr + 1;
- len -= (int)Len;
- }
- else
- return;
- }
-}
-
-static VOID TCPConnect(void * unused)
-{
- int err, ret;
- u_long param=1;
- BOOL bcopt=TRUE;
- fd_set readfs;
- fd_set errorfs;
- struct timeval timeout;
- struct sockaddr_in destaddr;
- SOCKET TCPSock;
-
- if (HostName[0] == 0)
- return;
-
- destaddr.sin_addr.s_addr = inet_addr(HostName);
- destaddr.sin_family = AF_INET;
- destaddr.sin_port = htons(HostPort);
-
- if (destaddr.sin_addr.s_addr == INADDR_NONE)
- {
- // Resolve name to address
-
- struct hostent * HostEnt = gethostbyname(HostName);
-
- if (!HostEnt)
- return; // Resolve failed
-
- memcpy(&destaddr.sin_addr.s_addr,HostEnt->h_addr,4);
- }
-
- TCPSock = socket(AF_INET,SOCK_STREAM,0);
-
- if (TCPSock == INVALID_SOCKET)
- {
- return;
- }
-
- setsockopt (TCPSock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
-
- BlueNMEAOK = TRUE; // So we don't try to reconnect while waiting
-
- if (connect(TCPSock,(LPSOCKADDR) &destaddr, sizeof(destaddr)) == 0)
- {
- //
- // Connected successful
- //
-
- ioctl(TCPSock, FIONBIO, ¶m);
- }
- else
- {
- err=WSAGetLastError();
-#ifdef LINBPQ
- printf("Connect Failed for AIS socket - error code = %d\n", err);
-#else
- Debugprintf("Connect Failed for AIS socket - error code = %d", err);
-#endif
- closesocket(TCPSock);
- BlueNMEAOK = FALSE;
-
- return;
- }
-
- BlueNMEAOK = TRUE;
-
- while (TRUE)
- {
- FD_ZERO(&readfs);
- FD_ZERO(&errorfs);
-
- FD_SET(TCPSock,&readfs);
- FD_SET(TCPSock,&errorfs);
-
- timeout.tv_sec = 900;
- timeout.tv_usec = 0; // We should get messages more frequently that this
-
- ret = select((int)TCPSock + 1, &readfs, NULL, &errorfs, &timeout);
-
- if (ret == SOCKET_ERROR)
- {
- goto Lost;
- }
- if (ret > 0)
- {
- // See what happened
-
- if (FD_ISSET(TCPSock, &readfs))
- {
- ProcessReceivedData(TCPSock);
- }
-
- if (FD_ISSET(TCPSock, &errorfs))
- {
-Lost:
-#ifdef LINBPQ
- printf("AIS Connection lost\n");
-#endif
- closesocket(TCPSock);
- BlueNMEAOK = FALSE;;
- return;
- }
- }
- else
- {
- // 15 mins without data. Shouldn't happen
-
- shutdown(TCPSock, SD_BOTH);
- Sleep(100);
-
- closesocket(TCPSock);
- BlueNMEAOK = FALSE;
- return;
- }
- }
-}
-
-int GPSDAlerted = 0;
-
-static VOID GPSDConnect(void * unused)
-{
- int err, ret;
- u_long param=1;
- BOOL bcopt=TRUE;
- fd_set readfs;
- fd_set errorfs;
- struct timeval timeout;
- struct sockaddr_in destaddr;
- SOCKET TCPSock;
-
- if (GPSDHost[0] == 0)
- return;
-
- destaddr.sin_addr.s_addr = inet_addr(GPSDHost);
- destaddr.sin_family = AF_INET;
- destaddr.sin_port = htons(GPSDPort);
-
- TCPSock = socket(AF_INET,SOCK_STREAM,0);
-
- if (TCPSock == INVALID_SOCKET)
- {
- return;
- }
-
- setsockopt (TCPSock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
-
- GPSDOK = TRUE; // So we don't try to reconnect while waiting
-
- if (connect(TCPSock,(LPSOCKADDR) &destaddr, sizeof(destaddr)) == 0)
- {
- //
- // Connected successful
- //
-
-#ifdef LINBPQ
- printf("GPSD Connected\n");
-#else
- Debugprintf("GPSD Connected");
-#endif
- GPSDAlerted = 0;
- ioctl(TCPSock, FIONBIO, ¶m);
-
- // Request data
-
- send(TCPSock, "?WATCH={\"enable\":true,\"nmea\":true}\r\n", 36, 0);
- }
- else
- {
- err=WSAGetLastError();
- if (GPSDAlerted == 0)
-#ifdef LINBPQ
- printf("GPSD Connect Failed - error code = %d\n", err);
-#else
- Debugprintf("GPSD Connect Failed - error code = %d", err);
-#endif
- GPSDAlerted = 1;
- closesocket(TCPSock);
- GPSDOK = FALSE;
-
- return;
- }
-
- while (TRUE)
- {
- FD_ZERO(&readfs);
- FD_ZERO(&errorfs);
-
- FD_SET(TCPSock,&readfs);
- FD_SET(TCPSock,&errorfs);
-
- timeout.tv_sec = 900;
- timeout.tv_usec = 0; // We should get messages more frequently that this
-
- ret = select((int)TCPSock + 1, &readfs, NULL, &errorfs, &timeout);
-
- if (ret == SOCKET_ERROR)
- {
- goto Lost;
- }
- if (ret > 0)
- {
- // See what happened
-
- if (FD_ISSET(TCPSock, &readfs))
- {
- char Buffer[65536];
- int len = recv(TCPSock, Buffer, 65500, 0);
- char TCPMsg[8192];
-
- char * ptr;
- char * Lastptr;
-
- if (len == 0)
- {
- closesocket(TCPSock);
- GPSDOK = FALSE;;
- return;
- }
-
- if (len < 9000)
- {
- Buffer[len] = 0;
-
- ptr = Lastptr = Buffer;
- Buffer[len] = 0;
-
- while (len > 0)
- {
- ptr = strchr(Lastptr, 10);
-
- if (ptr)
- {
- size_t Len = ptr - Lastptr -1;
-
- if (Len > 8100)
- return;
-
- memcpy(TCPMsg, Lastptr, Len);
- TCPMsg[Len++] = 13;
- TCPMsg[Len++] = 10;
- TCPMsg[Len] = 0;
-
- if (!Check0183CheckSum(TCPMsg, Len))
- {
- Debugprintf("Checksum Error %s", TCPMsg);
- }
- else
- {
- if (memcmp(&TCPMsg[3], "RMC", 3) == 0)
- DecodeRMC(TCPMsg, Len);
- }
- Lastptr = ptr + 1;
- len -= (int)Len;
- }
- else
- return;
- }
- }
- }
-
- if (FD_ISSET(TCPSock, &errorfs))
- {
-Lost:
-#ifdef LINBPQ
- printf("GPSD Connection lost\n");
-#endif
- closesocket(TCPSock);
- GPSDOK = FALSE;;
- return;
- }
- }
- else
- {
- // 15 mins without data. Shouldn't happen
-
- shutdown(TCPSock, SD_BOTH);
- Sleep(100);
-
- closesocket(TCPSock);
- GPSDOK = FALSE;
- return;
- }
- }
-}
-
-
-
-
-
-// Code Moved from APRS Application
-
-//
-// APRS Mapping and Messaging App for BPQ32 Switch.
-//
-
-
-VOID APIENTRY APRSConnect(char * Call, char * Filter);
-VOID APIENTRY APRSDisconnect();
-BOOL APIENTRY GetAPRSFrame(char * Frame, char * Call);
-BOOL APIENTRY PutAPRSFrame(char * Frame, int Len, int Port);
-BOOL APIENTRY PutAPRSMessage(char * Frame, int Len);
-BOOL APIENTRY GetAPRSLatLon(double * PLat, double * PLon);
-BOOL APIENTRY GetAPRSLatLonString(char * PLat, char * PLon);
-VOID APIENTRY APISendBeacon();
-
-
-int NewLine(HWND hWnd);
-VOID ProcessBuff(HWND hWnd, MESSAGE * buff,int len,int stamp);
-int TogglePort(HWND hWnd, int Item, int mask);
-VOID SendFrame(UCHAR * buff, int txlen);
-int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len);
-int KissDecode(UCHAR * inbuff, int len);
-//void UpdateStation(char * Call, char * Path, char * Comment, double V_Lat, double V_Lon, double V_SOG, double V_COG, int iconRow, int iconCol);
-VOID FindStationsByPixel(int MouseX, int MouseY);
-void RefreshStation(struct STATIONRECORD * ptr);
-void RefreshStationList();
-void RefreshStationMap();
-BOOL DecodeLocationString(UCHAR * Payload, struct STATIONRECORD * Station);
-VOID Decode_MIC_E_Packet(char * Payload, struct STATIONRECORD * Station);
-BOOL GetLocPixels(double Lat, double Lon, int * X, int * Y);
-VOID APRSPoll();
-VOID OSMThread();
-VOID ResolveThread();
-VOID RefreshTile(char * FN, int Zoom, int x, int y);
-int ProcessMessage(char * Payload, struct STATIONRECORD * Station);
-VOID APRSSecTimer();
-double myBearing(double laa, double loa);
-
-BOOL CreatePipeThread();
-
-VOID SendWeatherBeacon();
-VOID DecodeWXPortList();
-
-
-VOID DecodeWXReport(struct APRSConnectionInfo * sockptr, char * WX)
-{
- UCHAR * ptr = strchr(WX, '_');
- char Type;
- int Val;
-
- if (ptr == 0)
- return;
-
- sockptr->WindDirn = atoi(++ptr);
- ptr += 4;
- sockptr->WindSpeed = atoi(ptr);
- ptr += 3;
-WXLoop:
-
- Type = *(ptr++);
-
- if (*ptr =='.') // Missing Value
- {
- while (*ptr == '.')
- ptr++;
-
- goto WXLoop;
- }
-
- Val = atoi(ptr);
-
- switch (Type)
- {
- case 'c': // = wind direction (in degrees).
-
- sockptr->WindDirn = Val;
- break;
-
- case 's': // = sustained one-minute wind speed (in mph).
-
- sockptr->WindSpeed = Val;
- break;
-
- case 'g': // = gust (peak wind speed in mph in the last 5 minutes).
-
- sockptr->WindGust = Val;
- break;
-
- case 't': // = temperature (in degrees Fahrenheit). Temperatures below zero are expressed as -01 to -99.
-
- sockptr->Temp = Val;
- break;
-
- case 'r': // = rainfall (in hundredths of an inch) in the last hour.
-
- sockptr->RainLastHour = Val;
- break;
-
- case 'p': // = rainfall (in hundredths of an inch) in the last 24 hours.
-
- sockptr->RainLastDay = Val;
- break;
-
- case 'P': // = rainfall (in hundredths of an inch) since midnight.
-
- sockptr->RainToday = Val;
- break;
-
- case 'h': // = humidity (in %. 00 = 100%).
-
- sockptr->Humidity = Val;
- break;
-
- case 'b': // = barometric pressure (in tenths of millibars/tenths of hPascal).
-
- sockptr->Pressure = Val;
- break;
-
- default:
-
- return;
- }
- while(isdigit(*ptr))
- {
- ptr++;
- }
-
- if (*ptr != ' ')
- goto WXLoop;
-}
-
-static char HeaderTemplate[] = "Accept: */*\r\nHost: %s\r\nConnection: close\r\nContent-Length: 0\r\nUser-Agent: BPQ32(G8BPQ)\r\n\r\n";
-//char Header[] = "Accept: */*\r\nHost: tile.openstreetmap.org\r\nConnection: close\r\nContent-Length: 0\r\nUser-Agent: BPQ32(G8BPQ)\r\n\r\n";
-
-char APRSMsg[300];
-
-Dll struct STATIONRECORD * APIENTRY APPLFindStation(char * Call, BOOL AddIfNotFount)
-{
- // Called from APRS Appl
-
- struct STATIONRECORD * Stn;
-
- GetSemaphore(&Semaphore, 12);
- Stn = FindStation(Call, AddIfNotFount) ;
- FreeSemaphore(&Semaphore);
-
- return Stn;
-}
-
-Dll struct APRSMESSAGE * APIENTRY APRSGetMessageBuffer()
-{
- struct APRSMESSAGE * ptr = MessageRecordPool;
-
- if (ptr == NULL)
- {
- // try getting oldest
-
- ptr = SMEM->Messages;
-
- if (ptr)
- {
- SMEM->Messages = ptr->Next;
- memset(ptr, 0, sizeof(struct APRSMESSAGE));
- }
- return ptr;
- }
-
- if (ptr)
- {
- MessageRecordPool = ptr->Next; // Unchain
- MessageCount++;
-
- ptr->Next = NULL;
-
- memset(ptr, 0, sizeof(struct APRSMESSAGE));
- }
-
- return ptr;
-}
-
-
-struct STATIONRECORD * FindStation(char * Call, BOOL AddIfNotFount)
-{
- int i = 0;
- struct STATIONRECORD * find;
- struct STATIONRECORD * ptr;
- struct STATIONRECORD * last = NULL;
- int sum = 0;
-
- if (APRSActive == 0 || StationRecords == 0)
- return FALSE;
-
- if (strlen(Call) > 9)
- {
- Debugprintf("APRS Call too long %s", Call);
- Call[9] = 0;
- }
-
- find = *StationRecords;
- while(find)
- {
- if (strlen(find->Callsign) > 9)
- {
- Debugprintf("APRS Call in Station List too long %s", find->Callsign);
- find->Callsign[9] = 0;
- }
-
- if (strcmp(find->Callsign, Call) == 0)
- return find;
-
- last = find;
- find = find->Next;
- i++;
- }
-
- // Not found - add on end
-
- if (AddIfNotFount)
- {
- // Get first from station record pool
-
- ptr = StationRecordPool;
-
- if (ptr)
- {
- StationRecordPool = ptr->Next; // Unchain
- StationCount++;
- }
- else
- {
- // Get First from Stations
-
- ptr = *StationRecords;
-
- if (ptr)
- *StationRecords = ptr->Next;
- }
-
- if (ptr == NULL)
- return NULL;
-
- memset(ptr, 0, sizeof(struct STATIONRECORD));
-
-// EnterCriticalSection(&Crit);
-
- if (*StationRecords == NULL)
- *StationRecords = ptr;
- else
- last->Next = ptr;
-
-// LeaveCriticalSection(&Crit);
-
- // Debugprintf("APRS Add Stn %s Station Count = %d", Call, StationCount);
-
- strcpy(ptr->Callsign, Call);
- ptr->TimeLastUpdated = ptr->TimeAdded = time(NULL);
- ptr->Index = i;
- ptr->NoTracks = DefaultNoTracks;
-
- for (i = 0; i < 9; i++)
- sum += Call[i];
-
- sum %= 20;
-
- ptr->TrackColour = sum;
- ptr->Moved = TRUE;
-
- return ptr;
- }
- else
- return NULL;
-}
-
-struct STATIONRECORD * ProcessRFFrame(char * Msg, int len, int * ourMessage)
-{
- char * Payload;
- char * Path = NULL;
- char * Comment = NULL;
- char * Callsign;
- char * ptr;
- int Port = 0;
-
- struct STATIONRECORD * Station = NULL;
-
- Msg[len - 1] = 0;
-
-// Debugprintf("RF Frame %s", Msg);
-
- Msg += 10; // Skip Timestamp
-
- Payload = strchr(Msg, ':'); // End of Address String
-
- if (Payload == NULL)
- {
- Debugprintf("Invalid Msg %s", Msg);
- return Station;
- }
-
- ptr = strstr(Msg, "Port=");
-
- if (ptr)
- Port = atoi(&ptr[5]);
-
- Payload++;
-
- if (*Payload != 0x0d)
- return Station;
-
- *Payload++ = 0;
-
- Callsign = Msg;
-
- Path = strchr(Msg, '>');
-
- if (Path == NULL)
- {
- Debugprintf("Invalid Header %s", Msg);
- return Station;
- }
-
- *Path++ = 0;
-
- ptr = strchr(Path, ' ');
-
- if (ptr)
- *ptr = 0;
-
- // Look up station - create a new one if not found
-
- if (strcmp(Callsign, "AIS") == 0)
- {
- if (needAIS)
- {
- Payload += 3;
- ProcessAISMessage(Payload, strlen(Payload));
- }
- else
- Debugprintf(Payload);
-
- return 0;
- }
-
- Station = FindStation(Callsign, TRUE);
-
- strcpy(Station->Path, Path);
- strcpy(Station->LastPacket, Payload);
- Station->LastPort = Port;
-
- *ourMessage = DecodeAPRSPayload(Payload, Station);
- Station->TimeLastUpdated = time(NULL);
-
- return Station;
-}
-
-
-/*
-2E0AYY>APU25N,TCPIP*,qAC,AHUBSWE2:=5105.18N/00108.19E-Paul in Folkestone Kent {UIV32N}
-G0AVP-12>APT310,MB7UC*,WIDE3-2,qAR,G3PWJ:!5047.19N\00108.45Wk074/000/Paul mobile
-G0CJM-12>CQ,TCPIP*,qAC,AHUBSWE2:=/3&Rio94sg
-M0HFC>APRS,WIDE2-1,qAR,G0MNI:!5342.83N/00013.79W# Humber Fortress ARC Look us up on QRZ
-G8WVW-3>APTT4,WIDE1-1,WIDE2-1,qAS,G8WVW:T#063,123,036,000,000,000,00000000
-*/
-
-
-struct STATIONRECORD * DecodeAPRSISMsg(char * Msg)
-{
- char * Payload;
- char * Path = NULL;
- char * Comment = NULL;
- char * Callsign;
- struct STATIONRECORD * Station = NULL;
-
-// Debugprintf(Msg);
-
- Payload = strchr(Msg, ':'); // End of Address String
-
- if (Payload == NULL)
- {
- Debugprintf("Invalid Msg %s", Msg);
- return Station;
- }
-
- *Payload++ = 0;
-
- Callsign = Msg;
-
- Path = strchr(Msg, '>');
-
- if (Path == NULL)
- {
- Debugprintf("Invalid Msg %s", Msg);
- return Station;
- }
-
- *Path++ = 0;
-
- // Look up station - create a new one if not found
-
- if (strlen(Callsign) > 11)
- {
- Debugprintf("Invalid Msg %s", Msg);
- return Station;
- }
-
- Station = FindStation(Callsign, TRUE);
-
- strcpy(Station->Path, Path);
- strcpy(Station->LastPacket, Payload);
- Station->LastPort = 0;
-
- DecodeAPRSPayload(Payload, Station);
- Station->TimeLastUpdated = time(NULL);
-
- return Station;
-}
-
-double Cube91 = 91.0 * 91.0 * 91.0;
-double Square91 = 91.0 * 91.0;
-
-BOOL DecodeLocationString(UCHAR * Payload, struct STATIONRECORD * Station)
-{
- UCHAR SymChar;
- char SymSet;
- char NS;
- char EW;
- double NewLat, NewLon;
- char LatDeg[3], LonDeg[4];
- char save;
-
- // Compressed has first character not a digit (it is symbol table)
-
- // /YYYYXXXX$csT
-
- if (Payload[0] == '!')
- return FALSE; // Ultimeter 2000 Weather Station
-
- if (!isdigit(*Payload))
- {
- int C, S;
-
- SymSet = *Payload;
- SymChar = Payload[9];
-
- NewLat = 90.0 - ((Payload[1] - 33) * Cube91 + (Payload[2] - 33) * Square91 +
- (Payload[3] - 33) * 91.0 + (Payload[4] - 33)) / 380926.0;
-
- Payload += 4;
-
- NewLon = -180.0 + ((Payload[1] - 33) * Cube91 + (Payload[2] - 33) * Square91 +
- (Payload[3] - 33) * 91.0 + (Payload[4] - 33)) / 190463.0;
-
- C = Payload[6] - 33;
-
- if (C >= 0 && C < 90 )
- {
- S = Payload[7] - 33;
-
- Station->Course = C * 4;
- Station->Speed = (pow(1.08, S) - 1) * 1.15077945; // MPH;
- }
-
-
-
- }
- else
- {
- // Standard format ddmm.mmN/dddmm.mmE?
-
- NS = Payload[7] & 0xdf; // Mask Lower Case Bit
- EW = Payload[17] & 0xdf;
-
- SymSet = Payload[8];
- SymChar = Payload[18];
-
- if (SymChar == '_') // WX
- {
- if (strlen(Payload) > 30)
- strcpy(Station->LastWXPacket, Payload);
- }
-
- memcpy(LatDeg, Payload,2);
- LatDeg[2]=0;
- NewLat = atof(LatDeg) + (atof(Payload+2) / 60);
-
- if (NS == 'S')
- NewLat = -NewLat;
- else
- if (NS != 'N')
- return FALSE;
-
- memcpy(LonDeg,Payload + 9, 3);
-
- if (SymChar != '_' && Payload[22] == '/') // not if WX
- {
- Station->Course = atoi(Payload + 19);
- Station->Speed = atoi(Payload + 23);
- }
-
- LonDeg[3]=0;
-
- save = Payload[17];
- Payload[17] = 0;
- NewLon = atof(LonDeg) + (atof(Payload+12) / 60);
- Payload[17] = save;
-
- if (EW == 'W')
- NewLon = -NewLon;
- else
- if (EW != 'E')
- return FALSE;
- }
-
- Station->Symbol = SymChar;
-
- if (SymChar > ' ' && SymChar < 0x7f)
- SymChar -= '!';
- else
- SymChar = 0;
-
- Station->IconOverlay = 0;
-
- if ((SymSet >= '0' && SymSet <= '9') || (SymSet >= 'A' && SymSet <= 'Z'))
- {
- SymChar += 96;
- Station->IconOverlay = SymSet;
- }
- else
- if (SymSet == '\\')
- SymChar += 96;
-
- Station->iconRow = SymChar >> 4;
- Station->iconCol = SymChar & 15;
-
- if (NewLat > 90 || NewLat < -90 || NewLon > 180 || NewLon < -180)
- return TRUE;
-
- if (Station->Lat != NewLat || Station->Lon != NewLon)
- {
- time_t NOW = time(NULL);
- time_t Age = NOW - Station->TimeLastTracked;
-
- if (Age > 15) // Don't update too often
- {
- // Add to track
-
- Station->TimeLastTracked = NOW;
-
-// if (memcmp(Station->Callsign, "ISS ", 4) == 0)
-// Debugprintf("%s %s %s ",Station->Callsign, Station->Path, Station->LastPacket);
-
- Station->LatTrack[Station->Trackptr] = NewLat;
- Station->LonTrack[Station->Trackptr] = NewLon;
- Station->TrackTime[Station->Trackptr] = NOW;
-
- Station->Trackptr++;
- Station->Moved = TRUE;
-
- if (Station->Trackptr == TRACKPOINTS)
- Station->Trackptr = 0;
- }
-
- Station->Lat = NewLat;
- Station->Lon = NewLon;
- Station->Approx = 0;
- }
-
-
- return TRUE;
-}
-
-int DecodeAPRSPayload(char * Payload, struct STATIONRECORD * Station)
-{
- char * TimeStamp;
- char * ObjName;
- char ObjState;
- struct STATIONRECORD * Object;
- BOOL Item = FALSE;
- char * ptr;
- char * Callsign;
- char * Path;
- char * Msg;
- char * context;
- struct STATIONRECORD * TPStation;
-
- Station->Object = NULL;
-
- if (strcmp(Station->Callsign, "LA1ZDA-2") == 0)
- {
- int i = 1;
- }
- switch(*Payload)
- {
- case '`':
- case 0x27: // '
- case 0x1c:
- case 0x1d: // MIC-E
-
- Decode_MIC_E_Packet(Payload, Station);
- return 0;
-
- case '$': // NMEA
- Debugprintf(Payload);
- break;
-
- case ')': // Item
-
-// Debugprintf("%s %s %s", Station->Callsign, Station->Path, Payload);
-
- Item = TRUE;
- ObjName = ptr = Payload + 1;
-
- while (TRUE)
- {
- ObjState = *ptr;
- if (ObjState == 0)
- return 0; // Corrupt
-
- if (ObjState == '!' || ObjState == '_') // Item Terminator
- break;
-
- ptr++;
- }
-
- *ptr = 0; // Terminate Name
-
- Object = FindStation(ObjName, TRUE);
- Object->ObjState = *ptr++ = ObjState;
-
- strcpy(Object->Path, Station->Callsign);
- strcat(Object->Path, ">");
- if (Object == Station)
- {
- char Temp[256];
- strcpy(Temp, Station->Path);
- strcat(Object->Path, Temp);
- Debugprintf("item is station %s", Payload);
- }
- else
- strcat(Object->Path, Station->Path);
-
- strcpy(Object->LastPacket, Payload);
-
- if (ObjState != '_') // Deleted Objects may have odd positions
- DecodeLocationString(ptr, Object);
-
- Object->TimeLastUpdated = time(NULL);
- Station->Object = Object;
- return 0;
-
-
- case ';': // Object
-
- ObjName = Payload + 1;
- ObjState = Payload[10]; // * Live, _Killed
-
- Payload[10] = 0;
- Object = FindStation(ObjName, TRUE);
- Object->ObjState = Payload[10] = ObjState;
-
- strcpy(Object->Path, Station->Callsign);
- strcat(Object->Path, ">");
- if (Object == Station)
- {
- char Temp[256];
- strcpy(Temp, Station->Path);
- strcat(Object->Path, Temp);
- Debugprintf("Object is station %s", Payload);
- }
- else
- strcat(Object->Path, Station->Path);
-
-
- strcpy(Object->LastPacket, Payload);
-
- TimeStamp = Payload + 11;
-
- if (ObjState != '_') // Deleted Objects may have odd positions
- DecodeLocationString(Payload + 18, Object);
-
- Object->TimeLastUpdated = time(NULL);
- Object->LastPort = Station->LastPort;
- Station->Object = Object;
- return 0;
-
- case '@':
- case '/': // Timestamp, No Messaging
-
- TimeStamp = ++Payload;
- Payload += 6;
-
- case '=':
- case '!':
-
- Payload++;
-
- DecodeLocationString(Payload, Station);
-
- return 0;
-
- case '>': // Status
-
- strcpy(Station->Status, &Payload[1]);
-
- case '<': // Capabilities
- case '_': // Weather
- case 'T': // Telemetry
-
- break;
-
- case ':': // Message
-
- return ProcessMessage(Payload, Station);
-
- case '}': // Third Party Header
-
- // Process Payload as a new message
-
- // }GM7HHB-9>APDR12,TCPIP,MM1AVR*:=5556.62N/00303.55W>204/000/A=000213 http://www.dstartv.com
-
- Callsign = Msg = &Payload[1];
- Path = strchr(Msg, '>');
-
- if (Path == NULL)
- return 0;
-
- *Path++ = 0;
-
- Payload = strchr(Path, ':');
-
- if (Payload == NULL)
- return 0;
-
- *(Payload++) = 0;
-
- // Check Dup Filter
-
- if (CheckforDups(Callsign, Payload, (int)strlen(Payload)))
- return 0;
-
- // Look up station - create a new one if not found
-
- TPStation = FindStation(Callsign, TRUE);
-
- strcpy(TPStation->Path, Path);
- strcpy(TPStation->LastPacket, Payload);
- TPStation->LastPort = 0; // Heard on RF, but info is from IS
-
- DecodeAPRSPayload(Payload, TPStation);
- TPStation->TimeLastUpdated = time(NULL);
-
- return 0;
-
- default:
-
- // Non - APRS Message. If Payload contains a valid 6 char locator derive a position from it
-
- if (Station->Lat != 0.0 || Station->Lon != 0.0)
- return 0; // already have position
-
- ptr = strtok_s(Payload, ",[](){} \n", &context);
-
- while (ptr && ptr[0])
- {
- if (strlen(ptr) == 6) // could be locator
- {
- double Lat = 0.0, Lon = 0.0;
-
- if (FromLOC(ptr, &Lat, &Lon))
- {
- if (Lat != 0.0 && Lon != 0.0)
- {
- // Randomise in locator square.
-
- Lat = Lat + ((rand() / 24.0) / RAND_MAX);
- Lon = Lon + ((rand() / 12.0) / RAND_MAX);
- Station->Lat = Lat;
- Station->Lon = Lon;
- Station->Approx = 1;
- Debugprintf("%s %s %s", Station->Callsign, Station->Path, Payload);
- }
- }
- }
-
- ptr = strtok_s(NULL, ",[](){} \n", &context);
- }
-
- return 0;
- }
- return 0;
-}
-
-// Convert MIC-E Char to Lat Digit (offset by 0x30)
-// 0123456789 @ABCDEFGHIJKLMNOPQRSTUVWXYZ
-char MicELat[] = "0123456789???????0123456789 ???0123456789 " ;
-
-char MicECode[]= "0000000000???????111111111110???22222222222" ;
-
-
-VOID Decode_MIC_E_Packet(char * Payload, struct STATIONRECORD * Station)
-{
- // Info is encoded in the Dest Addr (in Station->Path) as well as Payload.
- // See APRS Spec for full details
-
- char Lat[10]; // DDMMHH
- char LatDeg[3];
- char * ptr;
- char c;
- int i, n;
- int LonDeg, LonMin;
- BOOL LonOffset = FALSE;
- char NS = 'S';
- char EW = 'E';
- UCHAR SymChar, SymSet;
- double NewLat, NewLon;
- int SP, DC, SE; // Course/Speed Encoded
- int Course, Speed;
-
- // Make sure packet is long enough to have an valid address
-
- if (strlen(Payload) < 9)
- return;
-
- ptr = &Station->Path[0];
-
- for (i = 0; i < 6; i++)
- {
- n = (*(ptr++)) - 0x30;
- c = MicELat[n];
-
- if (c == '?') // Illegal
- return;
-
- if (c == ' ')
- c = '0'; // Limited Precision
-
- Lat[i] = c;
-
- }
-
- Lat[6] = 0;
-
- if (Station->Path[3] > 'O')
- NS = 'N';
-
- if (Station->Path[5] > 'O')
- EW = 'W';
-
- if (Station->Path[4] > 'O')
- LonOffset = TRUE;
-
- n = Payload[1] - 28; // Lon Degrees S9PU0T,WIDE1-1,WIDE2-2,qAR,WB9TLH-15:`rB0oII>/]"6W}44
-
- if (LonOffset)
- n += 100;
-
- if (n > 179 && n < 190)
- n -= 80;
- else
- if (n > 189 && n < 200)
- n -= 190;
-
- LonDeg = n;
-
-/*
- To decode the longitude degrees value:
-1. subtract 28 from the d+28 value to obtain d.
-2. if the longitude offset is +100 degrees, add 100 to d.
-3. subtract 80 if 180 ˜ d ˜ 189
-(i.e. the longitude is in the range 100–109 degrees).
-4. or, subtract 190 if 190 ˜ d ˜ 199.
-(i.e. the longitude is in the range 0–9 degrees).
-*/
-
- n = Payload[2] - 28; // Lon Mins
-
- if (n > 59)
- n -= 60;
-
- LonMin = n;
-
- n = Payload[3] - 28; // Lon Mins/100;
-
-//1. subtract 28 from the m+28 value to obtain m.
-//2. subtract 60 if m ™ 60.
-//(i.e. the longitude minutes is in the range 0–9).
-
-
- memcpy(LatDeg, Lat, 2);
- LatDeg[2]=0;
-
- NewLat = atof(LatDeg) + (atof(Lat+2) / 6000.0);
-
- if (NS == 'S')
- NewLat = -NewLat;
-
- NewLon = LonDeg + LonMin / 60.0 + n / 6000.0;
-
- if (EW == 'W') // West
- NewLon = -NewLon;
-
-
- SP = Payload[4] - 28;
- DC = Payload[5] - 28;
- SE = Payload[6] - 28; // Course 100 and 10 degs
-
- Speed = DC / 10; // Quotient = Speed Units
- Course = DC - (Speed * 10); // Remainder = Course Deg/100
-
- Course = SE + (Course * 100);
-
- Speed += SP * 10;
-
- if (Speed >= 800)
- Speed -= 800;
-
- if (Course >= 400)
- Course -= 400;
-
- Station->Course = Course;
- Station->Speed = Speed * 1.15077945; // MPH
-
-// Debugprintf("MIC-E Course/Speed %s %d %d", Station->Callsign, Course, Speed);
-
- SymChar = Payload[7]; // Symbol
- SymSet = Payload[8]; // Symbol
-
- SymChar -= '!';
-
- Station->IconOverlay = 0;
-
- if ((SymSet >= '0' && SymSet <= '9') || (SymSet >= 'A' && SymSet <= 'Z'))
- {
- SymChar += 96;
- Station->IconOverlay = SymSet;
- }
- else
- if (SymSet == '\\')
- SymChar += 96;
-
- Station->iconRow = SymChar >> 4;
- Station->iconCol = SymChar & 15;
-
- if (NewLat > 90 || NewLat < -90 || NewLon > 180 || NewLon < -180)
- return;
-
- if (Station->Lat != NewLat || Station->Lon != NewLon)
- {
- time_t NOW = time(NULL);
- time_t Age = NOW - Station->TimeLastUpdated;
-
- if (Age > 15) // Don't update too often
- {
- // Add to track
-
-// if (memcmp(Station->Callsign, "ISS ", 4) == 0)
-// Debugprintf("%s %s %s ",Station->Callsign, Station->Path, Station->LastPacket);
-
- Station->LatTrack[Station->Trackptr] = NewLat;
- Station->LonTrack[Station->Trackptr] = NewLon;
- Station->TrackTime[Station->Trackptr] = NOW;
-
- Station->Trackptr++;
- Station->Moved = TRUE;
-
- if (Station->Trackptr == TRACKPOINTS)
- Station->Trackptr = 0;
- }
-
- Station->Lat = NewLat;
- Station->Lon = NewLon;
- Station->Approx = 0;
- }
-
- return;
-
-}
-
-/*
-
-INT_PTR CALLBACK ChildDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-// This processes messages from controls on the tab subpages
- int Command;
-
-// int retCode, disp;
-// char Key[80];
-// HKEY hKey;
-// BOOL OK;
-// OPENFILENAME ofn;
-// char Digis[100];
-
- int Port = PortNum[CurrentPage];
-
- switch (message)
- {
- case WM_NOTIFY:
-
- switch (((LPNMHDR)lParam)->code)
- {
- case TCN_SELCHANGE:
- OnSelChanged(hDlg);
- return TRUE;
- // More cases on WM_NOTIFY switch.
- case NM_CHAR:
- return TRUE;
- }
-
- break;
- case WM_INITDIALOG:
- OnChildDialogInit( hDlg);
- return (INT_PTR)TRUE;
-
- case WM_CTLCOLORDLG:
-
- return (LONG)bgBrush;
-
- case WM_CTLCOLORSTATIC:
- {
- HDC hdcStatic = (HDC)wParam;
- SetTextColor(hdcStatic, RGB(0, 0, 0));
- SetBkMode(hdcStatic, TRANSPARENT);
- return (LONG)bgBrush;
- }
-
-
- case WM_COMMAND:
-
- Command = LOWORD(wParam);
-
- if (Command == 2002)
- return TRUE;
-
- switch (Command)
- {
-/* case IDC_FILE:
-
- memset(&ofn, 0, sizeof (OPENFILENAME));
- ofn.lStructSize = sizeof (OPENFILENAME);
- ofn.hwndOwner = hDlg;
- ofn.lpstrFile = &FN[Port][0];
- ofn.nMaxFile = 250;
- ofn.lpstrTitle = "File to send as beacon";
- ofn.lpstrInitialDir = GetBPQDirectory();
-
- if (GetOpenFileName(&ofn))
- SetDlgItemText(hDlg, IDC_FILENAME, &FN[Port][0]);
-
- break;
-
-
- case IDOK:
-
- GetDlgItemText(hDlg, IDC_UIDEST, &UIDEST[Port][0], 10);
-
- if (UIDigi[Port])
- {
- free(UIDigi[Port]);
- UIDigi[Port] = NULL;
- }
-
- if (UIDigiAX[Port])
- {
- free(UIDigiAX[Port]);
- UIDigiAX[Port] = NULL;
- }
-
- GetDlgItemText(hDlg, IDC_UIDIGIS, Digis, 99);
-
- UIDigi[Port] = _strdup(Digis);
-
- GetDlgItemText(hDlg, IDC_FILENAME, &FN[Port][0], 255);
- GetDlgItemText(hDlg, IDC_MESSAGE, &Message[Port][0], 1000);
-
- Interval[Port] = GetDlgItemInt(hDlg, IDC_INTERVAL, &OK, FALSE);
-
- MinCounter[Port] = Interval[Port];
-
- SendFromFile[Port] = IsDlgButtonChecked(hDlg, IDC_FROMFILE);
-
- sprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\UIUtil\\UIPort%d", PortNum[CurrentPage]);
-
- retCode = RegCreateKeyEx(REGTREE,
- Key, 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, &disp);
-
- if (retCode == ERROR_SUCCESS)
- {
- retCode = RegSetValueEx(hKey, "UIDEST", 0, REG_SZ,(BYTE *)&UIDEST[Port][0], strlen(&UIDEST[Port][0]));
- retCode = RegSetValueEx(hKey, "FileName", 0, REG_SZ,(BYTE *)&FN[Port][0], strlen(&FN[Port][0]));
- retCode = RegSetValueEx(hKey, "Message", 0, REG_SZ,(BYTE *)&Message[Port][0], strlen(&Message[Port][0]));
- retCode = RegSetValueEx(hKey, "Interval", 0, REG_DWORD,(BYTE *)&Interval[Port], 4);
- retCode = RegSetValueEx(hKey, "SendFromFile", 0, REG_DWORD,(BYTE *)&SendFromFile[Port], 4);
- retCode = RegSetValueEx(hKey, "Enabled", 0, REG_DWORD,(BYTE *)&UIEnabled[Port], 4);
- retCode = RegSetValueEx(hKey, "Digis",0, REG_SZ, Digis, strlen(Digis));
-
- RegCloseKey(hKey);
- }
-
- SetupUI(Port);
-
- return (INT_PTR)TRUE;
-
-
- case IDCANCEL:
-
- EndDialog(hDlg, LOWORD(wParam));
- return (INT_PTR)TRUE;
-
- case ID_TEST:
-
- SendBeacon(Port);
- return TRUE;
-
-
-
-
- }
- break;
-
- }
- return (INT_PTR)FALSE;
-}
-
-
-
-
-VOID WINAPI OnTabbedDialogInit(HWND hDlg)
-{
- DLGHDR *pHdr = (DLGHDR *) LocalAlloc(LPTR, sizeof(DLGHDR));
- DWORD dwDlgBase = GetDialogBaseUnits();
- int cxMargin = LOWORD(dwDlgBase) / 4;
- int cyMargin = HIWORD(dwDlgBase) / 8;
-
- TC_ITEM tie;
- RECT rcTab;
-
- int i, pos, tab = 0;
- INITCOMMONCONTROLSEX init;
-
- char PortNo[60];
- struct _EXTPORTDATA * PORTVEC;
-
- hwndDlg = hDlg; // Save Window Handle
-
- // Save a pointer to the DLGHDR structure.
-
- SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) pHdr);
-
- // Create the tab control.
-
-
- init.dwICC = ICC_STANDARD_CLASSES;
- init.dwSize=sizeof(init);
- i=InitCommonControlsEx(&init);
-
- pHdr->hwndTab = CreateWindow(WC_TABCONTROL, "", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
- 0, 0, 100, 100, hwndDlg, NULL, hInst, NULL);
-
- if (pHdr->hwndTab == NULL) {
-
- // handle error
-
- }
-
- // Add a tab for each of the child dialog boxes.
-
- tie.mask = TCIF_TEXT | TCIF_IMAGE;
-
- tie.iImage = -1;
-
- for (i = 1; i <= GetNumberofPorts(); i++)
- {
- // Only allow UI on ax.25 ports
-
- PORTVEC = (struct _EXTPORTDATA * )GetPortTableEntry(i);
-
- if (PORTVEC->PORTCONTROL.PORTTYPE == 16) // EXTERNAL
- if (PORTVEC->PORTCONTROL.PROTOCOL == 10) // Pactor/WINMOR
- continue;
-
- sprintf(PortNo, "Port %2d", GetPortNumber(i));
- PortNum[tab] = GetPortNumber(i);
-
- tie.pszText = PortNo;
- TabCtrl_InsertItem(pHdr->hwndTab, tab, &tie);
-
- pHdr->apRes[tab++] = DoLockDlgRes("PORTPAGE");
-
- }
-
- PageCount = tab;
-
- // Determine the bounding rectangle for all child dialog boxes.
-
- SetRectEmpty(&rcTab);
-
- for (i = 0; i < PageCount; i++)
- {
- if (pHdr->apRes[i]->cx > rcTab.right)
- rcTab.right = pHdr->apRes[i]->cx;
-
- if (pHdr->apRes[i]->cy > rcTab.bottom)
- rcTab.bottom = pHdr->apRes[i]->cy;
-
- }
-
- MapDialogRect(hwndDlg, &rcTab);
-
-// rcTab.right = rcTab.right * LOWORD(dwDlgBase) / 4;
-
-// rcTab.bottom = rcTab.bottom * HIWORD(dwDlgBase) / 8;
-
- // Calculate how large to make the tab control, so
-
- // the display area can accomodate all the child dialog boxes.
-
- TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
-
- OffsetRect(&rcTab, cxMargin - rcTab.left, cyMargin - rcTab.top);
-
- // Calculate the display rectangle.
-
- CopyRect(&pHdr->rcDisplay, &rcTab);
-
- TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay);
-
- // Set the size and position of the tab control, buttons,
-
- // and dialog box.
-
- SetWindowPos(pHdr->hwndTab, NULL, rcTab.left, rcTab.top, rcTab.right - rcTab.left, rcTab.bottom - rcTab.top, SWP_NOZORDER);
-
- // Move the Buttons to bottom of page
-
- pos=rcTab.left+cxMargin;
-
-
- // Size the dialog box.
-
- SetWindowPos(hwndDlg, NULL, 0, 0, rcTab.right + cyMargin + 2 * GetSystemMetrics(SM_CXDLGFRAME),
- rcTab.bottom + 2 * cyMargin + 2 * GetSystemMetrics(SM_CYDLGFRAME) + GetSystemMetrics(SM_CYCAPTION),
- SWP_NOMOVE | SWP_NOZORDER);
-
- // Simulate selection of the first item.
-
- OnSelChanged(hwndDlg);
-
-}
-
-// DoLockDlgRes - loads and locks a dialog template resource.
-
-// Returns a pointer to the locked resource.
-
-// lpszResName - name of the resource
-
-DLGTEMPLATE * WINAPI DoLockDlgRes(LPCSTR lpszResName)
-{
- HRSRC hrsrc = FindResource(NULL, lpszResName, RT_DIALOG);
- HGLOBAL hglb = LoadResource(hInst, hrsrc);
-
- return (DLGTEMPLATE *) LockResource(hglb);
-}
-
-//The following function processes the TCN_SELCHANGE notification message for the main dialog box. The function destroys the dialog box for the outgoing page, if any. Then it uses the CreateDialogIndirect function to create a modeless dialog box for the incoming page.
-
-// OnSelChanged - processes the TCN_SELCHANGE notification.
-
-// hwndDlg - handle of the parent dialog box
-
-VOID WINAPI OnSelChanged(HWND hwndDlg)
-{
- char PortDesc[40];
- int Port;
-
- DLGHDR *pHdr = (DLGHDR *) GetWindowLong(hwndDlg, GWL_USERDATA);
-
- CurrentPage = TabCtrl_GetCurSel(pHdr->hwndTab);
-
- // Destroy the current child dialog box, if any.
-
- if (pHdr->hwndDisplay != NULL)
-
- DestroyWindow(pHdr->hwndDisplay);
-
- // Create the new child dialog box.
-
- pHdr->hwndDisplay = CreateDialogIndirect(hInst, pHdr->apRes[CurrentPage], hwndDlg, ChildDialogProc);
-
- hwndDisplay = pHdr->hwndDisplay; // Save
-
- Port = PortNum[CurrentPage];
- // Fill in the controls
-
- GetPortDescription(PortNum[CurrentPage], PortDesc);
-
- SetDlgItemText(hwndDisplay, IDC_PORTNAME, PortDesc);
-
-// CheckDlgButton(hwndDisplay, IDC_FROMFILE, SendFromFile[Port]);
-
-// SetDlgItemInt(hwndDisplay, IDC_INTERVAL, Interval[Port], FALSE);
-
- SetDlgItemText(hwndDisplay, IDC_UIDEST, &UIDEST[Port][0]);
- SetDlgItemText(hwndDisplay, IDC_UIDIGIS, UIDigi[Port]);
-
-
-
-// SetDlgItemText(hwndDisplay, IDC_FILENAME, &FN[Port][0]);
-// SetDlgItemText(hwndDisplay, IDC_MESSAGE, &Message[Port][0]);
-
- ShowWindow(pHdr->hwndDisplay, SW_SHOWNORMAL);
-
-}
-
-//The following function processes the WM_INITDIALOG message for each of the child dialog boxes. You cannot specify the position of a dialog box created using the CreateDialogIndirect function. This function uses the SetWindowPos function to position the child dialog within the tab control's display area.
-
-// OnChildDialogInit - Positions the child dialog box to fall
-
-// within the display area of the tab control.
-
-VOID WINAPI OnChildDialogInit(HWND hwndDlg)
-{
- HWND hwndParent = GetParent(hwndDlg);
- DLGHDR *pHdr = (DLGHDR *) GetWindowLong(hwndParent, GWL_USERDATA);
-
- SetWindowPos(hwndDlg, HWND_TOP, pHdr->rcDisplay.left, pHdr->rcDisplay.top, 0, 0, SWP_NOSIZE);
-}
-
-
-*/
-
-
-/*
-VOID ProcessMessage(char * Payload, struct STATIONRECORD * Station)
-{
- char MsgDest[10];
- struct APRSMESSAGE * Message;
- struct APRSMESSAGE * ptr = Messages;
- char * TextPtr = &Payload[11];
- char * SeqPtr;
- int n = 0;
- char FromCall[10] = " ";
- struct tm * TM;
- time_t NOW;
-
- memcpy(FromCall, Station->Callsign, (int)strlen(Station->Callsign));
- memcpy(MsgDest, &Payload[1], 9);
- MsgDest[9] = 0;
-
- SeqPtr = strchr(TextPtr, '{');
-
- if (SeqPtr)
- {
- *(SeqPtr++) = 0;
- if(strlen(SeqPtr) > 6)
- SeqPtr[7] = 0;
- }
-
- if (_memicmp(TextPtr, "ack", 3) == 0)
- {
- // Message Ack. See if for one of our messages
-
- ptr = OutstandingMsgs;
-
- if (ptr == 0)
- return;
-
- do
- {
- if (strcmp(ptr->FromCall, MsgDest) == 0
- && strcmp(ptr->ToCall, FromCall) == 0
- && strcmp(ptr->Seq, &TextPtr[3]) == 0)
- {
- // Message is acked
-
- ptr->Retries = 0;
- ptr->Acked = TRUE;
-// if (hMsgsOut)
-// UpdateTXMessageLine(hMsgsOut, n, ptr);
-
- return;
- }
- ptr = ptr->Next;
- n++;
-
- } while (ptr);
-
- return;
- }
-
- Message = malloc(sizeof(struct APRSMESSAGE));
- memset(Message, 0, sizeof(struct APRSMESSAGE));
- strcpy(Message->FromCall, Station->Callsign);
- strcpy(Message->ToCall, MsgDest);
-
- if (SeqPtr)
- {
- strcpy(Message->Seq, SeqPtr);
-
- // If a REPLY-ACK Seg, copy to LastRXSeq, and see if it acks a message
-
- if (SeqPtr[2] == '}')
- {
- struct APRSMESSAGE * ptr1;
- int nn = 0;
-
- strcpy(Station->LastRXSeq, SeqPtr);
-
- ptr1 = OutstandingMsgs;
-
- while (ptr1)
- {
- if (strcmp(ptr1->FromCall, MsgDest) == 0
- && strcmp(ptr1->ToCall, FromCall) == 0
- && memcmp(&ptr1->Seq, &SeqPtr[3], 2) == 0)
- {
- // Message is acked
-
- ptr1->Acked = TRUE;
- ptr1->Retries = 0;
-// if (hMsgsOut)
-// UpdateTXMessageLine(hMsgsOut, nn, ptr);
-
- break;
- }
- ptr1 = ptr1->Next;
- nn++;
- }
- }
- else
- {
- // Station is not using reply-ack - set to send simple numeric sequence (workround for bug in APRS Messanger
-
- Station->SimpleNumericSeq = TRUE;
- }
- }
-
- if (strlen(TextPtr) > 100)
- TextPtr[100] = 0;
-
- strcpy(Message->Text, TextPtr);
-
- NOW = time(NULL);
-
- if (DefaultLocalTime)
- TM = localtime(&NOW);
- else
- TM = gmtime(&NOW);
-
- sprintf(Message->Time, "%.2d:%.2d", TM->tm_hour, TM->tm_min);
-
- if (_stricmp(MsgDest, APRSCall) == 0 && SeqPtr) // ack it if it has a sequence
- {
- // For us - send an Ack
-
- char ack[30];
-
- int n = sprintf(ack, ":%-9s:ack%s", Message->FromCall, Message->Seq);
- PutAPRSMessage(ack, n);
- }
-
- if (ptr == NULL)
- {
- Messages = Message;
- }
- else
- {
- n++;
- while(ptr->Next)
- {
- ptr = ptr->Next;
- n++;
- }
- ptr->Next = Message;
- }
-
- if (strcmp(MsgDest, APRSCall) == 0) // to me?
- {
- }
-}
-
-*/
-
-VOID APRSSecTimer()
-{
-
- // Check Message Retries
-
- struct APRSMESSAGE * ptr = SMEM->OutstandingMsgs;
- int n = 0;
-
- if (SendWX)
- SendWeatherBeacon();
-
-
- while (ptr)
- {
- if (ptr->Acked == FALSE)
- {
- if (ptr->Retries)
- {
- ptr->RetryTimer--;
-
- if (ptr->RetryTimer == 0)
- {
- ptr->Retries--;
-
- if (ptr->Retries)
- {
- // Send Again
-
- char Msg[255];
- APRSHEARDRECORD * STN;
-
- sprintf(Msg, ":%-9s:%s{%s", ptr->ToCall, ptr->Text, ptr->Seq);
-
- STN = FindStationInMH(ptr->ToCall);
-
- if (STN)
- SendAPRSMessage(Msg, STN->rfPort);
- else
- {
- if (memcmp(ptr->ToCall, "SERVER ", 9))
- SendAPRSMessage(Msg, -1); // All RF ports unless to SERVER
- SendAPRSMessage(Msg, 0); // IS
- }
- ptr->RetryTimer = RetryTimer;
- }
- }
- }
- }
-
- ptr = ptr->Next;
- n++;
- }
-}
-
-double radians(double Degrees)
-{
- return M_PI * Degrees / 180;
-}
-double degrees(double Radians)
-{
- return Radians * 180 / M_PI;
-}
-
-double Distance(double laa, double loa, double lah, double loh, BOOL KM)
-{
-
-/*
-
-'Great Circle Calculations.
-
-'dif = longitute home - longitute away
-
-
-' (this should be within -180 to +180 degrees)
-' (Hint: This number should be non-zero, programs should check for
-' this and make dif=0.0001 as a minimum)
-'lah = latitude of home
-'laa = latitude of away
-
-'dis = ArcCOS(Sin(lah) * Sin(laa) + Cos(lah) * Cos(laa) * Cos(dif))
-'distance = dis / 180 * pi * ERAD
-'angle = ArcCOS((Sin(laa) - Sin(lah) * Cos(dis)) / (Cos(lah) * Sin(dis)))
-
-'p1 = 3.1415926535: P2 = p1 / 180: Rem -- PI, Deg =>= Radians
-*/
-
- loh = radians(loh); lah = radians(lah);
- loa = radians(loa); laa = radians(laa);
-
- loh = 60*degrees(acos(sin(lah) * sin(laa) + cos(lah) * cos(laa) * cos(loa-loh))) * 1.15077945;
-
- if (KM)
- loh *= 1.60934;
-
- return loh;
-}
-
-
-double myDistance(double laa, double loa, BOOL KM)
-{
- double lah, loh;
-
- GetAPRSLatLon(&lah, &loh);
-
- return Distance(laa, loa, lah, loh, KM);
-}
-
-/*
-
-'Great Circle Calculations.
-
-'dif = longitute home - longitute away
-
-
-' (this should be within -180 to +180 degrees)
-' (Hint: This number should be non-zero, programs should check for
-' this and make dif=0.0001 as a minimum)
-'lah = latitude of home
-'laa = latitude of away
-
-'dis = ArcCOS(Sin(lah) * Sin(laa) + Cos(lah) * Cos(laa) * Cos(dif))
-'distance = dis / 180 * pi * ERAD
-'angle = ArcCOS((Sin(laa) - Sin(lah) * Cos(dis)) / (Cos(lah) * Sin(dis)))
-
-'p1 = 3.1415926535: P2 = p1 / 180: Rem -- PI, Deg =>= Radians
-
-
- loh = radians(loh); lah = radians(lah);
- loa = radians(loa); laa = radians(laa);
-
- loh = 60*degrees(acos(sin(lah) * sin(laa) + cos(lah) * cos(laa) * cos(loa-loh))) * 1.15077945;
-
- if (KM)
- loh *= 1.60934;
-
- return loh;
-}
-*/
-
-double Bearing(double lat2, double lon2, double lat1, double lon1)
-{
- double dlat, dlon, TC1;
-
- lat1 = radians(lat1);
- lat2 = radians(lat2);
- lon1 = radians(lon1);
- lon2 = radians(lon2);
-
- dlat = lat2 - lat1;
- dlon = lon2 - lon1;
-
- if (dlat == 0 || dlon == 0) return 0;
-
- TC1 = atan((sin(lon1 - lon2) * cos(lat2)) / (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2)));
- TC1 = degrees(TC1);
-
- if (fabs(TC1) > 89.5) if (dlon > 0) return 90; else return 270;
-
- if (dlat > 0)
- {
- if (dlon > 0) return -TC1;
- if (dlon < 0) return 360 - TC1;
- return 0;
- }
-
- if (dlat < 0)
- {
- if (dlon > 0) return TC1 = 180 - TC1;
- if (dlon < 0) return TC1 = 180 - TC1; // 'ok?
- return 180;
- }
-
- return 0;
-}
-
-
-double myBearing(double lat2, double lon2)
-{
- double lat1, lon1;
-
- GetAPRSLatLon(&lat1, &lon1);
-
- return Bearing(lat2, lon2, lat1, lon1);
-}
-/*
-
-
-
-
- lat1 = radians(lat1);
- lat2 = radians(lat2);
- lon1 = radians(lon1);
- lon2 = radians(lon2);
-
- dlat = lat2 - lat1;
- dlon = lon2 - lon1;
-
- if (dlat == 0 || dlon == 0) return 0;
-
- TC1 = atan((sin(lon1 - lon2) * cos(lat2)) / (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2)));
- TC1 = degrees(TC1);
-
- if (fabs(TC1) > 89.5) if (dlon > 0) return 90; else return 270;
-
- if (dlat > 0)
- {
- if (dlon > 0) return -TC1;
- if (dlon < 0) return 360 - TC1;
- return 0;
- }
-
- if (dlat < 0)
- {
- if (dlon > 0) return TC1 = 180 - TC1;
- if (dlon < 0) return TC1 = 180 - TC1; // 'ok?
- return 180;
- }
-
- return 0;
-}
-*/
-
-// Weather Data
-
-static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
-VOID SendWeatherBeacon()
-{
- char Msg[256];
- char DD[3]="";
- char HH[3]="";
- char MM[3]="";
- char Lat[10], Lon[10];
- size_t Len;
- int index;
- char WXMessage[1024];
- char * WXptr;
- char * WXend;
- time_t WXTime;
- time_t now = time(NULL);
- FILE * hFile;
- struct tm * TM;
- struct stat STAT;
-
- WXCounter++;
-
- if (WXCounter < WXInterval * 60)
- return;
-
- WXCounter = 0;
-
-// Debugprintf("BPQAPRS - Trying to open WX file %s", WXFileName);
-
- if (stat(WXFileName, &STAT))
- {
- Debugprintf("APRS WX File %s stat() failed %d", WXFileName, GetLastError());
- return;
- }
-
- WXTime = (now - STAT.st_mtime) /60; // Minutes
-
- if (WXTime > (3 * WXInterval))
- {
- Debugprintf("APRS Send WX File %s too old - %d minutes", WXFileName, WXTime);
- return;
- }
-
- hFile = fopen(WXFileName, "rb");
-
- if (hFile)
- Len = fread(WXMessage, 1, 1024, hFile);
- else
- {
- Debugprintf("APRS WX File %s open() failed %d", WXFileName, GetLastError());
- return;
- }
-
-
- if (Len < 30)
- {
- Debugprintf("BPQAPRS - WX file %s is too short - %d Chars", WXFileName, Len);
- fclose(hFile);
- return;
- }
-
- WXMessage[Len] = 0;
-
- // see if wview format
-
-//04-09-13, 2245
-//TempIn 23
-//TempEx 18
-//WindHi 0
-//WindAv 0
-//WindDr 200
-//BarmPs 30167
-//HumdIn 56
-//HumdEx 100
-//RnFall 0.00
-//DailyRnFall 0.00
-
- if (strstr(WXMessage, "TempIn"))
- {
- int Wind = 0;
- int Gust = 0;
- int Temp = 0;
- int Winddir = 0;
- int Humidity = 0;
- int Raintoday = 0;
- int Rain24hrs = 0;
- int Pressure = 0;
-
- char * ptr;
-
- ptr = strstr(WXMessage, "TempEx");
- if (ptr)
- Temp = (int)(atof(ptr + 7) * 1.8) + 32;
-
- ptr = strstr(WXMessage, "WindHi");
- if (ptr)
- Gust = atoi(ptr + 7);
-
- ptr = strstr(WXMessage, "WindAv");
- if (ptr)
- Wind = atoi(ptr + 7);
-
- ptr = strstr(WXMessage, "WindDr");
- if (ptr)
- Winddir = atoi(ptr + 7);
-
- ptr = strstr(WXMessage, "BarmPs");
- if (ptr)
- Pressure = (int)(atof(ptr + 7) * 0.338638866667); // Inches to 1/10 millbars
-
- ptr = strstr(WXMessage, "HumdEx");
- if (ptr)
- Humidity = atoi(ptr + 7);
-
- ptr = strstr(WXMessage, "RnFall");
- if (ptr)
- Rain24hrs = (int)(atof(ptr + 7) * 100.0);
-
- ptr = strstr(WXMessage, "DailyRnFall");
- if (ptr)
- Raintoday = (int)(atof(ptr + 12) * 100.0);
-
- if (Humidity > 99)
- Humidity = 99;
-
- sprintf(WXMessage, "%03d/%03dg%03dt%03dr%03dP%03dp%03dh%02db%05d",
- Winddir, Wind, Gust, Temp, 0, Raintoday, Rain24hrs, Humidity, Pressure);
-
- }
-
- WXptr = strchr(WXMessage, 10);
-
- if (WXptr)
- {
- WXend = strchr(++WXptr, 13);
- if (WXend == 0)
- WXend = strchr(WXptr, 10);
- if (WXend)
- *WXend = 0;
- }
- else
- WXptr = &WXMessage[0];
-
- // Get DDHHMM from Filetime
-
- TM = gmtime(&STAT.st_mtime);
-
- sprintf(DD, "%02d", TM->tm_mday);
- sprintf(HH, "%02d", TM->tm_hour);
- sprintf(MM, "%02d", TM->tm_min);
-
- GetAPRSLatLonString(Lat, Lon);
-
- Len = sprintf(Msg, "@%s%s%sz%s/%s_%s%s", DD, HH, MM, Lat, Lon, WXptr, WXComment);
-
- Debugprintf(Msg);
-
- for (index = 0; index < MaxBPQPortNo; index++)
- {
- if (WXPort[index])
- SendAPRSMessageEx(Msg, index, WXCall, FALSE);
- }
-
- fclose(hFile);
-}
-
-
-/*
-Jan 22 2012 14:10
-123/005g011t031r000P000p000h00b10161
-
-/MITWXN Mitchell IN weather Station N9LYA-3 {UIV32}
-< previous
-
-@221452z3844.42N/08628.33W_203/006g007t032r000P000p000h00b10171
-Complete Weather Report Format — with Lat/Long position, no Timestamp
-! or = Lat Sym Table ID Long Symbol Code _ Wind Directn/ Speed Weather Data APRS Software WX Unit uuuu
- 1 8 1 9 1 7 n 1 2-4
-Examples
-!4903.50N/07201.75W_220/004g005t077r000p000P000h50b09900wRSW
-!4903.50N/07201.75W_220/004g005t077r000p000P000h50b.....wRSW
-
-*/
-
-// Web Server Code
-
-// The actual HTTP socket code is in bpq32.dll. Any requests for APRS data are passed in
-// using a Named Pipe. The request looks exactly like one from a local socket, and the respone is
-// a fully pormatted HTTP packet
-
-
-#define InputBufferLen 1000
-
-
-#define MaxSessions 100
-
-
-HANDLE PipeHandle;
-
-int HTTPPort = 80;
-BOOL IPV6 = TRUE;
-
-#define MAX_PENDING_CONNECTS 5
-
-BOOL OpenSockets6();
-
-char HTDocs[MAX_PATH] = "HTML";
-char SpecialDocs[MAX_PATH] = "Special Pages";
-
-char SymbolText[192][20] = {
-
-"Police Stn", "No Symbol", "Digi", "Phone", "DX Cluster", "HF Gateway", "Plane sm", "Mob Sat Stn",
-"WheelChair", "Snowmobile", "Red Cross", "Boy Scout", "Home", "X", "Red Dot", "Circle (0)",
-"Circle (1)", "Circle (2)", "Circle (3)", "Circle (4)", "Circle (5)", "Circle (6)", "Circle (7)", "Circle (8)",
-"Circle (9)", "Fire", "Campground", "Motorcycle", "Rail Eng.", "Car", "File svr", "HC Future",
-
-"Aid Stn", "BBS", "Canoe", "No Symbol", "Eyeball", "Tractor", "Grid Squ.", "Hotel",
-"Tcp/ip", "No Symbol", "School", "Usr Log-ON", "MacAPRS", "NTS Stn", "Balloon", "Police",
-"TBD", "Rec Veh'le", "Shuttle", "SSTV", "Bus", "ATV", "WX Service", "Helo",
-"Yacht", "WinAPRS", "Jogger", "Triangle", "PBBS", "Plane lrge", "WX Station", "Dish Ant.",
-
-"Ambulance", "Bike", "ICP", "Fire Station", "Horse", "Fire Truck", "Glider", "Hospital",
-"IOTA", "Jeep", "Truck", "Laptop", "Mic-E Rptr", "Node", "EOC", "Rover",
-"Grid squ.", "Antenna", "Power Boat", "Truck Stop", "Truck 18wh", "Van", "Water Stn", "XAPRS",
-"Yagi", "Shelter", "No Symbol", "No Symbol", "No Symbol", "No Symbol", "", "",
-
-"Emergency", "No Symbol", "No. Digi", "Bank", "No Symbol", "No. Diam'd", "Crash site", "Cloudy",
-"MEO", "Snow", "Church", "Girl Scout", "Home (HF)", "UnknownPos", "Destination", "No. Circle",
-"No Symbol", "No Symbol", "No Symbol", "No Symbol", "No Symbol", "No Symbol", "No Symbol", "No Symbol",
-"Petrol Stn", "Hail", "Park", "Gale Fl", "No Symbol", "No. Car", "Info Kiosk", "Hurricane",
-
-"No. Box", "Snow blwng", "Coast G'rd", "Drizzle", "Smoke", "Fr'ze Rain", "Snow Shwr", "Haze",
-"Rain Shwr", "Lightning", "Kenwood", "Lighthouse", "No Symbol", "Nav Buoy", "Rocket", "Parking ",
-"Quake", "Restaurant", "Sat/Pacsat", "T'storm", "Sunny", "VORTAC", "No. WXS", "Pharmacy",
-"No Symbol", "No Symbol", "Wall Cloud", "No Symbol", "No Symbol", "No. Plane", "No. WX Stn", "Rain",
-
-"No. Diamond", "Dust blwng", "No. CivDef", "DX Spot", "Sleet", "Funnel Cld", "Gale", "HAM store",
-"No. Blk Box", "WorkZone", "SUV", "Area Locns", "Milepost", "No. Triang", "Circle sm", "Part Cloud",
-"No Symbol", "Restrooms", "No. Boat", "Tornado", "No. Truck", "No. Van", "Flooding", "No Symbol",
-"Sky Warn", "No Symbol", "Fog", "No Symbol", "No Symbol", "No Symbol", "", ""};
-
-// All Calls (8 per line)
-
-//
");
- HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
- send(sockptr->sock, Header, HeaderLen, 0);
- send(sockptr->sock, OutBuffer, OutputLen, 0);
-
- return;
- }
- }
-
- URL = &MsgPtr[4];
-
- ptr = strstr(URL, " HTTP");
-
- if (ptr)
- *ptr = 0;
-
- if (_stricmp(URL, "/APRS") == 0)
- {
- // Return APRS Index Page
-
- OutputLen = sprintf(OutBuffer, APRSIndexPage, "");
- HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
- send(sockptr->sock, Header, HeaderLen, 0);
- send(sockptr->sock, OutBuffer, OutputLen, 0);
-
- return;
- }
-
-
- if (_memicmp(URL, "/aprs/msgs/entermsg", 19) == 0 || _memicmp(URL, "/aprs/entermsg", 14) == 0)
- {
- char * To = strchr(URL, '=');
-
- if (LOCAL == FALSE && COOKIE == FALSE)
- {
- // Send Not Authorized
-
- OutputLen = sprintf(OutBuffer, APRSIndexPage, " Not authorized - please return to Node Menu and sign in");
- HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", (int)(OutputLen + strlen(Tail)));
- send(sock, Header, HeaderLen, 0);
- send(sock, OutBuffer, OutputLen, 0);
- send(sock, Tail, (int)strlen(Tail), 0);
- return;
- }
-
-
- if (To)
- {
- To++;
- UndoTransparency(To);
- strlop(To, '&');
- }
- else
- To = "";
-
- OutputLen = sprintf(OutBuffer, SendMsgPage, To);
- HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
- send(sockptr->sock, Header, HeaderLen, 0);
- send(sockptr->sock, OutBuffer, OutputLen, 0);
-
- return;
-
- }
-
- else if (_memicmp(URL, "/aprs/msgs", 10) == 0)
- {
- // Return Messages Received Page
-
- struct APRSMESSAGE * ptr = SMEM->Messages;
- int n = 0;
- char BaseCall[10];
- char BaseFrom[10];
- char * MsgCall = LoppedAPRSCall;
- BOOL OnlyMine = TRUE;
- BOOL AllSSID = TRUE;
- BOOL OnlySeq = FALSE;
- BOOL ShowBulls = TRUE;
-
- // Parse parameters
-
- // ?call=g8bpq&bulls=true&seqonly=true&onlymine=true
-
- char * params = strchr(URL, '?');
-
- if (params)
- {
- char * param, * context;
-
- param = strtok_s(++params, "&", &context);
-
- while (param)
- {
- char * val = strlop(param, '=');
-
- if (val)
- {
- strlop(val, ' ');
- if (_stricmp(param, "call") == 0)
- MsgCall = _strupr(val);
- else if (_stricmp(param, "bulls") == 0)
- ShowBulls = !_stricmp(val, "true");
- else if (_stricmp(param, "onlyseq") == 0)
- OnlySeq = !_stricmp(val, "true");
- else if (_stricmp(param, "onlymine") == 0)
- OnlyMine = !_stricmp(val, "true");
- else if (_stricmp(param, "AllSSID") == 0)
- AllSSID = !_stricmp(val, "true");
- }
- param = strtok_s(NULL,"&", &context);
- }
- }
- if (AllSSID)
- {
- memcpy(BaseCall, MsgCall, 10);
- strlop(BaseCall, '-');
- }
-
- OutputLen = sprintf(OutBuffer, WebHeader, MsgCall, MsgCall);
-
- while (ptr)
- {
- char ToLopped[11] = "";
- memcpy(ToLopped, ptr->ToCall, 10);
- strlop(ToLopped, ' ');
-
- if (memcmp(ToLopped, "BLN", 3) == 0)
- if (ShowBulls == TRUE)
- goto wantit;
-
- if (strcmp(ToLopped, MsgCall) == 0) // to me?
- goto wantit;
-
- if (strcmp(ptr->FromCall, MsgCall) == 0) // to me?
- goto wantit;
-
- if (AllSSID)
- {
- memcpy(BaseFrom, ToLopped, 10);
- strlop(BaseFrom, '-');
-
- if (strcmp(BaseFrom, BaseCall) == 0)
- goto wantit;
-
- memcpy(BaseFrom, ptr->FromCall, 10);
- strlop(BaseFrom, '-');
-
- if (strcmp(BaseFrom, BaseCall) == 0)
- goto wantit;
-
- }
-
- if (OnlyMine == FALSE) // Want All
- if (OnlySeq == FALSE || ptr->Seq[0] != 0)
- goto wantit;
-
- // ignore
-
- ptr = ptr->Next;
- continue;
- wantit:
- OutputLen += sprintf(&OutBuffer[OutputLen], WebLine,
- ptr->FromCall, ptr->ToCall, ptr->Seq, ptr->Time,
- ptr->FromCall, ptr->ToCall, ptr->Text);
-
- ptr = ptr->Next;
-
- if (OutputLen > 99000)
- break;
-
- }
-
- OutputLen += sprintf(&OutBuffer[OutputLen], WebTrailer);
-
- HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
- sendandcheck(sock, Header, HeaderLen);
- sendandcheck(sock, OutBuffer, OutputLen);
-
- return;
-
- }
-
- else if (_memicmp(URL, "/aprs/txmsgs", 12) == 0)
- {
- // Return Messages Received Page
-
- struct APRSMESSAGE * ptr = SMEM->OutstandingMsgs;
- char * MsgCall = LoppedAPRSCall;
-
- char Retries[10];
-
-
- OutputLen = sprintf(OutBuffer, WebTXHeader, MsgCall, MsgCall);
-
- while (ptr)
- {
- char ToLopped[11] = "";
-
- if (ptr->Acked)
- strcpy(Retries, "A");
- else if (ptr->Retries == 0)
- strcpy(Retries, "F");
- else
- sprintf(Retries, "%d", ptr->Retries);
-
- memcpy(ToLopped, ptr->ToCall, 10);
- strlop(ToLopped, ' ');
-
- OutputLen += sprintf(&OutBuffer[OutputLen], WebTXLine,
- ptr->ToCall, ptr->Seq, ptr->Time, Retries, ptr->Text);
- ptr = ptr->Next;
-
- if (OutputLen > 99000)
- break;
-
- }
-
- OutputLen += sprintf(&OutBuffer[OutputLen], WebTrailer);
-
- HeaderLen = sprintf(Header, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", OutputLen);
- sendandcheck(sock, Header, HeaderLen);
- sendandcheck(sock, OutBuffer, OutputLen);
-
- return;
-
- }
-
-
- if (_memicmp(URL, "/aprs/find.cgi?call=", 20) == 0)
- {
- // return Station details
-
- char * Call = &URL[20];
- BOOL RFOnly, WX, Mobile, Object = FALSE;
- struct STATIONRECORD * stn;
- char * Referrer = strstr(ptr + 1, "Referer:");
-
- // Undo any % transparency in call
-
- char * ptr1 = Call;
- char * ptr2 = Key;
- char c;
-
- c = *(ptr1++);
-
- while (c)
- {
- if (c == '%')
- {
- int n;
- int m = *(ptr1++) - '0';
- if (m > 9) m = m - 7;
- n = *(ptr1++) - '0';
- if (n > 9) n = n - 7;
-
- *(ptr2++) = m * 16 + n;
- }
- else if (c == '+')
- *(ptr2++) = ' ';
- else
- *(ptr2++) = c;
-
- c = *(ptr1++);
- }
-
- *(ptr2++) = 0;
-
- if (Referrer)
- {
- ptr = strchr(Referrer, 13);
- if (ptr)
- {
- *ptr = 0;
- RFOnly = !(strstr(Referrer, "rf") == NULL);
- WX = !(strstr(Referrer, "wx") == NULL);
- Mobile = !(strstr(Referrer, "mobile") == NULL);
- Object = !(strstr(Referrer, "obj") == NULL);
-
- if (WX)
- strcpy(URL, "/aprs/infowx_call.html");
- else if (Mobile)
- strcpy(URL, "/aprs/infomobile_call.html");
- else if (Object)
- strcpy(URL, "/aprs/infoobj_call.html");
- else
- strcpy(URL, "/aprs/info_call.html");
- }
- }
-
- if (Object)
- {
- // Name is space padded, and could have embedded spaces
-
- int Keylen = (int)strlen(Key);
-
- if (Keylen < 9)
- memset(&Key[Keylen], 32, 9 - Keylen);
- }
-
- stn = FindStation(Key, FALSE);
-
- if (stn == NULL)
- strcpy(URL, "/aprs/noinfo.html");
- else
- sockptr->SelCall = stn;
- }
-
-
- strcpy(sockptr->Callsign, Key);
-
- APRSSendMessageFile(sockptr, URL);
-
- return;
-}
-
-// Code for handling APRS messages within BPQ32/LinBPQ instead of GUI
-
-
-int ProcessMessage(char * Payload, struct STATIONRECORD * Station)
-{
- char MsgDest[10];
- struct APRSMESSAGE * Message;
- struct APRSMESSAGE * ptr = SMEM->Messages;
- char * TextPtr = &Payload[11];
- char * SeqPtr;
- int n = 0;
- char FromCall[10] = " ";
- struct tm * TM;
- time_t NOW;
- char noSeq[] = "";
- int ourMessage = 0;
-
- memcpy(FromCall, Station->Callsign, strlen(Station->Callsign));
- memcpy(MsgDest, &Payload[1], 9);
- MsgDest[9] = 0;
-
- if (strcmp(MsgDest, CallPadded) == 0) // to me?
- {
- SMEM->NeedRefresh = 255; // Flag to control Msg popup
- ourMessage = 1;
- }
- else
- SMEM->NeedRefresh = 1;
-
- SeqPtr = strchr(TextPtr, '{');
-
- if (SeqPtr)
- {
- *(SeqPtr++) = 0;
- if(strlen(SeqPtr) > 6)
- SeqPtr[7] = 0;
- }
- else
- SeqPtr = noSeq;
-
- if (_memicmp(TextPtr, "ack", 3) == 0)
- {
- // Message Ack. See if for one of our messages
-
- ptr = SMEM->OutstandingMsgs;
-
- if (ptr == 0)
- return ourMessage;
-
- do
- {
- if (strcmp(ptr->FromCall, MsgDest) == 0
- && strcmp(ptr->ToCall, FromCall) == 0
- && strcmp(ptr->Seq, &TextPtr[3]) == 0)
- {
- // Message is acked
-
- ptr->Retries = 0;
- ptr->Acked = TRUE;
-
- return ourMessage;
- }
- ptr = ptr->Next;
- n++;
-
- } while (ptr);
-
- return ourMessage;
- }
-
- // See if we already have this message
-
- ptr = SMEM->Messages;
-
- while(ptr)
- {
- if (strcmp(ptr->ToCall, MsgDest) == 0
- && strcmp(ptr->FromCall, FromCall) == 0
- && strcmp(ptr->Seq, SeqPtr) == 0
- && strcmp(ptr->Text, TextPtr) == 0)
-
- // Duplicate
-
- return ourMessage;
-
- ptr = ptr->Next;
- }
-
- Message = APRSGetMessageBuffer();
-
- if (Message == NULL)
- return ourMessage;
-
- memset(Message, 0, sizeof(struct APRSMESSAGE));
- memset(Message->FromCall, ' ', 9);
- memcpy(Message->FromCall, Station->Callsign, strlen(Station->Callsign));
- strcpy(Message->ToCall, MsgDest);
-
- if (SeqPtr)
- {
- strcpy(Message->Seq, SeqPtr);
-
- // If a REPLY-ACK Seg, copy to LastRXSeq, and see if it acks a message
-
- if (SeqPtr[2] == '}')
- {
- struct APRSMESSAGE * ptr1;
- int nn = 0;
-
- strcpy(Station->LastRXSeq, SeqPtr);
-
- ptr1 = SMEM->OutstandingMsgs;
-
- while (ptr1)
- {
- if (strcmp(ptr1->FromCall, MsgDest) == 0
- && strcmp(ptr1->ToCall, FromCall) == 0
- && memcmp(&ptr1->Seq, &SeqPtr[3], 2) == 0)
- {
- // Message is acked
-
- ptr1->Acked = TRUE;
- ptr1->Retries = 0;
-
- break;
- }
- ptr1 = ptr1->Next;
- nn++;
- }
- }
- else
- {
- // Station is not using reply-ack - set to send simple numeric sequence (workround for bug in APRS Messanges
-
- Station->SimpleNumericSeq = TRUE;
- }
- }
-
- if (strlen(TextPtr) > 100)
- TextPtr[100] = 0;
-
- strcpy(Message->Text, TextPtr);
-
- NOW = time(NULL);
-
- if (DefaultLocalTime)
- TM = localtime(&NOW);
- else
- TM = gmtime(&NOW);
-
- sprintf(Message->Time, "%.2d:%.2d", TM->tm_hour, TM->tm_min);
-
- if (_stricmp(MsgDest, CallPadded) == 0 && SeqPtr) // ack it if it has a sequence
- {
- // For us - send an Ack
-
- char ack[30];
- APRSHEARDRECORD * STN;
-
- sprintf(ack, ":%-9s:ack%s", Message->FromCall, Message->Seq);
-
- if (memcmp(Message->FromCall, "SERVER ", 9) == 0)
- {
- SendAPRSMessage(ack, 0); // IS
- }
- else
- {
- STN = FindStationInMH(Message->ToCall);
-
- if (STN)
- SendAPRSMessage(ack, STN->rfPort);
- else
- {
- SendAPRSMessage(ack, -1); // All RF ports
- SendAPRSMessage(ack, 0); // IS
- }
- }
- }
-
- if (SaveAPRSMsgs)
- SaveAPRSMessage(Message);
-
- ptr = SMEM->Messages;
-
- if (ptr == NULL)
- {
- SMEM->Messages = Message;
- }
- else
- {
- n++;
- while(ptr->Next)
- {
- ptr = ptr->Next;
- n++;
- }
- ptr->Next = Message;
- }
-
- return ourMessage;
-}
-
-BOOL InternalSendAPRSMessage(char * Text, char * Call)
-{
- char Msg[255];
- size_t len = strlen(Call);
- APRSHEARDRECORD * STN;
- struct tm * TM;
- time_t NOW;
-
- struct APRSMESSAGE * Message;
- struct APRSMESSAGE * ptr = SMEM->OutstandingMsgs;
-
- Message = APRSGetMessageBuffer();
-
- if (Message == NULL)
- return FALSE;
-
- memset(Message, 0, sizeof(struct APRSMESSAGE));
- strcpy(Message->FromCall, CallPadded);
-
- memset(Message->ToCall, ' ', 9);
- memcpy(Message->ToCall, Call, len);
-
- Message->ToStation = FindStation(Call, TRUE);
-
- if (Message->ToStation == NULL)
- return FALSE;
-
- SMEM->NeedRefresh = TRUE;
-
- if (Message->ToStation->LastRXSeq[0]) // Have we received a Reply-Ack message from him?
- sprintf(Message->Seq, "%02X}%c%c", ++Message->ToStation->NextSeq, Message->ToStation->LastRXSeq[0], Message->ToStation->LastRXSeq[1]);
- else
- {
- if (Message->ToStation->SimpleNumericSeq)
- sprintf(Message->Seq, "%d", ++Message->ToStation->NextSeq);
- else
- sprintf(Message->Seq, "%02X}", ++Message->ToStation->NextSeq); // Don't know, so assume message-ack capable
- }
-
- if (strlen(Text) > 100)
- Text[100] = 0;
-
- strcpy(Message->Text, Text);
- Message->Retries = RetryCount;
- Message->RetryTimer = RetryTimer;
-
- NOW = time(NULL);
-
- if (DefaultLocalTime)
- TM = localtime(&NOW);
- else
- TM = gmtime(&NOW);
-
- sprintf(Message->Time, "%.2d:%.2d", TM->tm_hour, TM->tm_min);
-
-
- // Chain to Outstanding Queue
-
- if (ptr == NULL)
- {
- SMEM->OutstandingMsgs = Message;
- }
- else
- {
- while(ptr->Next)
- {
- ptr = ptr->Next;
- }
- ptr->Next = Message;
- }
-
- sprintf(Msg, ":%-9s:%s{%s", Call, Text, Message->Seq);
-
- if (strcmp(Call, "SERVER") == 0)
- {
- SendAPRSMessage(Msg, 0); // IS
- return TRUE;
- }
-
- STN = FindStationInMH(Message->ToCall);
-
- if (STN && STN->MHTIME > (time(NULL) - 900)) // Heard in last 15 mins
- SendAPRSMessage(Msg, STN->rfPort);
- else
- {
- SendAPRSMessage(Msg, -1); // All RF ports
- SendAPRSMessage(Msg, 0); // IS
- }
- return TRUE;
-}
-
-
-
-
-
-extern BOOL APRSReconfigFlag;
-extern struct DATAMESSAGE * REPLYBUFFER;
-extern char COMMANDBUFFER[81];
-extern char OrigCmdBuffer[81];
-
-BOOL isSYSOP(TRANSPORTENTRY * Session, char * Bufferptr);
-
-VOID APRSCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, CMDX * CMD)
-{
- // APRS Subcommands. Default for compatibility is APRSMH
-
- // Others are STATUS ENABLEIGATE DISABLEIGATE RECONFIG
-
- APRSHEARDRECORD * MH = MHDATA;
- int n = MAXHEARDENTRIES;
- char * ptr;
- char * Pattern, * context;
- int Port = -1;
- char dummypattern[] ="";
-
- if (memcmp(CmdTail, "? ", 2) == 0)
- {
- Bufferptr = Cmdprintf(Session, Bufferptr, "APRS Subcommmands:\r");
- Bufferptr = Cmdprintf(Session, Bufferptr, "STATUS SEND MSGS SENT ENABLEIGATE DISABLEIGATE BEACON RECONFIG\r");
- Bufferptr = Cmdprintf(Session, Bufferptr, "Default is Station list - Params [Port] [Pattern]\r");
-
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (memcmp(CmdTail, "RECONFIG ", 5) == 0)
- {
- if (isSYSOP(Session, Bufferptr) == FALSE)
- return;
-
- if (!ProcessConfig())
- {
- Bufferptr = Cmdprintf(Session, Bufferptr, "Configuration File check failed - will continue with old config");
- }
- else
- {
- APRSReconfigFlag=TRUE;
- Bufferptr = Cmdprintf(Session, Bufferptr, "Reconfiguration requested\r");
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
- }
-
- if (memcmp(CmdTail, "ENABLEIGATE ", 6) == 0)
- {
- if (isSYSOP(Session, Bufferptr) == FALSE)
- return;
-
- IGateEnabled = TRUE;
- Bufferptr = Cmdprintf(Session, Bufferptr, "IGate Enabled\r");
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (memcmp(CmdTail, "DISABLEIGATE ", 6) == 0)
- {
- if (isSYSOP(Session, Bufferptr) == FALSE)
- return;
-
- IGateEnabled = FALSE;
- Bufferptr = Cmdprintf(Session, Bufferptr, "IGate Disabled\r");
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (memcmp(CmdTail, "STATUS ", 7) == 0)
- {
- if (IGateEnabled == FALSE)
- Bufferptr = Cmdprintf(Session, Bufferptr, "IGate Disabled\r");
- else
- {
- Bufferptr = Cmdprintf(Session, Bufferptr, "IGate Enabled ");
- if (APRSISOpen)
- Bufferptr = Cmdprintf(Session, Bufferptr, "and connected to %s\r", RealISHost);
- else
- Bufferptr = Cmdprintf(Session, Bufferptr, "but not connected\r");
- }
-
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (memcmp(CmdTail, "BEACON ", 7) == 0)
- {
- if (isSYSOP(Session, Bufferptr) == FALSE)
- return;
-
- BeaconCounter = 2;
- Bufferptr = Cmdprintf(Session, Bufferptr, "Beacons requested\r");
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (memcmp(CmdTail, "MSGS ", 5) == 0)
- {
- struct APRSMESSAGE * ptr = SMEM->Messages;
- char Addrs[32];
-
- Bufferptr = Cmdprintf(Session, Bufferptr,
- "\rTime Calls Seq Text\r");
-
- while (ptr)
- {
- char ToLopped[11] = "";
-
- memcpy(ToLopped, ptr->ToCall, 10);
- strlop(ToLopped, ' ');
-
- sprintf(Addrs, "%s>%s", ptr->FromCall, ToLopped);
-
- Bufferptr = Cmdprintf(Session, Bufferptr, "%s %-20s%-5s %s\r",
- ptr->Time, Addrs, ptr->Seq, ptr->Text);
-
- ptr = ptr->Next;
- }
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (memcmp(CmdTail, "SENT ", 5) == 0)
- {
- struct APRSMESSAGE * ptr = SMEM->OutstandingMsgs;
- char Addrs[32];
-
- Bufferptr = Cmdprintf(Session, Bufferptr,
- "\rTime Calls Seq State Text\r");
-
- while (ptr)
- {
- char ToLopped[11] = "";
- char Retries[10];
-
- if (ptr->Acked)
- strcpy(Retries, "A");
- else if (ptr->Retries == 0)
- strcpy(Retries, "F");
- else
- sprintf(Retries, "%d", ptr->Retries);
-
-
- memcpy(ToLopped, ptr->ToCall, 10);
- strlop(ToLopped, ' ');
-
- sprintf(Addrs, "%s>%s", ptr->FromCall, ToLopped);
-
- Bufferptr = Cmdprintf(Session, Bufferptr, "%s %-20s%-5s %-2s %s\r",
- ptr->Time, Addrs, ptr->Seq, Retries, ptr->Text);
-
- ptr = ptr->Next;
- }
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (memcmp(CmdTail, "SEND ", 5) == 0)
- {
- // Send Message. Params are Call and Message
-
- char * Call = strtok_s(&CmdTail[5], " \r", &context);
- char * Text = strtok_s(NULL, " \r", &context);
- int len = 0;
-
- if (isSYSOP(Session, Bufferptr) == FALSE)
- return;
-
- if (Call)
- len = (int)strlen(Call);
-
- if (len < 3 || len > 9)
- {
- Bufferptr = Cmdprintf(Session, Bufferptr, "Invalid Callsign\r");
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- if (Text == NULL)
- {
- Bufferptr = Cmdprintf(Session, Bufferptr, "No Message Text\r");
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
- // Replace command tail with original (before conversion to upper case
-
- Text = Text + (OrigCmdBuffer - COMMANDBUFFER);
-
- InternalSendAPRSMessage(Text, Call);
-
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- return;
- }
-
- // DISPLAY APRS HEARD LIST
-
- // APRS [Port] [Pattern]
-
- Pattern = strtok_s(CmdTail, " \r", &context);
-
- if (Pattern && (int)strlen(Pattern) < 3)
- {
- // could be port number
-
- if (isdigit(Pattern[0]) && (Pattern[1] == 0 || isdigit(Pattern[1])))
- {
- Port = atoi(Pattern);
- Pattern = strtok_s(NULL, " \r", &context);
- }
- }
-
- // Param is a pattern to match
-
- if (Pattern == NULL)
- Pattern = dummypattern;
-
- if (Pattern[0] == ' ')
- {
- // Prepare Pattern
-
- char * ptr1 = Pattern + 1;
- char * ptr2 = Pattern;
- char c;
-
- do
- {
- c = *ptr1++;
- *(ptr2++) = c;
- }
- while (c != ' ');
-
- *(--ptr2) = 0;
- }
-
- strlop(Pattern, ' ');
- _strupr(Pattern);
-
- *(Bufferptr++) = 13;
-
- while (n--)
- {
- if (MH->MHCALL[0] == 0)
- break;
-
- if ((Port > -1) && Port != MH->rfPort)
- {
- MH++;
- continue;
- }
-
- ptr = FormatAPRSMH(MH);
-
- MH++;
-
- if (ptr)
- {
- if (Pattern[0] && strstr(ptr, Pattern) == 0)
- continue;
-
- Bufferptr = Cmdprintf(Session, Bufferptr, "%s", ptr);
- }
- }
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
-}
-
-int GetPosnFromAPRS(char * Call, double * Lat, double * Lon)
-{
- struct STATIONRECORD * Station;
-
- Station = FindStation(Call, FALSE);
-
- if (Station)
- {
- *Lat = Station->Lat;
- *Lon = Station->Lon;
-
- return 1;
- }
-
- return 0;
-}
-
-// Station Name Font
-
-const unsigned char ASCII[][5] = {
-//const u08 ASCII[][5] = {
- {0x00, 0x00, 0x00, 0x00, 0x00} // 20
- ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
- ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
- ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
- ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
- ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
- ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
- ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
- ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
- ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
- ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
- ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
- ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
- ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
- ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
- ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
- ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
- ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
- ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
- ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
- ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
- ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
- ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
- ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
- ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
- ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
- ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
- ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
- ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
- ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
- ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
- ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
- ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
- ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
- ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
- ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
- ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
- ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
- ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
- ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
- ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
- ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
- ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
- ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
- ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
- ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
- ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
- ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
- ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
- ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
- ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
- ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
- ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
- ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
- ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
- ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
- ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
- ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
- ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
- ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
- ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c
- ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
- ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
- ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
- ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
- ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
- ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
- ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
- ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
- ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
- ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
- ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
- ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
- ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
- ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
- ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
- ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
- ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
- ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
- ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
- ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
- ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
- ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
- ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
- ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
- ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
- ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
- ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
- ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
- ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
- ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
- ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
- ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
- ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
- ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ~
- ,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f DEL
-};
-
-
-// APRS Web Map Code
-
-// Not sure yet what is best way to do station icons but for now build and cache any needed icons
-
-extern int IconDataLen;
-extern unsigned long long IconData[]; // Symbols as a png image.&
-
-// IconData is a png image, so needs to be uncompressed to an RGB array
-
-
-// Will key cached icons by IconRow, IconCol, Overlay Char - xxxxA
-
-int cachedIconCount = 0;
-
-// We need key, icon data, icon len for each. Maybe a simple linked list - we never remove any
-
-struct iconCacheEntry
-{
- struct iconCacheEntry * Next;
- char key[8];
- int pngimagelen;
- int pngmalloclen;
- unsigned char * pngimage;
-};
-
-struct iconCacheEntry * iconCache = NULL;
-
-
-// Each icon has to be created as an RGB array, then converted to a png image, as
-// Leaflet icons need a png file
-
-#include "mypng.h"
-
-
-struct png_info_struct * info_ptr = NULL;
-
-unsigned char * PngEncode (png_byte *pDiData, int iWidth, int iHeight, struct iconCacheEntry * Icon);
-
-void createIcon(char * Key, int iconRow, int iconCol, char Overlay)
-{
- int i, j, index, mask;
- int row;
- int col; // First row
- unsigned char * rgbData = malloc(68 * 22); // 1323
- unsigned char * ptr = rgbData;
- png_color colour = {0, 0, 0};
- int Pointer;
- char c;
- int bit;
- struct iconCacheEntry * Icon = zalloc(sizeof(struct iconCacheEntry));
-
- strcpy(Icon->key, Key);
-
- // icon data is in info_ptr->row_pointers (we have 255 of them)
-
- row = iconRow * 21;
- col = iconCol * 21 * 3;
-
- for (j = 0; j < 22; j++)
- {
- memcpy(ptr, info_ptr->row_pointers[row + j] + col, 22 * 3); // One scan line
- ptr += 68; // Rounded up to mod 4
- }
-
-
- // This code seems to assume an icon is 16 pixels, but image is 22 x 22 ???
-
-// j = ptr->iconRow * 21 * 337 * 3 + ptr->iconCol * 21 * 3 + 9 + 337 * 9;
-// for (i = 0; i < 16; i++)
-// {
-// memcpy(nptr, &iconImage[j], 16 * 3);
-// nptr += 6144;
-// j += 337 * 3;
-// }
-
-
- // If an overlay is specified, add it
-
- if (Overlay)
- {
- Pointer = 68 * 7 + 7 * 3; // 7th row, 7th col
- mask = 1;
-
- for (index = 0 ; index < 7 ; index++)
- {
- rgbData[Pointer++] = 255; // Blank line above chars
- rgbData[Pointer++] = 255;
- rgbData[Pointer++] = 255;
- }
-
- Pointer = 68 * 8 + 7 * 3; // 8th row, 7th col
-
- for (i = 0; i < 7; i++)
- {
- rgbData[Pointer++] = 255; // Blank col
- rgbData[Pointer++] = 255;
- rgbData[Pointer++] = 255;
-
- for (index = 0 ; index < 5 ; index++)
- {
- c = ASCII[Overlay - 0x20][index]; // Font data
- bit = c & mask;
-
- if (bit)
- {
- rgbData[Pointer++] = 0;
- rgbData[Pointer++] = 0;
- rgbData[Pointer++] = 0;
- }
- else
- {
- rgbData[Pointer++] = 255;
- rgbData[Pointer++] = 255;
- rgbData[Pointer++] = 255;
- }
- }
-
- rgbData[Pointer++] = 255; // Blank col
- rgbData[Pointer++] = 255;
- rgbData[Pointer++] = 255;
-
- mask <<= 1;
- Pointer += 47;
- }
- for (index = 0 ; index < 7 ; index++)
- {
- rgbData[Pointer++] = 255; // Blank line above chars
- rgbData[Pointer++] = 255;
- rgbData[Pointer++] = 255;
- }
- }
-
- // Encode
-
- PngEncode(rgbData, 22, 22, Icon);
-
- if (iconCache)
- Icon->Next = iconCache;
-
- iconCache = Icon;
-
-}
-
-int GetAPRSIcon(unsigned char * _REPLYBUFFER, char * NodeURL)
-{
- char Key[8] = "";
- struct iconCacheEntry * Icon = iconCache;
-
- memcpy(Key, &NodeURL[5], 5);
-
- while (Icon)
- {
- if (strcmp(Icon->key, Key) == 0) // Have it
- {
- memcpy(_REPLYBUFFER, Icon->pngimage, Icon->pngimagelen);
- return Icon->pngimagelen;
- }
- Icon = Icon->Next;
- }
-
- return 0;
-}
-
-char * doHTMLTransparency(char * string)
-{
- // Make sure string doesn't contain forbidden XML chars (<>"'&)
-
- char * newstring = malloc(5 * strlen(string) + 1); // If len is zero still need null terminator
-
- char * in = string;
- char * out = newstring;
- char c;
-
- c = *(in++);
-
- while (c)
- {
- switch (c)
- {
- case '<':
-
- strcpy(out, "<");
- out += 4;
- break;
-
- case '>':
-
- strcpy(out, ">");
- out += 4;
- break;
-
- case '"':
-
- strcpy(out, """);
- out += 6;
- break;
-
- case '\'':
-
- strcpy(out, "'");
- out += 6;
- break;
-
- case '&':
-
- strcpy(out, "&");
- out += 5;
- break;
-
- case ',':
-
- strcpy(out, ",");
- out += 5;
- break;
-
- case '|':
-
- strcpy(out, "|");
- out += 5;
- break;
-
- default:
-
- *(out++) = c;
- }
- c = *(in++);
- }
-
- *(out++) = 0;
- return newstring;
-}
-
-int GetAPRSPageInfo(char * Buffer, double N, double S, double W, double E, int aprs, int ais, int adsb)
-{
- struct STATIONRECORD * ptr = *StationRecords;
- int n = 0, Len = 0;
- struct tm * TM;
- time_t NOW = time(NULL);
- char popup[65536] = "";
- char Msg[2048];
- int LocalTime = 0;
- int KM = DefaultDistKM;
- char * ptr1;
-
- while (ptr && aprs && Len < 240000)
- {
- if (ptr->Lat != 0.0 && ptr->Lon != 0.0)
- {
- if (ptr->Lat > S && ptr->Lat < N && ptr->Lon > W && ptr->Lon < E)
- {
- // See if we have the Icon - if not build
-
- char IconKey[6];
- struct iconCacheEntry * Icon = iconCache;
-
- sprintf(IconKey, "%02X%02X ", ptr->iconRow, ptr->iconCol);
-
- if (ptr->IconOverlay)
- IconKey[4] = ptr->IconOverlay;
- else
- IconKey[4] = '@';
-
- while (Icon)
- {
- if (strcmp(Icon->key, IconKey) == 0) // Have it
- break;
-
- Icon = Icon->Next;
- }
-
- if (Icon == NULL)
- createIcon(IconKey, ptr->iconRow, ptr->iconCol, ptr->IconOverlay);
-
- popup[0] = 0;
-
- if (ptr->Approx)
- {
- sprintf(Msg, "Approximate Position From Locator ");
- strcat(popup, Msg);
- }
- ptr1 = doHTMLTransparency(ptr->Path);
- sprintf(Msg, "%s ", ptr1);
- strcat(popup, Msg);
- free(ptr1);
- ptr1 = doHTMLTransparency(ptr->LastPacket);
- sprintf(Msg, "%s ", ptr1);
- strcat(popup, Msg);
- free(ptr1);
- ptr1 = doHTMLTransparency(ptr->Status);
- sprintf(Msg, "%s ", ptr1);
- strcat(popup, Msg);
- free(ptr1);
- if (LocalTime)
- TM = localtime(&ptr->TimeLastUpdated);
- else
- TM = gmtime(&ptr->TimeLastUpdated);
-
- sprintf(Msg, "Last Heard: %.2d:%.2d:%.2d on Port %d ",
- TM->tm_hour, TM->tm_min, TM->tm_sec, ptr->LastPort);
-
- strcat(popup, Msg);
-
- sprintf(Msg, "Distance %6.1f Bearing %3.0f Course %1.0f° Speed %3.1f ",
- myDistance(ptr->Lat, ptr->Lon, KM),
- myBearing(ptr->Lat, ptr->Lon), ptr->Course, ptr->Speed);
- strcat(popup, Msg);
-
- if (ptr->LastWXPacket[0])
- {
- //display wx info
-
- struct APRSConnectionInfo temp;
-
- memset(&temp, 0, sizeof(temp));
-
- DecodeWXReport(&temp, ptr->LastWXPacket);
-
- sprintf(Msg, "Wind Speed %d MPH ", temp.WindSpeed);
- strcat(popup, Msg);
-
- sprintf(Msg, "Wind Gust %d MPH ", temp.WindGust);
- strcat(popup, Msg);
-
- sprintf(Msg, "Wind Direction %d\xC2\xB0 ", temp.WindDirn);
- strcat(popup, Msg);
-
- sprintf(Msg, "Temperature %d\xC2\xB0 F ", temp.Temp);
- strcat(popup, Msg);
-
- sprintf(Msg, "Pressure %05.1f ", temp.Pressure / 10.0);
- strcat(popup, Msg);
-
- sprintf(Msg, "Humidity %d%% ", temp.Humidity);
- strcat(popup, Msg);
-
- sprintf(Msg, "Rainfall Last Hour/Last 24H/Today %5.2f, %5.2f, %5.2f (inches)",
- temp.RainLastHour / 100.0, temp.RainLastDay / 100.0, temp.RainToday / 100.0);
-
- ptr1 = doHTMLTransparency(Msg);
- sprintf(Msg, "%s ", ptr1);
- strcat(popup, Msg);
- free(ptr1);
- }
-
- Len += sprintf(&Buffer[Len],"A,%.4f,%.4f,%s,%s,%s,%d\r\n|",
- ptr->Lat, ptr->Lon, ptr->Callsign, popup, IconKey,
- NOW - ptr->TimeLastUpdated);
-
- if (ptr->TrackTime[0] && ptr->TrackTime[1]) // Have trackpoints
- {
- int n = ptr->Trackptr;
- int i;
- double lastLat = 0;
-
- // We read from next track point (oldest) for TRACKPOINT records, ignoring zeros
-
- Len += sprintf(&Buffer[Len],"T,");
-
- for (i = 0; i < TRACKPOINTS; i++)
- {
- if (ptr->TrackTime[n])
- {
- Len += sprintf(&Buffer[Len],"%.4f,%.4f,", ptr->LatTrack[n], ptr->LonTrack[n]);
- lastLat = ptr->LatTrack[n];
- }
-
- n++;
- if (n == TRACKPOINTS)
- n = 0;
- }
- if (lastLat != ptr->Lat)
- Len += sprintf(&Buffer[Len],"%.4f,%.4f,\r\n|", ptr->Lat, ptr->Lon); //Add current position to end of track
- else
- Len += sprintf(&Buffer[Len],"\r\n|");
- }
- }
- }
-
- ptr = ptr->Next;
- }
- return Len;
-}
-
-
-
-
- /* The png_jmpbuf() macro, used in error handling, became available in
- * libpng version 1.0.6. If you want to be able to run your code with older
- * versions of libpng, you must define the macro yourself (but only if it
- * is not already defined by libpng!).
- */
-#ifndef png_jmpbuf
-# define png_jmpbuf(png_ptr) ((png_ptr)->png_jmpbuf)
-#endif
-/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
- * returns zero if the image is a PNG and nonzero if it isn't a PNG.
- *
- * The function check_if_png() shown here, but not used, returns nonzero (true)
- * if the file can be opened and is a PNG, 0 (false) otherwise.
- *
- * If this call is successful, and you are going to keep the file open,
- * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
- * you have created the png_ptr, so that libpng knows your application
- * has read that many bytes from the start of the file. Make sure you
- * don't call png_set_sig_bytes() with more than 8 bytes read or give it
- * an incorrect number of bytes read, or you will either have read too
- * many bytes (your fault), or you are telling libpng to read the wrong
- * number of magic bytes (also your fault).
- *
- * Many applications already read the first 2 or 4 bytes from the start
- * of the image to determine the file type, so it would be easiest just
- * to pass the bytes to png_sig_cmp() or even skip that if you know
- * you have a PNG file, and call png_set_sig_bytes().
- */
-
-unsigned char * user_io_ptr = 0;
-
-void __cdecl user_read_fn(png_struct * png, png_bytep Buffer, png_size_t Len)
-{
- unsigned char ** ptr = png->io_ptr;
- unsigned char * ptr1;
-
- ptr1 = ptr[0];
-
- memcpy(Buffer, ptr1, Len);
- ptr[0]+= Len;
-}
-
-
-// This is based on example https://www1.udel.edu/CIS/software/dist/libpng-1.2.8/example.c
-
-// This decodes a png encoded image from memory
-
-int read_png(unsigned char *bytes)
-{
- png_structp png_ptr;
- unsigned int sig_read = 0;
-
- /* Create and initialize the png_struct with the desired error handler
- * functions. If you want to use the default stderr and longjump method,
- * you can supply NULL for the last three parameters. We also supply the
- * the compiler header file version, so that we know if the application
- * was compiled with a compatible version of the library. REQUIRED
- */
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
- if (png_ptr == NULL)
- {
- return (0);
- }
- /* Allocate/initialize the memory for image information. REQUIRED. */
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL)
- {
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- return (0);
- }
- /* Set error handling if you are using the setjmp/longjmp method (this is
- * the normal method of doing things with libpng). REQUIRED unless you
- * set up your own error handlers in the png_create_read_struct() earlier.
- */
-
- user_io_ptr = (unsigned char *)&IconData;
-
- png_set_read_fn(png_ptr, (void *)&user_io_ptr,(png_rw_ptr)user_read_fn);
-
- png_set_sig_bytes(png_ptr, sig_read);
-
- png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, NULL);
-
- // Data is in info->row_pointers. Can we use it from there ??
-
-// printf("%d %d %d\n", info_ptr->width, info_ptr->height, info_ptr->valid);
-
- return TRUE;
-}
-
-void Myabort()
-{}
-
-// This is based on pngfile.c
-
-//-------------------------------------
-// PNGFILE.C -- Image File Functions
-//-------------------------------------
-
-// Copyright 2000, Willem van Schaik. For conditions of distribution and
-// use, see the copyright/license/disclaimer notice in png.h
-
-// Encodes pDiData to png format in memory
-
-
-
-void my_png_write_data(struct png_struct_def * png_ptr, png_bytep data, png_size_t length)
-{
- struct iconCacheEntry * Icon = png_ptr->io_ptr;
-
- if (Icon->pngimagelen + (int)length > Icon->pngmalloclen)
- {
- Icon->pngmalloclen += length;
- Icon->pngimage = realloc(Icon->pngimage, Icon->pngmalloclen);
- }
-
- memcpy(&Icon->pngimage[Icon->pngimagelen], data, length);
- Icon->pngimagelen += length;
-}
-
- // io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
- // Area png_uint_32 check;
-
-
-
-static void png_flush(png_structp png_ptr)
-{
-}
-
-unsigned char * PngEncode (png_byte *pDiData, int iWidth, int iHeight, struct iconCacheEntry * Icon)
-{
- const int ciBitDepth = 8;
- const int ciChannels = 3;
- png_structp png_ptr;
- png_infop info_ptr = NULL;
- png_uint_32 ulRowBytes;
- static png_byte **ppbRowPointers = NULL;
- int i;
-
- // Set up image array and pointer. First allocate a buffer as big as the original
- // in the unlikely event of it being too small write_data will realloc it
-
- Icon->pngmalloclen = iWidth * iHeight * 3;
- Icon->pngimage = malloc(Icon->pngmalloclen);
- Icon->pngimagelen = 0;
-
- // prepare the standard PNG structures
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
- if (!png_ptr)
- {
- return FALSE;
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
- {
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
- return FALSE;
- }
-
- {
- // initialize the png structure
-
- png_set_write_fn(png_ptr, Icon, my_png_write_data, png_flush);
-
- png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth,
- PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
- PNG_FILTER_TYPE_BASE);
-
- // write the file header information
-
- png_write_info(png_ptr, info_ptr);
-
- // row_bytes is the width x number of channels
-
- ulRowBytes = iWidth * ciChannels;
-
- // we can allocate memory for an array of row-pointers
-
- if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL)
- Debugprintf( "Visualpng: Out of memory");
-
- // set the individual row-pointers to point at the correct offsets
-
- for (i = 0; i < iHeight; i++)
- ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2);
-
- // write out the entire image data in one call
-
- png_write_image (png_ptr, ppbRowPointers);
-
- // write the additional chunks to the PNG file (not really needed)
-
- png_write_end(png_ptr, info_ptr);
-
- // and we're done
-
- free (ppbRowPointers);
- ppbRowPointers = NULL;
-
- // clean up after the write, and free any memory allocated
-
- png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-
- // yepp, done
- }
-
- return Icon->pngimage;
-}
-
-void SaveAPRSMessage(struct APRSMESSAGE * ptr)
-{
- // Save messages in case of a restart
-
- char FN[250];
- FILE *file;
-
- // Set up filename
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(FN,"APRSMsgs.dat");
- }
- else
- {
- strcpy(FN,BPQDirectory);
- strcat(FN,"/");
- strcat(FN,"APRSMsgs.dat");
- }
-
- if ((file = fopen(FN, "a")) == NULL)
- return ;
-
- fprintf(file, "%d %s,%s,%s,%s,%s\n", time(NULL), ptr->FromCall, ptr->ToCall, ptr->Seq, ptr->Time, ptr->Text);
-
- fclose(file);
-}
-
-void ClearSavedMessages()
-{
- char FN[250];
- FILE *file;
-
- // Set up filename
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(FN,"APRSMsgs.dat");
- }
- else
- {
- strcpy(FN,BPQDirectory);
- strcat(FN,"/");
- strcat(FN,"APRSMsgs.dat");
- }
-
- if ((file = fopen(FN, "w")) == NULL)
- return ;
-
- fclose(file);
-}
-
-void GetSavedAPRSMessages()
-{
- // Get Saved messages
-
- // 1668768157 SERVER ,GM8BPQ-2 ,D7Yx,10:42,filter m/200 active
-
- char FN[250];
- FILE *file;
- struct APRSMESSAGE * Message;
- struct APRSMESSAGE * ptr;
- char Line[512];
- char * Stamp = 0;
- char * From = 0;
- char * To = 0;
- char * Seq = 0;
- char * Time = 0;
- char * Text = 0;
-
- // Set up filename
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(FN,"APRSMsgs.dat");
- }
- else
- {
- strcpy(FN,BPQDirectory);
- strcat(FN,"/");
- strcat(FN,"APRSMsgs.dat");
- }
-
- if ((file = fopen(FN, "r")) == NULL)
- return ;
-
- while (fgets(Line, 512, file))
- {
- Stamp = Line;
- From = strlop(Stamp, ' ');
- To = strlop(From, ',');
- Seq = strlop(To, ',');
- Time = strlop(Seq, ',');
- Text = strlop(Time, ',');
-
- if (Stamp && From && To && Seq && Time && Text)
- {
- Message = APRSGetMessageBuffer();
-
- if (Message == NULL)
- break;
-
- memset(Message, 0, sizeof(struct APRSMESSAGE));
-
- strcpy(Message->FromCall, From);
- strcpy(Message->ToCall, To);
- strcpy(Message->Seq, Seq);
- strcpy(Message->Time, Time);
- strcpy(Message->Text, Text);
-
- ptr = SMEM->Messages;
-
- if (ptr == NULL)
- {
- SMEM->Messages = Message;
- }
- else
- {
- while(ptr->Next)
- {
- ptr = ptr->Next;
- }
- ptr->Next = Message;
- }
-
- }
- }
- fclose(file);
-}
diff --git a/APRSCode.c.rej b/APRSCode.c.rej
deleted file mode 100644
index 1137117..0000000
--- a/APRSCode.c.rej
+++ /dev/null
@@ -1,139 +0,0 @@
---- APRSCode.c
-+++ APRSCode.c
-@@ -3674,7 +3674,7 @@
- if (ptr1)
- *ptr1 = 0;
-
--// Debugprintf("Duplicate Message supressed %s", Msg);
-+// Debugprintf("Duplicate Message suppressed %s", Msg);
- return TRUE; // Duplicate
- }
- }
---- BPQChat.rc
-+++ BPQChat.rc
-@@ -162,7 +162,7 @@
- WS_VSCROLL
- DEFPUSHBUTTON "Save Welcome Message",SAVEWELCOME,140,296,91,14,
- BS_CENTER | BS_VCENTER
-- LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
-+ LTEXT " If the node is not directly connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT",
- IDC_STATIC,9,52,355,24
- END
-
---- BPQMail.rc
-+++ BPQMail.rc
-@@ -1045,7 +1045,7 @@
- CONTROL "Delete Log and Message Files to Recycle Bin",
- IDC_DELETETORECYCLE,"Button",BS_AUTOCHECKBOX |
- BS_LEFTTEXT | BS_MULTILINE | WS_TABSTOP,5,142,115,20
-- CONTROL "Supress Mailing of Housekeeping Results",
-+ CONTROL "Suppress Mailing of Housekeeping Results",
- IDC_MAINTNOMAIL,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT |
- BS_MULTILINE | WS_TABSTOP,5,182,115,20
- CONTROL "Generate Traffic Report",IDC_MAINTTRAFFIC,"Button",
---- HanksRT.c
-+++ HanksRT.c
-@@ -1186,7 +1186,7 @@
- // Duplicate, so discard, but save time
-
- DupInfo[i].DupTime = Now;
-- Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s supressed", Call, Msg);
-+ Logprintf(LOG_CHAT, circuit, '?', "Duplicate Message From %s %s suppressed", Call, Msg);
-
- return TRUE; // Duplicate
- }
---- RigControl.c
-+++ RigControl.c
-@@ -8385,7 +8385,7 @@
-
- switch (Msg[0])
- {
-- case 'f': // Get Freqency
-+ case 'f': // Get Frequency
-
- HLGetFreq(Sock, RIG, sep);
- return 0;
---- UZ7HODrv.c
-+++ UZ7HODrv.c
-@@ -374,7 +374,7 @@
- {
- // Read Freq
-
-- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Freqency %d\r", AGW->CenterFreq);
-+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Modem Frequency %d\r", AGW->CenterFreq);
- return 1;
- }
-
-@@ -382,7 +382,7 @@
-
- if (AGW->CenterFreq == 0)
- {
-- buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Freqency\r");
-+ buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "UZ7HO} Invalid Modem Frequency\r");
- return 1;
- }
-
---- WinRPRHelper.c
-+++ WinRPRHelper.c
-@@ -111,7 +111,7 @@
-
- if (argc < 3)
- {
-- printf ("Missing paramters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
-+ printf ("Missing parameters - you need COM port and IP Address and rigctl port of BPQ, eg \r\n"
- " WinRPRHelper com10 192.168.1.64:4532\r\n\r\n"
- "Press any key to exit\r\n");
-
---- config.c
-+++ config.c
-@@ -649,7 +649,7 @@
- if (LOCATOR[0] == 0 && LocSpecified == 0 && RFOnly == 0)
- {
- Consoleprintf("");
-- Consoleprintf("Please enter a LOCATOR statment in your BPQ32.cfg");
-+ Consoleprintf("Please enter a LOCATOR statement in your BPQ32.cfg");
- Consoleprintf("If you really don't want to be on the Node Map you can enter LOCATOR=NONE");
- Consoleprintf("");
-
---- kiss.c
-+++ kiss.c
-@@ -1485,7 +1485,7 @@
- }
- }
- else
-- Debugprintf("Polled KISS - response from wrong address - Polled %d Reponse %d",
-+ Debugprintf("Polled KISS - response from wrong address - Polled %d Response %d",
- KISS->POLLPOINTER->OURCTRL, (Port->RXMSG[0] & 0xf0));
-
- goto SeeifMore; // SEE IF ANYTHING ELSE
---- templatedefs.c
-+++ templatedefs.c
-@@ -1165,7 +1165,7 @@
- "Send Non-delivery Notifications \r\n"
- "for P and T messages \r\n"
- " \r\n"
-- "Supress Mailing of \r\n"
-+ "Suppress Mailing of \r\n"
- "Housekeeping Result
\r\n"
- "Generate Traffic Report
\r\n"
- "\r\n"
-@@ -1454,7 +1454,7 @@
- "
The Nodes to link to box defines which other Chat Nodes should be connected to, or from which "
- "connections may be accepted. The format is ALIAS:CALL, eg BPQCHT:G8BPQ-4. If the node is not directly "
- "connectable (ie is not in your NODES table) you can add a connect script. This consists of a series of commands "
-- "seperared by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
-+ "separated by |, eg NOTCHT:G8BPQ-4|C 3 GM8BPQ-9|CHAT"
-
- "
The Callsign of the Chat Node is not defined here - it is obtained from the bpq32.cfg APPLICATION line corresponding to the Chat Appl Number. \r\n"
- "
\n"
---- WebMail.c
-+++ WebMail.c
-@@ -2020,7 +2020,7 @@
- "document.getElementById('myform').action = '/WebMail/QuoteOriginal' + '?%s';"
- " document.getElementById('myform').submit();}"
- "";
-+ "value='Include Original Msg'>";
-
- char Temp[1024];
- char ReplyAddr[128];
diff --git a/ARDOP.c b/ARDOP.c
index 4e4cc8d..8cae151 100644
--- a/ARDOP.c
+++ b/ARDOP.c
@@ -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)
diff --git a/BPQINP3.c b/BPQINP3.c
index 38c49b9..dcc17c6 100644
--- a/BPQINP3.c
+++ b/BPQINP3.c
@@ -932,7 +932,7 @@ int SendRIPTimer()
// Delay more if Locked - they could be retrying for a long time
- if ((Route->NEIGHBOUR_FLAG & 1)) // LOCKED ROUTE
+ if ((Route->NEIGHBOUR_FLAG)) // LOCKED ROUTE
INP3Delay = 1200;
else
INP3Delay = 600;
diff --git a/BPQMail.c b/BPQMail.c
index f566d64..a0971d9 100644
--- a/BPQMail.c
+++ b/BPQMail.c
@@ -1147,6 +1147,7 @@
// Send forwarding info to packetnodes.spots.radio database (51)
// Fix bug in WP Message processing (56)
// Fix treating addresses ending in WW as Internet (57)
+// Run sending to packetnodes.spots.radio in a separate thread (61)
#include "bpqmail.h"
#include "winstdint.h"
diff --git a/Bpq32-skigdebian.c b/Bpq32-skigdebian.c
deleted file mode 100644
index a78510b..0000000
--- a/Bpq32-skigdebian.c
+++ /dev/null
@@ -1,6741 +0,0 @@
-/*
-Copyright 2001-2022 John Wiseman G8BPQ
-
-This file is part of LinBPQ/BPQ32.
-
-LinBPQ/BPQ32 is free software: you can redistribute it and/or modifyextern int HTTP
-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
-*/
-//
-// 409l Oct 2001 Fix l3timeout for KISS
-//
-// 409m Oct 2001 Fix Crossband Digi
-//
-// 409n May 2002 Change error handling on load ext DLL
-
-// 409p March 2005 Allow Multidigit COM Ports (kiss.c)
-
-// 409r August 2005 Treat NULL string in Registry as use current directory
-// Allow shutdown to close BPQ Applications
-
-// 409s October 2005 Add DLL:Export entries to API for BPQTNC2
-
-// 409t January 2006
-//
-// Add API for Perl "GetPerlMsg"
-// Add API for BPQ1632 "GETBPQAPI" - returns address of Assembler API routine
-// Add Registry Entry "BPQ Directory". If present, overrides "Config File Location"
-// Add New API "GetBPQDirectory" - Returns location of config file
-// Add New API "ChangeSessionCallsign" - equivalent to "*** linked to" command
-// Rename BPQNODES to BPQNODES.dat
-// New API "GetAttachedProcesses" - returns number of processes connected.
-// Warn if user trys to close Console Window.
-// Add Debug entries to record Process Attach/Detach
-// Fix recovery following closure of first process
-
-// 409t Beta 2 February 2006
-//
-// Add API Entry "GetPortNumber"
-//
-// 409u February 2006
-//
-// Fix crash if allocate/deallocate called with stream=0
-// Add API to ch
-// Display config file path
-// Fix saving of Locked Node flag
-// Added SAVENODES SYSOP command
-//
-// 409u 2 March 2006
-//
-// Fix SetupBPQDirectory
-// Add CopyBPQDirectory (for Basic Programs)
-//
-// 409u 3 March 2006
-//
-// Release streams on DLL unload
-
-// 409v October 2006
-//
-// Support Minimize to Tray for all BPQ progams
-// Implement L4 application callsigns
-
-// 410 November 2006
-//
-// Modified to compile with C++ 2005 Express Edition
-// Make MCOM MTX MMASK local variables
-//
-// 410a January 2007
-//
-// Add program name to Attach-Detach messages
-// Attempt to detect processes which have died
-// Fix bug in NETROM and IFrame decode which would cause crash if frame was corrupt
-// Add BCALL - origin call for Beacons
-// Fix KISS ACKMODE ACK processing
-//
-
-// 410b November 2007
-//
-// Allow CTEXT of up to 510, and enforce PACLEN, fragmenting if necessary
-
-// 410c December 2007
-
-// Fix problem with NT introduced in V410a
-// Display location of DLL on Console
-
-// 410d January 2008
-
-// Fix crash in DLL Init caused by long path to program
-// Invoke Appl2 alias on C command (if enabled)
-// Allow C command to be disabled
-// Remove debug trap in GETRAWFRAME
-// Validate Alias of directly connected node, mainly for KPC3 DISABL Problem
-// Move Port statup code out of DLLInit (mainly for perl)
-// Changes to allow Load/Unload of bpq32.dll by appl
-// CloseBPQ32 API added
-// Ext Driver Close routes called
-// Changes to release Mutex
-
-// 410e May 2008
-
-// Fix missing SSID on last call of UNPROTO string (CONVTOAX25 in main.asm)
-// Fix VCOM Driver (RX Len was 1 byte too long)
-// Fix possible crash on L4CODE if L4DACK received out of sequence
-// Add basic IP decoding
-
-// 410f October 2008
-
-// Add IP Gateway
-// Add Multiport DIGI capability
-// Add GetPortDescription API
-// Fix potential hangs if RNR lost
-// Fix problem if External driver failes to load
-// Put pushad/popad round _INITIALISEPORTS (main.asm)
-// Add APIs GetApplCallVB and GetPortDescription (mainly for RMS)
-// Ensure Route Qual is updated if Port Qual changed
-// Add Reload Option, plus menu items for DUMP and SAVENODES
-
-// 410g December 2008
-
-// Restore API Exports BPQHOSTAPIPTR and MONDECODEPTR (accidentally deleted)
-// Fix changed init of BPQDirectory (accidentally changed)
-// Fix Checks for lost processes (accidentally deleted)
-// Support HDLC Cards on W2K and above
-// Delete Tray List entries for crashed processes
-// Add Option to NODES command to sort by Callsign
-// Add options to save or clear BPQNODES before Reconfig.
-// Fix Reconfig in Win98
-// Monitor buffering tweaks
-// Fix Init for large (>64k) tables
-// Fix Nodes count in Stats
-
-// 410h January 2009
-
-// Add Start Minimized Option
-// Changes to KISS for WIn98 Virtual COM
-// Open \\.\com instead of //./COM
-// Extra Dignostics
-
-// 410i Febuary 2009
-
-// Revert KISS Changes
-// Save Window positions
-
-// 410j June 2009
-
-// Fix tidying of window List when program crashed
-// Add Max Nodes to Stats
-// Don't update APPLnALIAS with received NODES info
-// Fix MH display in other timezones
-// Fix Possible crash when processing NETROM type Zero frames (eg NRR)
-// Basic INP3 Stuff
-// Add extra diagnostics to Lost Process detection
-// Process Netrom Record Route frames.
-
-// 410k June 2009
-
-// Fix calculation of %retries in extended ROUTES display
-// Fix corruption of ROUTES table
-
-// 410l October 2009
-
-// Add GetVersionString API call.
-// Add GetPortTableEntry API call
-// Keep links to neighbouring nodes open
-
-// Build 2
-
-// Fix PE in NOROUTETODEST (missing POP EBX)
-
-// 410m November 2009
-
-// Changes for PACTOR and WINMOR to support the ATTACH command
-// Enable INP3 if configured on a route.
-// Fix count of nodes in Stats Display
-// Overwrite the worst quality unused route if a call is received from a node not in your
-// table when the table is full
-
-// Build 5
-
-// Rig Control Interface
-// Limit KAM VHF attach and RADIO commands to authorised programs (MailChat and BPQTerminal)
-
-// Build 6
-
-// Fix reading INP3 Flag from BPQNODES
-
-// Build 7
-
-// Add MAXHOPS and MAXRTT config options
-
-// Build 8
-
-// Fix INP3 deletion of Application Nodes.
-// Fix GETCALLSIGN for Pactor Sessions
-// Add N Call* to display all SSID's of a call
-// Fix flow control on Pactor sessions.
-
-// Build 9
-
-// HDLC Support for XP
-// Add AUTH routines
-
-// Build 10
-
-// Fix handling commands split over more that one packet.
-
-// Build 11
-
-// Attach cmd changes for winmor disconnecting state
-// Option Interlock Winmor/Pactor ports
-
-// Build 12
-
-// Add APPLS export for winmor
-// Handle commands ending CR LF
-
-// Build 13
-
-// Incorporate Rig Control in Kernel
-
-// Build 14
-
-// Fix config reload for Rig COntrol
-
-// 410n March 2010
-
-// Implement C P via PACTOR/WINMOR (for Airmail)
-
-// Build 2
-
-// Don't flip SSID bits on Downlink Connect if uplink is Pactor/WINMOR
-// Fix resetting IDLE Timer on Pactor/WINMOR sessions
-// Send L4 KEEPLI messages based on IDLETIME
-
-// 410o July 2010
-
-// Read bpqcfg.txt instead of .bin
-// Support 32 bit MMASK (Allowing 32 Ports)
-// Support 32 bit _APPLMASK (Allowing 32 Applications)
-// Allow more commands
-// Allow longer command aliases
-// Fix logic error in RIGControl Port Initialisation (wasn't always raising RTS and DTR
-// Clear RIGControl RTS and DTR on close
-
-// 410o Build 2 August 2010
-
-// Fix couple of errors in config (needed APPLICATIONS and BBSCALL/ALIAS/QUAL)
-// Fix Kenwood Rig Control when more than one message received at once.
-// Save minimzed state of Rigcontrol Window
-
-// 410o Build 3 August 2010
-
-// Fix reporting of set errors in scan to a random session
-
-// 410o Build 4 August 2010
-
-// Change All xxx Ports are in use to no xxxx Ports are available if there are no sessions with _APPLMASK
-// Fix validation of TRANSDELAY
-
-// 410o Build 5 August 2010
-
-// Add Repeater Shift and Set Data Mode options to Rigcontrol (for ICOM only)
-// Add WINMOR and SCS Pactor mode control option to RigControl
-// Extend INFOMSG to 2000 bytes
-// Improve Scan freq change lock (check both SCS and WINMOR Ports)
-
-// 410o Build 6 September 2010
-
-// Incorporate IPGateway in main code.
-// Fix GetSessionInfo for Pactor/Winmor Ports
-// Add Antenna Selection to RigControl
-// Allow Bandwidth options on RADIO command line (as well as in Scan definitions)
-
-// 410o Build 7 September 2010
-
-// Move rigconrtol display to driver windows
-// Move rigcontrol config to driver config.
-// Allow driver and IPGateway config info in bpq32.cfg
-// Move IPGateway, AXIP, VKISS, AGW and WINMOR drivers into bpq32.dll
-// Add option to reread IP Gateway config.
-// Fix Reinit after process with timer closes (error in TellSessions).
-
-// 410p Build 2 October 2010
-
-// Move KAM and SCS drivers to bpq32.dll
-
-// 410p Build 3 October 2010
-
-// Support more than one axip port.
-
-// 410p Build 4 October 2010
-
-// Dynamically load psapi.dll (for 98/ME)
-
-// 410p Build 5 October 2010
-
-// Incorporate TelnetServer
-// Fix AXIP ReRead Config
-// Report AXIP accept() fails to syslog, not a popup.
-
-// 410p Build 6 October 2010
-
-// Includes HAL support
-// Changes to Pactor Drivers disconnect code
-// AXIP now sends with source port = dest port, unless overridden by SOURCEPORT param
-// Config now checks for duplicate port definitions
-// Add Node Map reporting
-// Fix WINMOR deferred disconnect.
-// Report Pactor PORTCALL to WL2K instead of RMS Applcall
-
-// 410p Build 7 October 2010
-
-// Add In/Out flag to Map reporting, and report centre, not dial
-// Write Telnet log to BPQ Directory
-// Add Port to AXIP resolver display
-// Send Reports to update.g8bpq.net:81
-// Add support for FT100 to Rigcontrol
-// Add timeout to Rigcontrol PTT
-// Add Save Registry Command
-
-// 410p Build 8 November 2010
-
-// Add NOKEEPALIVES Port Param
-// Renumbered for release
-
-// 410p Build 9 November 2010
-
-// Get Bandwith for map report from WL2K Report Command
-// Fix freq display for FT100 (was KHz, not MHz)
-// Don't try to change SCS mode whilst initialising
-// Allow reporting of Lat/Lon as well as Locator
-// Fix Telnet Log Name
-// Fix starting with Minimized windows when Minimizetotray isn't set
-// Extra Program Error trapping in SessionControl
-// Fix reporting same freq with different bandwidths at different times.
-// Code changes to support SCS Robust Packet Mode.
-// Add FT2000 to Rigcontrol
-// Only Send CTEXT to connects to Node (not to connects to an Application Call)
-
-// Released as Build 10
-
-// 410p Build 11 January 2011
-
-// Fix MH Update for SCS Outgoing Calls
-// Add Direct CMS Access to TelnetServer
-// Restructure DISCONNECT processing to run in Timer owning process
-
-// 410p Build 12 January 2011
-
-// Add option for Hardware PTT to use a different com port from the scan port
-// Add CAT PTT for Yaesu 897 (and maybe others)
-// Fix RMS Packet ports busy after restart
-// Fix CMS Telnet with MAXSESSIONS > 10
-
-// 410p Build 13 January 2011
-
-// Fix loss of buffers in TelnetServer
-// Add CMS logging.
-// Add non - Promiscuous mode option for BPQETHER
-
-// 410p Build 14 January 2011
-
-// Add support for BPQTermTCP
-// Allow more that one FBBPORT
-// Allow Telnet FBB mode sessions to send CRLF as well as CR on user and pass msgs
-// Add session length to CMS Telnet logging.
-// Return Secure Session Flag from GetConnectionInfo
-// Show Uptime as dd/hh/mm
-
-// 4.10.16.17 March 2011
-
-// Add "Close all programs" command
-// Add BPQ Program Directory registry key
-// Use HKEY_CURRENT_USER on Vista and above (and move registry if necessary)
-// Time out IP Gateway ARP entries, and only reload ax.25 ARP entries
-// Add support for SCS Tracker HF Modes
-// Fix WL2K Reporting
-// Report Version to WL2K
-// Add Driver to support Tracker with multiple sessions (but no scanning, wl2k report, etc)
-
-
-// Above released as 5.0.0.1
-
-// 5.2.0.1
-
-// Add caching of CMS Server IP addresses
-// Initialise TNC State on Pactor Dialogs
-// Add Shortened (6 digit) AUTH mode.
-// Update MH with all frames (not just I/UI)
-// Add IPV6 Support for TelnetServer and AXIP
-// Fix TNC OK Test for Tracker
-// Fix crash in CMS mode if terminal disconnects while tcp commect in progress
-// Add WL2K reporting for Robust Packet
-// Add option to suppress WL2K reporting for specific frequencies
-// Fix Timeband processing for Rig Control
-// New Driver for SCS Tracker allowing multiple connects, so Tracker can be used for user access
-// New Driver for V4 TNC
-
-// 5.2.1.3 October 2011
-
-// Combine busy detector on Interlocked Ports (SCS PTC, WINMOR or KAM)
-// Improved program error logging
-// WL2K reporting changed to new format agreed with Lee Inman
-
-// 5.2.3.1 January 2012
-
-// Connects from the console to an APPLCALL or APPLALIAS now invoke any Command Alias that has been defined.
-// Fix reporting of Tracker freqs to WL2K.
-// Fix Tracker monitoring setup (sending M UISC)
-// Fix possible call/application routing error on RP
-// Changes for P4Dragon
-// Include APRS Digi/IGate
-// Tracker monitoring now includes DIGIS
-// Support sending UI frames using SCSTRACKER, SCTRKMULTI and UZ7HO drivers
-// Include driver for UZ7HO soundcard modem.
-// Accept DRIVER as well as DLLNAME, and COMPORT as well as IOADDR in bpq32.cfg. COMPORT is decimal
-// No longer supports separate config files, or BPQTELNETSERVER.exe
-// Improved flow control for Telnet CMS Sessions
-// Fix handling Config file without a newline after last line
-// Add non - Promiscuous mode option for BPQETHER
-// Change Console Window to a Dialog Box.
-// Fix possible corruption and loss of buffers in Tracker drivers
-// Add Beacon After Session option to Tracker and UZ7HO Drivers
-// Rewrite RigControl and add "Reread Config Command"
-// Support User Mode VCOM Driver for VKISS ports
-
-// 5.2.4.1 January 2012
-
-// Remove CR from Telnet User and Password Prompts
-// Add Rigcontrol to UZ7HO driver
-// Fix corruption of Free Buffer Count by Rigcontol
-// Fix WINMOR and V4 PTT
-// Add MultiPSK Driver
-// Add SendBeacon export for BPQAPRS
-// Add SendChatReport function
-// Fix check on length of Port Config ID String with trailing spaces
-// Fix interlock when Port Number <> Port Slot
-// Add NETROMCALL for L3 Activity
-// Add support for APRS Application
-// Fix Telnet with FBBPORT and no TCPPORT
-// Add Reread APRS Config
-// Fix switching to Pactor after scanning in normal packet mode (PTC)
-
-// 5.2.5.1 February 2012
-
-// Stop reading Password file.
-// Add extra MPSK commands
-// Fix MPSK Transparency
-// Make LOCATOR command compulsory
-// Add MobileBeaconInterval APRS param
-// Send Course and Speed when APRS is using GPS
-// Fix Robust Packet reporting in PTC driver
-// Fix corruption of some MIC-E APRS packets
-
-// 5.2.6.1 February 2012
-
-// Convert to MDI presentation of BPQ32.dll windows
-// Send APRS Status packets
-// Send QUIT not EXIT in PTC Init
-// Implement new WL2K reporting format and include traffic reporting info in CMS signon
-// New WL2KREPORT format
-// Prevent loops when APPL alias refers to itself
-// Add RigControl for Flex radios and ICOM IC-M710 Marine radio
-
-// 5.2.7.1
-
-// Fix opening more thn one console window on Win98
-// Change method of configuring multiple timelots on WL2K reporting
-// Add option to update WK2K Sysop Database
-// Add Web server
-// Add UIONLY port option
-
-// 5.2.7.2
-
-// Fix handling TelnetServer packets over 500 bytes in normal mode
-
-// 5.2.7.3
-
-// Fix Igate handling packets from UIView
-
-// 5.2.7.4
-
-// Prototype Baycom driver.
-
-// 5.2.7.5
-
-// Set WK2K group ref to MARS (3) if using a MARS service code
-
-// 5.2.7.7
-
-// Check for programs calling CloseBPQ32 when holding semaphore
-// Try/Except round Status Timer Processing
-
-// 5.2.7.8
-
-// More Try/Except round Timer Processing
-
-// 5.2.7.9
-
-// Enable RX in Baycom, and remove test loopback in tx
-
-// 5.2.7.10
-
-// Try/Except round ProcessHTTPMessage
-
-// 5.2.7.11
-
-// BAYCOM tweaks
-
-// 5.2.7.13
-
-// Release semaphore after program error in Timer Processing
-// Check fro valid dest in REFRESHROUTE
-
-
-// Add TNC-X KISSOPTION (includes the ACKMODE bytes in the checksum(
-
-// Version 5.2.9.1 Sept 2012
-
-// Fix using KISS ports with COMn > 16
-// Add "KISS over UDP" driver for PI as a TNC concentrator
-
-// Version 6.0.1.1
-
-// Convert to C for linux portability
-// Try to speed up kiss polling
-
-// Version 6.0.2.1
-
-// Fix operation on Win98
-// Fix callsign error with AGWtoBPQ
-// Fix PTT problem with WINMOR
-// Fix Reread telnet config
-// Add Secure CMS signon
-// Fix error in cashing addresses of CMS servers
-// Fix Port Number when using Send Raw.
-// Fix PE in KISS driver if invalid subchannel received
-// Fix Orignal address of beacons
-// Speed up Telnet port monitoring.
-// Add TNC Emulators
-// Add CountFramesQueuedOnStream API
-// Limit number of frames that can be queued on a session.
-// Add XDIGI feature
-// Add Winmor Robust Mode switching for compatibility with new Winmor TNC
-// Move most APRS code from BPQAPRS to here
-// Stop corruption caused by overlong KISS frames
-
-// Version 6.0.3.1
-
-// Add starting/killing WINMOR TNC on remote host
-// Fix Program Error when APRS Item or Object name is same as call of reporting station
-// Dont digi a frame that we have already digi'ed
-// Add ChangeSessionIdleTime API
-// Add WK2KSYSOP Command
-// Add IDLETIME Command
-// Fix Errors in RELAYAPPL processing
-// Fix PE cauaed by invalid Rigcontrol Line
-
-// Version 6.0.4.1
-
-// Add frequency dependent autoconnect appls for SCS Pactor
-// Fix DED Monitoring of I and UI with no data
-// Include AGWPE Emulator (from AGWtoBPQ)
-// accept DEL (Hex 7F) as backspace in Telnet
-// Fix re-running resolver on re-read AXIP config
-// Speed up processing, mainly for Telnet Sessions
-// Fix APRS init on restart of bpq32.exe
-// Change to 2 stop bits
-// Fix scrolling of WINMOR trace window
-// Fix Crash when ueing DED TNC Emulator
-// Fix Disconnect when using BPQDED2 Driver with Telnet Sessions
-// Allow HOST applications even when CMS option is disabled
-// Fix processing of APRS DIGIMAP command with no targets (didn't suppress default settings)
-
-// Version 6.0.5.1 January 2014
-
-// Add UTF8 conversion mode to Telnet (converts non-UTF-8 chars to UTF-8)
-// Add "Clear" option to MH command
-// Add "Connect to RMS Relay" Option
-// Revert to one stop bit on serial ports, explictly set two on FT2000 rig control
-// Fix routing of first call in Robust Packet
-// Add Options to switch input source on rigs with build in soundcards (sor far only IC7100 and Kenwood 590)
-// Add RTS>CAT PTT option for Sound Card rigs
-// Add Clear Nodes Option (NODE DEL ALL)
-// SCS Pactor can set differeant APPLCALLS when scanning.
-// Fix possible Scan hangup after a manual requency change with SCS Pactor
-// Accept Scan entry of W0 to disable WINMOR on that frequency
-// Fix corruption of NETROMCALL by SIMPLE config command
-// Enforce Pactor Levels
-// Add Telnet outward connect
-// Add Relay/Trimode Emulation
-// Fix V4 Driver
-// Add PTT Mux
-// Add Locked ARP Entries (via bpq32.cfg)
-// Fix IDLETIME node command
-// Fix STAY param on connect
-// Add STAY option to Attach and Application Commands
-// Fix crash on copying a large AXIP MH Window
-// Fix possible crash when bpq32.exe dies
-// Fix DIGIPORT for UI frames
-
-// Version 6.0.6.1 April 2014
-
-// FLDigi Interface
-// Fix "All CMS Servers are inaccessible" message so Mail Forwarding ELSE works.
-// Validate INP3 messages to try to prevent crash
-// Fix possible crash if an overlarge KISS frame is received
-// Fix error in AXR command
-// Add LF to Telnet Outward Connect signin if NEEDLF added to connect line
-// Add CBELL to TNC21 emulator
-// Add sent objects and third party messages to APRS Dup List
-// Incorporate UIUtil
-// Use Memory Mapped file to pass APRS info to BPQAPRS, and process APRS HTTP in BPQ32
-// Improvements to FLDIGI interlocking
-// Fix TNC State Display for Tracker
-// Cache CMS Addresses on LinBPQ
-// Fix count error on DED Driver when handling 256 byte packets
-// Add basic SNMP interface for MRTG
-// Fix memory loss from getaddrinfo
-// Process "BUSY" response from Tracker
-// Handle serial port writes that don't accept all the data
-// Trap Error 10038 and try to reopen socket
-// Fix crash if overlong command line received
-
-// Version 6.0.7.1 Aptil 2014
-// Fix RigContol with no frequencies for Kenwood and Yaesu
-// Add busy check to FLDIGI connects
-
-// Version 6.0.8.1 August 2014
-
-// Use HKEY_CURRENT_USER on all OS versions
-// Fix crash when APRS symbol is a space.
-// Fixes for FT847 CAT
-// Fix display of 3rd byte of FRMR
-// Add "DEFAULT ROBUST" and "FORCE ROBUST" commands to SCSPactor Driver
-// Fix possible memory corruption in WINMOR driver
-// Fix FT2000 Modes
-// Use new WL2K reporting system (Web API Based)
-// APRS Server now cycles through hosts if DNS returns more than one
-// BPQ32 can now start and stop FLDIGI
-// Fix loss of AXIP Resolver when running more than one AXIP port
-
-// Version 6.0.9.1 November 2014
-
-// Fix setting NOKEEPALIVE flag on route created from incoming L3 message
-// Ignore NODES from locked route with quality 0
-// Fix seting source port in AXIP
-// Fix Dual Stack (IPV4/V6) on Linux.
-// Fix RELAYSOCK if IPv6 is enabled.
-// Add support for FT1000
-// Fix hang when APRS Messaging packet received on RF
-// Attempt to normalize Node qualies when stations use widely differing Route qualities
-// Add NODES VIA command to display nodes reachable via a specified neighbour
-// Fix applying "DisconnectOnClose" setting on HOST API connects (Telnet Server)
-// Fix buffering large messages in Telnet Host API
-// Fix occasional crash in terminal part line processing
-// Add "NoFallback" command to Telnet server to disable "fallback to Relay"
-// Improved support for APPLCALL scanning with Pactor
-// MAXBUFFS config statement is no longer needed.
-// Fix USEAPPLCALLS with Tracker when connect to APPLCALL fails
-// Implement LISTEN and CQ commands
-// FLDIGI driver can now start FLDIGI on a remote system.
-// Add IGNOREUNLOCKEDROUTES parameter
-// Fix error if too many Telnet server connections
-
-// Version 6.0.10.1 Feb 2015
-
-// Fix crash if corrupt HTML request received.
-// Allow SSID's of 'R' and 'T' on non-ax.25 ports for WL2K Radio Only network.
-// Make HTTP server HTTP Version 1.1 complient - use persistent conections and close after 2.5 mins
-// Add INP3ONLY flag.
-// Fix program error if enter UNPROTO without a destination path
-// Show client IP address on HTTP sessions in Telnet Server
-// Reduce frequency and number of attempts to connect to routes when Keepalives or INP3 is set
-// Add FT990 RigControl support, fix FT1000MP support.
-// Support ARMV5 processors
-// Changes to support LinBPQ APRS Client
-// Add IC7410 to supported Soundcard rigs
-// Add CAT PTT to NMEA type (for ICOM Marine Radios_
-// Fix ACKMODE
-// Add KISS over TCP
-// Support ACKMode on VKISS
-// Improved reporting of configuration file format errors
-// Experimental driver to support ARQ sessions using UI frames
-
-// Version 6.0.11.1 September 2015
-
-// Fixes for IPGateway configuration and Virtual Circuit Mode
-// Separate Portmapper from IPGateway
-// Add PING Command
-// Add ARDOP Driver
-// Add basic APPLCALL support for PTC-PRO/Dragon 7800 Packet (using MYALIAS)
-// Add "VeryOldMode" for KAM Version 5.02
-// Add KISS over TCP Slave Mode.
-// Support Pactor and Packet on P4Dragon on one port
-// Add "Remote Staton Quality" to Web ROUTES display
-// Add Virtual Host option for IPGateway NET44 Encap
-// Add NAT for local hosts to IPGateway
-// Fix setting filter from RADIO command for IC7410
-// Add Memory Channel Scanning for ICOM Radios
-// Try to reopen Rig Control port if it fails (could be unplugged USB)
-// Fix restoring position of Monitor Window
-// Stop Codec on Winmor and ARDOP when an interlocked port is attached (instead of listen false)
-// Support APRS beacons in RP mode on Dragon//
-// Change Virtual MAC address on IPGateway to include last octet of IP Address
-// Fix "NOS Fragmentation" in IP over ax.25 Virtual Circuit Mode
-// Fix sending I frames before L2 session is up
-// Fix Flow control on Telnet outbound sessions.
-// Fix reporting of unterminatred comments in config
-// Add option for RigControl to not change mode on FT100/FT990/FT1000
-// Add "Attach and Connect" for Telnet ports
-
-// Version 6.0.12.1 November 2015
-
-// Fix logging of IP addresses for connects to FBBPORT
-// Allow lower case user and passwords in Telnet "Attach and Connect"
-// Fix possible hang in KISS over TCP Slave mode
-// Fix duplicating LinBPQ process if running ARDOP fails
-// Allow lower case command aliases and increase alias length to 48
-// Fix saving long IP frames pending ARP resolution
-// Fix dropping last entry from a RIP44 message.
-// Fix displaying Digis in MH list
-// Add port name to Monitor config screen port list
-// Fix APRS command display filter and add port filter
-// Support port names in BPQTermTCP Monitor config
-// Add FINDBUFFS command to dump lost buffers to Debugview/Syslog
-// Buffer Web Mgmt Edit Config output
-// Add WebMail Support
-// Fix not closing APRS Send WX file.
-// Add RUN option to APRS Config to start APRS Client
-// LinBPQ run FindLostBuffers and exit if QCOUNT < 5
-// Close and reopen ARDOP connection if nothing received for 90 secs
-// Add facility to bridge traffic between ports (similar to APRS Bridge but for all frame types)
-// Add KISSOPTION TRACKER to set SCS Tracker into KISS Mode
-
-// 6.0.13.1
-
-// Allow /ex to exit UNPROTO mode
-// Support ARQBW commands.
-// Support IC735
-// Fix sending ARDOP beacons after a busy holdoff
-// Enable BPQDED driver to beacon via non-ax.25 ports.
-// Fix channel number in UZ7HO monitoring
-// Add SATGate mode to APRSIS Code.
-// Fix crash caused by overlong user name in telnet logon
-// Add option to log L4 connects
-// Add AUTOADDQuiet mode to AXIP.
-// Add EXCLUDE processing
-// Support WinmorControl in UZ7HO driver and fix starting TNC on Linux
-// Convert calls in MAP entries to upper case.
-// Support Linux COM Port names for APRS GPS
-// Fix using NETROM serial protocol on ASYNC Port
-// Fix setting MYLEVEL by scanner after manual level change.
-// Add DEBUGLOG config param to SCS Pactor Driver to log serial port traffic
-// Uue #myl to set SCS Pactor MYLEVEL, and add checklevel command
-// Add Multicast RX interface to FLDIGI Driver
-// Fix processing application aliases to a connect command.
-// Fix Buffer loss if radio connected to PTC rig port but BPQ not configured to use it
-// Save backups of bpq32.cfg when editing with Web interface and report old and new length
-// Add DD command to SCS Pactor, and use it for forced disconnect.
-// Add ARDOP mode select to scan config
-// ARDOP changes for ARDOP V 0.5+
-// Flip SSID bits on UZ7HO downlink connects
-
-
-// Version 6.0.14.1
-
-// Fix Socket leak in ARDOP and FLDIGI drivers.
-// Add option to change CMS Server hostname
-// ARDOP Changes for 0.8.0+
-// Discard Terminal Keepalive message (two nulls) in ARDOP command hander
-// Allow parameters to be passed to ARDOP TNC when starting it
-// Fix Web update of Beacon params
-// Retry connects to KISS ports after failure
-// Add support for ARDOP Serial Interface Native mode.
-// Fix gating APRS-IS Messages to RF
-// Fix Beacons when PORTNUM used
-// Make sure old monitor flag is cleared for TermTCP sessions
-// Add CI-V antenna control for IC746
-// Don't allow ARDOP beacons when connected
-// Add support for ARDOP Serial over I2C
-// Fix possble crash when using manual RADIO messages
-// Save out of sequence L2 frames for possible reuse after retry
-// Add KISS command to send KISS control frame to TNC
-// Stop removing unused digis from packets sent to APRS-IS
-
-// Processing of ARDOP PING and PINGACK responses
-// Handle changed encoding of WL2K update responses.
-// Allow anonymous logon to telnet
-// Don't use APPL= for RP Calls in Dragon Single mode.
-// Add basic messaging page to APRS Web Server
-// Add debug log option to SCSTracker and TrkMulti Driver
-// Support REBOOT command on LinBPQ
-// Allow LISTEN command on all ports that support ax.25 monitoring
-
-// Version 6.0.15.1 Feb 2018
-
-// partial support for ax.25 V2.2
-// Add MHU and MHL commands and MH filter option
-// Fix scan interlock with ARDOP
-// Add Input source seiect for IC7300
-// Remove % transparency from web terminal signon message
-// Fix L4 Connects In count on stats
-// Fix crash caused by corrupt CMSInfo.txt
-// Add Input peaks display to ARDOP status window
-// Add options to show time in local and distances in KM on APRS Web pages
-// Add VARA support
-// Fix WINMOR Busy left set when port Suspended
-// Add ARDOP-Packet Support
-// Add Antenna Switching for TS 480
-// Fix possible crash in Web Terminal
-// Support different Code Pages on Console sessions
-// Use new Winlink API interface (api.winlink.org)
-// Support USB/ACC switching on TS590SG
-// Fix scanning when ARDOP or WINMOR is used without an Interlocked Pactor port.
-// Set NODECALL to first Application Callsign if NODE=0 and BBSCALL not set.
-// Add RIGCONTROL TUNE and POWER commands for some ICOM and Kenwwod rigs
-// Fix timing out ARDOP PENDING Lock
-// Support mixed case WINLINK Passwords
-// Add TUNE and POWER Rigcontol Commands for some radios
-// ADD LOCALTIME and DISPKM options to APRS Digi/Igate
-
-// 6.0.16.1 March 2018
-
-// Fix Setting data mode and filter for IC7300 radios
-// Add VARA to WL2KREPORT
-// Add trace to SCS Tracker status window
-// Fix possible hang in IPGATEWAY
-// Add BeacontoIS parameter to APRSDIGI. Allows you to stop sending beacons to APRS-IS.
-// Fix sending CTEXT on WINMOR sessions
-
-// 6.0.17.1 November 2018
-
-// Change WINMOR Restart after connection to Restart after Failure and add same option to ARDOP and VARA
-// Add Abort Connection to WINMOR and VARA Interfaces
-// Reinstate accidentally removed CMS Access logging
-// Fix MH CLEAR
-// Fix corruption of NODE table if NODES received from station with null alias
-// Fix loss of buffer if session closed with something in PARTCMDBUFFER
-// Fix Spurious GUARD ZONE CORRUPT message in IP Code.
-// Remove "reread bpq32.cfg and reconfigure" menu options
-// Add support for PTT using CM108 based soundcard interfaces
-// Datestamp Telnet log files and delete old Telnet and CMSAcces logs
-
-// 6.0.18.1 January 2019
-
-// Fix validation of NODES broadcasts
-// Fix HIDENODES
-// Check for failure to reread config on axip reconfigure
-// Fix crash if STOPPORT or STARTPORT used on KISS over TCP port
-// Send Beacons from BCALL or PORTCALL if configured
-// Fix possible corruption of last entry in MH display
-// Ensure RTS/DTR is down when opening PTT Port
-// Remove RECONFIG command
-// Preparations for 64 bit version
-
-// 6.0.19 Sept 2019
-// Fix UZ7HO interlock
-// Add commands to set Centre Frequency and Modem with UZ7HO Soundmodem (on Windows only)
-// Add option to save and restore MH lists and SAVEMH command
-// Add Frequency (if known) to UZ7HO MH lists
-// Add Gateway option to Telnet for PAT
-// Try to fix SCS Tracker recovery
-// Ensure RTS/DTR is down on CAT port if using that line for PTT
-// Experimental APRS Messaging in Kernel
-// Add Rigcontrol on remote PC's using WinmorControl
-// ADD VARAFM and VARAFM96 WL2KREPORT modes
-// Fix WL2K sysop update for new Winlink API
-// Fix APRS when using PORTNUM higher than the number of ports
-// Add Serial Port Type
-// Add option to linbpq to log APRS-IS messages.
-// Send WL2K Session Reports
-// Drop Tunneled Packets from 44.192 - 44.255
-// Log incoming Telnet Connects
-// Add IPV4: and IPV6: overrides on AXIP Resolver.
-// Add SessionTimeLimit to HF sessions (ARDOP, SCSPactor, WINMOR, VARA)
-// Add RADIO FREQ command to display current frequency
-
-// 6.0.20 April 2020
-
-// Trap and reject YAPP file transfer request.
-// Fix possible overrun of TCP to Node Buffer
-// Fix possible crash if APRS WX file doesn't have a terminating newline
-// Change communication with BPQAPRS.exe to restore old message popup behaviour
-// Preparation for 64 bit version
-// Improve flow control on SCS Dragon
-// Fragment messages from network links to L2 links with smaller paclen
-// Change WL2K report rate to once every two hours
-// Add PASS, CTEXT and CMSG commands and Stream Switch support to TNC2 Emulator
-// Add SessionTimeLimit command to HF drivers (ARDOP, SCSPactor, WINMOR, VARA)
-// Add links to Ports Web Manangement Page to open individual Driver windows
-// Add STOPPORT/STARTPORT support to ARDOP, KAM and SCSPactor drivers
-// Add CLOSE and OPEN RADIO command so Rigcontrol port can be freed fpr other use.
-// Don't try to send WL2K Traffic report if Internet is down
-// Move WL2K Traffic reporting to a separate thread so it doesn't block if it can't connect to server
-// ADD AGWAPPL config command to set application number. AGWMASK is still supported
-// Register Node Alias with UZ7HO Driver
-// Register calls when UZ7HO TNC Restarts and at intervals afterwards
-// Fix crash when no IOADDR or COMPORT in async port definition
-// Fix Crash with Paclink-Unix when parsing ; VE7SPR-10 DE N7NIX QTC 1
-// Only apply BBSFLAG=NOBBS to APPPLICATION 1
-// Add RIGREONFIG command
-// fix APRS RECONFIG on LinBPQ
-// Fix Web Terminal scroll to end problem on some browsers
-// Add PTT_SETS_INPUT option for IC7600
-// Add TELRECONFIG command to reread users or whole config
-// Enforce PACLEN on UZ7HO ports
-// Fix PACLEN on Command Output.
-// Retry axip resolver if it fails at startup
-// Fix AGWAPI connect via digis
-// Fix Select() for Linux in MultiPSK, UZ7HO and V4 drivers
-// Limit APRS OBJECT length to 80 chars
-// UZ7HO disconnect incoming call if no free streams
-// Improve response to REJ (no F) followed by RR (F).
-// Try to prevent more than MAXFRAME frames outstanding when transmitting
-// Allow more than one instance of APRS on Linux
-// Stop APRS digi by originating station
-// Send driver window trace to main monitor system
-// Improve handling of IPOLL messages
-// Fix setting end of address bit on dest call on connects to listening sessions
-// Set default BBS and CHAT application number and number of streams on LinBPQ
-// Support #include in bpq32.cfg processing
-
-// Version 6.0.21 14 December 2020
-
-// Fix occasional missing newlines in some node command reponses
-// More 64 bit fixes
-// Add option to stop setting PDUPLEX param in SCSPACTOR
-// Try to fix buffer loss
-// Remove extra space from APRS position reports
-// Suppress VARA IAMALIVE messages
-// Add display and control of QtSoundModem modems
-// Only send "No CMS connection available" message if fallbacktorelay is set.
-// Add HAMLIB backend and emulator support to RIGCONTROL
-// Ensure all beacons are sent even with very short beacon intervals
-// Add VARA500 WL2K Reporting Mode
-// Fix problem with prpcessing frame collector
-// Temporarily disable L2 and L4 collectors till I can find problem
-// Fix possible problem with interactive RADIO commands not giving a response,
-// Incease maximum length of NODE command responses to handle maximum length INFO message,
-// Allow WL2KREPORT in CONFIG section of UZ7HO port config.
-// Fix program error in processing hamlib frame
-// Save RestartAfterFailure option for VARA
-// Check callsign has a winlink account before sending WL2KREPORT messages
-// Add Bandwidth control to VARA scanning
-// Renable L2 collector
-// Fix TNCPORT reconnect on Linux
-// Add SecureTelnet option to limit telnet outward connect to sysop mode sessions or Application Aliases
-// Add option to suppress sending call to application in Telnet HOST API
-// Add FT991A support to RigControl
-// Use background.jpg for Edit Config page
-// Send OK response to SCS Pactor commands starting with #
-// Resend ICOM PTT OFF command after 30 seconds
-// Add WXCall to APRS config
-// Fixes for AEAPactor
-// Allow PTTMUX to use real or com0com com ports
-// Fix monitoring with AGW Emulator
-// Derive approx position from packets on APRS ports with a valid 6 char location
-// Fix corruption of APRS message lists if the station table fills up.
-// Don't accept empty username or password on Relay sessions.
-// Fix occasional empty Nodes broadcasts
-// Add Digis to UZ7HO Port MH list
-// Add PERMITTEDAPPLS port param
-// Fix WK2K Session Record Reporting for Airmail and some Pactor Modes.
-// Fix handling AX/IP (proto 93) frames
-// Fix possible corruption sending APRS messages
-// Allow Telnet connections to be made using Connect command as well as Attach then Connect
-// Fix Cancel Sysop Signin
-// Save axip resolver info and restore on restart
-// Add Transparent mode to Telnet Server HOST API
-// Fix Tracker driver if WL2KREPRRT is in main config section
-// SNMP InOctets count corrected to include all frames and encoding of zero values fixed.
-// Change IP Gateway to exclude handling bits of 44 Net sold to Amazon
-// Fix crash in Web terminal when processing very long lines
-
-// Version 6.0.22.1 August 2021
-
-// Fix bug in KAM TNCEMULATOR
-// Add WinRPR Driver (DED over TCP)
-// Fix handling of VARA config commands FM1200 and FM9600
-// Improve Web Termanal Line folding
-// Add StartTNC to WinRPR driver
-// Add support for VARA2750 Mode
-// Add support for VARA connects via a VARA Digipeater
-// Add digis to SCSTracker and WinRPR MHeard
-// Separate RIGCONTROL config from PORT config and add RigControl window
-// Fix crash when a Windows HID device doesn't have a product_string
-// Changes to VARA TNC connection and restart process
-// Trigger FALLBACKTORELAY if attempt to connect to all CMS servers fail.
-// Fix saving part lines in adif log and Winlink Session reporting
-// Add port specific CTEXT
-// Add FRMR monitoring to UZ7HO driver
-// Add audio input switching for IC7610
-// Include Rigcontrol Support for IC-F8101E
-// Process any response to KISS command
-// Fix NODE ADD command
-// Add noUpdate flag to AXIP MAP
-// Fix clearing NOFALLBACK flag in Telnet Server
-// Allow connects to RMS Relay running on another host
-// Allow use of Power setting in Rigcontol scan lines for Kenwood radios
-// Prevent problems caused by using "CMS" as a Node Alias
-// Include standard APRS Station pages in code
-// Fix VALIDCALLS processing in HF drivers
-// Send Netrom Link reports to Node Map
-// Add REALTELNET mode to Telnet Outward Connect
-// Fix using S (Stay) parameter on Telnet connects when using CMDPORT and C HOST
-// Add Default frequency to rigcontrol to set a freq/mode to return to after a connection
-// Fix long (> 60 seconds) scan intervals
-// Improved debugging of stuck semaphores
-// Fix potential securiby bug in BPQ Web server
-// Send Chat Updates to chatupdate.g8bpq.net port 81
-// Add ReportRelayTraffic to Telnet config to send WL2K traffic reports for connections to RELAY
-// Add experimental Mode reporting
-// Add SendTandRtoRelay param to SCS Pactor, ARDOP and VARA drivers to divert calls to CMS for -T and -R to RELAY
-// Add UPNP Support
-
-// Version 6.0.23.1 June 2022
-
-// Add option to control which applcalls are enabled in VARA
-// Add support for rtl_udp to Rig Control
-// Fix Telnet Auto Conneect to Application when using TermTCP or Web Terminal
-// Allow setting css styles for Web Terminal
-// And Kill TNC and Kill and Restart TNC commands to Web Driver Windows
-// More flexible RigControl for split frequency operation, eg for QO100
-// Increase stack size for ProcessHTMLMessage (.11)
-// Fix HTML Content-Type on images (.12)
-// Add AIS and ADSB Support (.13)
-// Compress web pages (.14)
-// Change minidump routine and close after program error (.15)
-// Add RMS Relay SYNC Mode (.17)
-// Changes for compatibility with Winlink Hybrid
-// Add Rigcontrol CMD feature to Yaesu code (21)
-// More diagnostic code
-// Trap potential buffer overrun in ax/tcp code
-// Fix possible hang in UZ7HO driver if connect takes a long time to succeed or fail
-// Add FLRIG as backend for RigControl (.24)
-// Fix bug in compressing some management web pages
-// Fix bugs in AGW Emulator (.25)
-// Add more PTT_Sets_Freq options for split frequency working (.26)
-// Allow RIGCONTROL using Radio Number (Rnn) as well as Port (.26)
-// Fix Telnet negotiation and backspace processing (.29)
-// Fix VARA Mode change when scanning (.30)
-// Add Web Mgmt Log Display (.33)
-// Fix crash when connecting to RELAY when CMS=0 (.36)
-// Send OK to user for manual freq changes with hamlib or flrig
-// Fix Rigcontrol leaving port disabled when using an empty timeband
-// Fix processing of backspace in Telnet character processing (.40)
-// Increase max size of connect script
-// Fix HAMLIB Slave Thread control
-// Add processing of VARA mode responses and display of VARA Mode (41)
-// Fix crash when VARA session aborted on LinBPQ (43)
-// Fix handling port selector (2:call or p2 call) on SCS PTC packet ports (44)
-// Include APRS Map web page
-// Add Enable/Disable to KAMPACTOR scan control (use P0 or P1) (45)
-// Add Basic DRATS interface (46)
-// Fix MYCALLS on VARA (49)
-// Add FreeData driver (51)
-// Add additonal Rigcontrol options for QO100 (51)
-// Set Content-Type: application/pdf for pdf files downloaded via web interface (51)
-// Fix sending large compressed web messages (52)
-// Fix freq display when using flrig or hamlib backends to rigcontrol
-// Change VARA Driver to send ABORT when Session Time limit expires
-// Add Chat Log to Web Logs display
-// Fix possible buffer loss in RigControl
-// Allow hosts on local lan to be treated as secure
-// Improve validation of data sent to Winlink SessionAdd API call
-// Add support for FreeDATA modem.
-// Add GetLOC API Call
-// Change Leaflet link in aprs map.
-// Add Connect Log (64)
-// Fix crash when Resolve CMS Servers returns ipv6 addresses
-// Fix Reporting P4 sessions to Winlink (68)
-// Add support for FreeBSD (68)
-// Fix Rigcontrol PTCPORT (69)
-// Set TNC Emulator sessions as secure (72)
-// Fix not always detecting loss of FLRIG (73)
-// Add ? and * wildcards to NODES command (74)
-// Add Port RADIO config parameter (74)
-
-// Version 6.0.24.1 August 2023
-
-// Apply NODES command wildcard to alias as well a call (2)
-// Add STOPPORT/STARTPORT to VARA Driver (2)
-// Add bandwidth setting to FLRIG interface. (2)
-// Fix N VIA (3)
-// Fix NODE ADD and NODE DEL (4)
-// Improvements to FLRIG Rigcontrol backend (6, 7)
-// Fix UZ7HO Window Title Update
-// Reject L2 calls with a blank from call (8)
-// Update WinRPR Window header with BPQ Port Description (8)
-// Fix error in blank call code (9)
-// Change web buttons to white on black when pressed (10)
-// Fix Port CTEXT paclen on Tracker and WinRPR drivers (11)
-// Add RADIO PTT command for testing PTT (11)
-// Fix using APPLCALLs on SCSTracker RP call (12)
-// Add Rigcntol Web Page (13)
-// Fix scan bandwidth change with ARDOPOFDM (13)
-// Fix setting Min Pactor Level in SCSPactor (13)
-// Fix length of commands sent via CMD_TO_APPL flag (14)
-// Add filter by quality option to N display (15)
-// Fix VARA Mode reporting to WL2K (16)
-// Add FLRIG POWER and TUNE commands (18)
-// Fix crash when processing "C " without a call in UZ7HO, FLDIGI or MULTIPSK drivers (19)
-// FLDIGI improvements (19)
-// Fix hang at start if Telnet port Number > Number of Telnet Streams (20)
-// Fix processing C command if first port driver is SCSPACTROR (20)
-// Fix crash in UZ7HO driver if bad raw frame received (21)
-// Fix using FLARQ chat mode with FLDIGI ddriover (22)
-// Fix to KISSHF driver (23)
-// Fix for application buffer loss (24)
-// Add Web Sockets auto-refresh option for Webmail index page (25)
-// Fix FREEDATA driver for compatibility with FreeData TNC version 0.6.4-alpha.3 (25)
-// Add SmartID for bridged frames - Send ID only if packets sent recently (26)
-// Add option to save and restore received APRS messages (27)
-// Add mechanism to run a user program on certain events (27)
-// If BeacontoIS is zero don't Gate any of our messages received locally to APRS-IS (28)
-// Add Node Help command (28)
-// Add APRS Igate RXOnly option (29)
-// Fix RMC message handling with prefixes other than GP (29)
-// Add GPSD support for APRS (30)
-// Attempt to fix Tracker/WinRPR reconnect code (30)
-// Changes to FreeDATA - Don't use deamon and add txlevel and send text commands (31)
-// Fix interactive commands in tracker driver (33)
-// Fix SESSIONTIMELIMIT processing
-// Add STOPPORT/STARTPORT for UZ7HO driver
-// Fix processing of extended QtSM 'g' frame (36)
-// Allow setting just freq on Yaseu rigs (37)
-// Enable KISSHF driver on Linux (40)
-// Allow AISHOST and ADSBHOST to be a name as well as an address (41)
-// Fix Interlock of incoming UZ7HO connections (41)
-// Disable VARA Actions menu if not sysop (41)
-// Fix Port CTEXT on UZ7HO B C or D channels (42)
-// Fix repeated trigger of SessionTimeLimit (43)
-// Fix posible memory corruption in UpateMH (44)
-// Add PHG to APRS beacons (45)
-// Dont send DM to stations in exclude list(45)
-// Improvements to RMS Relay SYNC Mode (46)
-// Check L4 connects against EXCLUDE list (47)
-// Add vaidation of LOC in WL2K Session Reports (49)
-// Change gpsd support for compatibility with Share Gps (50)
-// Switch APRS Map to my Tiles (52)
-// Fix using ; in UNPROTO Mode messages (52)
-// Use sha1 code from https://www.packetizer.com/security/sha1/ instead of openssl (53)
-// Fix TNC Emulator Monitoring (53)
-// Fix attach and connect on Telnet port bug introduced in .55 (56)
-// Fix stopping WinRPR TNC and Start/Stop UZ7HO TNCX on Linux (57)
-// Fix stack size in beginthread for MAC (58)
-// Add NETROM over VARA (60)
-// Add Disconnect Script (64)
-// Add node commands to set UZ7HO modem mode and freq (64)
-// Trap empty NODECALL or NETROMCALL(65)
-// Trap NODES messages with empty From Call (65)
-// Add RigControl for SDRConsole (66)
-// Fix FLRig crash (66)
-// Fix VARA disconnect handling (67)
-// Support 64 ports (69)
-// Fix Node commands for setting UZ7HO Modem (70)
-// Fix processing SABM on an existing session (71)
-// Extend KISS Node command to send more than one parameter byte (72)
-// Add G7TAJ's code to record activity of HF ports for stats display (72)
-// Add option to send KISS command to TNC on startup (73)
-// Fix Bug in DED Emulator Monitor code (74)
-// Add Filters to DED Monitor code (75)
-// Detect loss of DED application (76)
-// Fix connects to Application Alias with UZ7HO Driver (76)
-// Fix Interlock of ports on same UZ7HO modem. (76)
-// Add extended Ports command (77)
-// Fix crash in Linbpq when stdout is redirected to /dev/tty? and stdin ia redirected (78)
-// Fix Web Terminal (80)
-// Trap ENCRYPTION message from VARA (81)
-// Fix processing of the Winlink API /account/exists response (82)
-// Fix sending CTEXT to L4 connects to Node when FULL_CTEXT is not set
-
-// Version 6.0.25.?
-
-// Fix 64 bit compatibility problems in SCSTracker and UZ7HO drivers
-// Add Chat PACLEN config (5)
-// Fix NC to Application Call (6)
-// Fix INP3 L3RTT messages on Linux and correct RTT calculation (9)
-// Get Beacon config from config file on Windows (9)
-// fix processing DED TNC Emulator M command with space between M and params (10)
-// Fix sending UI frames on SCSPACTOR (11)
-// Dont allow ports that can't set digi'ed bit in callsigns to digipeat. (11)
-// Add SDRAngel rig control (11)
-// Add option to specify config and data directories on linbpq (12)
-// Allow zero resptime (send RR immediately) (13)
-// Make sure CMD bit is set on UI frames
-// Add setting Modem Flags in QtSM AGW mode
-// If FT847 om PTC Port send a "Cat On" command (17)
-// Fix some 63 port bugs in RigCOntrol (17)
-// Fix 63 port bug in Bridging (18)
-// Add FTDX10 Rigcontrol (19)
-// Fix 64 bit bug in displaying INP3 Messages (20)
-// Improve restart of WinRPR TNC on remote host (21)
-// Fix some Rigcontrol issues with empty timebands (22)
-// Fix 64 bit bug in processing INP3 Messages (22)
-// First pass at api (24)
-// Send OK in response to Rigcontrol CMD (24)
-// Disable CTS check in WriteComBlock (26)
-// Improvments to reporting to M0LTE Map (26)
-// IPGateway fix from github user isavitsky (27)
-// Fix possible crash in SCSPactor PTCPORT code (29)
-// Add NodeAPI call sendLinks and remove get from other calls (32)
-// Improve validation of Web Beacon Config (33)
-// Support SNMP via host ip stack as well as IPGateway (34)
-// Switch APRS Map to OSM tile servers (36)
-// Fix potential buffer overflow in Telnet login (36)
-// Allow longer serial device names (37)
-// Fix ICF8101 Mode setting (37)
-// Kill link if we are getting repeated RR(F) after timeout
-// (Indicating other station is seeing our RR(P) but not the resent I frame) (40)
-// Change default of SECURETELNET to 1 (41)
-// Add optional ATTACH time limit for ARDOP (42)
-// Fix buffer overflow risk in HTTP Terminal(42)
-// Fix KISSHF Interlock (43)
-// Support other than channel A on HFKISS (43)
-// Support additional port info reporting for M0LTE Map (44)
-// Allow interlocking of KISS and Session mode ports (eg ARDOP and VARA) (45)
-// Add ARDOP UI Packets to MH (45)
-// Add support for Qtsm Mgmt Interface (45)
-// NodeAPI improvements (46)
-// Add MQTT Interface (46)
-// Fix buffer leak in ARDOP code(46)
-// Fix possible crash if MQTT not in use (47)
-// Add optional ATTACH time limit for VARA (48)
-// API format fixes (48)
-// AGWAPI Add protection against accidental connects from a non-agw application (50)
-// Save MH and NODES every hour (51)
-// Fix handling long unix device names (now max 250 bytes) (52)
-// Fix error reporting in api update (53)
-// Coding changes to remove some compiler warnings (53, 54)
-// Add MQTT reporting of Mail Events (54)
-// Fix beaconong on KISSHF ports (55)
-// Fix MailAPI msgs endpoint
-// Attempt to fix NC going to wrong application. (57)
-// Improve ARDOP send of session code (58)
-
-
-#define CKernel
-
-#include "Versions.h"
-
-#define _CRT_SECURE_NO_DEPRECATE
-
-#pragma data_seg("_BPQDATA")
-
-#include "time.h"
-#include "stdio.h"
-#include
-
-#include "compatbits.h"
-#include "AsmStrucs.h"
-
-#include "SHELLAPI.H"
-#include "kernelresource.h"
-
-#include
-#include
-#include "BPQTermMDI.h"
-
-#include "GetVersion.h"
-
-#define DllImport __declspec( dllimport )
-
-#define CheckGuardZone() _CheckGuardZone(__FILE__, __LINE__)
-void _CheckGuardZone(char * File, int Line);
-
-#define CHECKLOADED 0
-#define SETAPPLFLAGS 1
-#define SENDBPQFRAME 2
-#define GETBPQFRAME 3
-#define GETSTREAMSTATUS 4
-#define CLEARSTREAMSTATUS 5
-#define BPQCONDIS 6
-#define GETBUFFERSTATUS 7
-#define GETCONNECTIONINFO 8
-#define BPQRETURN 9 // GETCALLS
-//#define RAWTX 10 //IE KISS TYPE DATA
-#define GETRAWFRAME 11
-#define UPDATESWITCH 12
-#define BPQALLOC 13
-//#define SENDNETFRAME 14
-#define GETTIME 15
-
-extern short NUMBEROFPORTS;
-extern long PORTENTRYLEN;
-extern long LINKTABLELEN;
-extern struct PORTCONTROL * PORTTABLE;
-extern void * FREE_Q;
-extern UINT APPL_Q; // Queue of frames for APRS Appl
-
-extern TRANSPORTENTRY * L4TABLE;
-extern UCHAR NEXTID;
-extern DWORD MAXCIRCUITS;
-extern DWORD L4DEFAULTWINDOW;
-extern DWORD L4T1;
-extern APPLCALLS APPLCALLTABLE[];
-extern char * APPLS;
-
-extern struct WL2KInfo * WL2KReports;
-
-extern int NUMBEROFTNCPORTS;
-
-
-void * VCOMExtInit(struct PORTCONTROL * PortEntry);
-void * AXIPExtInit(struct PORTCONTROL * PortEntry);
-void * SCSExtInit(struct PORTCONTROL * PortEntry);
-void * AEAExtInit(struct PORTCONTROL * PortEntry);
-void * KAMExtInit(struct PORTCONTROL * PortEntry);
-void * HALExtInit(struct PORTCONTROL * PortEntry);
-void * ETHERExtInit(struct PORTCONTROL * PortEntry);
-void * AGWExtInit(struct PORTCONTROL * PortEntry);
-void * WinmorExtInit(EXTPORTDATA * PortEntry);
-void * TelnetExtInit(EXTPORTDATA * PortEntry);
-//void * SoundModemExtInit(EXTPORTDATA * PortEntry);
-void * TrackerExtInit(EXTPORTDATA * PortEntry);
-void * TrackerMExtInit(EXTPORTDATA * PortEntry);
-void * V4ExtInit(EXTPORTDATA * PortEntry);
-void * UZ7HOExtInit(EXTPORTDATA * PortEntry);
-void * MPSKExtInit(EXTPORTDATA * PortEntry);
-void * FLDigiExtInit(EXTPORTDATA * PortEntry);
-void * UIARQExtInit(EXTPORTDATA * PortEntry);
-void * SerialExtInit(EXTPORTDATA * PortEntry);
-void * ARDOPExtInit(EXTPORTDATA * PortEntry);
-void * VARAExtInit(EXTPORTDATA * PortEntry);
-void * KISSHFExtInit(EXTPORTDATA * PortEntry);
-void * WinRPRExtInit(EXTPORTDATA * PortEntry);
-void * HSMODEMExtInit(EXTPORTDATA * PortEntry);
-void * FreeDataExtInit(EXTPORTDATA * PortEntry);
-void * SIXPACKExtInit(EXTPORTDATA * PortEntry);
-
-extern char * ConfigBuffer; // Config Area
-VOID REMOVENODE(dest_list * DEST);
-DllExport int ConvFromAX25(unsigned char * incall,unsigned char * outcall);
-DllExport int ConvToAX25(unsigned char * incall,unsigned char * outcall);
-VOID GetUIConfig();
-VOID ADIFWriteFreqList();
-void SaveAIS();
-void initAIS();
-void initADSB();
-
-extern BOOL ADIFLogEnabled;
-
-int CloseOnError = 0;
-
-char UIClassName[]="UIMAINWINDOW"; // the main window class name
-
-HWND UIhWnd;
-
-extern char AUTOSAVE;
-extern char AUTOSAVEMH;
-
-extern char MYNODECALL; // 10 chars,not null terminated
-
-extern QCOUNT;
-extern BPQVECSTRUC BPQHOSTVECTOR[];
-#define BPQHOSTSTREAMS 64
-#define IPHOSTVECTOR BPQHOSTVECTOR[BPQHOSTSTREAMS + 3]
-
-extern char * CONFIGFILENAME;
-
-DllExport BPQVECSTRUC * BPQHOSTVECPTR;
-
-extern int DATABASESTART;
-
-extern struct ROUTE * NEIGHBOURS;
-extern int ROUTE_LEN;
-extern int MAXNEIGHBOURS;
-
-extern struct DEST_LIST * DESTS; // NODE LIST
-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 double LatFromLOC;
-extern double LonFromLOC;
-
-
-extern int BPQHOSTAPI();
-extern int INITIALISEPORTS();
-extern int TIMERINTERRUPT();
-extern int MONDECODE();
-extern int BPQMONOPTIONS();
-extern char PWTEXT[];
-extern char PWLen;
-
-extern int FINDFREEDESTINATION();
-extern int RAWTX();
-extern int RELBUFF();
-extern int SENDNETFRAME();
-extern char MYCALL[]; // 7 chars, ax.25 format
-
-extern HWND hIPResWnd;
-extern BOOL IPMinimized;
-
-extern int NODESINPROGRESS;
-extern VOID * CURRENTNODE;
-
-
-BOOL Start();
-
-VOID SaveWindowPos(int port);
-VOID SaveAXIPWindowPos(int port);
-VOID SetupRTFHddr();
-DllExport VOID APIENTRY CreateNewTrayIcon();
-int DoReceivedData(int Stream);
-int DoStateChange(int Stream);
-int DoMonData(int Stream);
-struct ConsoleInfo * CreateChildWindow(int Stream, BOOL DuringInit);
-CloseHostSessions();
-SaveHostSessions();
-VOID SaveBPQ32Windows();
-VOID CloseDriverWindow(int port);
-VOID CheckWL2KReportTimer();
-VOID SetApplPorts();
-VOID WriteMiniDump();
-VOID FindLostBuffers();
-BOOL InitializeTNCEmulator();
-VOID TNCTimer();
-char * strlop(char * buf, char delim);
-
-DllExport int APIENTRY Get_APPLMASK(int Stream);
-DllExport int APIENTRY GetStreamPID(int Stream);
-DllExport int APIENTRY GetApplFlags(int Stream);
-DllExport int APIENTRY GetApplNum(int Stream);
-DllExport BOOL APIENTRY GetAllocationState(int Stream);
-DllExport int APIENTRY GetMsg(int stream, char * msg, int * len, int * count );
-DllExport int APIENTRY RXCount(int Stream);
-DllExport int APIENTRY TXCount(int Stream);
-DllExport int APIENTRY MONCount(int Stream);
-DllExport int APIENTRY GetCallsign(int stream, char * callsign);
-DllExport VOID APIENTRY RelBuff(VOID * Msg);
-void SaveMH();
-void DRATSPoll();
-
-#define C_Q_ADD(s, b) _C_Q_ADD(s, b, __FILE__, __LINE__);
-int _C_Q_ADD(VOID *PQ, VOID *PBUFF, char * File, int Line);
-
-VOID SetWindowTextSupport();
-int WritetoConsoleSupport(char * buff);
-VOID PMClose();
-VOID MySetWindowText(HWND hWnd, char * Msg);
-BOOL CreateMonitorWindow(char * MonSize);
-VOID FormatTime3(char * Time, time_t cTime);
-
-char EXCEPTMSG[80] = "";
-
-char SIGNONMSG[128] = "";
-char SESSIONHDDR[80] = "";
-int SESSHDDRLEN = 0;
-
-BOOL IncludesMail = FALSE;
-BOOL IncludesChat = FALSE; // Set if pgram is running - used for Web Page Index
-
-
-char WL2KCall[10];
-char WL2KLoc[7];
-
-extern char LOCATOR[]; // Locator for Reporting - may be Maidenhead or LAT:LON
-extern char MAPCOMMENT[]; // Locator for Reporting - may be Maidenhead or LAT:LON
-extern char LOC[7]; // Maidenhead Locator for Reporting
-extern char ReportDest[7];
-
-extern UCHAR ConfigDirectory[260];
-
-extern uint64_t timeLoadedMS;
-
-VOID __cdecl Debugprintf(const char * format, ...);
-VOID __cdecl Consoleprintf(const char * format, ...);
-
-DllExport int APIENTRY CloseBPQ32();
-DllExport char * APIENTRY GetLOC();
-DllExport int APIENTRY SessionControl(int stream, int command, int param);
-
-int DoRefreshWebMailIndex();
-
-BOOL APIENTRY Init_IP();
-BOOL APIENTRY Poll_IP();
-
-BOOL APIENTRY Init_PM();
-BOOL APIENTRY Poll_PM();
-
-BOOL APIENTRY Init_APRS();
-BOOL APIENTRY Poll_APRS();
-VOID HTTPTimer();
-
-BOOL APIENTRY Rig_Init();
-BOOL APIENTRY Rig_Close();
-BOOL Rig_Poll();
-
-VOID IPClose();
-VOID APRSClose();
-VOID CloseTNCEmulator();
-
-VOID Poll_AGW();
-void RHPPoll();
-BOOL AGWAPIInit();
-int AGWAPITerminate();
-
-int * Flag = (int *)&Flag; // for Dump Analysis
-int MAJORVERSION=4;
-int MINORVERSION=9;
-
-struct SEM Semaphore = {0, 0, 0, 0};
-struct SEM APISemaphore = {0, 0, 0, 0};
-int SemHeldByAPI = 0;
-int LastSemGets = 0;
-UINT Sem_eax = 0;
-UINT Sem_ebx = 0;
-UINT Sem_ecx = 0;
-UINT Sem_edx = 0;
-UINT Sem_esi = 0;
-UINT Sem_edi = 0;
-
-
-#define GetSemaphore(Semaphore,ID) _GetSemaphore(Semaphore, ID, __FILE__, __LINE__)
-void _GetSemaphore(struct SEM * Semaphore, int ID, char * File, int Line);
-void FreeSemaphore(struct SEM * Semaphore);
-
-DllExport void * BPQHOSTAPIPTR = &BPQHOSTAPI;
-//DllExport long MONDECODEPTR = (long)&MONDECODE;
-
-extern UCHAR BPQDirectory[];
-extern UCHAR LogDirectory[];
-extern UCHAR BPQProgramDirectory[];
-
-static char BPQWinMsg[] = "BPQWindowMessage";
-
-static char ClassName[] = "BPQMAINWINDOW";
-
-HKEY REGTREE = HKEY_CURRENT_USER;
-char REGTREETEXT[100] = "HKEY_CURRENT_USER";
-
-UINT BPQMsg=0;
-
-#define MAXLINELEN 120
-#define MAXSCREENLEN 50
-
-#define BGCOLOUR RGB(236,233,216)
-
-HBRUSH bgBrush = NULL;
-
-//int LINELEN=120;
-//int SCREENLEN=50;
-
-//char Screen[MAXLINELEN*MAXSCREENLEN]={0};
-
-//int lineno=0;
-//int col=0;
-
-#define REPORTINTERVAL 15 * 549; // Magic Ticks Per Minute for PC's nominal 100 ms timer
-int ReportTimer = 0;
-
-HANDLE OpenConfigFile(char * file);
-
-VOID SetupBPQDirectory();
-VOID SendLocation();
-
-//uintptr_t _beginthread(void(*start_address)(), unsigned stack_size, int arglist);
-
-#define TRAY_ICON_ID 1 // ID number for the Notify Icon
-#define MY_TRAY_ICON_MESSAGE WM_APP // the message ID sent to our window
-
-NOTIFYICONDATA niData;
-
-int SetupConsoleWindow();
-
-BOOL StartMinimized=FALSE;
-BOOL MinimizetoTray=TRUE;
-
-BOOL StatusMinimized = FALSE;
-BOOL ConsoleMinimized = FALSE;
-
-HMENU trayMenu=0;
-
-HWND hConsWnd = NULL, hWndCons = NULL, hWndBG = NULL, ClientWnd = NULL, FrameWnd = NULL, StatusWnd = NULL;
-
-BOOL FrameMaximized = FALSE;
-
-BOOL IGateEnabled = TRUE;
-extern int ISDelayTimer; // Time before trying to reopen APRS-IS link
-extern int ISPort;
-
-UINT * WINMORTraceQ = NULL;
-UINT * SetWindowTextQ = NULL;
-
-static RECT Rect = {100,100,400,400}; // Console Window Position
-RECT FRect = {100,100,800,600}; // Frame
-static RECT StatusRect = {100,100,850,500}; // Status Window
-
-DllExport int APIENTRY DumpSystem();
-DllExport int APIENTRY SaveNodes ();
-DllExport int APIENTRY ClearNodes ();
-DllExport int APIENTRY SetupTrayIcon();
-
-#define Q_REM(s) _Q_REM(s, __FILE__, __LINE__)
-
-VOID * _Q_REM(VOID *Q, char * File, int Line);
-
-UINT ReleaseBuffer(UINT *BUFF);
-
-
-VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime );
-
-DllExport int APIENTRY DeallocateStream(int stream);
-
-int VECTORLENGTH = sizeof (struct _BPQVECSTRUC);
-
-int FirstEntry = 1;
-BOOL CloseLast = TRUE; // If the user started BPQ32.exe, don't close it when other programs close
-BOOL Closing = FALSE; // Set if Close All called - prevents respawning bpq32.exe
-
-BOOL BPQ32_EXE; // Set if Process is running BPQ32.exe. Not initialised.
- // Used to Kill surplus BPQ32.exe processes
-
-DWORD Our_PID; // Our Process ID - local variable
-
-void * InitDone = 0;
-int FirstInitDone = 0;
-int PerlReinit = 0;
-UINT_PTR TimerHandle = 0;
-UINT_PTR SessHandle = 0;
-
-BOOL EventsEnabled = 0;
-
-unsigned int TimerInst = 0xffffffff;
-
-HANDLE hInstance = 0;
-
-int AttachedProcesses = 0;
-int AttachingProcess = 0;
-HINSTANCE hIPModule = 0;
-HINSTANCE hRigModule = 0;
-
-BOOL ReconfigFlag = FALSE;
-BOOL RigReconfigFlag = FALSE;
-BOOL APRSReconfigFlag = FALSE;
-BOOL CloseAllNeeded = FALSE;
-BOOL NeedWebMailRefresh = FALSE;
-
-int AttachedPIDList[100] = {0};
-
-HWND hWndArray[100] = {0};
-int PIDArray[100] = {0};
-char PopupText[30][100] = {""};
-
-// Next 3 should be uninitialised so they are local to each process
-
-UCHAR MCOM;
-UCHAR MTX; // Top bit indicates use local time
-uint64_t MMASK;
-UCHAR MUIONLY;
-
-UCHAR AuthorisedProgram; // Local Variable. Set if Program is on secure list
-
-char pgm[256]; // Uninitialised so per process
-
-HANDLE Mutex;
-
-BOOL PartLine = FALSE;
-int pindex = 0;
-DWORD * WritetoConsoleQ;
-
-
-LARGE_INTEGER lpFrequency = {0};
-LARGE_INTEGER lastRunTime;
-LARGE_INTEGER currentTime;
-
-int ticksPerMillisec;
-int interval;
-
-
-VOID CALLBACK SetupTermSessions(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
-
-
-TIMERPROC lpTimerFunc = (TIMERPROC) TimerProc;
-TIMERPROC lpSetupTermSessions = (TIMERPROC) SetupTermSessions;
-
-
-BOOL ProcessConfig();
-VOID FreeConfig();
-
-DllExport int APIENTRY WritetoConsole(char * buff);
-
-BOOLEAN CheckifBPQ32isLoaded();
-BOOLEAN StartBPQ32();
-DllExport VOID APIENTRY Send_AX(VOID * Block, DWORD len, UCHAR Port);
-BOOL LoadIPDriver();
-BOOL Send_IP(VOID * Block, DWORD len);
-VOID CheckforLostProcesses();
-BOOL LoadRigDriver();
-VOID SaveConfig();
-VOID CreateRegBackup();
-VOID ResolveUpdateThread();
-VOID OpenReportingSockets();
-DllExport VOID APIENTRY CloseAllPrograms();
-DllExport BOOL APIENTRY SaveReg(char * KeyIn, HANDLE hFile);
-int upnpClose();
-
-BOOL IPActive = FALSE;
-extern BOOL IPRequired;
-BOOL PMActive = FALSE;
-extern BOOL PMRequired;
-BOOL RigRequired = TRUE;
-BOOL RigActive = FALSE;
-BOOL APRSActive = FALSE;
-BOOL AGWActive = FALSE;
-BOOL needAIS = FALSE;
-int needADSB = 0;
-
-extern int AGWPort;
-
-Tell_Sessions();
-
-
-typedef int (WINAPI FAR *FARPROCX)();
-
-FARPROCX CreateToolHelp32SnapShotPtr;
-FARPROCX Process32Firstptr;
-FARPROCX Process32Nextptr;
-
-void LoadToolHelperRoutines()
-{
- HINSTANCE ExtDriver=0;
- int err;
- char msg[100];
-
- ExtDriver=LoadLibrary("kernel32.dll");
-
- if (ExtDriver == NULL)
- {
- err=GetLastError();
- sprintf(msg,"BPQ32 Error loading kernel32.dll - Error code %d\n", err);
- OutputDebugString(msg);
- return;
- }
-
- CreateToolHelp32SnapShotPtr = (FARPROCX)GetProcAddress(ExtDriver,"CreateToolhelp32Snapshot");
- Process32Firstptr = (FARPROCX)GetProcAddress(ExtDriver,"Process32First");
- Process32Nextptr = (FARPROCX)GetProcAddress(ExtDriver,"Process32Next");
-
- if (CreateToolHelp32SnapShotPtr == 0)
- {
- err=GetLastError();
- sprintf(msg,"BPQ32 Error getting CreateToolhelp32Snapshot entry point - Error code %d\n", err);
- OutputDebugString(msg);
- return;
- }
-}
-
-BOOL GetProcess(int ProcessID, char * Program)
-{
- HANDLE hProcessSnap;
- PROCESSENTRY32 pe32;
- int p;
-
- if (CreateToolHelp32SnapShotPtr==0)
- {
- return (TRUE); // Routine not available
- }
- // Take a snapshot of all processes in the system.
- hProcessSnap = (HANDLE)CreateToolHelp32SnapShotPtr(TH32CS_SNAPPROCESS, 0);
- if( hProcessSnap == INVALID_HANDLE_VALUE )
- {
- OutputDebugString( "CreateToolhelp32Snapshot (of processes) Failed\n" );
- return( FALSE );
- }
-
- // Set the size of the structure before using it.
- pe32.dwSize = sizeof( PROCESSENTRY32 );
-
- // Retrieve information about the first process,
- // and exit if unsuccessful
- if( !Process32Firstptr( hProcessSnap, &pe32 ) )
- {
- OutputDebugString( "Process32First Failed\n" ); // Show cause of failure
- CloseHandle( hProcessSnap ); // Must clean up the snapshot object!
- return( FALSE );
- }
-
- // Now walk the snapshot of processes, and
- // display information about each process in turn
- do
- {
- if (ProcessID==pe32.th32ProcessID)
- {
- // if running on 98, program contains the full path - remove it
-
- for (p = (int)strlen(pe32.szExeFile); p >= 0; p--)
- {
- if (pe32.szExeFile[p]=='\\')
- {
- break;
- }
- }
- p++;
-
- sprintf(Program,"%s", &pe32.szExeFile[p]);
- CloseHandle( hProcessSnap );
- return( TRUE );
- }
-
- } while( Process32Nextptr( hProcessSnap, &pe32 ) );
-
-
- sprintf(Program,"PID %d Not Found", ProcessID);
- CloseHandle( hProcessSnap );
- return(FALSE);
-}
-
-BOOL IsProcess(int ProcessID)
-{
- // Check that Process exists
-
- HANDLE hProcessSnap;
- PROCESSENTRY32 pe32;
-
- if (CreateToolHelp32SnapShotPtr==0) return (TRUE); // Routine not available
-
- hProcessSnap = (HANDLE)CreateToolHelp32SnapShotPtr(TH32CS_SNAPPROCESS, 0);
-
- if( hProcessSnap == INVALID_HANDLE_VALUE )
- {
- OutputDebugString( "CreateToolhelp32Snapshot (of processes) Failed\n" );
- return(TRUE); // Don't know, so assume ok
- }
-
- pe32.dwSize = sizeof( PROCESSENTRY32 );
-
- if( !Process32Firstptr( hProcessSnap, &pe32 ) )
- {
- OutputDebugString( "Process32First Failed\n" ); // Show cause of failure
- CloseHandle( hProcessSnap ); // Must clean up the snapshot object!
- return(TRUE); // Don't know, so assume ok
- }
-
- do
- {
- if (ProcessID==pe32.th32ProcessID)
- {
- CloseHandle( hProcessSnap );
- return( TRUE );
- }
-
- } while( Process32Nextptr( hProcessSnap, &pe32 ) );
-
- CloseHandle( hProcessSnap );
- return(FALSE);
-}
-
-#include "DbgHelp.h"
-
-VOID MonitorThread(int x)
-{
- // Thread to detect killed processes. Runs in process owning timer.
-
- // Obviously can't detect loss of timer owning thread!
-
- do
- {
- if (Semaphore.Gets == LastSemGets && Semaphore.Flag)
- {
- // It is stuck - try to release
-
- Debugprintf ("Semaphore locked - Process ID = %d, Held By %d from %s Line %d",
- Semaphore.SemProcessID, SemHeldByAPI, Semaphore.File, Semaphore.Line);
-
- // Write a minidump
-
- WriteMiniDump();
-
- Semaphore.Flag = 0;
- }
-
- LastSemGets = Semaphore.Gets;
-
- Sleep(30000);
- CheckforLostProcesses();
-
- } while (TRUE);
-}
-
-VOID CheckforLostProcesses()
-{
- UCHAR buff[100];
- char Log[80];
- int i, n, ProcessID;
-
- for (n=0; n < AttachedProcesses; n++)
- {
- ProcessID=AttachedPIDList[n];
-
- if (!IsProcess(ProcessID))
- {
- // Process has died - Treat as a detach
-
- sprintf(Log,"BPQ32 Process %d Died\n", ProcessID);
- OutputDebugString(Log);
-
- // Remove Tray Icon Entry
-
- for( i = 0; i < 100; ++i )
- {
- if (PIDArray[i] == ProcessID)
- {
- hWndArray[i] = 0;
- sprintf(Log,"BPQ32 Removing Tray Item %s\n", PopupText[i]);
- OutputDebugString(Log);
- DeleteMenu(trayMenu,TRAYBASEID+i,MF_BYCOMMAND);
- }
- }
-
- // If process had the semaphore, release it
-
- if (Semaphore.Flag == 1 && ProcessID == Semaphore.SemProcessID)
- {
- OutputDebugString("BPQ32 Process was holding Semaphore - attempting recovery\r\n");
- Debugprintf("Last Sem Call %d %x %x %x %x %x %x", SemHeldByAPI,
- Sem_eax, Sem_ebx, Sem_ecx, Sem_edx, Sem_esi, Sem_edi);
-
- Semaphore.Flag = 0;
- SemHeldByAPI = 0;
- }
-
- for (i=1;i<65;i++)
- {
- if (BPQHOSTVECTOR[i-1].STREAMOWNER == AttachedPIDList[n])
- {
- DeallocateStream(i);
- }
- }
-
- if (TimerInst == ProcessID)
- {
- KillTimer(NULL,TimerHandle);
- TimerHandle=0;
- TimerInst=0xffffffff;
-// Tell_Sessions();
- OutputDebugString("BPQ32 Process was running timer \n");
-
- if (MinimizetoTray)
- Shell_NotifyIcon(NIM_DELETE,&niData);
-
-
- }
-
- // Remove this entry from PID List
-
- for (i=n; i< AttachedProcesses; i++)
- {
- AttachedPIDList[i]=AttachedPIDList[i+1];
- }
- AttachedProcesses--;
-
- sprintf(buff,"BPQ32 Lost Process - %d Process(es) Attached\n", AttachedProcesses);
- OutputDebugString(buff);
- }
- }
-}
-VOID MonitorTimerThread(int x)
-{
- // Thread to detect killed timer process. Runs in all other BPQ32 processes.
-
- do {
-
- Sleep(60000);
-
- if (TimerInst != 0xffffffff && !IsProcess(TimerInst))
- {
- // Timer owning Process has died - Force a new timer to be created
- // New timer thread will detect lost process and tidy up
-
- Debugprintf("BPQ32 Process %d with Timer died", TimerInst);
-
- // If process was holding the semaphore, release it
-
- if (Semaphore.Flag == 1 && TimerInst == Semaphore.SemProcessID)
- {
- OutputDebugString("BPQ32 Process was holding Semaphore - attempting recovery\r\n");
- Debugprintf("Last Sem Call %d %x %x %x %x %x %x", SemHeldByAPI,
- Sem_eax, Sem_ebx, Sem_ecx, Sem_edx, Sem_esi, Sem_edi);
- Semaphore.Flag = 0;
- SemHeldByAPI = 0;
- }
-
-// KillTimer(NULL,TimerHandle);
-// TimerHandle=0;
-// TimerInst=0xffffffff;
-// Tell_Sessions();
-
- CheckforLostProcesses(); // Normally only done in timer thread, which is now dead
-
- // Timer can only run in BPQ32.exe
-
- TimerInst=0xffffffff; // So we dont keep doing it
- TimerHandle = 0; // So new process attaches
-
- if (Closing == FALSE && AttachingProcess == FALSE)
- {
- OutputDebugString("BPQ32 Reloading BPQ32.exe\n");
- StartBPQ32();
- }
-
-// if (MinimizetoTray)
-// Shell_NotifyIcon(NIM_DELETE,&niData);
- }
-
- } while (TRUE);
-}
-
-VOID WritetoTraceSupport(struct TNCINFO * TNC, char * Msg, int Len);
-
-VOID TimerProcX();
-
-VOID CALLBACK TimerProc(
- HWND hwnd, // handle of window for timer messages
- UINT uMsg, // WM_TIMER message
- UINT idEvent, // timer identifier
- DWORD dwTime) // current system time
-{
- KillTimer(NULL,TimerHandle);
- TimerProcX();
- TimerHandle = SetTimer(NULL,0,100,lpTimerFunc);
-}
-VOID TimerProcX()
-{
- struct _EXCEPTION_POINTERS exinfo;
-
- //
- // Get semaphore before proceeeding
- //
-
- GetSemaphore(&Semaphore, 2);
-
- // Get time since last run
-
- QueryPerformanceCounter(¤tTime);
-
- interval = (int)(currentTime.QuadPart - lastRunTime.QuadPart) / ticksPerMillisec;
- lastRunTime.QuadPart = currentTime.QuadPart;
-
- //Debugprintf("%d", interval);
-
- // Process WINMORTraceQ
-
- while (WINMORTraceQ)
- {
- UINT * Buffer = Q_REM(&WINMORTraceQ);
- struct TNCINFO * TNC = (struct TNCINFO * )Buffer[1];
- int Len = Buffer[2];
- char * Msg = (char *)&Buffer[3];
-
- WritetoTraceSupport(TNC, Msg, Len);
- RelBuff(Buffer);
- }
-
- if (SetWindowTextQ)
- SetWindowTextSupport();
-
- while (WritetoConsoleQ)
- {
- UINT * Buffer = Q_REM(&WritetoConsoleQ);
- WritetoConsoleSupport((char *)&Buffer[2]);
- RelBuff(Buffer);
- }
-
- strcpy(EXCEPTMSG, "Timer ReconfigProcessing");
-
- __try
- {
-
- if (trayMenu == NULL)
- SetupTrayIcon();
-
- // See if reconfigure requested
-
- if (CloseAllNeeded)
- {
- CloseAllNeeded = FALSE;
- CloseAllPrograms();
- }
-
- if (ReconfigFlag)
- {
- // Only do it it timer owning process, or we could get in a real mess!
-
- if(TimerInst == GetCurrentProcessId())
- {
- int i;
- BPQVECSTRUC * HOSTVEC;
- PEXTPORTDATA PORTVEC=(PEXTPORTDATA)PORTTABLE;
- WSADATA WsaData; // receives data from WSAStartup
- RECT cRect;
-
- ReconfigFlag = FALSE;
-
- SetupBPQDirectory();
-
- WritetoConsole("Reconfiguring ...\n\n");
- OutputDebugString("BPQ32 Reconfiguring ...\n");
-
- GetWindowRect(FrameWnd, &FRect);
-
- SaveWindowPos(70); // Rigcontrol
-
- for (i=0;iPORTCONTROL.PORTTYPE == 0x10) // External
- {
- if (PORTVEC->PORT_EXT_ADDR)
- {
- SaveWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
- SaveAXIPWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
- CloseDriverWindow(PORTVEC->PORTCONTROL.PORTNUMBER);
- PORTVEC->PORT_EXT_ADDR(5,PORTVEC->PORTCONTROL.PORTNUMBER, NULL); // Close External Ports
- }
- }
- PORTVEC->PORTCONTROL.PORTCLOSECODE(&PORTVEC->PORTCONTROL);
- PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
- }
-
- IPClose();
- PMClose();
- APRSClose();
- Rig_Close();
- CloseTNCEmulator();
- if (AGWActive)
- AGWAPITerminate();
-
- WSACleanup();
-
- WL2KReports = NULL;
-
- Sleep(2000);
-
- WSAStartup(MAKEWORD(2, 0), &WsaData);
-
- Consoleprintf("G8BPQ AX25 Packet Switch System Version %s %s", TextVerstring, Datestring);
- Consoleprintf(VerCopyright);
-
- Start();
-
- INITIALISEPORTS(); // Restart Ports
-
- SetApplPorts();
-
- FreeConfig();
-
- for (i=1; i<68; i++) // Include Telnet, APRS and IP Vec
- {
- HOSTVEC=&BPQHOSTVECTOR[i-1];
-
- HOSTVEC->HOSTTRACEQ=0; // Clear header (pool has been reinitialized
-
- if (HOSTVEC->HOSTSESSION !=0)
- {
- // Had a connection
-
- HOSTVEC->HOSTSESSION=0;
- HOSTVEC->HOSTFLAGS |=3; // Disconnected
-
- PostMessage(HOSTVEC->HOSTHANDLE, BPQMsg, i, 4);
- }
- }
-
- // Free the APRS Appl Q
-
- APPL_Q = 0;
-
- OpenReportingSockets();
-
- WritetoConsole("\n\nReconfiguration Complete\n");
-
- if (IPRequired) IPActive = Init_IP();
- if (PMRequired) PMActive = Init_PM();
-
- APRSActive = Init_APRS();
-
- if (ISPort == 0)
- IGateEnabled = 0;
-
- CheckDlgButton(hConsWnd, IDC_ENIGATE, IGateEnabled);
-
- GetClientRect(hConsWnd, &cRect);
- MoveWindow(hWndBG, 0, 0, cRect.right, 26, TRUE);
- if (APRSActive)
- MoveWindow(hWndCons, 2, 26, cRect.right-4, cRect.bottom - 32, TRUE);
- else
- {
- ShowWindow(GetDlgItem(hConsWnd, IDC_GPS), SW_HIDE);
- MoveWindow(hWndCons, 2, 2, cRect.right-4, cRect.bottom - 4, TRUE);
- }
- InvalidateRect(hConsWnd, NULL, TRUE);
-
- RigActive = Rig_Init();
-
- if (NUMBEROFTNCPORTS)
- {
- FreeSemaphore(&Semaphore);
- InitializeTNCEmulator();
- GetSemaphore(&Semaphore, 0);
- }
-
- FreeSemaphore(&Semaphore);
- AGWActive = AGWAPIInit();
- GetSemaphore(&Semaphore, 0);
-
- OutputDebugString("BPQ32 Reconfiguration Complete\n");
- }
- }
-
-
- if (RigReconfigFlag)
- {
- // Only do it it timer owning process, or we could get in a real mess!
-
- if(TimerInst == GetCurrentProcessId())
- {
- RigReconfigFlag = FALSE;
- CloseDriverWindow(70);
- Rig_Close();
- Sleep(6000); // Allow any CATPTT, HAMLIB and FLRIG threads to close
- RigActive = Rig_Init();
-
- WritetoConsole("Rigcontrol Reconfiguration Complete\n");
- }
- }
-
- if (APRSReconfigFlag)
- {
- // Only do it it timer owning process, or we could get in a real mess!
-
- if(TimerInst == GetCurrentProcessId())
- {
- APRSReconfigFlag = FALSE;
- APRSClose();
- APRSActive = Init_APRS();
-
- WritetoConsole("APRS Reconfiguration Complete\n");
- }
- }
-
- }
- #include "StdExcept.c"
-
- if (Semaphore.Flag && Semaphore.SemProcessID == GetCurrentProcessId())
- FreeSemaphore(&Semaphore);
-
- }
-
- strcpy(EXCEPTMSG, "Timer Processing");
-
- __try
- {
- if (IPActive) Poll_IP();
- if (PMActive) Poll_PM();
- if (RigActive) Rig_Poll();
-
- if (NeedWebMailRefresh)
- DoRefreshWebMailIndex();
-
- CheckGuardZone();
-
- if (APRSActive)
- {
- Poll_APRS();
- CheckGuardZone();
- }
-
- CheckWL2KReportTimer();
-
- CheckGuardZone();
-
- TIMERINTERRUPT();
-
- CheckGuardZone();
-
- FreeSemaphore(&Semaphore); // SendLocation needs to get the semaphore
-
- if (NUMBEROFTNCPORTS)
- TNCTimer();
-
- if (AGWActive)
- Poll_AGW();
-
- DRATSPoll();
- RHPPoll();
-
- CheckGuardZone();
-
- strcpy(EXCEPTMSG, "HTTP Timer Processing");
-
- HTTPTimer();
-
- CheckGuardZone();
-
- strcpy(EXCEPTMSG, "WL2K Report Timer Processing");
-
- if (ReportTimer)
- {
- ReportTimer--;
-
- if (ReportTimer == 0)
- {
- ReportTimer = REPORTINTERVAL;
- SendLocation();
- }
- }
- }
-
- #include "StdExcept.c"
-
- if (Semaphore.Flag && Semaphore.SemProcessID == GetCurrentProcessId())
- FreeSemaphore(&Semaphore);
-
- }
-
- CheckGuardZone();
-
- return;
-}
-
-HANDLE NPHandle;
-
-int (WINAPI FAR *GetModuleFileNameExPtr)() = NULL;
-int (WINAPI FAR *EnumProcessesPtr)() = NULL;
-
-FirstInit()
-{
- WSADATA WsaData; // receives data from WSAStartup
- HINSTANCE ExtDriver=0;
- RECT cRect;
-
-
- // First Time Ports and Timer init
-
- // Moved from DLLINIT to sort out perl problem, and meet MS Guidelines on minimising DLLMain
-
- // Call wsastartup - most systems need winsock, and duplicate statups could be a problem
-
- WSAStartup(MAKEWORD(2, 0), &WsaData);
-
- // Load Psapi.dll if possible
-
- ExtDriver=LoadLibrary("Psapi.dll");
-
- SetupTrayIcon();
-
- if (ExtDriver)
- {
- GetModuleFileNameExPtr = (FARPROCX)GetProcAddress(ExtDriver,"GetModuleFileNameExA");
- EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses");
- }
-
- timeLoadedMS = GetTickCount();
-
- INITIALISEPORTS();
-
- OpenReportingSockets();
-
- WritetoConsole("\n");
- WritetoConsole("Port Initialisation Complete\n");
-
- if (IPRequired) IPActive = Init_IP();
- if (PMRequired) PMActive = Init_PM();
-
- APRSActive = Init_APRS();
-
- if (APRSActive)
- {
- hWndBG = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 0,0,40,546, hConsWnd, NULL, hInstance, NULL);
-
- CreateWindowEx(0, "STATIC", "Enable IGate", WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE,
- 8,0,90,24, hConsWnd, (HMENU)-1, hInstance, NULL);
-
- CreateWindowEx(0, "BUTTON", "", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,
- 95,1,18,24, hConsWnd, (HMENU)IDC_ENIGATE, hInstance, NULL);
-
- CreateWindowEx(0, "STATIC", "IGate State - Disconnected",
- WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE, 125, 0, 195, 24, hConsWnd, (HMENU)IGATESTATE, hInstance, NULL);
-
- CreateWindowEx(0, "STATIC", "IGATE Stats - Msgs 0 Local Stns 0",
- WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE, 320, 0, 240, 24, hConsWnd, (HMENU)IGATESTATS, hInstance, NULL);
-
- CreateWindowEx(0, "STATIC", "GPS Off",
- WS_CHILD | WS_VISIBLE | SS_CENTERIMAGE, 560, 0, 80, 24, hConsWnd, (HMENU)IDC_GPS, hInstance, NULL);
- }
-
- if (ISPort == 0)
- IGateEnabled = 0;
-
- CheckDlgButton(hConsWnd, IDC_ENIGATE, IGateEnabled);
-
- GetClientRect(hConsWnd, &cRect);
- MoveWindow(hWndBG, 0, 0, cRect.right, 26, TRUE);
- if (APRSActive)
- MoveWindow(hWndCons, 2, 26, cRect.right-4, cRect.bottom - 32, TRUE);
- else
- {
- ShowWindow(GetDlgItem(hConsWnd, IDC_GPS), SW_HIDE);
- MoveWindow(hWndCons, 2, 2, cRect.right-4, cRect.bottom - 4, TRUE);
- }
- InvalidateRect(hConsWnd, NULL, TRUE);
-
- RigActive = Rig_Init();
-
- _beginthread(MonitorThread,0,0);
-
- TimerHandle=SetTimer(NULL,0,100,lpTimerFunc);
- TimerInst=GetCurrentProcessId();
- SessHandle = SetTimer(NULL, 0, 5000, lpSetupTermSessions);
-
- // If ARIF reporting is enabled write a Trimode Like ini for RMS Analyser
-
- if (ADIFLogEnabled)
- ADIFWriteFreqList();
-
- OutputDebugString("BPQ32 Port Initialisation Complete\n");
-
- if (needAIS)
- initAIS();
-
- if (needADSB)
- initADSB();
-
- return 0;
-}
-
-Check_Timer()
-{
- if (Closing)
- return 0;
-
- if (Semaphore.Flag)
- return 0;
-
- if (InitDone == (void *)-1)
- {
- GetSemaphore(&Semaphore, 3);
- Sleep(15000);
- FreeSemaphore(&Semaphore);
- exit (0);
- }
-
- if (FirstInitDone == 0)
- {
- GetSemaphore(&Semaphore, 3);
-
- if (_stricmp(pgm, "bpq32.exe") == 0)
- {
- FirstInit();
- FreeSemaphore(&Semaphore);
- if (NUMBEROFTNCPORTS)
- InitializeTNCEmulator();
-
- AGWActive = AGWAPIInit();
- FirstInitDone=1; // Only init in BPQ32.exe
- return 0;
- }
- else
- {
- FreeSemaphore(&Semaphore);
- return 0;
- }
- }
-
- if (TimerHandle == 0 && FirstInitDone == 1)
- {
- WSADATA WsaData; // receives data from WSAStartup
- HINSTANCE ExtDriver=0;
- RECT cRect;
-
- // Only attach timer to bpq32.exe
-
- if (_stricmp(pgm, "bpq32.exe") != 0)
- {
- return 0;
- }
-
- GetSemaphore(&Semaphore, 3);
- OutputDebugString("BPQ32 Reinitialising External Ports and Attaching Timer\n");
-
- if (!ProcessConfig())
- {
- ShowWindow(hConsWnd, SW_RESTORE);
- SendMessage(hConsWnd, WM_PAINT, 0, 0);
- SetForegroundWindow(hConsWnd);
-
- InitDone = (void *)-1;
- FreeSemaphore(&Semaphore);
-
- MessageBox(NULL,"Configuration File Error","BPQ32",MB_ICONSTOP);
-
- exit (0);
- }
-
- GetVersionInfo("bpq32.dll");
-
- SetupConsoleWindow();
-
- Consoleprintf("G8BPQ AX25 Packet Switch System Version %s %s", TextVerstring, Datestring);
- Consoleprintf(VerCopyright);
- Consoleprintf("Reinitialising...");
-
- SetupBPQDirectory();
-
- Sleep(1000); // Allow time for sockets to close
-
- WSAStartup(MAKEWORD(2, 0), &WsaData);
-
- // Load Psapi.dll if possible
-
- ExtDriver = LoadLibrary("Psapi.dll");
-
- SetupTrayIcon();
-
- if (ExtDriver)
- {
- GetModuleFileNameExPtr = (FARPROCX)GetProcAddress(ExtDriver,"GetModuleFileNameExA");
- EnumProcessesPtr = (FARPROCX)GetProcAddress(ExtDriver,"EnumProcesses");
- }
-
- Start();
-
- INITIALISEPORTS();
-
- OpenReportingSockets();
-
- NODESINPROGRESS = 0;
- CURRENTNODE = 0;
-
- SetApplPorts();
-
- WritetoConsole("\n\nPort Reinitialisation Complete\n");
-
- BPQMsg = RegisterWindowMessage(BPQWinMsg);
-
- CreateMutex(NULL,TRUE,"BPQLOCKMUTEX");
-
-// NPHandle=CreateNamedPipe("\\\\.\\pipe\\BPQ32pipe",
-// PIPE_ACCESS_DUPLEX,0,64,4096,4096,1000,NULL);
-
- if (IPRequired) IPActive = Init_IP();
- if (PMRequired) PMActive = Init_PM();
-
- RigActive = Rig_Init();
- APRSActive = Init_APRS();
-
- if (ISPort == 0)
- IGateEnabled = 0;
-
- CheckDlgButton(hConsWnd, IDC_ENIGATE, IGateEnabled);
-
- GetClientRect(hConsWnd, &cRect);
- MoveWindow(hWndBG, 0, 0, cRect.right, 26, TRUE);
-
- if (APRSActive)
- MoveWindow(hWndCons, 2, 26, cRect.right-4, cRect.bottom - 32, TRUE);
- else
- {
- ShowWindow(GetDlgItem(hConsWnd, IDC_GPS), SW_HIDE);
- MoveWindow(hWndCons, 2, 2, cRect.right-4, cRect.bottom - 4, TRUE);
- }
- InvalidateRect(hConsWnd, NULL, TRUE);
-
- FreeConfig();
-
- _beginthread(MonitorThread,0,0);
-
- ReportTimer = 0;
-
- OpenReportingSockets();
-
- FreeSemaphore(&Semaphore);
-
- if (NUMBEROFTNCPORTS)
- InitializeTNCEmulator();
-
- AGWActive = AGWAPIInit();
-
- if (StartMinimized)
- if (MinimizetoTray)
- ShowWindow(FrameWnd, SW_HIDE);
- else
- ShowWindow(FrameWnd, SW_SHOWMINIMIZED);
- else
- ShowWindow(FrameWnd, SW_RESTORE);
-
- TimerHandle=SetTimer(NULL,0,100,lpTimerFunc);
- TimerInst=GetCurrentProcessId();
- SessHandle = SetTimer(NULL, 0, 5000, lpSetupTermSessions);
-
- return (1);
- }
-
- return (0);
-}
-
-DllExport INT APIENTRY CheckTimer()
-{
- return Check_Timer();
-}
-
-Tell_Sessions()
-{
- //
- // Post a message to all listening sessions, so they call the
- // API, and cause a new timer to be allocated
- //
- HWND hWnd;
- int i;
-
- for (i=1;i<65;i++)
- {
- if (BPQHOSTVECTOR[i-1].HOSTFLAGS & 0x80)
- {
- hWnd = BPQHOSTVECTOR[i-1].HOSTHANDLE;
- PostMessage(hWnd, BPQMsg,i, 1);
- PostMessage(hWnd, BPQMsg,i, 2);
- }
- }
- return (0);
-}
-
-BOOL APIENTRY DllMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReserved)
-{
- DWORD n;
- char buf[350];
-
- int i;
- unsigned int ProcessID;
-
- OSVERSIONINFO osvi;
-
- memset(&osvi, 0, sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- GetVersionEx(&osvi);
-
-
- switch( ul_reason_being_called )
- {
- case DLL_PROCESS_ATTACH:
-
- if (sizeof(HDLCDATA) > PORTENTRYLEN + 200) // 200 bytes of Hardwaredata
- {
- // Catastrophic - Refuse to load
-
- MessageBox(NULL,"BPQ32 Too much HDLC data - Recompile","BPQ32", MB_OK);
- return 0;
- }
-
- if (sizeof(struct KISSINFO) > PORTENTRYLEN + 200) // 200 bytes of Hardwaredata
- {
- // Catastrophic - Refuse to load
-
- MessageBox(NULL,"BPQ32 Too much KISS data - Recompile","BPQ32", MB_OK);
- return 0;
- }
-
- if (sizeof(struct _EXTPORTDATA) > PORTENTRYLEN + 200) // 200 bytes of Hardwaredata
- {
- // Catastrophic - Refuse to load
-
- MessageBox(NULL,"BPQ32 Too much _EXTPORTDATA data - Recompile","BPQ32", MB_OK);
- return 0;
- }
-
- if (sizeof(LINKTABLE) != LINK_TABLE_LEN)
- {
- // Catastrophic - Refuse to load
-
- MessageBox(NULL,"L2 LINK Table .c and .asm mismatch - fix and rebuild","BPQ32", MB_OK);
- return 0;
- }
- if (sizeof(struct ROUTE) != ROUTE_LEN)
- {
- // Catastrophic - Refuse to load
-
- MessageBox(NULL,"ROUTE Table .c and .asm mismatch - fix and rebuild", "BPQ32", MB_OK);
- return 0;
- }
-
- if (sizeof(struct DEST_LIST) != DEST_LIST_LEN)
- {
- // Catastrophic - Refuse to load
-
- MessageBox(NULL,"NODES Table .c and .asm mismatch - fix and rebuild", "BPQ32", MB_OK);
- return 0;
- }
-
- GetSemaphore(&Semaphore, 4);
-
- BPQHOSTVECPTR = &BPQHOSTVECTOR[0];
-
- LoadToolHelperRoutines();
-
- Our_PID = GetCurrentProcessId();
-
- QueryPerformanceFrequency(&lpFrequency);
-
- ticksPerMillisec = (int)lpFrequency.QuadPart / 1000;
-
- lastRunTime.QuadPart = lpFrequency.QuadPart;
-
- GetProcess(Our_PID, pgm);
-
- if (_stricmp(pgm, "regsvr32.exe") == 0 || _stricmp(pgm, "bpqcontrol.exe") == 0)
- {
- AttachedProcesses++; // We will get a detach
- FreeSemaphore(&Semaphore);
- return 1;
- }
-
- if (_stricmp(pgm,"BPQ32.exe") == 0)
- BPQ32_EXE = TRUE;
-
- if (_stricmp(pgm,"BPQMailChat.exe") == 0)
- IncludesMail = TRUE;
-
- if (_stricmp(pgm,"BPQMail.exe") == 0)
- IncludesMail = TRUE;
-
- if (_stricmp(pgm,"BPQChat.exe") == 0)
- IncludesChat = TRUE;
-
- if (FirstEntry) // If loaded by BPQ32.exe, dont close it at end
- {
- FirstEntry = 0;
- if (BPQ32_EXE)
- CloseLast = FALSE;
- }
- else
- {
- if (BPQ32_EXE && AttachingProcess == 0)
- {
- AttachedProcesses++; // We will get a detach
- FreeSemaphore(&Semaphore);
- MessageBox(NULL,"BPQ32.exe is already running\r\n\r\nIt should only be run once", "BPQ32", MB_OK);
- return 0;
- }
- }
-
- if (_stricmp(pgm,"BPQTelnetServer.exe") == 0)
- {
- MessageBox(NULL,"BPQTelnetServer is no longer supported\r\n\r\nUse the TelnetServer in BPQ32.dll", "BPQ32", MB_OK);
- AttachedProcesses++; // We will get a detach
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- if (_stricmp(pgm,"BPQUIUtil.exe") == 0)
- {
- MessageBox(NULL,"BPQUIUtil is now part of BPQ32.dll\r\nBPQUIUtil.exe cannot be run\r\n", "BPQ32", MB_OK);
- AttachedProcesses++; // We will get a detach
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- if (_stricmp(pgm,"BPQMailChat.exe") == 0)
- {
- MessageBox(NULL,"BPQMailChat is obsolete. Run BPQMail.exe and/or BPQChat.exe instead", "BPQ32", MB_OK);
- AttachedProcesses++; // We will get a detach
- FreeSemaphore(&Semaphore);
- return 0;
- }
- AuthorisedProgram = TRUE;
-
- if (InitDone == 0)
- {
-// #pragma warning(push)
-// #pragma warning(disable : 4996)
-
-// if (_winver < 0x0600)
-// #pragma warning(pop)
-// {
-// // Below Vista
-//
-// REGTREE = HKEY_LOCAL_MACHINE;
-// strcpy(REGTREETEXT, "HKEY_LOCAL_MACHINE");
-// }
-
- hInstance=hInst;
-
- Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"BPQLOCKMUTEX");
-
- if (Mutex != NULL)
- {
- OutputDebugString("Another BPQ32.dll is loaded\n");
- i=MessageBox(NULL,"BPQ32 DLL already loaded from another directory\nIf you REALLY want this, hit OK, else hit Cancel","BPQ32",MB_OKCANCEL);
- FreeSemaphore(&Semaphore);
-
- if (i != IDOK) return (0);
-
- CloseHandle(Mutex);
- }
-
- if (!BPQ32_EXE)
- {
- if (CheckifBPQ32isLoaded() == FALSE) // Start BPQ32.exe if needed
- {
- // Wasn't Loaded, so we have started it, and should let it init system
-
- goto SkipInit;
- }
- }
-
- GetVersionInfo("bpq32.dll");
-
- sprintf (SIGNONMSG, "G8BPQ AX25 Packet Switch System Version %s %s\r\n%s\r\n",
- TextVerstring, Datestring, VerCopyright);
-
- SESSHDDRLEN = sprintf(SESSIONHDDR, "G8BPQ Network System %s for Win32 (", TextVerstring);
-
- SetupConsoleWindow();
- SetupBPQDirectory();
-
- if (!ProcessConfig())
- {
- StartMinimized = FALSE;
- MinimizetoTray = FALSE;
- ShowWindow(FrameWnd, SW_MAXIMIZE);
- ShowWindow(hConsWnd, SW_MAXIMIZE);
- ShowWindow(StatusWnd, SW_HIDE);
-
- SendMessage(hConsWnd, WM_PAINT, 0, 0);
- SetForegroundWindow(hConsWnd);
-
- InitDone = (void *)-1;
- FreeSemaphore(&Semaphore);
-
- MessageBox(NULL,"Configuration File Error\r\nProgram will close in 15 seconds","BPQ32",MB_ICONSTOP);
-
- return (0);
- }
-
- Consoleprintf("G8BPQ AX25 Packet Switch System Version %s %s", TextVerstring, Datestring);
- Consoleprintf(VerCopyright);
-
- if (Start() !=0)
- {
- Sleep(3000);
- FreeSemaphore(&Semaphore);
- return (0);
- }
- else
- {
- SetApplPorts();
-
- GetUIConfig();
-
- InitDone = &InitDone;
- BPQMsg = RegisterWindowMessage(BPQWinMsg);
-// TimerHandle=SetTimer(NULL,0,100,lpTimerFunc);
-// TimerInst=GetCurrentProcessId();
-
-/* Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"BPQLOCKMUTEX");
-
- if (Mutex != NULL)
- {
- OutputDebugString("Another BPQ32.dll is loaded\n");
- MessageBox(NULL,"BPQ32 DLL already loaded from another directory","BPQ32",MB_ICONSTOP);
- FreeSemaphore(&Semaphore);
- return (0);
- }
-
-*/
- Mutex=CreateMutex(NULL,TRUE,"BPQLOCKMUTEX");
-
-// CreatePipe(&H1,&H2,NULL,1000);
-
-// GetLastError();
-
-// NPHandle=CreateNamedPipe("\\\\.\\pipe\\BPQ32pipe",
-// PIPE_ACCESS_DUPLEX,0,64,4096,4096,1000,NULL);
-
-// GetLastError();
-
-/*
- //
- // Read SYSOP password
- //
-
- if (PWTEXT[0] == 0)
- {
- handle = OpenConfigFile("PASSWORD.BPQ");
-
- if (handle == INVALID_HANDLE_VALUE)
- {
- WritetoConsole("Can't open PASSWORD.BPQ\n");
- PWLen=0;
- PWTEXT[0]=0;
- }
- else
- {
- ReadFile(handle,PWTEXT,78,&n,NULL);
- CloseHandle(handle);
- }
- }
-*/
- for (i=0;PWTEXT[i] > 0x20;i++); //Scan for cr or null
- PWLen=i;
-
- }
- }
- else
- {
- if (InitDone != &InitDone)
- {
- MessageBox(NULL,"BPQ32 DLL already loaded at another address","BPQ32",MB_ICONSTOP);
- FreeSemaphore(&Semaphore);
- return (0);
- }
- }
-
- // Run timer monitor thread in all processes - it is possible for the TImer thread not to be the first thread
-SkipInit:
-
- _beginthread(MonitorTimerThread,0,0);
-
- FreeSemaphore(&Semaphore);
-
- AttachedPIDList[AttachedProcesses++] = GetCurrentProcessId();
-
- if (_stricmp(pgm,"bpq32.exe") == 0 && AttachingProcess == 1) AttachingProcess = 0;
-
- GetProcess(GetCurrentProcessId(),pgm);
- n=sprintf(buf,"BPQ32 DLL Attach complete - Program %s - %d Process(es) Attached\n",pgm,AttachedProcesses);
- OutputDebugString(buf);
-
- // Set up local variables
-
- MCOM=1;
- MTX=1;
- MMASK=0xffffffffffffffff;
-
-// if (StartMinimized)
-// if (MinimizetoTray)
-// ShowWindow(FrameWnd, SW_HIDE);
-// else
-// ShowWindow(FrameWnd, SW_SHOWMINIMIZED);
-// else
-// ShowWindow(FrameWnd, SW_RESTORE);
-
- return 1;
-
- case DLL_THREAD_ATTACH:
-
- return 1;
-
- case DLL_THREAD_DETACH:
-
- return 1;
-
- case DLL_PROCESS_DETACH:
-
- if (_stricmp(pgm,"BPQMailChat.exe") == 0)
- IncludesMail = FALSE;
-
- if (_stricmp(pgm,"BPQChat.exe") == 0)
- IncludesChat = FALSE;
-
- ProcessID=GetCurrentProcessId();
-
- Debugprintf("BPQ32 Process %d Detaching", ProcessID);
-
- // Release any streams that the app has failed to release
-
- for (i=1;i<65;i++)
- {
- if (BPQHOSTVECTOR[i-1].STREAMOWNER == ProcessID)
- {
- // If connected, disconnect
-
- SessionControl(i, 2, 0);
- DeallocateStream(i);
- }
- }
-
- // Remove any Tray Icon Entries
-
- for( i = 0; i < 100; ++i )
- {
- if (PIDArray[i] == ProcessID)
- {
- char Log[80];
- hWndArray[i] = 0;
- sprintf(Log,"BPQ32 Removing Tray Item %s\n", PopupText[i]);
- OutputDebugString(Log);
- DeleteMenu(trayMenu,TRAYBASEID+i,MF_BYCOMMAND);
- }
- }
-
- if (Mutex) CloseHandle(Mutex);
-
- // Remove our entry from PID List
-
- for (i=0; i< AttachedProcesses; i++)
- if (AttachedPIDList[i] == ProcessID)
- break;
-
- for (; i< AttachedProcesses; i++)
- {
- AttachedPIDList[i]=AttachedPIDList[i+1];
- }
-
- AttachedProcesses--;
-
- if (TimerInst == ProcessID)
- {
- PEXTPORTDATA PORTVEC=(PEXTPORTDATA)PORTTABLE;
-
- OutputDebugString("BPQ32 Process with Timer closing\n");
-
- // Call Port Close Routines
-
- for (i=0;iPORTCONTROL.PORTTYPE == 0x10) // External
- {
- if (PORTVEC->PORT_EXT_ADDR && PORTVEC->DLLhandle == NULL) // Don't call if real .dll - it's not there!
- {
- SaveWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
- SaveAXIPWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
- PORTVEC->PORT_EXT_ADDR(5,PORTVEC->PORTCONTROL.PORTNUMBER, NULL); // Close External Ports
- }
- }
-
- PORTVEC->PORTCONTROL.PORTCLOSECODE(&PORTVEC->PORTCONTROL);
-
- PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
- }
-
-
- IPClose();
- PMClose();
- APRSClose();
- Rig_Close();
- CloseTNCEmulator();
- if (AGWActive)
- AGWAPITerminate();
-
- upnpClose();
-
- WSACleanup();
- WSAGetLastError();
-
- if (MinimizetoTray)
- Shell_NotifyIcon(NIM_DELETE,&niData);
-
- if (hConsWnd) DestroyWindow(hConsWnd);
-
- KillTimer(NULL,TimerHandle);
- TimerHandle=0;
- TimerInst=0xffffffff;
-
- if (AttachedProcesses && Closing == FALSE && AttachingProcess == 0) // Other processes
- {
- OutputDebugString("BPQ32 Reloading BPQ32.exe\n");
- StartBPQ32();
- }
- }
- else
- {
- // Not Timer Process
-
- if (AttachedProcesses == 1 && CloseLast) // Only bpq32.exe left
- {
- Debugprintf("Only BPQ32.exe running - close it");
- CloseAllNeeded = TRUE;
- }
- }
-
- if (AttachedProcesses < 2)
- {
- if (AUTOSAVE)
- SaveNodes();
- if (AUTOSAVEMH)
- SaveMH();
-
- if (needAIS)
- SaveAIS();
- }
- if (AttachedProcesses == 0)
- {
- Closing = TRUE;
- KillTimer(NULL,TimerHandle);
-
- if (MinimizetoTray)
- Shell_NotifyIcon(NIM_DELETE,&niData);
-
- // Unload External Drivers
-
- {
- PEXTPORTDATA PORTVEC=(PEXTPORTDATA)PORTTABLE;
-
- for (i=0;iPORTCONTROL.PORTTYPE == 0x10 && PORTVEC->DLLhandle)
- FreeLibrary(PORTVEC->DLLhandle);
-
- PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
- }
- }
- }
-
- GetProcess(GetCurrentProcessId(),pgm);
- n=sprintf(buf,"BPQ32 DLL Detach complete - Program %s - %d Process(es) Attached\n",pgm,AttachedProcesses);
- OutputDebugString(buf);
-
- return 1;
- }
- return 1;
-}
-
-DllExport int APIENTRY CloseBPQ32()
-{
- // Unload External Drivers
-
- PEXTPORTDATA PORTVEC=(PEXTPORTDATA)PORTTABLE;
- int i;
- int ProcessID = GetCurrentProcessId();
-
- if (Semaphore.Flag == 1 && ProcessID == Semaphore.SemProcessID)
- {
- OutputDebugString("BPQ32 Process holding Semaphore called CloseBPQ32 - attempting recovery\r\n");
- Debugprintf("Last Sem Call %d %x %x %x %x %x %x", SemHeldByAPI,
- Sem_eax, Sem_ebx, Sem_ecx, Sem_edx, Sem_esi, Sem_edi);
-
- Semaphore.Flag = 0;
- SemHeldByAPI = 0;
- }
-
- if (TimerInst == ProcessID)
- {
- OutputDebugString("BPQ32 Process with Timer called CloseBPQ32\n");
-
- if (MinimizetoTray)
- Shell_NotifyIcon(NIM_DELETE,&niData);
-
- for (i=0;iPORTCONTROL.PORTTYPE == 0x10) // External
- {
- if (PORTVEC->PORT_EXT_ADDR)
- {
- PORTVEC->PORT_EXT_ADDR(5,PORTVEC->PORTCONTROL.PORTNUMBER, NULL);
- }
- }
- PORTVEC->PORTCONTROL.PORTCLOSECODE(&PORTVEC->PORTCONTROL);
-
- PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
- }
-
- KillTimer(NULL,TimerHandle);
- TimerHandle=0;
- TimerInst=0xffffffff;
-
- IPClose();
- PMClose();
- APRSClose();
- Rig_Close();
- if (AGWActive)
- AGWAPITerminate();
-
- upnpClose();
-
- CloseTNCEmulator();
- WSACleanup();
-
- if (hConsWnd) DestroyWindow(hConsWnd);
-
- Debugprintf("AttachedProcesses %d ", AttachedProcesses);
-
- if (AttachedProcesses > 1 && Closing == FALSE && AttachingProcess == 0) // Other processes
- {
- OutputDebugString("BPQ32 Reloading BPQ32.exe\n");
- StartBPQ32();
- }
- }
-
- return 0;
-}
-
-BOOL CopyReg(HKEY hKeyIn, HKEY hKeyOut);
-
-VOID SetupBPQDirectory()
-{
- HKEY hKey = 0;
- HKEY hKeyIn = 0;
- HKEY hKeyOut = 0;
- int disp;
- int retCode,Type,Vallen=MAX_PATH,i;
- char msg[512];
- char ValfromReg[MAX_PATH] = "";
- char DLLName[256]="Not Known";
- char LogDir[256];
- char Time[64];
-
-/*
-•NT4 was/is '4'
-•Win 95 is 4.00.950
-•Win 98 is 4.10.1998
-•Win 98 SE is 4.10.2222
-•Win ME is 4.90.3000
-•2000 is NT 5.0.2195
-•XP is actually 5.1
-•Vista is 6.0
-•Win7 is 6.1
-
- i = _osver; / Build
- i = _winmajor;
- i = _winminor;
-*/
-/*
-#pragma warning(push)
-#pragma warning(disable : 4996)
-
-if (_winver < 0x0600)
-#pragma warning(pop)
- {
- // Below Vista
-
- REGTREE = HKEY_LOCAL_MACHINE;
- strcpy(REGTREETEXT, "HKEY_LOCAL_MACHINE");
- ValfromReg[0] = 0;
- }
- else
-*/
- {
- if (_stricmp(pgm, "regsvr32.exe") == 0)
- {
- Debugprintf("BPQ32 loaded by regsvr32.exe - Registry not copied");
- }
- else
- {
- // If necessary, move reg from HKEY_LOCAL_MACHINE to HKEY_CURRENT_USER
-
- retCode = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- "SOFTWARE\\G8BPQ\\BPQ32",
- 0,
- KEY_READ,
- &hKeyIn);
-
- retCode = RegCreateKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\G8BPQ\\BPQ32", 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKeyOut, &disp);
-
- // See if Version Key exists in HKEY_CURRENT_USER - if it does, we have already done the copy
-
- Vallen = MAX_PATH;
- retCode = RegQueryValueEx(hKeyOut, "Version" ,0 , &Type,(UCHAR *)&msg, &Vallen);
-
- if (retCode != ERROR_SUCCESS)
- if (hKeyIn)
- CopyReg(hKeyIn, hKeyOut);
-
- RegCloseKey(hKeyIn);
- RegCloseKey(hKeyOut);
- }
- }
-
- GetModuleFileName(hInstance,DLLName,256);
-
- BPQDirectory[0]=0;
-
- retCode = RegOpenKeyEx (REGTREE,
- "SOFTWARE\\G8BPQ\\BPQ32",
- 0,
- KEY_QUERY_VALUE,
- &hKey);
-
- if (retCode == ERROR_SUCCESS)
- {
- // Try "BPQ Directory"
-
- Vallen = MAX_PATH;
- retCode = RegQueryValueEx(hKey,"BPQ Directory",0,
- &Type,(UCHAR *)&ValfromReg,&Vallen);
-
- if (retCode == ERROR_SUCCESS)
- {
- if (strlen(ValfromReg) == 2 && ValfromReg[0] == '"' && ValfromReg[1] == '"')
- ValfromReg[0]=0;
- }
-
- if (ValfromReg[0] == 0)
- {
- // BPQ Directory absent or = "" - try "Config File Location"
-
- Vallen = MAX_PATH;
-
- retCode = RegQueryValueEx(hKey,"Config File Location",0,
- &Type,(UCHAR *)&ValfromReg,&Vallen);
-
- if (retCode == ERROR_SUCCESS)
- {
- if (strlen(ValfromReg) == 2 && ValfromReg[0] == '"' && ValfromReg[1] == '"')
- ValfromReg[0]=0;
- }
- }
-
- if (ValfromReg[0] == 0) GetCurrentDirectory(MAX_PATH, ValfromReg);
-
- // Get StartMinimized and MinimizetoTray flags
-
- Vallen = 4;
- retCode = RegQueryValueEx(hKey, "Start Minimized", 0, &Type, (UCHAR *)&StartMinimized, &Vallen);
-
- Vallen = 4;
- retCode = RegQueryValueEx(hKey, "Minimize to Tray", 0, &Type, (UCHAR *)&MinimizetoTray, &Vallen);
-
- ExpandEnvironmentStrings(ValfromReg, BPQDirectory, MAX_PATH);
-
- // Also get "BPQ Program Directory"
-
- ValfromReg[0] = 0;
- Vallen = MAX_PATH;
-
- retCode = RegQueryValueEx(hKey, "BPQ Program Directory",0 , &Type, (UCHAR *)&ValfromReg, &Vallen);
-
- if (retCode == ERROR_SUCCESS)
- ExpandEnvironmentStrings(ValfromReg, BPQProgramDirectory, MAX_PATH);
-
- // And Log Directory
-
- ValfromReg[0] = 0;
- Vallen = MAX_PATH;
-
- retCode = RegQueryValueEx(hKey, "Log Directory",0 , &Type, (UCHAR *)&ValfromReg, &Vallen);
-
- if (retCode == ERROR_SUCCESS)
- ExpandEnvironmentStrings(ValfromReg, LogDirectory, MAX_PATH);
-
- RegCloseKey(hKey);
- }
-
- strcpy(ConfigDirectory, BPQDirectory);
-
- if (LogDirectory[0] == 0)
- strcpy(LogDirectory, BPQDirectory);
-
- if (BPQProgramDirectory[0] == 0)
- strcpy(BPQProgramDirectory, BPQDirectory);
-
- sprintf(msg,"BPQ32 Ver %s Loaded from: %s by %s\n", VersionString, DLLName, pgm);
- WritetoConsole(msg);
- OutputDebugString(msg);
- FormatTime3(Time, time(NULL));
- sprintf(msg,"Loaded %s\n", Time);
- WritetoConsole(msg);
- OutputDebugString(msg);
-
-#pragma warning(push)
-#pragma warning(disable : 4996)
-
-#if _MSC_VER >= 1400
-
-#define _winmajor 6
-#define _winminor 0
-
-#endif
-
- i=sprintf(msg,"Windows Ver %d.%d, Using Registry Key %s\n" ,_winmajor, _winminor, REGTREETEXT);
-
-#pragma warning(pop)
-
- WritetoConsole(msg);
- OutputDebugString(msg);
-
- i=sprintf(msg,"BPQ32 Using config from: %s\n\n",BPQDirectory);
- WritetoConsole(&msg[6]);
- msg[i-1]=0;
- OutputDebugString(msg);
-
- // Don't write the Version Key if loaded by regsvr32.exe (Installer is running with Admin rights,
- // so will write the wrong tree on )
-
- if (_stricmp(pgm, "regsvr32.exe") == 0)
- {
- Debugprintf("BPQ32 loaded by regsvr32.exe - Version String not written");
- }
- else
- {
- retCode = RegCreateKeyEx(REGTREE, "SOFTWARE\\G8BPQ\\BPQ32", 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, &disp);
-
- sprintf(msg,"%d,%d,%d,%d", Ver[0], Ver[1], Ver[2], Ver[3]);
- retCode = RegSetValueEx(hKey, "Version",0, REG_SZ,(BYTE *)msg, strlen(msg) + 1);
-
- RegCloseKey(hKey);
- }
-
- // Make sure Logs Directory exists
-
- sprintf(LogDir, "%s/Logs", LogDirectory);
-
- CreateDirectory(LogDir, NULL);
-
- return;
-}
-
-HANDLE OpenConfigFile(char *fn)
-{
- HANDLE handle;
- UCHAR Value[MAX_PATH];
- FILETIME LastWriteTime;
- SYSTEMTIME Time;
- char Msg[256];
-
-
- // If no directory, use current
- if (BPQDirectory[0] == 0)
- {
- strcpy(Value,fn);
- }
- else
- {
- strcpy(Value,BPQDirectory);
- strcat(Value,"\\");
- strcat(Value,fn);
- }
-
- handle = CreateFile(Value,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- GetFileTime(handle, NULL, NULL, &LastWriteTime);
- FileTimeToSystemTime(&LastWriteTime, &Time);
-
- sprintf(Msg,"BPQ32 Config File %s Created %.2d:%.2d %d/%.2d/%.2d\n", Value,
- Time.wHour, Time.wMinute, Time.wYear, Time.wMonth, Time.wDay);
-
- OutputDebugString(Msg);
-
- return(handle);
-}
-
-#ifdef _WIN64
-int BPQHOSTAPI()
-{
- return 0;
-}
-#endif
-
-
-DllExport int APIENTRY GETBPQAPI()
-{
- return (int)BPQHOSTAPI;
-}
-
-//DllExport UINT APIENTRY GETMONDECODE()
-//{
-// return (UINT)MONDECODE;
-//}
-
-
-DllExport INT APIENTRY BPQAPI(int Fn, char * params)
-{
-
-/*
-;
-; BPQ HOST MODE SUPPORT CODE
-;
-; 22/11/95
-;
-; MOVED FROM TNCODE.ASM COS CONITIONALS WERE GETTING TOO COMPLICATED
-; (OS2 VERSION HAD UPSET KANT VERISON
-;
-;
-*/
-
-
-/*
-
- BPQHOSTPORT:
-;
-; SPECIAL INTERFACE, MAINLY FOR EXTERNAL HOST MODE SUPPORT PROGS
-;
-; COMMANDS SUPPORTED ARE
-;
-; AH = 0 Get node/switch version number and description. On return
-; AH='B',AL='P',BH='Q',BL=' '
-; DH = major version number and DL = minor version number.
-;
-;
-; AH = 1 Set application mask to value in DL (or even DX if 16
-; applications are ever to be supported).
-;
-; Set application flag(s) to value in CL (or CX).
-; whether user gets connected/disconnected messages issued
-; by the node etc.
-;
-;
-; AH = 2 Send frame in ES:SI (length CX)
-;
-;
-; AH = 3 Receive frame into buffer at ES:DI, length of frame returned
-; in CX. BX returns the number of outstanding frames still to
-; be received (ie. after this one) or zero if no more frames
-; (ie. this is last one).
-;
-;
-;
-; AH = 4 Get stream status. Returns:
-;
-; CX = 0 if stream disconnected or CX = 1 if stream connected
-; DX = 0 if no change of state since last read, or DX = 1 if
-; the connected/disconnected state has changed since
-; last read (ie. delta-stream status).
-;
-;
-;
-; AH = 6 Session control.
-;
-; CX = 0 Conneect - _APPLMASK in DL
-; CX = 1 connect
-; CX = 2 disconnect
-; CX = 3 return user to node
-;
-;
-; AH = 7 Get buffer counts for stream. Returns:
-;
-; AX = number of status change messages to be received
-; BX = number of frames queued for receive
-; CX = number of un-acked frames to be sent
-; DX = number of buffers left in node
-; SI = number of trace frames queued for receive
-;
-;AH = 8 Port control/information. Called with a stream number
-; in AL returns:
-;
-; AL = Radio port on which channel is connected (or zero)
-; AH = SESSION TYPE BITS
-; BX = L2 paclen for the radio port
-; CX = L2 maxframe for the radio port
-; DX = L4 window size (if L4 circuit, or zero)
-; ES:DI = CALLSIGN
-
-;AH = 9 Fetch node/application callsign & alias. AL = application
-; number:
-;
-; 0 = node
-; 1 = BBS
-; 2 = HOST
-; 3 = SYSOP etc. etc.
-;
-; Returns string with alias & callsign or application name in
-; user's buffer pointed to by ES:SI length CX. For example:
-;
-; "WORCS:G8TIC" or "TICPMS:G8TIC-10".
-;
-;
-; AH = 10 Unproto transmit frame. Data pointed to by ES:SI, of
-; length CX, is transmitted as a HDLC frame on the radio
-; port (not stream) in AL.
-;
-;
-; AH = 11 Get Trace (RAW Data) Frame into ES:DI,
-; Length to CX, Timestamp to AX
-;
-;
-; AH = 12 Update Switch. At the moment only Beacon Text may be updated
-; DX = Function
-; 1=update BT. ES:SI, Len CX = Text
-; 2=kick off nodes broadcast
-;
-; AH = 13 Allocate/deallocate stream
-; If AL=0, return first free stream
-; If AL>0, CL=1, Allocate stream. If aleady allocated,
-; return CX nonzero, else allocate, and return CX=0
-; If AL>0, CL=2, Release stream
-;
-;
-; AH = 14 Internal Interface for IP Router
-;
-; Send frame - to NETROM L3 if DL=0
-; to L2 Session if DL<>0
-;
-;
-; AH = 15 Get interval timer
-
-
-*/
-
-
- switch(Fn)
- {
-
- case CHECKLOADED:
-
- params[0]=MAJORVERSION;
- params[1]=MINORVERSION;
- params[2]=QCOUNT;
-
- return (1);
- }
- return 0;
-}
-
-DllExport int APIENTRY InitSwitch()
-{
- return (0);
-}
-
-/*DllExport int APIENTRY SwitchTimer()
-{
- GetSemaphore((&Semaphore);
-
- TIMERINTERRUPT();
-
- FreeSemaphore(&Semaphore);
-
- return (0);
-}
-*/
-DllExport int APIENTRY GetFreeBuffs()
-{
-// Returns number of free buffers
-// (BPQHOST function 7 (part)).
- return (QCOUNT);
-}
-
-DllExport UCHAR * APIENTRY GetNodeCall()
-{
- return (&MYNODECALL);
-}
-
-
-DllExport UCHAR * APIENTRY GetNodeAlias()
-{
- return (&MYALIASTEXT[0]);
-}
-
-DllExport UCHAR * APIENTRY GetBBSCall()
-{
- return (UCHAR *)(&APPLCALLTABLE[0].APPLCALL_TEXT);
-}
-
-
-DllExport UCHAR * APIENTRY GetBBSAlias()
-{
- return (UCHAR *)(&APPLCALLTABLE[0].APPLALIAS_TEXT);
-}
-
-DllExport VOID APIENTRY GetApplCallVB(int Appl, char * ApplCall)
-{
- if (Appl < 1 || Appl > NumberofAppls ) return;
-
- strncpy(ApplCall,(char *)&APPLCALLTABLE[Appl-1].APPLCALL_TEXT, 10);
-}
-
-BOOL UpdateNodesForApp(int Appl);
-
-DllExport BOOL APIENTRY SetApplCall(int Appl, char * NewCall)
-{
- char Call[10]=" ";
- int i;
-
- if (Appl < 1 || Appl > NumberofAppls ) return FALSE;
-
- i=strlen(NewCall);
-
- if (i > 10) i=10;
-
- strncpy(Call,NewCall,i);
-
- strncpy((char *)&APPLCALLTABLE[Appl-1].APPLCALL_TEXT,Call,10);
-
- if (!ConvToAX25(Call,APPLCALLTABLE[Appl-1].APPLCALL)) return FALSE;
-
- UpdateNodesForApp(Appl);
-
- return TRUE;
-
-}
-
-DllExport BOOL APIENTRY SetApplAlias(int Appl, char * NewCall)
-{
- char Call[10]=" ";
- int i;
-
- if (Appl < 1 || Appl > NumberofAppls ) return FALSE;
-
- i=strlen(NewCall);
-
- if (i > 10) i=10;
-
- strncpy(Call,NewCall,i);
-
- strncpy((char *)&APPLCALLTABLE[Appl-1].APPLALIAS_TEXT,Call,10);
-
- if (!ConvToAX25(Call,APPLCALLTABLE[Appl-1].APPLALIAS)) return FALSE;
-
- UpdateNodesForApp(Appl);
-
- return TRUE;
-
-}
-
-
-
-DllExport BOOL APIENTRY SetApplQual(int Appl, int NewQual)
-{
- if (Appl < 1 || Appl > NumberofAppls ) return FALSE;
-
- APPLCALLTABLE[Appl-1].APPLQUAL=NewQual;
-
- UpdateNodesForApp(Appl);
-
- return TRUE;
-
-}
-
-
-BOOL UpdateNodesForApp(int Appl)
-{
- int App=Appl-1;
- int DestLen = sizeof (struct DEST_LIST);
- int n = MAXDESTS;
-
- struct DEST_LIST * DEST = APPLCALLTABLE[App].NODEPOINTER;
- APPLCALLS * APPL=&APPLCALLTABLE[App];
-
- if (DEST == NULL)
- {
- // No dest at the moment. If we have valid call and Qual, create an entry
-
- if (APPLCALLTABLE[App].APPLQUAL == 0) return FALSE;
-
- if (APPLCALLTABLE[App].APPLCALL[0] < 41) return FALSE;
-
-
- GetSemaphore(&Semaphore, 5);
-
- DEST = DESTS;
-
- while (n--)
- {
- if (DEST->DEST_CALL[0] == 0) // Spare
- break;
- }
-
- if (n == 0)
- {
- // no dests
-
- FreeSemaphore(&Semaphore);
- return FALSE;
- }
-
- NUMBEROFNODES++;
- APPL->NODEPOINTER = DEST;
-
- memmove (DEST->DEST_CALL,APPL->APPLCALL,13);
-
- DEST->DEST_STATE=0x80; // SPECIAL ENTRY
-
- DEST->NRROUTE[0].ROUT_QUALITY = (BYTE)APPL->APPLQUAL;
- DEST->NRROUTE[0].ROUT_OBSCOUNT = 255;
-
- FreeSemaphore(&Semaphore);
-
- return TRUE;
- }
-
- // We have a destination. If Quality is zero, remove it, else update it
-
- if (APPLCALLTABLE[App].APPLQUAL == 0)
- {
- GetSemaphore(&Semaphore, 6);
-
- REMOVENODE(DEST); // Clear buffers, Remove from Sorted Nodes chain, and zap entry
-
- APPL->NODEPOINTER=NULL;
-
- FreeSemaphore(&Semaphore);
- return FALSE;
-
- }
-
- if (APPLCALLTABLE[App].APPLCALL[0] < 41) return FALSE;
-
- GetSemaphore(&Semaphore, 7);
-
- memmove (DEST->DEST_CALL,APPL->APPLCALL,13);
-
- DEST->DEST_STATE=0x80; // SPECIAL ENTRY
-
- DEST->NRROUTE[0].ROUT_QUALITY = (BYTE)APPL->APPLQUAL;
- DEST->NRROUTE[0].ROUT_OBSCOUNT = 255;
-
- FreeSemaphore(&Semaphore);
- return TRUE;
-
-}
-
-
-DllExport UCHAR * APIENTRY GetSignOnMsg()
-{
- return (&SIGNONMSG[0]);
-}
-
-
-DllExport HKEY APIENTRY GetRegistryKey()
-{
- return REGTREE;
-}
-
-DllExport char * APIENTRY GetRegistryKeyText()
-{
- return REGTREETEXT;;
-}
-
-DllExport UCHAR * APIENTRY GetBPQDirectory()
-{
- while (BPQDirectory[0] == 0)
- {
- Debugprintf("BPQ Directory not set up - waiting");
- Sleep(1000);
- }
- return (&BPQDirectory[0]);
-}
-
-DllExport UCHAR * APIENTRY GetProgramDirectory()
-{
- return (&BPQProgramDirectory[0]);
-}
-
-DllExport UCHAR * APIENTRY GetLogDirectory()
-{
- return (&LogDirectory[0]);
-}
-
-// Version for Visual Basic
-
-DllExport char * APIENTRY CopyBPQDirectory(char * dir)
-{
- return (strcpy(dir,BPQDirectory));
-}
-
-DllExport int APIENTRY GetMsgPerl(int stream, char * msg)
-{
- int len,count;
-
- GetMsg(stream, msg, &len, &count );
-
- return len;
-}
-
-int Rig_Command(int Session, char * Command);
-
-BOOL Rig_CommandInt(int Session, char * Command)
-{
- return Rig_Command(Session, Command);
-}
-
-DllExport int APIENTRY BPQSetHandle(int Stream, HWND hWnd)
-{
- BPQHOSTVECTOR[Stream-1].HOSTHANDLE=hWnd;
- return (0);
-}
-
-#define L4USER 0
-
-BPQVECSTRUC * PORTVEC ;
-
-VOID * InitializeExtDriver(PEXTPORTDATA PORTVEC)
-{
- HINSTANCE ExtDriver=0;
- char msg[128];
- int err=0;
- HKEY hKey=0;
- UCHAR Value[MAX_PATH];
-
- // If no directory, use current
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(Value,PORTVEC->PORT_DLL_NAME);
- }
- else
- {
- strcpy(Value,BPQDirectory);
- strcat(Value,"\\");
- strcat(Value,PORTVEC->PORT_DLL_NAME);
- }
-
- // Several Drivers are now built into bpq32.dll
-
- _strupr(Value);
-
- if (strstr(Value, "BPQVKISS"))
- return VCOMExtInit;
-
- if (strstr(Value, "BPQAXIP"))
- return AXIPExtInit;
-
- if (strstr(Value, "BPQETHER"))
- return ETHERExtInit;
-
- if (strstr(Value, "BPQTOAGW"))
- return AGWExtInit;
-
- if (strstr(Value, "AEAPACTOR"))
- return AEAExtInit;
-
- if (strstr(Value, "HALDRIVER"))
- return HALExtInit;
-
- if (strstr(Value, "KAMPACTOR"))
- return KAMExtInit;
-
- if (strstr(Value, "SCSPACTOR"))
- return SCSExtInit;
-
- if (strstr(Value, "WINMOR"))
- return WinmorExtInit;
-
- if (strstr(Value, "V4"))
- return V4ExtInit;
-
- if (strstr(Value, "TELNET"))
- return TelnetExtInit;
-
-// if (strstr(Value, "SOUNDMODEM"))
-// return SoundModemExtInit;
-
- if (strstr(Value, "SCSTRACKER"))
- return TrackerExtInit;
-
- if (strstr(Value, "TRKMULTI"))
- return TrackerMExtInit;
-
- if (strstr(Value, "UZ7HO"))
- return UZ7HOExtInit;
-
- if (strstr(Value, "MULTIPSK"))
- return MPSKExtInit;
-
- if (strstr(Value, "FLDIGI"))
- return FLDigiExtInit;
-
- if (strstr(Value, "UIARQ"))
- return UIARQExtInit;
-
-// if (strstr(Value, "BAYCOM"))
-// return (UINT) BaycomExtInit;
-
- if (strstr(Value, "VARA"))
- return VARAExtInit;
-
- if (strstr(Value, "ARDOP"))
- return ARDOPExtInit;
-
- if (strstr(Value, "SERIAL"))
- return SerialExtInit;
-
- if (strstr(Value, "KISSHF"))
- return KISSHFExtInit;
-
- if (strstr(Value, "WINRPR"))
- return WinRPRExtInit;
-
- if (strstr(Value, "HSMODEM"))
- return HSMODEMExtInit;
-
- if (strstr(Value, "FREEDATA"))
- return FreeDataExtInit;
-
- if (strstr(Value, "6PACK"))
- return SIXPACKExtInit;
-
- ExtDriver = LoadLibrary(Value);
-
- if (ExtDriver == NULL)
- {
- err=GetLastError();
-
- sprintf(msg,"Error loading Driver %s - Error code %d",
- PORTVEC->PORT_DLL_NAME,err);
-
- MessageBox(NULL,msg,"BPQ32",MB_ICONSTOP);
-
- return(0);
- }
-
- PORTVEC->DLLhandle=ExtDriver;
-
- return (GetProcAddress(ExtDriver,"_ExtInit@4"));
-
-}
-
-/*
-_DATABASE LABEL BYTE
-
-FILLER DB 14 DUP (0) ; PROTECTION AGENST BUFFER PROBLEMS!
- DB MAJORVERSION,MINORVERSION
-_NEIGHBOURS DD 0
- DW TYPE ROUTE
-_MAXNEIGHBOURS DW 20 ; MAX ADJACENT NODES
-
-_DESTS DD 0 ; NODE LIST
- DW TYPE DEST_LIST
-MAXDESTS DW 100 ; MAX NODES IN SYSTEM
-*/
-
-
-DllExport int APIENTRY GetAttachedProcesses()
-{
- return (AttachedProcesses);
-}
-
-DllExport int * APIENTRY GetAttachedProcessList()
-{
- return (&AttachedPIDList[0]);
-}
-
-DllExport int * APIENTRY SaveNodesSupport()
-{
- return (&DATABASESTART);
-}
-
-//
-// Internal BPQNODES support
-//
-
-#define UCHAR unsigned char
-
-/*
-ROUTE ADD G1HTL-1 2 200 0 0 0
-ROUTE ADD G4IRX-3 2 200 0 0 0
-NODE ADD MAPPLY:G1HTL-1 G1HTL-1 2 200 G4IRX-3 2 98
-NODE ADD NOT:GB7NOT G1HTL-1 2 199 G4IRX-3 2 98
-
-*/
-
-struct DEST_LIST * Dests;
-struct ROUTE * Routes;
-
-int MaxNodes;
-int MaxRoutes;
-int NodeLen;
-int RouteLen;
-
-int count;
-int cursor;
-
-int len,i;
-
-ULONG cnt;
-char Normcall[10];
-char Portcall[10];
-char Alias[7];
-
-char line[100];
-
-HANDLE handle;
-
-int APIENTRY Restart()
-{
- int i, Count = AttachedProcesses;
- HANDLE hProc;
- DWORD PID;
-
- for (i = 0; i < Count; i++)
- {
- PID = AttachedPIDList[i];
-
- // Kill Timer Owner last
-
- if (TimerInst != PID)
- {
- hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
-
- if (hProc)
- {
- TerminateProcess(hProc, 0);
- CloseHandle(hProc);
- }
- }
- }
-
- hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, TimerInst);
-
- if (hProc)
- {
- TerminateProcess(hProc, 0);
- CloseHandle(hProc);
- }
-
-
- return 0;
-}
-
-int APIENTRY Reboot()
-{
- // Run shutdown -r -f
-
- STARTUPINFO SInfo;
- PROCESS_INFORMATION PInfo;
- char Cmd[] = "shutdown -r -f";
-
- SInfo.cb=sizeof(SInfo);
- SInfo.lpReserved=NULL;
- SInfo.lpDesktop=NULL;
- SInfo.lpTitle=NULL;
- SInfo.dwFlags=0;
- SInfo.cbReserved2=0;
- SInfo.lpReserved2=NULL;
-
- return CreateProcess(NULL, Cmd, NULL, NULL, FALSE,0 ,NULL ,NULL, &SInfo, &PInfo);
-}
-/*
-int APIENTRY Reconfig()
-{
- if (!ProcessConfig())
- {
- return (0);
- }
- SaveNodes();
- WritetoConsole("Nodes Saved\n");
- ReconfigFlag=TRUE;
- WritetoConsole("Reconfig requested ... Waiting for Timer Poll\n");
- return 1;
-}
-*/
-// Code to support minimizing all BPQ Apps to a single Tray ICON
-
-// As we can't minimize the console window to the tray, I'll use an ordinary
-// window instead. This also gives me somewhere to post the messages to
-
-
-char AppName[] = "BPQ32";
-char Title[80] = "BPQ32.dll Console";
-
-int NewLine();
-
-char FrameClassName[] = TEXT("MdiFrame");
-
-HWND ClientWnd; //This stores the MDI client area window handle
-
-LOGFONT LFTTYFONT ;
-
-HFONT hFont ;
-
-HMENU hPopMenu, hWndMenu;
-HMENU hMainFrameMenu = NULL;
-HMENU hBaseMenu = NULL;
-HMENU hConsMenu = NULL;
-HMENU hTermMenu = NULL;
-HMENU hMonMenu = NULL;
-HMENU hTermActMenu, hTermCfgMenu, hTermEdtMenu, hTermHlpMenu;
-HMENU hMonActMenu, hMonCfgMenu, hMonEdtMenu, hMonHlpMenu;
-
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-
-DllExport int APIENTRY DeleteTrayMenuItem(HWND hWnd);
-
-#define BPQMonitorAvail 1
-#define BPQDataAvail 2
-#define BPQStateChange 4
-
-VOID GetJSONValue(char * _REPLYBUFFER, char * Name, char * Value);
-SOCKET OpenWL2KHTTPSock();
-SendHTTPRequest(SOCKET sock, char * Request, char * Params, int Len, char * Return);
-
-BOOL GetWL2KSYSOPInfo(char * Call, char * _REPLYBUFFER);
-BOOL UpdateWL2KSYSOPInfo(char * Call, char * SQL);
-
-
-static INT_PTR CALLBACK ConfigWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch (message)
- {
- case WM_INITDIALOG:
- {
- char _REPLYBUFFER[1000] = "";
- char Value[1000];
-
- if (GetWL2KSYSOPInfo(WL2KCall, _REPLYBUFFER))
- {
-// if (strstr(_REPLYBUFFER, "\"ErrorMessage\":") == 0)
-
- GetJSONValue(_REPLYBUFFER, "\"SysopName\":", Value);
- SetDlgItemText(hDlg, NAME, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"GridSquare\":", Value);
- SetDlgItemText(hDlg, IDC_Locator, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"StreetAddress1\":", Value);
- SetDlgItemText(hDlg, ADDR1, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"StreetAddress2\":", Value);
- SetDlgItemText(hDlg, ADDR2, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"City\":", Value);
- SetDlgItemText(hDlg, CITY, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"State\":", Value);
- SetDlgItemText(hDlg, STATE, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"Country\":", Value);
- SetDlgItemText(hDlg, COUNTRY, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"PostalCode\":", Value);
- SetDlgItemText(hDlg, POSTCODE, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"Email\":", Value);
- SetDlgItemText(hDlg, EMAIL, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"Website\":", Value);
- SetDlgItemText(hDlg, WEBSITE, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"Phones\":", Value);
- SetDlgItemText(hDlg, PHONE, Value);
-
- GetJSONValue(_REPLYBUFFER, "\"Comments\":", Value);
- SetDlgItemText(hDlg, ADDITIONALDATA, Value);
-
- }
-
- return (INT_PTR)TRUE;
- }
- case WM_COMMAND:
-
- switch(LOWORD(wParam))
- {
-
- case ID_SAVE:
- {
- char Name[100];
- char PasswordText[100];
- char LocatorText[100];
- char Addr1[100];
- char Addr2[100];
- char City[100];
- char State[100];
- char Country[100];
- char PostCode[100];
- char Email[100];
- char Website[100];
- char Phone[100];
- char Data[100];
-
- SOCKET sock;
-
- int Len;
- char Message[2048];
- char Reply[2048] = "";
-
-
- GetDlgItemText(hDlg, NAME, Name, 99);
- GetDlgItemText(hDlg, IDC_Password, PasswordText, 99);
- GetDlgItemText(hDlg, IDC_Locator, LocatorText, 99);
- GetDlgItemText(hDlg, ADDR1, Addr1, 99);
- GetDlgItemText(hDlg, ADDR2, Addr2, 99);
- GetDlgItemText(hDlg, CITY, City, 99);
- GetDlgItemText(hDlg, STATE, State, 99);
- GetDlgItemText(hDlg, COUNTRY, Country, 99);
- GetDlgItemText(hDlg, POSTCODE, PostCode, 99);
- GetDlgItemText(hDlg, EMAIL, Email, 99);
- GetDlgItemText(hDlg, WEBSITE, Website, 99);
- GetDlgItemText(hDlg, PHONE, Phone, 99);
- GetDlgItemText(hDlg, ADDITIONALDATA, Data, 99);
-
-
-//{"Callsign":"String","GridSquare":"String","SysopName":"String",
-//"StreetAddress1":"String","StreetAddress2":"String","City":"String",
-//"State":"String","Country":"String","PostalCode":"String","Email":"String",
-//"Phones":"String","Website":"String","Comments":"String"}
-
- Len = sprintf(Message,
- "\"Callsign\":\"%s\","
- "\"Password\":\"%s\","
- "\"GridSquare\":\"%s\","
- "\"SysopName\":\"%s\","
- "\"StreetAddress1\":\"%s\","
- "\"StreetAddress2\":\"%s\","
- "\"City\":\"%s\","
- "\"State\":\"%s\","
- "\"Country\":\"%s\","
- "\"PostalCode\":\"%s\","
- "\"Email\":\"%s\","
- "\"Phones\":\"%s\","
- "\"Website\":\"%s\","
- "\"Comments\":\"%s\"",
-
- WL2KCall, PasswordText, LocatorText, Name, Addr1, Addr2, City, State, Country, PostCode, Email, Phone, Website, Data);
-
- Debugprintf("Sending %s", Message);
-
- sock = OpenWL2KHTTPSock();
-
- if (sock)
- {
- char * ptr;
-
- SendHTTPRequest(sock,
- "/sysop/add", Message, Len, Reply);
-
- ptr = strstr(Reply, "\"ErrorCode\":");
-
- if (ptr)
- {
- ptr = strstr(ptr, "Message");
- if (ptr)
- {
- ptr += 10;
- strlop(ptr, '"');
- MessageBox(NULL ,ptr, "Error", MB_OK);
- }
- }
- else
- MessageBox(NULL, "Sysop Record Updated", "BPQ32", MB_OK);
-
- }
- closesocket(sock);
- }
-
- case ID_CANCEL:
- {
- EndDialog(hDlg, LOWORD(wParam));
- return (INT_PTR)TRUE;
- }
- break;
- }
- }
- return (INT_PTR)FALSE;
-}
-
-
-
-LRESULT CALLBACK UIWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
-VOID WINAPI OnTabbedDialogInit(HWND hDlg);
-
-LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- int wmId, wmEvent;
- POINT pos;
- BOOL ret;
-
- CLIENTCREATESTRUCT MDIClientCreateStruct; // Structure to be used for MDI client area
- //HWND m_hwndSystemInformation = 0;
-
- if (message == BPQMsg)
- {
- if (lParam & BPQDataAvail)
- DoReceivedData(wParam);
-
- if (lParam & BPQMonitorAvail)
- DoMonData(wParam);
-
- if (lParam & BPQStateChange)
- DoStateChange(wParam);
-
- return (0);
- }
-
- switch (message)
- {
- case MY_TRAY_ICON_MESSAGE:
-
- switch(lParam)
- {
- case WM_RBUTTONUP:
- case WM_LBUTTONUP:
-
- GetCursorPos(&pos);
-
- // SetForegroundWindow(FrameWnd);
-
- TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, FrameWnd, 0);
- return 0;
- }
-
- break;
-
- case WM_CTLCOLORDLG:
- return (LONG)bgBrush;
-
- case WM_SIZING:
- case WM_SIZE:
-
- SendMessage(ClientWnd, WM_MDIICONARRANGE, 0 ,0);
- break;
-
- case WM_NCCREATE:
-
- ret = DefFrameProc(hWnd, ClientWnd, message, wParam, lParam);
- return TRUE;
-
- case WM_CREATE:
-
- // On creation of main frame, create the MDI client area
-
- MDIClientCreateStruct.hWindowMenu = NULL;
- MDIClientCreateStruct.idFirstChild = IDM_FIRSTCHILD;
-
- ClientWnd = CreateWindow(TEXT("MDICLIENT"), // predefined value for MDI client area
- NULL, // no caption required
- WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
- 0, // No need to give any x/y or height/width since this client
- // will just be used to get client windows created, effectively
- // in the main window we will be seeing the mainframe window client area itself.
- 0,
- 0,
- 0,
- hWnd,
- NULL,
- hInstance,
- (void *) &MDIClientCreateStruct);
-
-
- return 0;
-
- case WM_COMMAND:
-
- wmId = LOWORD(wParam); // Remember, these are...
- wmEvent = HIWORD(wParam); // ...different for Win32!
-
- if (wmId >= TRAYBASEID && wmId < (TRAYBASEID + 100))
- {
- handle=hWndArray[wmId-TRAYBASEID];
-
- if (handle == FrameWnd)
- ShowWindow(handle, SW_NORMAL);
-
- if (handle == FrameWnd && FrameMaximized == TRUE)
- PostMessage(handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
- else
- PostMessage(handle, WM_SYSCOMMAND, SC_RESTORE, 0);
-
- SetForegroundWindow(handle);
- return 0;
- }
-
- switch(wmId)
- {
- struct ConsoleInfo * Cinfo = NULL;
-
- case ID_NEWWINDOW:
- Cinfo = CreateChildWindow(0, FALSE);
- if (Cinfo)
- SendMessage(ClientWnd, WM_MDIACTIVATE, (WPARAM)Cinfo->hConsole, 0);
- break;
-
- case ID_WINDOWS_CASCADE:
- SendMessage(ClientWnd, WM_MDICASCADE, 0, 0);
- return 0;
-
- case ID_WINDOWS_TILE:
- SendMessage(ClientWnd, WM_MDITILE , MDITILE_HORIZONTAL, 0);
- return 0;
-
- case BPQCLOSEALL:
- CloseAllPrograms();
- // SendMessage(ClientWnd, WM_MDIICONARRANGE, 0 ,0);
-
- return 0;
-
- case BPQUICONFIG:
- {
- int err, i=0;
- char Title[80];
- WNDCLASS wc;
-
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = UIWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = DLGWINDOWEXTRA;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON) );
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = bgBrush;
-
- wc.lpszMenuName = NULL;
- wc.lpszClassName = UIClassName;
-
- RegisterClass(&wc);
-
- UIhWnd = CreateDialog(hInstance, UIClassName, 0, NULL);
-
- if (!UIhWnd)
- {
- err=GetLastError();
- return FALSE;
- }
-
- wsprintf(Title,"BPQ32 Beacon Configuration");
- MySetWindowText(UIhWnd, Title);
- ShowWindow(UIhWnd, SW_NORMAL);
-
- OnTabbedDialogInit(UIhWnd); // Set up pages
-
- // UpdateWindow(UIhWnd);
- return 0;
- }
-
-
- case IDD_WL2KSYSOP:
-
- if (WL2KCall[0] == 0)
- {
- MessageBox(NULL,"WL2K Reporting is not configured","BPQ32", MB_OK);
- break;
- }
-
- DialogBox(hInstance, MAKEINTRESOURCE(IDD_WL2KSYSOP), hWnd, ConfigWndProc);
- break;
-
-
- // Handle MDI Window commands
-
- default:
- {
- if(wmId >= IDM_FIRSTCHILD)
- {
- DefFrameProc(hWnd, ClientWnd, message, wParam, lParam);
- }
- else
- {
- HWND hChild = (HWND)SendMessage(ClientWnd, WM_MDIGETACTIVE,0,0);
-
- if(hChild)
- SendMessage(hChild, WM_COMMAND, wParam, lParam);
- }
- }
- }
-
- break;
-
- case WM_INITMENUPOPUP:
- {
- HWND hChild = (HWND)SendMessage(ClientWnd, WM_MDIGETACTIVE,0,0);
-
- if(hChild)
- SendMessage(hChild, WM_INITMENUPOPUP, wParam, lParam);
- }
-
- case WM_SYSCOMMAND:
-
- wmId = LOWORD(wParam); // Remember, these are...
- wmEvent = HIWORD(wParam); // ...different for Win32!
-
- switch (wmId)
- {
- case SC_MAXIMIZE:
-
- FrameMaximized = TRUE;
- break;
-
- case SC_RESTORE:
-
- FrameMaximized = FALSE;
- break;
-
- case SC_MINIMIZE:
-
- if (MinimizetoTray)
- {
- ShowWindow(hWnd, SW_HIDE);
- return TRUE;
- }
- }
-
- return (DefFrameProc(hWnd, ClientWnd, message, wParam, lParam));
-
- case WM_CLOSE:
-
- PostQuitMessage(0);
-
- if (MinimizetoTray)
- DeleteTrayMenuItem(hWnd);
-
- break;
-
- default:
- return (DefFrameProc(hWnd, ClientWnd, message, wParam, lParam));
-
- }
- return (DefFrameProc(hWnd, ClientWnd, message, wParam, lParam));
-}
-
-int OffsetH, OffsetW;
-
-int SetupConsoleWindow()
-{
- WNDCLASS wc;
- int i;
- int retCode, Type, Vallen;
- HKEY hKey=0;
- char Size[80];
- WNDCLASSEX wndclassMainFrame;
- RECT CRect;
-
- retCode = RegOpenKeyEx (REGTREE,
- "SOFTWARE\\G8BPQ\\BPQ32",
- 0,
- KEY_QUERY_VALUE,
- &hKey);
-
- if (retCode == ERROR_SUCCESS)
- {
- Vallen=80;
-
- retCode = RegQueryValueEx(hKey,"FrameWindowSize",0,
- (ULONG *)&Type,(UCHAR *)&Size,(ULONG *)&Vallen);
-
- if (retCode == ERROR_SUCCESS)
- sscanf(Size,"%d,%d,%d,%d",&FRect.left,&FRect.right,&FRect.top,&FRect.bottom);
-
- if (FRect.top < - 500 || FRect.left < - 500)
- {
- FRect.left = 0;
- FRect.top = 0;
- FRect.right = 600;
- FRect.bottom = 400;
- }
-
-
- Vallen=80;
- retCode = RegQueryValueEx(hKey,"WindowSize",0,
- (ULONG *)&Type,(UCHAR *)&Size,(ULONG *)&Vallen);
-
- if (retCode == ERROR_SUCCESS)
- sscanf(Size,"%d,%d,%d,%d,%d",&Rect.left,&Rect.right,&Rect.top,&Rect.bottom, &ConsoleMinimized);
-
- if (Rect.top < - 500 || Rect.left < - 500)
- {
- Rect.left = 0;
- Rect.top = 0;
- Rect.right = 600;
- Rect.bottom = 400;
- }
-
- Vallen=80;
-
- retCode = RegQueryValueEx(hKey,"StatusWindowSize",0,
- (ULONG *)&Type,(UCHAR *)&Size,(ULONG *)&Vallen);
-
- if (retCode == ERROR_SUCCESS)
- sscanf(Size, "%d,%d,%d,%d,%d", &StatusRect.left, &StatusRect.right,
- &StatusRect.top, &StatusRect.bottom, &StatusMinimized);
-
- if (StatusRect.top < - 500 || StatusRect.left < - 500)
- {
- StatusRect.left = 0;
- StatusRect.top = 0;
- StatusRect.right = 850;
- StatusRect.bottom = 500;
- }
-
-
- // Get StartMinimized and MinimizetoTray flags
-
- Vallen = 4;
- retCode = RegQueryValueEx(hKey, "Start Minimized", 0, &Type, (UCHAR *)&StartMinimized, &Vallen);
-
- Vallen = 4;
- retCode = RegQueryValueEx(hKey, "Minimize to Tray", 0, &Type, (UCHAR *)&MinimizetoTray, &Vallen);
- }
-
- wndclassMainFrame.cbSize = sizeof(WNDCLASSEX);
- wndclassMainFrame.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE;
- wndclassMainFrame.lpfnWndProc = FrameWndProc;
- wndclassMainFrame.cbClsExtra = 0;
- wndclassMainFrame.cbWndExtra = 0;
- wndclassMainFrame.hInstance = hInstance;
- wndclassMainFrame.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON));
- wndclassMainFrame.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclassMainFrame.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);
- wndclassMainFrame.lpszMenuName = NULL;
- wndclassMainFrame.lpszClassName = FrameClassName;
- wndclassMainFrame.hIconSm = NULL;
-
- if(!RegisterClassEx(&wndclassMainFrame))
- {
- return 0;
- }
-
- pindex = 0;
- PartLine = FALSE;
-
- bgBrush = CreateSolidBrush(BGCOLOUR);
-
-// hMainFrameMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME_MENU));
-
- hBaseMenu = LoadMenu(hInstance, MAKEINTRESOURCE(CONS_MENU));
- hConsMenu = GetSubMenu(hBaseMenu, 1);
- hWndMenu = GetSubMenu(hBaseMenu, 0);
-
- hTermMenu = LoadMenu(hInstance, MAKEINTRESOURCE(TERM_MENU));
- hTermActMenu = GetSubMenu(hTermMenu, 1);
- hTermCfgMenu = GetSubMenu(hTermMenu, 2);
- hTermEdtMenu = GetSubMenu(hTermMenu, 3);
- hTermHlpMenu = GetSubMenu(hTermMenu, 4);
-
- hMonMenu = LoadMenu(hInstance, MAKEINTRESOURCE(MON_MENU));
- hMonCfgMenu = GetSubMenu(hMonMenu, 1);
- hMonEdtMenu = GetSubMenu(hMonMenu, 2);
- hMonHlpMenu = GetSubMenu(hMonMenu, 3);
-
- hMainFrameMenu = CreateMenu();
- AppendMenu(hMainFrameMenu, MF_STRING + MF_POPUP, (UINT)hWndMenu, "Window");
-
- //Create the main MDI frame window
-
- ClientWnd = NULL;
-
- FrameWnd = CreateWindow(FrameClassName,
- "BPQ32 Console",
- WS_OVERLAPPEDWINDOW |WS_CLIPCHILDREN,
- FRect.left,
- FRect.top,
- FRect.right - FRect.left,
- FRect.bottom - FRect.top,
- NULL, // handle to parent window
- hMainFrameMenu, // handle to menu
- hInstance, // handle to the instance of module
- NULL); // Long pointer to a value to be passed to the window through the
- // CREATESTRUCT structure passed in the lParam parameter the WM_CREATE message
-
-
- // Get Client Params
-
- if (FrameWnd == 0)
- {
- Debugprintf("SetupConsoleWindow Create Frame failed %d", GetLastError());
- return 0;
- }
-
- ShowWindow(FrameWnd, SW_RESTORE);
-
-
- GetWindowRect(FrameWnd, &FRect);
- OffsetH = FRect.bottom - FRect.top;
- OffsetW = FRect.right - FRect.left;
- GetClientRect(FrameWnd, &CRect);
- OffsetH -= CRect.bottom;
- OffsetW -= CRect.right;
- OffsetH -= 4;
-
- // Create Console Window
-
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE;
- wc.lpfnWndProc = (WNDPROC)WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = DLGWINDOWEXTRA;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(BPQICON));
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.lpszMenuName = 0;
- wc.lpszClassName = ClassName;
-
- i=RegisterClass(&wc);
-
- sprintf (Title, "BPQ32.dll Console Version %s", VersionString);
-
- hConsWnd = CreateMDIWindow(ClassName, "Console", 0,
- 0,0,0,0, ClientWnd, hInstance, 1234);
-
- i = GetLastError();
-
- if (!hConsWnd) {
- return (FALSE);
- }
-
- wc.style = CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE;
- wc.lpfnWndProc = (WNDPROC)StatusWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = DLGWINDOWEXTRA;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(BPQICON));
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.lpszMenuName = 0;
- wc.lpszClassName = "Status";
-
- i=RegisterClass(&wc);
-
- if (StatusRect.top < OffsetH) // Make sure not off top of MDI frame
- {
- int Error = OffsetH - StatusRect.top;
- StatusRect.top += Error;
- StatusRect.bottom += Error;
- }
-
- StatusWnd = CreateMDIWindow("Status", "Stream Status", 0,
- StatusRect.left, StatusRect.top, StatusRect.right - StatusRect.left,
- StatusRect.bottom - StatusRect.top, ClientWnd, hInstance, 1234);
-
- SetTimer(StatusWnd, 1, 1000, NULL);
-
- hPopMenu = GetSubMenu(hBaseMenu, 1) ;
-
- if (MinimizetoTray)
- CheckMenuItem(hPopMenu, BPQMINTOTRAY, MF_CHECKED);
- else
- CheckMenuItem(hPopMenu, BPQMINTOTRAY, MF_UNCHECKED);
-
- if (StartMinimized)
- CheckMenuItem(hPopMenu, BPQSTARTMIN, MF_CHECKED);
- else
- CheckMenuItem(hPopMenu, BPQSTARTMIN, MF_UNCHECKED);
-
- DrawMenuBar(hConsWnd);
-
- // 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 = 0;
- LFTTYFONT.lfOutPrecision = OUT_DEFAULT_PRECIS ;
- LFTTYFONT.lfClipPrecision = CLIP_DEFAULT_PRECIS ;
- LFTTYFONT.lfQuality = DEFAULT_QUALITY ;
- LFTTYFONT.lfPitchAndFamily = FIXED_PITCH;
- lstrcpy(LFTTYFONT.lfFaceName, "FIXEDSYS" ) ;
-
- hFont = CreateFontIndirect(&LFTTYFONT) ;
-
- SetWindowText(hConsWnd,Title);
-
- if (Rect.right < 100 || Rect.bottom < 100)
- {
- GetWindowRect(hConsWnd, &Rect);
- }
-
- if (Rect.top < OffsetH) // Make sure not off top of MDI frame
- {
- int Error = OffsetH - Rect.top;
- Rect.top += Error;
- Rect.bottom += Error;
- }
-
-
- MoveWindow(hConsWnd, Rect.left - (OffsetW /2), Rect.top - OffsetH, Rect.right-Rect.left, Rect.bottom-Rect.top, TRUE);
-
- MoveWindow(StatusWnd, StatusRect.left - (OffsetW /2), StatusRect.top - OffsetH,
- StatusRect.right-StatusRect.left, StatusRect.bottom-StatusRect.top, TRUE);
-
- hWndCons = CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", "",
- WS_CHILD | WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
- LBS_DISABLENOSCROLL | LBS_NOSEL | WS_VSCROLL | WS_HSCROLL,
- Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top,
- hConsWnd, NULL, hInstance, NULL);
-
-// SendMessage(hWndCons, WM_SETFONT, hFont, 0);
-
- SendMessage(hWndCons, LB_SETHORIZONTALEXTENT , 1000, 0);
-
- if (ConsoleMinimized)
- ShowWindow(hConsWnd, SW_SHOWMINIMIZED);
- else
- ShowWindow(hConsWnd, SW_RESTORE);
-
- if (StatusMinimized)
- ShowWindow(StatusWnd, SW_SHOWMINIMIZED);
- else
- ShowWindow(StatusWnd, SW_RESTORE);
-
- ShowWindow(FrameWnd, SW_RESTORE);
-
-
- LoadLibrary("riched20.dll");
-
- if (StartMinimized)
- if (MinimizetoTray)
- ShowWindow(FrameWnd, SW_HIDE);
- else
- ShowWindow(FrameWnd, SW_SHOWMINIMIZED);
- else
- ShowWindow(FrameWnd, SW_RESTORE);
-
- CreateMonitorWindow(Size);
-
- return 0;
-}
-
-DllExport int APIENTRY SetupTrayIcon()
-{
- if (MinimizetoTray == 0)
- return 0;
-
- trayMenu = CreatePopupMenu();
-
- for( i = 0; i < 100; ++i )
- {
- if (strcmp(PopupText[i],"BPQ32 Console") == 0)
- {
- hWndArray[i] = FrameWnd;
- goto doneit;
- }
- }
-
- for( i = 0; i < 100; ++i )
- {
- if (hWndArray[i] == 0)
- {
- hWndArray[i] = FrameWnd;
- strcpy(PopupText[i],"BPQ32 Console");
- break;
- }
- }
-doneit:
-
- for( i = 0; i < 100; ++i )
- {
- if (hWndArray[i] != 0)
- AppendMenu(trayMenu,MF_STRING,TRAYBASEID+i,PopupText[i]);
- }
-
- // Set up Tray ICON
-
- ZeroMemory(&niData,sizeof(NOTIFYICONDATA));
-
- niData.cbSize = sizeof(NOTIFYICONDATA);
-
- // the ID number can be any UINT you choose and will
- // be used to identify your icon in later calls to
- // Shell_NotifyIcon
-
- niData.uID = TRAY_ICON_ID;
-
- // state which structure members are valid
- // here you can also choose the style of tooltip
- // window if any - specifying a balloon window:
- // NIF_INFO is a little more complicated
-
- strcpy(niData.szTip,"BPQ32 Windows");
-
- niData.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
-
- // load the icon note: you should destroy the icon
- // after the call to Shell_NotifyIcon
-
- niData.hIcon =
-
- //LoadIcon(NULL, IDI_APPLICATION);
-
- (HICON)LoadImage( hInstance,
- MAKEINTRESOURCE(BPQICON),
- IMAGE_ICON,
- GetSystemMetrics(SM_CXSMICON),
- GetSystemMetrics(SM_CYSMICON),
- LR_DEFAULTCOLOR);
-
-
- // set the window you want to receive event messages
-
- niData.hWnd = FrameWnd;
-
- // set the message to send
- // note: the message value should be in the
- // range of WM_APP through 0xBFFF
-
- niData.uCallbackMessage = MY_TRAY_ICON_MESSAGE;
-
- // Call Shell_NotifyIcon. NIM_ADD adds a new tray icon
-
- if (Shell_NotifyIcon(NIM_ADD,&niData))
- Debugprintf("BPQ32 Create Tray Icon Ok");
-// else
-// Debugprintf("BPQ32 Create Tray Icon failed %d", GetLastError());
-
- return 0;
-}
-
-VOID SaveConfig()
-{
- HKEY hKey=0;
- int retCode, disp;
-
- retCode = RegCreateKeyEx(REGTREE,
- "SOFTWARE\\G8BPQ\\BPQ32",
- 0, // Reserved
- 0, // Class
- 0, // Options
- KEY_ALL_ACCESS,
- NULL, // Security Attrs
- &hKey,
- &disp);
-
- if (retCode == ERROR_SUCCESS)
- {
- retCode = RegSetValueEx(hKey, "Start Minimized", 0, REG_DWORD, (UCHAR *)&StartMinimized, 4);
- retCode = RegSetValueEx(hKey, "Minimize to Tray", 0, REG_DWORD, (UCHAR *)&MinimizetoTray, 4);
- }
-}
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- int wmId, wmEvent;
- POINT pos;
- HWND handle;
- RECT cRect;
-
- switch (message)
- {
- case WM_MDIACTIVATE:
-
- // Set the system info menu when getting activated
-
- if (lParam == (LPARAM) hWnd)
- {
- // Activate
-
- // GetSubMenu function should retrieve a handle to the drop-down menu or submenu.
-
- RemoveMenu(hBaseMenu, 1, MF_BYPOSITION);
- AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hConsMenu, "Actions");
- SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hBaseMenu, (LPARAM) hWndMenu);
- }
- else
- {
- // Deactivate
-
- SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hMainFrameMenu, (LPARAM) NULL);
- }
-
- DrawMenuBar(FrameWnd);
-
- return TRUE; //DefMDIChildProc(hWnd, message, wParam, lParam);
-
- case MY_TRAY_ICON_MESSAGE:
-
- switch(lParam)
- {
- case WM_RBUTTONUP:
- case WM_LBUTTONUP:
-
- GetCursorPos(&pos);
-
- SetForegroundWindow(hWnd);
-
- TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, hWnd, 0);
- return 0;
- }
-
- break;
-
- case WM_CTLCOLORDLG:
- return (LONG)bgBrush;
-
- case WM_COMMAND:
-
- wmId = LOWORD(wParam); // Remember, these are...
- wmEvent = HIWORD(wParam); // ...different for Win32!
-
- if (wmId == IDC_ENIGATE)
- {
- int retCode, disp;
- HKEY hKey=0;
-
- IGateEnabled = IsDlgButtonChecked(hWnd, IDC_ENIGATE);
-
- if (IGateEnabled)
- ISDelayTimer = 60;
-
- retCode = RegCreateKeyEx(REGTREE,
- "SOFTWARE\\G8BPQ\\BPQ32",
- 0, // Reserved
- 0, // Class
- 0, // Options
- KEY_ALL_ACCESS,
- NULL, // Security Attrs
- &hKey,
- &disp);
-
- if (retCode == ERROR_SUCCESS)
- {
- retCode = RegSetValueEx(hKey,"IGateEnabled", 0 , REG_DWORD,(BYTE *)&IGateEnabled, 4);
- RegCloseKey(hKey);
- }
-
- return 0;
- }
-
- if (wmId == BPQSAVENODES)
- {
- SaveNodes();
- WritetoConsole("Nodes Saved\n");
- return 0;
- }
- if (wmId == BPQCLEARRECONFIG)
- {
- if (!ProcessConfig())
- {
- MessageBox(NULL,"Configuration File check falled - will continue with old config","BPQ32",MB_OK);
- return (0);
- }
-
- ClearNodes();
- WritetoConsole("Nodes file Cleared\n");
- ReconfigFlag=TRUE;
- WritetoConsole("Reconfig requested ... Waiting for Timer Poll\n");
- return 0;
- }
- if (wmId == BPQRECONFIG)
- {
- if (!ProcessConfig())
- {
- MessageBox(NULL,"Configuration File check falled - will continue with old config","BPQ32",MB_OK);
- return (0);
- }
- SaveNodes();
- WritetoConsole("Nodes Saved\n");
- ReconfigFlag=TRUE;
- WritetoConsole("Reconfig requested ... Waiting for Timer Poll\n");
- return 0;
- }
-
- if (wmId == SCANRECONFIG)
- {
- if (!ProcessConfig())
- {
- MessageBox(NULL,"Configuration File check falled - will continue with old config","BPQ32",MB_OK);
- return (0);
- }
-
- RigReconfigFlag = TRUE;
- WritetoConsole("Rigcontrol Reconfig requested ... Waiting for Timer Poll\n");
- return 0;
- }
-
- if (wmId == APRSRECONFIG)
- {
- if (!ProcessConfig())
- {
- MessageBox(NULL,"Configuration File check falled - will continue with old config","BPQ32",MB_OK);
- return (0);
- }
-
- APRSReconfigFlag=TRUE;
- WritetoConsole("APRS Reconfig requested ... Waiting for Timer Poll\n");
- return 0;
- }
- if (wmId == BPQDUMP)
- {
- DumpSystem();
- return 0;
- }
-
- if (wmId == BPQCLOSEALL)
- {
- CloseAllPrograms();
- return 0;
- }
-
- if (wmId == BPQUICONFIG)
- {
- int err, i=0;
- char Title[80];
- WNDCLASS wc;
-
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = UIWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = DLGWINDOWEXTRA;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(BPQICON) );
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = bgBrush;
-
- wc.lpszMenuName = NULL;
- wc.lpszClassName = UIClassName;
-
- RegisterClass(&wc);
-
- UIhWnd = CreateDialog(hInstance, UIClassName,0,NULL);
-
- if (!UIhWnd)
- {
- err=GetLastError();
- return FALSE;
- }
-
- wsprintf(Title,"BPQ32 Beacon Utility Version");
- MySetWindowText(UIhWnd, Title);
- return 0;
- }
-
- if (wmId == BPQSAVEREG)
- {
- CreateRegBackup();
- return 0;
- }
-
- if (wmId == BPQMINTOTRAY)
- {
- MinimizetoTray = !MinimizetoTray;
-
- if (MinimizetoTray)
- CheckMenuItem(hPopMenu, BPQMINTOTRAY, MF_CHECKED);
- else
- CheckMenuItem(hPopMenu, BPQMINTOTRAY, MF_UNCHECKED);
-
- SaveConfig();
- return 0;
- }
-
- if (wmId == BPQSTARTMIN)
- {
- StartMinimized = !StartMinimized;
-
- if (StartMinimized)
- CheckMenuItem(hPopMenu, BPQSTARTMIN, MF_CHECKED);
- else
- CheckMenuItem(hPopMenu, BPQSTARTMIN, MF_UNCHECKED);
-
- SaveConfig();
- return 0;
- }
-
- if (wmId >= TRAYBASEID && wmId < (TRAYBASEID + 100))
- {
- handle=hWndArray[wmId-TRAYBASEID];
-
- if (handle == FrameWnd && FrameMaximized == TRUE)
- PostMessage(handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
- else
- PostMessage(handle, WM_SYSCOMMAND, SC_RESTORE, 0);
-
- SetForegroundWindow(handle);
- return 0;
- }
-
- case WM_SYSCOMMAND:
-
- wmId = LOWORD(wParam); // Remember, these are...
- wmEvent = HIWORD(wParam); // ...different for Win32!
-
- switch (wmId)
- {
- case SC_MINIMIZE:
-
- ConsoleMinimized = TRUE;
- break;
-
- case SC_RESTORE:
-
- ConsoleMinimized = FALSE;
- SendMessage(ClientWnd, WM_MDIRESTORE, (WPARAM)hWnd, 0);
-
- break;
- }
-
- return DefMDIChildProc(hWnd, message, wParam, lParam);
-
-
- case WM_SIZE:
-
- GetClientRect(hWnd, &cRect);
-
- MoveWindow(hWndBG, 0, 0, cRect.right, 26, TRUE);
-
- if (APRSActive)
- MoveWindow(hWndCons, 2, 26, cRect.right-4, cRect.bottom - 32, TRUE);
- else
- MoveWindow(hWndCons, 2, 2, cRect.right-4, cRect.bottom - 4, TRUE);
-
-// InvalidateRect(hWnd, NULL, TRUE);
- break;
-
-/*
- case WM_PAINT:
-
- hdc = BeginPaint (hWnd, &ps);
-
- hOldFont = SelectObject( hdc, hFont) ;
-
- for (i=0; i 300)
- len = 300;
-
- memcpy(&buffptr[2], buff, len + 1);
-
- C_Q_ADD(&WritetoConsoleQ, buffptr);
-
- return 0;
-}
-
-int WritetoConsoleSupport(char * buff)
-{
-
- int len=strlen(buff);
- char Temp[2000]= "";
- char * ptr;
-
- if (PartLine)
- {
- SendMessage(hWndCons, LB_GETTEXT, pindex, (LPARAM)(LPCTSTR) Temp);
- SendMessage(hWndCons, LB_DELETESTRING, pindex, 0);
- PartLine = FALSE;
- }
-
- if ((strlen(Temp) + strlen(buff)) > 1990)
- Temp[0] = 0; // Should never have anything this long
-
- strcat(Temp, buff);
-
- ptr = strchr(Temp, '\n');
-
- if (ptr)
- *ptr = 0;
- else
- PartLine = TRUE;
-
- pindex=SendMessage(hWndCons, LB_ADDSTRING, 0, (LPARAM)(LPCTSTR) Temp);
- return 0;
- }
-
-DllExport VOID APIENTRY BPQOutputDebugString(char * String)
-{
- OutputDebugString(String);
- return;
- }
-
-HANDLE handle;
-char fn[]="BPQDUMP";
-ULONG cnt;
-char * stack;
-//char screen[1920];
-//COORD ReadCoord;
-
-#define DATABYTES 400000
-
-extern UCHAR DATAAREA[];
-
-DllExport int APIENTRY DumpSystem()
-{
- char fn[200];
- char Msg[250];
-
- sprintf(fn,"%s\\BPQDUMP",BPQDirectory);
-
- handle = CreateFile(fn,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
-#ifndef _WIN64
-
- _asm {
-
- mov stack,esp
- }
-
- WriteFile(handle,stack,128,&cnt,NULL);
-#endif
-
-// WriteFile(handle,Screen,MAXLINELEN*MAXSCREENLEN,&cnt,NULL);
-
- WriteFile(handle,DATAAREA, DATABYTES,&cnt,NULL);
-
- CloseHandle(handle);
-
- sprintf(Msg, "Dump to %s Completed\n", fn);
- WritetoConsole(Msg);
-
- FindLostBuffers();
-
- return (0);
-}
-
-BOOLEAN CheckifBPQ32isLoaded()
-{
- HANDLE Mutex;
-
- // See if BPQ32 is running - if we create it in the NTVDM address space by
- // loading bpq32.dll it will not work.
-
- Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,"BPQLOCKMUTEX");
-
- if (Mutex == NULL)
- {
- if (AttachingProcess == 0) // Already starting BPQ32
- {
- OutputDebugString("BPQ32 No other bpq32 programs running - Loading BPQ32.exe\n");
- StartBPQ32();
- }
- return FALSE;
- }
-
- CloseHandle(Mutex);
-
- return TRUE;
-}
-
-BOOLEAN StartBPQ32()
-{
- UCHAR Value[100];
-
- char bpq[]="BPQ32.exe";
- char *fn=(char *)&bpq;
- HKEY hKey=0;
- int ret,Type,Vallen=99;
-
- char Errbuff[100];
- char buff[20];
-
- STARTUPINFO StartupInfo; // pointer to STARTUPINFO
- PROCESS_INFORMATION ProcessInformation; // pointer to PROCESS_INFORMATION
-
- AttachingProcess = 1;
-
-// Get address of BPQ Directory
-
- Value[0]=0;
-
- ret = RegOpenKeyEx (REGTREE,
- "SOFTWARE\\G8BPQ\\BPQ32",
- 0,
- KEY_QUERY_VALUE,
- &hKey);
-
- if (ret == ERROR_SUCCESS)
- {
- ret = RegQueryValueEx(hKey, "BPQ Program Directory", 0, &Type,(UCHAR *)&Value, &Vallen);
-
- if (ret == ERROR_SUCCESS)
- {
- if (strlen(Value) == 2 && Value[0] == '"' && Value[1] == '"')
- Value[0]=0;
- }
-
-
- if (Value[0] == 0)
- {
-
- // BPQ Directory absent or = "" - "try Config File Location"
-
- ret = RegQueryValueEx(hKey,"BPQ Directory",0,
- &Type,(UCHAR *)&Value,&Vallen);
-
- if (ret == ERROR_SUCCESS)
- {
- if (strlen(Value) == 2 && Value[0] == '"' && Value[1] == '"')
- Value[0]=0;
- }
-
- }
- RegCloseKey(hKey);
- }
-
- if (Value[0] == 0)
- {
- strcpy(Value,fn);
- }
- else
- {
- strcat(Value,"\\");
- strcat(Value,fn);
- }
-
- StartupInfo.cb=sizeof(StartupInfo);
- StartupInfo.lpReserved=NULL;
- StartupInfo.lpDesktop=NULL;
- StartupInfo.lpTitle=NULL;
- StartupInfo.dwFlags=0;
- StartupInfo.cbReserved2=0;
- StartupInfo.lpReserved2=NULL;
-
- if (!CreateProcess(Value,NULL,NULL,NULL,FALSE,
- CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
- NULL,NULL,&StartupInfo,&ProcessInformation))
- {
- ret=GetLastError();
-
- _itoa(ret,buff,10);
-
- strcpy(Errbuff, "BPQ32 Load ");
- strcat(Errbuff,Value);
- strcat(Errbuff," failed ");
- strcat(Errbuff,buff);
- OutputDebugString(Errbuff);
- AttachingProcess = 0;
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-DllExport BPQVECSTRUC * APIENTRY GetIPVectorAddr()
-{
- return &IPHOSTVECTOR;
-}
-
-DllExport UINT APIENTRY GETSENDNETFRAMEADDR()
-{
- return (UINT)&SENDNETFRAME;
-}
-
-DllExport VOID APIENTRY RelBuff(VOID * Msg)
-{
- UINT * pointer, * BUFF = Msg;
-
- if (Semaphore.Flag == 0)
- Debugprintf("ReleaseBuffer called without semaphore");
-
- pointer = FREE_Q;
-
- *BUFF =(UINT)pointer;
-
- FREE_Q = BUFF;
-
- QCOUNT++;
-
- return;
-}
-
-extern int MINBUFFCOUNT;
-
-DllExport VOID * APIENTRY GetBuff()
-{
- UINT * Temp = Q_REM(&FREE_Q);
-
- if (Semaphore.Flag == 0)
- Debugprintf("GetBuff called without semaphore");
-
- if (Temp)
- {
- QCOUNT--;
-
- if (QCOUNT < MINBUFFCOUNT)
- MINBUFFCOUNT = QCOUNT;
- }
-
- return Temp;
-}
-
-
-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;
-}
-
-unsigned short int compute_crc(unsigned char *buf, int txlen);
-
-extern SOCKADDR_IN reportdest;
-
-extern SOCKET ReportSocket;
-
-extern SOCKADDR_IN Chatreportdest;
-
-DllExport VOID APIENTRY SendChatReport(SOCKET ChatReportSocket, char * buff, int txlen)
-{
- unsigned short int crc = compute_crc(buff, txlen);
-
- crc ^= 0xffff;
-
- buff[txlen++] = (crc&0xff);
- buff[txlen++] = (crc>>8);
-
- sendto(ChatReportSocket, buff, txlen, 0, (LPSOCKADDR)&Chatreportdest, sizeof(Chatreportdest));
-}
-
-VOID CreateRegBackup()
-{
- char Backup1[MAX_PATH];
- char Backup2[MAX_PATH];
- char RegFileName[MAX_PATH];
- char Msg[80];
- HANDLE handle;
- int len, written;
- char RegLine[300];
-
-// SHELLEXECUTEINFO sei;
-// STARTUPINFO SInfo;
-// PROCESS_INFORMATION PInfo;
-
- sprintf(RegFileName, "%s\\BPQ32.reg", BPQDirectory);
-
- // Keep 4 Generations
-
- strcpy(Backup2, RegFileName);
- strcat(Backup2, ".bak.3");
-
- strcpy(Backup1, RegFileName);
- strcat(Backup1, ".bak.2");
-
- DeleteFile(Backup2); // Remove old .bak.3
- MoveFile(Backup1, Backup2); // Move .bak.2 to .bak.3
-
- strcpy(Backup2, RegFileName);
- strcat(Backup2, ".bak.1");
-
- MoveFile(Backup2, Backup1); // Move .bak.1 to .bak.2
-
- strcpy(Backup1, RegFileName);
- strcat(Backup1, ".bak");
-
- MoveFile(Backup1, Backup2); //Move .bak to .bak.1
-
- strcpy(Backup2, RegFileName);
- strcat(Backup2, ".bak");
-
- CopyFile(RegFileName, Backup2, FALSE); // Copy to .bak
-
- handle = CreateFile(RegFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if (handle == INVALID_HANDLE_VALUE)
- {
- sprintf(Msg, "Failed to open Registry Save File\n");
- WritetoConsole(Msg);
- return;
- }
-
- len = sprintf(RegLine, "Windows Registry Editor Version 5.00\r\n\r\n");
- WriteFile(handle, RegLine, len, &written, NULL);
-
- if (SaveReg("Software\\G8BPQ\\BPQ32", handle))
- WritetoConsole("Registry Save complete\n");
- else
- WritetoConsole("Registry Save failed\n");
-
- CloseHandle(handle);
- return ;
-/*
-
- if (REGTREE == HKEY_LOCAL_MACHINE) // < Vista
- {
- sprintf(cmd,
- "regedit /E \"%s\\BPQ32.reg\" %s\\Software\\G8BPQ\\BPQ32", BPQDirectory, REGTREETEXT);
-
- ZeroMemory(&SInfo, sizeof(SInfo));
-
- SInfo.cb=sizeof(SInfo);
- SInfo.lpReserved=NULL;
- SInfo.lpDesktop=NULL;
- SInfo.lpTitle=NULL;
- SInfo.dwFlags=0;
- SInfo.cbReserved2=0;
- SInfo.lpReserved2=NULL;
-
- if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0 ,NULL, NULL, &SInfo, &PInfo) == 0)
- {
- sprintf(Msg, "Error: CreateProcess for regedit failed 0%d\n", GetLastError() );
- WritetoConsole(Msg);
- return;
- }
- }
- else
- {
-
- sprintf(cmd,
- "/E \"%s\\BPQ32.reg\" %s\\Software\\G8BPQ\\BPQ32", BPQDirectory, REGTREETEXT);
-
- ZeroMemory(&sei, sizeof(sei));
-
- sei.cbSize = sizeof(SHELLEXECUTEINFOW);
- sei.hwnd = hWnd;
- sei.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI;
- sei.lpVerb = "runas";
- sei.lpFile = "regedit.exe";
- sei.lpParameters = cmd;
- sei.nShow = SW_SHOWNORMAL;
-
- if (!ShellExecuteEx(&sei))
- {
- sprintf(Msg, "Error: ShellExecuteEx for regedit failed %d\n", GetLastError() );
- WritetoConsole(Msg);
- return;
- }
- }
-
- sprintf(Msg, "Registry Save Initiated\n", fn);
- WritetoConsole(Msg);
-
- return ;
-*/
-}
-
-BOOL CALLBACK EnumForCloseProc(HWND hwnd, LPARAM lParam)
-{
- struct TNCINFO * TNC = (struct TNCINFO *)lParam;
- UINT ProcessId;
-
- GetWindowThreadProcessId(hwnd, &ProcessId);
-
- for (i=0; i< AttachedProcesses; i++)
- {
- if (AttachedPIDList[i] == ProcessId)
- {
- Debugprintf("BPQ32 Close All Closing PID %d", ProcessId);
- PostMessage(hwnd, WM_CLOSE, 1, 1);
- // AttachedPIDList[i] = 0; // So we don't do it again
- break;
- }
- }
-
- return (TRUE);
-}
-DllExport BOOL APIENTRY RestoreFrameWindow()
-{
- return ShowWindow(FrameWnd, SW_RESTORE);
-}
-
-DllExport VOID APIENTRY CreateNewTrayIcon()
-{
- Shell_NotifyIcon(NIM_DELETE,&niData);
- trayMenu = NULL;
-}
-
-DllExport VOID APIENTRY CloseAllPrograms()
-{
-// HANDLE hProc;
-
- // Close all attached BPQ32 programs
-
- Closing = TRUE;
-
- ShowWindow(FrameWnd, SW_RESTORE);
-
- GetWindowRect(FrameWnd, &FRect);
-
- SaveBPQ32Windows();
- CloseHostSessions();
-
- if (AttachedProcesses == 1)
- CloseBPQ32();
-
- Debugprintf("BPQ32 Close All Processes %d PIDS %d %d %d %d", AttachedProcesses, AttachedPIDList[0],
- AttachedPIDList[1], AttachedPIDList[2], AttachedPIDList[3]);
-
- if (MinimizetoTray)
- Shell_NotifyIcon(NIM_DELETE,&niData);
-
- EnumWindows(EnumForCloseProc, (LPARAM)NULL);
-}
-
-#define MAX_KEY_LENGTH 255
-#define MAX_VALUE_NAME 16383
-#define MAX_VALUE_DATA 65536
-
-BOOL CopyReg(HKEY hKeyIn, HKEY hKeyOut)
-{
- TCHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
- DWORD cbName; // size of name string
- TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
- DWORD cchClassName = MAX_PATH; // size of class string
- DWORD cSubKeys=0; // number of subkeys
- DWORD cbMaxSubKey; // longest subkey size
- DWORD cchMaxClass; // longest class string
- DWORD cValues; // number of values for key
- DWORD cchMaxValue; // longest value name
- DWORD cbMaxValueData; // longest value data
- DWORD cbSecurityDescriptor; // size of security descriptor
- FILETIME ftLastWriteTime; // last write time
-
- DWORD i, retCode;
-
- TCHAR achValue[MAX_VALUE_NAME];
- DWORD cchValue = MAX_VALUE_NAME;
-
- // Get the class name and the value count.
- retCode = RegQueryInfoKey(
- hKeyIn, // key handle
- achClass, // buffer for class name
- &cchClassName, // size of class string
- NULL, // reserved
- &cSubKeys, // number of subkeys
- &cbMaxSubKey, // longest subkey size
- &cchMaxClass, // longest class string
- &cValues, // number of values for this key
- &cchMaxValue, // longest value name
- &cbMaxValueData, // longest value data
- &cbSecurityDescriptor, // security descriptor
- &ftLastWriteTime); // last write time
-
- // Enumerate the subkeys, until RegEnumKeyEx fails.
-
- if (cSubKeys)
- {
- Debugprintf( "\nNumber of subkeys: %d\n", cSubKeys);
-
- for (i=0; i 76)
- {
- len = sprintf(RegLine, "%s\\\r\n", RegLine);
- WriteFile(hFile, RegLine, len, &written, NULL);
- strcpy(RegLine, " ");
- len = 2;
- }
-
- len = sprintf(RegLine, "%s%02x,", RegLine, Value[k]);
- }
- RegLine[--len] = 0x0d;
- RegLine[++len] = 0x0a;
- len++;
-
- break;
-
- case REG_DWORD: //( 4 ) // 32-bit number
-// case REG_DWORD_LITTLE_ENDIAN: //( 4 ) // 32-bit number (same as REG_DWORD)
-
- memcpy(&Intval, Value, 4);
- len = sprintf(RegLine, "\"%s\"=dword:%08x\r\n", achValue, Intval);
- break;
-
- case REG_DWORD_BIG_ENDIAN: //( 5 ) // 32-bit number
- break;
- case REG_LINK: //( 6 ) // Symbolic Link (unicode)
- break;
- case REG_MULTI_SZ: //( 7 ) // Multiple Unicode strings
-
- len = sprintf(RegLine, "\"%s\"=hex(7):%02x,00,", achValue, Value[0]);
- for (k = 1; k < ValLen; k++)
- {
- if (len > 76)
- {
- len = sprintf(RegLine, "%s\\\r\n", RegLine);
- WriteFile(hFile, RegLine, len, &written, NULL);
- strcpy(RegLine, " ");
- len = 2;
- }
- len = sprintf(RegLine, "%s%02x,", RegLine, Value[k]);
- if (len > 76)
- {
- len = sprintf(RegLine, "%s\\\r\n", RegLine);
- WriteFile(hFile, RegLine, len, &written, NULL);
- strcpy(RegLine, " ");
- }
- len = sprintf(RegLine, "%s00,", RegLine);
- }
-
- RegLine[--len] = 0x0d;
- RegLine[++len] = 0x0a;
- len++;
- break;
-
- case REG_RESOURCE_LIST: //( 8 ) // Resource list in the resource map
- break;
- case REG_FULL_RESOURCE_DESCRIPTOR: //( 9 ) // Resource list in the hardware description
- break;
- case REG_RESOURCE_REQUIREMENTS_LIST://( 10 )
- break;
- case REG_QWORD: //( 11 ) // 64-bit number
-// case REG_QWORD_LITTLE_ENDIAN: //( 11 ) // 64-bit number (same as REG_QWORD)
- break;
-
- }
-
- WriteFile(hFile, RegLine, len, &written, NULL);
- }
- }
- }
-
- WriteFile(hFile, "\r\n", 2, &written, NULL);
-
- // Enumerate the subkeys, until RegEnumKeyEx fails.
-
- if (cSubKeys)
- {
- for (i=0; i> 1;
- }
-
- Flags=GetApplFlags(i);
-
- if (OneBits > 1)
- sprintf(&NewScreen[(i+1)*54],"%2d%s%3d %3d %3d %03x %3x %10s%-20s",
- i, flag, RXCount(i), TXCount(i), MONCount(i), Mask, Flags, callsign,
- BPQHOSTVECTOR[i-1].PgmName);
- else
- sprintf(&NewScreen[(i+1)*54],"%2d%s%3d %3d %3d %3d %3x %10s%-20s",
- i, flag, RXCount(i), TXCount(i), MONCount(i), AppNumber, Flags, callsign,
- BPQHOSTVECTOR[i-1].PgmName);
-
- }
- }
-
- #include "StdExcept.c"
-
- if (Semaphore.Flag && Semaphore.SemProcessID == GetCurrentProcessId())
- FreeSemaphore(&Semaphore);
-
- }
-
- if (memcmp(Screen, NewScreen, 33 * 108) == 0) // No Change
- return 0;
-
- memcpy(Screen, NewScreen, 33 * 108);
- InvalidateRect(StatusWnd,NULL,FALSE);
-
- return(0);
-}
-
-LRESULT CALLBACK StatusWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- int wmId, wmEvent;
- PAINTSTRUCT ps;
- HDC hdc;
- HFONT hOldFont ;
- HGLOBAL hMem;
- MINMAXINFO * mmi;
- int i;
-
- switch (message)
- {
- case WM_TIMER:
-
- if (Semaphore.Flag == 0)
- DoStatus();
- break;
-
- case WM_MDIACTIVATE:
-
- // Set the system info menu when getting activated
-
- if (lParam == (LPARAM) hWnd)
- {
- // Activate
-
- RemoveMenu(hBaseMenu, 1, MF_BYPOSITION);
- AppendMenu(hBaseMenu, MF_STRING + MF_POPUP, (UINT)hConsMenu, "Actions");
- SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hBaseMenu, (LPARAM) hWndMenu);
- }
- else
- {
- SendMessage(ClientWnd, WM_MDISETMENU, (WPARAM) hMainFrameMenu, (LPARAM) NULL);
- }
-
- DrawMenuBar(FrameWnd);
-
- return TRUE; //DefMDIChildProc(hWnd, message, wParam, lParam);
-
- case WM_GETMINMAXINFO:
-
- mmi = (MINMAXINFO *)lParam;
- mmi->ptMaxSize.x = 850;
- mmi->ptMaxSize.y = 500;
- mmi->ptMaxTrackSize.x = 850;
- mmi->ptMaxTrackSize.y = 500;
-
-
- case WM_COMMAND:
-
- wmId = LOWORD(wParam); // Remember, these are...
- wmEvent = HIWORD(wParam); // ...different for Win32!
-
- //Parse the menu selections:
-
- switch (wmId)
- {
-
-/*
- case BPQSTREAMS:
-
- CheckMenuItem(hMenu,BPQSTREAMS,MF_CHECKED);
- CheckMenuItem(hMenu,BPQIPSTATUS,MF_UNCHECKED);
-
- StreamDisplay = TRUE;
-
- break;
-
- case BPQIPSTATUS:
-
- CheckMenuItem(hMenu,BPQSTREAMS,MF_UNCHECKED);
- CheckMenuItem(hMenu,BPQIPSTATUS,MF_CHECKED);
-
- StreamDisplay = FALSE;
- memset(Screen, ' ', 4000);
-
-
- break;
-
-*/
-
- case BPQCOPY:
-
- //
- // Copy buffer to clipboard
- //
- hMem=GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 33*110);
-
- if (hMem != 0)
- {
- if (OpenClipboard(hWnd))
- {
-// CopyScreentoBuffer(GlobalLock(hMem));
- GlobalUnlock(hMem);
- EmptyClipboard();
- SetClipboardData(CF_TEXT,hMem);
- CloseClipboard();
- }
- else
- {
- GlobalFree(hMem);
- }
-
- }
-
- break;
-
- }
-
- return DefMDIChildProc(hWnd, message, wParam, lParam);
-
-
- case WM_SYSCOMMAND:
-
- wmId = LOWORD(wParam); // Remember, these are...
- wmEvent = HIWORD(wParam); // ...different for Win32!
-
- switch (wmId)
- {
- case SC_MAXIMIZE:
-
- break;
-
- case SC_MINIMIZE:
-
- StatusMinimized = TRUE;
- break;
-
- case SC_RESTORE:
-
- StatusMinimized = FALSE;
- SendMessage(ClientWnd, WM_MDIRESTORE, (WPARAM)hWnd, 0);
- break;
- }
-
- return DefMDIChildProc(hWnd, message, wParam, lParam);
-
- case WM_PAINT:
-
- hdc = BeginPaint (hWnd, &ps);
-
- hOldFont = SelectObject( hdc, hFont) ;
-
- for (i=0; i<33; i++)
- {
- TextOut(hdc,0,i*14,&Screen[i*108],108);
- }
-
- SelectObject( hdc, hOldFont ) ;
- EndPaint (hWnd, &ps);
-
- break;
-
- case WM_DESTROY:
-
-// PostQuitMessage(0);
-
- break;
-
-
- default:
-
- return DefMDIChildProc(hWnd, message, wParam, lParam);
-
- }
- return (0);
-}
-
-VOID SaveMDIWindowPos(HWND hWnd, char * RegKey, char * Value, BOOL Minimized)
-{
- HKEY hKey=0;
- char Size[80];
- char Key[80];
- int retCode, disp;
- RECT Rect;
-
- if (IsWindow(hWnd) == FALSE)
- return;
-
- ShowWindow(hWnd, SW_RESTORE);
-
- if (GetWindowRect(hWnd, &Rect) == FALSE)
- return;
-
- // Make relative to Frame
-
- Rect.top -= FRect.top ;
- Rect.left -= FRect.left;
- Rect.bottom -= FRect.top;
- Rect.right -= FRect.left;
-
- sprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\%s", RegKey);
-
- retCode = RegCreateKeyEx(REGTREE, Key, 0, 0, 0,
- KEY_ALL_ACCESS, NULL, &hKey, &disp);
-
- if (retCode == ERROR_SUCCESS)
- {
- sprintf(Size,"%d,%d,%d,%d,%d", Rect.left, Rect.right, Rect.top ,Rect.bottom, Minimized);
- retCode = RegSetValueEx(hKey, Value, 0, REG_SZ,(BYTE *)&Size, strlen(Size));
- RegCloseKey(hKey);
- }
-}
-
-extern int GPSPort;
-extern char LAT[]; // in standard APRS Format
-extern char LON[]; // in standard APRS Format
-
-VOID SaveBPQ32Windows()
-{
- HKEY hKey=0;
- char Size[80];
- int retCode, disp;
- PEXTPORTDATA PORTVEC=(PEXTPORTDATA)PORTTABLE;
- int i;
-
- retCode = RegCreateKeyEx(REGTREE, "SOFTWARE\\G8BPQ\\BPQ32", 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, &disp);
-
- if (retCode == ERROR_SUCCESS)
- {
- sprintf(Size,"%d,%d,%d,%d", FRect.left, FRect.right, FRect.top, FRect.bottom);
- retCode = RegSetValueEx(hKey, "FrameWindowSize", 0, REG_SZ, (BYTE *)&Size, strlen(Size));
-
- // Save GPS Position
-
- if (GPSPort)
- {
- sprintf(Size, "%s, %s", LAT, LON);
- retCode = RegSetValueEx(hKey, "GPS", 0, REG_SZ,(BYTE *)&Size, strlen(Size));
- }
-
- RegCloseKey(hKey);
- }
-
- SaveMDIWindowPos(StatusWnd, "", "StatusWindowSize", StatusMinimized);
- SaveMDIWindowPos(hConsWnd, "", "WindowSize", ConsoleMinimized);
-
- for (i=0; iPORTCONTROL.PORTTYPE == 0x10) // External
- {
- if (PORTVEC->PORT_EXT_ADDR)
- {
- SaveWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
- SaveAXIPWindowPos(PORTVEC->PORTCONTROL.PORTNUMBER);
- }
- }
- PORTVEC=(PEXTPORTDATA)PORTVEC->PORTCONTROL.PORTPOINTER;
- }
-
- SaveWindowPos(70); // Rigcontrol
-
-
- if (hIPResWnd)
- SaveMDIWindowPos(hIPResWnd, "", "IPResSize", IPMinimized);
-
- SaveHostSessions();
-}
-
-DllExport BOOL APIENTRY CheckIfOwner()
-{
- //
- // Returns TRUE if current process is root process
- // that loaded the DLL
- //
-
- if (TimerInst == GetCurrentProcessId())
-
- return (TRUE);
- else
- return (FALSE);
-}
-
-VOID GetParam(char * input, char * key, char * value)
-{
- char * ptr = strstr(input, key);
- char Param[2048];
- char * ptr1, * ptr2;
- char c;
-
-
- if (ptr)
- {
- ptr2 = strchr(ptr, '&');
- if (ptr2) *ptr2 = 0;
- strcpy(Param, ptr + strlen(key));
- if (ptr2) *ptr2 = '&'; // Restore string
-
- // Undo any % transparency
-
- ptr1 = Param;
- ptr2 = Param;
-
- c = *(ptr1++);
-
- while (c)
- {
- if (c == '%')
- {
- int n;
- int m = *(ptr1++) - '0';
- if (m > 9) m = m - 7;
- n = *(ptr1++) - '0';
- if (n > 9) n = n - 7;
-
- *(ptr2++) = m * 16 + n;
- }
- else if (c == '+')
- *(ptr2++) = ' ';
- else
- *(ptr2++) = c;
-
- c = *(ptr1++);
- }
-
- *(ptr2++) = 0;
-
- strcpy(value, Param);
- }
-}
-
-int GetListeningPortsPID(int Port)
-{
- MIB_TCPTABLE_OWNER_PID * TcpTable = NULL;
- PMIB_TCPROW_OWNER_PID Row;
- int dwSize = 0;
- DWORD n;
-
- // Get PID of process for this TCP Port
-
- // Get Length of table
-
- GetExtendedTcpTable(TcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
-
- TcpTable = malloc(dwSize);
-
- if (TcpTable == NULL)
- return 0;
-
- GetExtendedTcpTable(TcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
-
- for (n = 0; n < TcpTable->dwNumEntries; n++)
- {
- Row = &TcpTable->table[n];
-
- if (Row->dwLocalPort == Port && Row->dwState == MIB_TCP_STATE_LISTEN)
- {
- return Row->dwOwningPid;
- break;
- }
- }
- return 0; // Not found
-}
-
-DllExport char * APIENTRY GetLOC()
-{
- return LOC;
-}
-
-DllExport void APIENTRY GetLatLon(double * lat, double * lon)
-{
- *lat = LatFromLOC;
- *lon = LonFromLOC;
- return;
-}
-
-
-// UZ7HO Dll PTT interface
-
-// 1 ext_PTT_info
-// 2 ext_PTT_settings
-// 3 ext_PTT_OFF
-// 4 ext_PTT_ON
-// 5 ext_PTT_close
-// 6 ext_PTT_open
-
-extern struct RIGINFO * DLLRIG; // Rig record for dll PTT interface (currently only for UZ7HO);
-
-VOID Rig_PTT(struct TNCINFO * TNC, BOOL PTTState);
-VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC);
-
-int WINAPI ext_PTT_info()
-{
- return 0;
-}
-
-int WINAPI ext_PTT_settings()
-{
- return 0;
-}
-
-int WINAPI ext_PTT_OFF(int Port)
-{
- if (DLLRIG)
- Rig_PTTEx(DLLRIG, 0, 0);
-
- return 0;
-}
-
-int WINAPI ext_PTT_ON(int Port)
-{
- if (DLLRIG)
- Rig_PTTEx(DLLRIG, 1, 0);
-
- return 0;
-}
-int WINAPI ext_PTT_close()
-{
- if (DLLRIG)
- Rig_PTTEx(DLLRIG, 0, 0);
-
- return 0;
-}
-
-DllExport INT WINAPI ext_PTT_open()
-{
- return 1;
-}
-
-char * stristr (char *ch1, char *ch2)
-{
- char *chN1, *chN2;
- char *chNdx;
- char *chRet = NULL;
-
- chN1 = _strdup(ch1);
- chN2 = _strdup(ch2);
-
- if (chN1 && chN2)
- {
- chNdx = chN1;
- while (*chNdx)
- {
- *chNdx = (char) tolower(*chNdx);
- chNdx ++;
- }
- chNdx = chN2;
-
- while (*chNdx)
- {
- *chNdx = (char) tolower(*chNdx);
- chNdx ++;
- }
-
- chNdx = strstr(chN1, chN2);
-
- if (chNdx)
- chRet = ch1 + (chNdx - chN1);
- }
-
- free (chN1);
- free (chN2);
- return chRet;
-}
-
diff --git a/Bpq32.c b/Bpq32.c
index b6acf29..944010b 100644
--- a/Bpq32.c
+++ b/Bpq32.c
@@ -1243,11 +1243,16 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
// Fix MailAPI msgs endpoint
// Attempt to fix NC going to wrong application. (57)
// Improve ARDOP end of session code (58)
-// Run M0LTE Map repoorting in a separate thread (59)
-// Add support fro WhatsPac (59)
-// Add timestamps to LIS monitor
-
-
+// Run M0LTE Map reporting in a separate thread (59/60)
+// Add RHP support for WhatsPac (59)
+// Add timestamps to LIS monitor (60)
+// Fix problem with L4 frames being delivered out of sequence (60)
+// Add Compression of Netrom connections (62)
+// Improve handling of Locked Routes (62)
+// Add L4 RESET (Paula G8PZT's extension to NETROM)
+// Fix problem using SENDRAW from BPQMail (63)
+// Fix compatibility with latest ardopcf (64)
+// Fix bug in RHP socket timeout code (65)
#define CKernel
diff --git a/Cmd.c b/Cmd.c
index c5f43dd..9ff56fe 100644
--- a/Cmd.c
+++ b/Cmd.c
@@ -1516,7 +1516,7 @@ VOID CMDP00(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct C
char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE * Routes, char Verbose)
{
char Normcall[10];
- char locked[] = " ! ";
+ char locked[4] = " ";
int NodeCount;
int Percent = 0;
char PercentString[20];
@@ -1530,11 +1530,16 @@ char * DisplayRoute(TRANSPORTENTRY * Session, char * Bufferptr, struct ROUTE *
Normcall[9]=0;
- if ((Routes->NEIGHBOUR_FLAG & 1) == 1)
+ if (Routes->NEIGHBOUR_FLAG == LOCKEDBYCONFIG)
strcpy(locked, "!");
+ else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP)
+ strcpy(locked, "!!");
+ else if (Routes->NEIGHBOUR_FLAG == LOCKEDBYSYSOP + LOCKEDBYCONFIG)
+ strcpy(locked, "!!!");
else
strcpy(locked, " ");
+
NodeCount = COUNTNODES(Routes);
if (Routes->NEIGHBOUR_LINK && Routes->NEIGHBOUR_LINK->L2STATE >= 5)
@@ -1678,7 +1683,7 @@ ROUTEUPDATE:
{
// Toggle Lock
- Routes->NEIGHBOUR_FLAG ^= 1; // FLIP LOCKED BIT
+ Routes->NEIGHBOUR_FLAG ^= LOCKEDBYSYSOP; // FLIP LOCKED BIT
goto Displayit;
}
@@ -1697,7 +1702,7 @@ ROUTEUPDATE:
{
// Toggle Lock
- Routes->NEIGHBOUR_FLAG ^= 1; // FLIP LOCKED BIT
+ Routes->NEIGHBOUR_FLAG ^= LOCKEDBYSYSOP; // FLIP LOCKED BIT
goto Displayit;
}
}
@@ -1711,167 +1716,6 @@ Displayit:
else
Bufferptr = Cmdprintf(Session, Bufferptr, "Not Found\r");
-
-
-/* MOV ROUTEDISP,1
-
- CMP BYTE PTR [ESI],20H
- JE SHORT JUSTDISPLAY
-
- MOV ZAPFLAG,0
-
- CMP BYTE PTR [ESI],'Z'
- JNE SHORT NOTZAP
-
- MOV ZAPFLAG,1
- JMP SHORT JUSTDISPLAY
-
- PUBLIC NOTZAP
-NOTZAP:
-
- MOV ROUTEDISP,2 ; LOCK UPDATE
-
- CMP BYTE PTR [ESI],'!'
- JE SHORT JUSTDISPLAY
-;
-; LOOK FOR V FOR ADDING A DIGI
-;
- CMP WORD PTR [ESI],' V' ; V [SPACE]
- JE ADDDIGI
-
- CALL GETVALUE ; GET NUMBER, UP TO SPACE , CR OR OFFH
- JC SHORT BADROUTECMD ; INVALID DIGITS
-
- MOV NEWROUTEVAL,AL
-
- MOV ROUTEDISP,0
-
- CALL SCAN ; SEE IF !
- MOV AH,[ESI]
-
-
- PUBLIC JUSTDISPLAY
-JUSTDISPLAY:
-
-
- MOV ESI,OFFSET32 AX25CALL
- CALL _FINDNEIGHBOUR
- JZ SHORT FOUNDROUTE ; IN LIST - OK
-
- CMP EBX,0
- JE SHORT BADROUTECMD ; TABLE FULL??
-
- MOV ECX,7
- MOV EDI,EBX
- REP MOVSB ; PUT IN CALL
-
- MOV AL,SAVEPORT
- MOV NEIGHBOUR_PORT[EBX],AL
-
- JMP SHORT FOUNDROUTE
-
-
- PUBLIC BADROUTECMD
-BADROUTECMD:
-
- POP EDI
-
- JMP PBADVALUE
-
- PUBLIC FOUNDROUTE
-FOUNDROUTE:
-
- CMP ZAPFLAG,1
- JNE SHORT NOTCLEARCOUNTS
-
- XOR AX,AX
- MOV ES:WORD PTR NBOUR_IFRAMES[EDI],AX
- MOV ES:WORD PTR NBOUR_IFRAMES+2[EDI],AX
- MOV ES:WORD PTR NBOUR_RETRIES[EDI],AX
- MOV ES:WORD PTR NBOUR_RETRIES+2[EDI],AX
-
- JMP SHORT NOUPDATE
-
- PUBLIC NOTCLEARCOUNTS
-NOTCLEARCOUNTS:
-
- CMP ROUTEDISP,1
- JE SHORT NOUPDATE
-
- CMP ROUTEDISP,2
- JE SHORT LOCKUPDATE
-
- MOV AL,NEWROUTEVAL
- MOV NEIGHBOUR_QUAL[EBX],AL
-
- CMP AH,'!'
- JNE SHORT NOUPDATE
-
- PUBLIC LOCKUPDATE
-LOCKUPDATE:
-
- XOR NEIGHBOUR_FLAG[EBX],1 ; FLIP LOCKED BIT
-
- PUBLIC NOUPDATE
-NOUPDATE:
-
- MOV ESI,EBX
- POP EDI
-
- POP EBX
- CALL DISPLAYROUTE
-
- JMP SENDCOMMANDREPLY
-
- PUBLIC ADDDIGI
-ADDDIGI:
-
- ADD ESI,2
- PUSH ESI ; SAVE INPUT BUFFER
-
- MOV ESI,OFFSET32 AX25CALL
- CALL _FINDNEIGHBOUR
-
- POP ESI
-
- JZ SHORT ADD_FOUND ; IN LIST - OK
-
- JMP BADROUTECMD
-
- PUBLIC ADD_FOUND
-ADD_FOUND:
-
- CALL CONVTOAX25 ; GET DIGI CALLSIGN
-
- PUSH ESI
-
- MOV ESI,OFFSET32 AX25CALL
- LEA EDI,NEIGHBOUR_DIGI[EBX]
- MOV ECX,7
- REP MOVSB
-
- POP ESI ; MSG BUFFER
-;
-; SEE IF ANOTHER DIGI
-;
- CMP BYTE PTR [ESI],20H
- JE SHORT NOMORE
-
- CALL CONVTOAX25 ; GET DIGI CALLSIGN
- MOV ESI,OFFSET32 AX25CALL
- LEA EDI,NEIGHBOUR_DIGI+7[EBX]
- MOV ECX,7
- REP MOVSB
-
- PUBLIC NOMORE
-NOMORE:
-
- JMP NOUPDATE
-
-
-
-*/
-
SendReply:
SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
@@ -4144,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;
}
@@ -4195,14 +4039,25 @@ VOID ATTACHCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc
- if (EXTPORT->ATTACHEDSESSIONS[sess] || PORT->PortSuspended)
+ if (EXTPORT->ATTACHEDSESSIONS[sess])
{
// In use
- 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);
diff --git a/CommonCode-skigdebian.c b/CommonCode-skigdebian.c
deleted file mode 100644
index 90e6a08..0000000
--- a/CommonCode-skigdebian.c
+++ /dev/null
@@ -1,5647 +0,0 @@
-/*
-Copyright 2001-2022 John Wiseman G8BPQ
-
-This file is part of LinBPQ/BPQ32.
-
-LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-LinBPQ/BPQ32 is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
-*/
-
-
-
-// General C Routines common to bpq32 and linbpq. Mainly moved from BPQ32.c
-
-#pragma data_seg("_BPQDATA")
-
-#define _CRT_SECURE_NO_DEPRECATE
-
-#include
-#include
-#include
-#include "mqtt.h"
-
-#pragma data_seg("_BPQDATA")
-
-#include "cheaders.h"
-#include "tncinfo.h"
-#include "configstructs.h"
-
-extern struct CONFIGTABLE xxcfg;
-
-#define LIBCONFIG_STATIC
-#include "libconfig.h"
-
-#ifndef LINBPQ
-
-//#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
-
-#include "commctrl.h"
-#include "Commdlg.h"
-
-#endif
-
-struct TNCINFO * TNCInfo[71]; // Records are Malloc'd
-
-extern int ReportTimer;
-
-Dll VOID APIENTRY Send_AX(UCHAR * Block, DWORD Len, UCHAR Port);
-TRANSPORTENTRY * SetupSessionFromHost(PBPQVECSTRUC HOST, UINT ApplMask);
-int Check_Timer();
-VOID SENDUIMESSAGE(struct DATAMESSAGE * Msg);
-DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
-VOID APIENTRY md5 (char *arg, unsigned char * checksum);
-VOID COMSetDTR(HANDLE fd);
-VOID COMClearDTR(HANDLE fd);
-VOID COMSetRTS(HANDLE fd);
-VOID COMClearRTS(HANDLE fd);
-
-VOID WriteMiniDump();
-void printStack(void);
-char * FormatMH(PMHSTRUC MH, char Format);
-void WriteConnectLog(char * fromCall, char * toCall, UCHAR * Mode);
-void SendDataToPktMap();
-
-extern BOOL LogAllConnects;
-extern BOOL M0LTEMap;
-
-char * stristr (char *ch1, char *ch2);
-
-extern VOID * ENDBUFFERPOOL;
-
-
-// Read/Write length field in a buffer header
-
-// Needed for Big/LittleEndian and ARM5 (unaligned operation problem) portability
-
-
-VOID PutLengthinBuffer(PDATAMESSAGE buff, USHORT datalen)
-{
- if (datalen <= sizeof(void *) + 4)
- datalen = sizeof(void *) + 4; // Protect
-
- memcpy(&buff->LENGTH, &datalen, 2);
-}
-
-int GetLengthfromBuffer(PDATAMESSAGE buff)
-{
- USHORT Length;
-
- memcpy(&Length, &buff->LENGTH, 2);
- return Length;
-}
-
-BOOL CheckQHeadder(UINT * Q)
-{
-#ifdef WIN32
- UINT Test;
-
- __try
- {
- Test = *Q;
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- Debugprintf("Invalid Q Header %p", Q);
- printStack();
- return FALSE;
- }
-#endif
- return TRUE;
-}
-
-// Get buffer from Queue
-
-
-VOID * _Q_REM(VOID **PQ, char * File, int Line)
-{
- void ** Q;
- void ** first;
- VOID * next;
- PMESSAGE Test;
-
- // PQ may not be word aligned, so copy as bytes (for ARM5)
-
- Q = PQ;
-
- if (Semaphore.Flag == 0)
- Debugprintf("Q_REM called without semaphore from %s Line %d", File, Line);
-
- if (CheckQHeadder((UINT *) Q) == 0)
- return(0);
-
- first = Q[0];
-
- if (first == 0)
- return (0); // Empty
-
- next = first[0]; // Address of next buffer
-
- Q[0] = next;
-
- // Make sure guard zone is zeros
-
- Test = (PMESSAGE)first;
-
- if (Test->GuardZone != 0)
- {
- Debugprintf("Q_REM %p GUARD ZONE CORRUPT %x Called from %s Line %d", first, Test->GuardZone, File, Line);
- printStack();
- }
-
- return first;
-}
-
-// Non=pool version (for IPGateway)
-
-VOID * _Q_REM_NP(VOID *PQ, char * File, int Line)
-{
- void ** Q;
- void ** first;
- void * next;
-
- // PQ may not be word aligned, so copy as bytes (for ARM5)
-
- Q = PQ;
-
- if (CheckQHeadder((UINT *)Q) == 0)
- return(0);
-
- first = Q[0];
-
- if (first == 0) return (0); // Empty
-
- next = first[0]; // Address of next buffer
-
- Q[0] = next;
-
- return first;
-}
-
-// Return Buffer to Free Queue
-
-extern VOID * BUFFERPOOL;
-extern void ** Bufferlist[1000];
-void printStack(void);
-
-void _CheckGuardZone(char * File, int Line)
-{
- int n = 0, i, offset = 0;
- PMESSAGE Test;
- UINT CodeDump[8];
- unsigned char * ptr;
-
- n = NUMBEROFBUFFERS;
-
- while (n--)
- {
- Test = (PMESSAGE)Bufferlist[n];
-
- if (Test && Test->GuardZone)
- {
- Debugprintf("CheckGuardZone %p GUARD ZONE CORRUPT %d Called from %s Line %d", Test, Test->Process, File, Line);
-
- offset = 0;
- ptr = (unsigned char *)Test;
-
- while (offset < 400)
- {
- memcpy(CodeDump, &ptr[offset], 32);
-
- for (i = 0; i < 8; i++)
- CodeDump[i] = htonl(CodeDump[i]);
-
- Debugprintf("%08x %08x %08x %08x %08x %08x %08x %08x %08x ",
- &ptr[offset], CodeDump[0], CodeDump[1], CodeDump[2], CodeDump[3], CodeDump[4], CodeDump[5], CodeDump[6], CodeDump[7]);
-
- offset += 32;
- }
- WriteMiniDump();
-#ifdef MDIKERNEL
- CloseAllNeeded = 1;
-#endif
- }
-
- }
-}
-
-UINT _ReleaseBuffer(VOID *pBUFF, char * File, int Line)
-{
- void ** pointer, ** BUFF = pBUFF;
- int n = 0;
- void ** debug;
- PMESSAGE Test;
- UINT CodeDump[16];
- int i;
- unsigned int rev;
-
- if (Semaphore.Flag == 0)
- Debugprintf("ReleaseBuffer called without semaphore from %s Line %d", File, Line);
-
- // Make sure address is within pool
-
- if ((uintptr_t)BUFF < (uintptr_t)BUFFERPOOL || (uintptr_t)BUFF > (uintptr_t)ENDBUFFERPOOL)
- {
- // Not pointing to a buffer . debug points to the buffer that this is chained from
-
- // Dump first chunk and source tag
-
- memcpy(CodeDump, BUFF, 64);
-
- Debugprintf("Releasebuffer Buffer not in pool from %s Line %d, ptr %p prev %d", File, Line, BUFF, 0);
-
- 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 ",
- Bufferlist[n], 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",
- CodeDump[8], CodeDump[9], CodeDump[10], CodeDump[11], CodeDump[12], CodeDump[13], CodeDump[14], CodeDump[15]);
-
-
- return 0;
- }
-
- Test = (PMESSAGE)pBUFF;
-
- if (Test->GuardZone != 0)
- {
- Debugprintf("_ReleaseBuffer %p GUARD ZONE CORRUPT %x Called from %s Line %d", pBUFF, Test->GuardZone, File, Line);
- }
-
- while (n <= NUMBEROFBUFFERS)
- {
- if (BUFF == Bufferlist[n++])
- goto BOK1;
- }
-
- Debugprintf("ReleaseBuffer %X not in Pool called from %s Line %d", BUFF, File, Line);
- printStack();
-
- return 0;
-
-BOK1:
-
- n = 0;
-
- // validate free Queue
-
- pointer = FREE_Q;
- debug = &FREE_Q;
-
- while (pointer)
- {
- // Validate pointer to make sure it is in pool - it may be a duff address if Q is corrupt
-
- Test = (PMESSAGE)pointer;
-
- if (Test->GuardZone || (uintptr_t)pointer < (uintptr_t)BUFFERPOOL || (uintptr_t)pointer > (uintptr_t)ENDBUFFERPOOL)
- {
- // Not pointing to a buffer . debug points to the buffer that this is chained from
-
- // Dump first chunk and source tag
-
- memcpy(CodeDump, debug, 64);
-
- Debugprintf("Releasebuffer Pool Corruption n = %d, ptr %p prev %p", n, pointer, debug);
-
- 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 ",
- Bufferlist[n], 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",
- CodeDump[8], CodeDump[9], CodeDump[10], CodeDump[11], CodeDump[12], CodeDump[13], CodeDump[14], CodeDump[15]);
-
- if (debug[400])
- Debugprintf(" %s", &debug[400]);
-
- }
-
- // See if already on free Queue
-
- if (pointer == BUFF)
- {
- Debugprintf("Trying to free buffer %p when already on FREE_Q called from %s Line %d", BUFF, File, Line);
-// WriteMiniDump();
- return 0;
- }
-
-// if (pointer[0] && pointer == pointer[0])
-// {
-// Debugprintf("Buffer chained to itself");
-// return 0;
-// }
-
- debug = pointer;
- pointer = pointer[0];
- n++;
-
- if (n > 1000)
- {
- Debugprintf("Loop searching free chain - pointer = %p %p", debug, pointer);
- return 0;
- }
- }
-
- pointer = FREE_Q;
-
- *BUFF = pointer;
-
- FREE_Q = BUFF;
-
- QCOUNT++;
-
- return 0;
-}
-
-int _C_Q_ADD(VOID *PQ, VOID *PBUFF, char * File, int Line)
-{
- void ** Q;
- void ** BUFF = PBUFF;
- void ** next;
- PMESSAGE Test;
-
-
- int n = 0;
-
-// PQ may not be word aligned, so copy as bytes (for ARM5)
-
- Q = PQ;
-
- if (Semaphore.Flag == 0)
- Debugprintf("C_Q_ADD called without semaphore from %s Line %d", File, Line);
-
- if (CheckQHeadder((UINT *)Q) == 0) // Make sure Q header is readable
- return(0);
-
- // Make sure guard zone is zeros
-
- Test = (PMESSAGE)PBUFF;
-
- if (Test->GuardZone != 0)
- {
- Debugprintf("C_Q_ADD %p GUARD ZONE CORRUPT %x Called from %s Line %d", PBUFF, Test->GuardZone, File, Line);
- }
-
- Test = (PMESSAGE)Q;
-
-
-
- // Make sure address is within pool
-
- while (n <= NUMBEROFBUFFERS)
- {
- if (BUFF == Bufferlist[n++])
- goto BOK2;
- }
-
- Debugprintf("C_Q_ADD %X not in Pool called from %s Line %d", BUFF, File, Line);
- printStack();
-
- return 0;
-
-BOK2:
-
- BUFF[0] = 0; // Clear chain in new buffer
-
- if (Q[0] == 0) // Empty
- {
- Q[0]=BUFF; // New one on front
- return(0);
- }
-
- next = Q[0];
-
- while (next[0] != 0)
- {
- next = next[0]; // Chain to end of queue
- }
- next[0] = BUFF; // New one on end
-
- return(0);
-}
-
-// Non-pool version
-
-int C_Q_ADD_NP(VOID *PQ, VOID *PBUFF)
-{
- void ** Q;
- void ** BUFF = PBUFF;
- void ** next;
- int n = 0;
-
-// PQ may not be word aligned, so copy as bytes (for ARM5)
-
- Q = PQ;
-
- if (CheckQHeadder((UINT *)Q) == 0) // Make sure Q header is readable
- return(0);
-
- BUFF[0]=0; // Clear chain in new buffer
-
- if (Q[0] == 0) // Empty
- {
- Q[0]=BUFF; // New one on front
-// memcpy(PQ, &BUFF, 4);
- return 0;
- }
- next = Q[0];
-
- while (next[0] != 0)
- next=next[0]; // Chain to end of queue
-
- next[0] = BUFF; // New one on end
-
- return(0);
-}
-
-
-int C_Q_COUNT(VOID *PQ)
-{
- void ** Q;
- int count = 0;
-
-// PQ may not be word aligned, so copy as bytes (for ARM5)
-
- Q = PQ;
-
- if (CheckQHeadder((UINT *)Q) == 0) // Make sure Q header is readable
- return(0);
-
- // SEE HOW MANY BUFFERS ATTACHED TO Q HEADER
-
- while (*Q)
- {
- count++;
- if ((count + QCOUNT) > MAXBUFFS)
- {
- Debugprintf("C_Q_COUNT Detected corrupt Q %p len %d", PQ, count);
- return count;
- }
- Q = *Q;
- }
-
- return count;
-}
-
-VOID * _GetBuff(char * File, int Line)
-{
- UINT * Temp;
- MESSAGE * Msg;
- char * fptr = 0;
- unsigned char * byteaddr;
-
- Temp = Q_REM(&FREE_Q);
-
-// FindLostBuffers();
-
- if (Semaphore.Flag == 0)
- Debugprintf("GetBuff called without semaphore from %s Line %d", File, Line);
-
- if (Temp)
- {
- QCOUNT--;
-
- if (QCOUNT < MINBUFFCOUNT)
- MINBUFFCOUNT = QCOUNT;
-
- Msg = (MESSAGE *)Temp;
- fptr = File + (int)strlen(File);
- while (*fptr != '\\' && *fptr != '/')
- fptr--;
- fptr++;
-
- // Buffer Length is BUFFLEN, but buffers are allocated 512
- // So add file info in gap between
-
- byteaddr = (unsigned char *)Msg;
-
-
- memset(&byteaddr[0], 0, 64); // simplify debugging lost buffers
- memset(&byteaddr[400], 0, 64); // simplify debugging lost buffers
- sprintf(&byteaddr[400], "%s %d", fptr, Line);
-
- Msg->Process = (short)GetCurrentProcessId();
- Msg->Linkptr = NULL;
- Msg->Padding[0] = 0; // Used for modem status info
- }
- else
- Debugprintf("Warning - Getbuff returned NULL");
-
- return Temp;
-}
-
-void * zalloc(int len)
-{
- // malloc and clear
-
- void * ptr;
-
- ptr=malloc(len);
-
- if (ptr)
- memset(ptr, 0, len);
-
- return ptr;
-}
-
-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;
-}
-
-VOID DISPLAYCIRCUIT(TRANSPORTENTRY * L4, char * Buffer)
-{
- UCHAR Type = L4->L4CIRCUITTYPE;
- struct PORTCONTROL * PORT;
- struct _LINKTABLE * LINK;
- BPQVECSTRUC * VEC;
- struct DEST_LIST * DEST;
-
- char Normcall[20] = ""; // Could be alias:call
- char Normcall2[11] = "";
- char Alias[11] = "";
-
- Buffer[0] = 0;
-
- switch (Type)
- {
- case PACTOR+UPLINK:
-
- PORT = L4->L4TARGET.PORT;
-
- ConvFromAX25(L4->L4USER, Normcall);
- strlop(Normcall, ' ');
-
- if (PORT)
- sprintf(Buffer, "%s %d/%d(%s)", "TNC Uplink Port", PORT->PORTNUMBER, L4->KAMSESSION, Normcall);
-
- return;
-
-
- case PACTOR+DOWNLINK:
-
- PORT = L4->L4TARGET.PORT;
-
- if (PORT)
- sprintf(Buffer, "%s %d/%d", "Attached to Port", PORT->PORTNUMBER, L4->KAMSESSION);
- return;
-
-
- case L2LINK+UPLINK:
-
- LINK = L4->L4TARGET.LINK;
-
- ConvFromAX25(L4->L4USER, Normcall);
- strlop(Normcall, ' ');
-
- if (LINK &&LINK->LINKPORT)
- sprintf(Buffer, "%s %d(%s)", "Uplink", LINK->LINKPORT->PORTNUMBER, Normcall);
-
- return;
-
- case L2LINK+DOWNLINK:
-
- LINK = L4->L4TARGET.LINK;
-
- if (LINK == NULL)
- return;
-
- ConvFromAX25(LINK->OURCALL, Normcall);
- strlop(Normcall, ' ');
-
- ConvFromAX25(LINK->LINKCALL, Normcall2);
- strlop(Normcall2, ' ');
-
- sprintf(Buffer, "%s %d(%s %s)", "Downlink", LINK->LINKPORT->PORTNUMBER, Normcall, Normcall2);
- return;
-
- case BPQHOST + UPLINK:
- case BPQHOST + DOWNLINK:
-
- // if the call has a Level 4 address display ALIAS:CALL, else just Call
-
- if (FindDestination(L4->L4USER, &DEST))
- Normcall[DecodeNodeName(DEST->DEST_CALL, Normcall)] = 0; // null terminate
- else
- Normcall[ConvFromAX25(L4->L4USER, Normcall)] = 0;
-
- VEC = L4->L4TARGET.HOST;
- sprintf(Buffer, "%s%02d(%s)", "Host", (int)(VEC - BPQHOSTVECTOR) + 1, Normcall);
- return;
-
- case SESSION + DOWNLINK:
- case SESSION + UPLINK:
-
- ConvFromAX25(L4->L4USER, Normcall);
- strlop(Normcall, ' ');
-
- DEST = L4->L4TARGET.DEST;
-
- if (DEST == NULL)
- return;
-
- ConvFromAX25(DEST->DEST_CALL, Normcall2);
- strlop(Normcall2, ' ');
-
- memcpy(Alias, DEST->DEST_ALIAS, 6);
- strlop(Alias, ' ');
-
- sprintf(Buffer, "Circuit(%s:%s %s)", Alias, Normcall2, Normcall);
-
- return;
- }
-}
-
-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))
-{
- void ** buffptr;
-
- if (TNC->PortRecord->ATTACHEDSESSIONS[Stream] == 0)
- {
- // Node has disconnected - clear any connection
-
- if (STREAM->Disconnecting)
- {
- // Already detected the detach, and have started to close
-
- STREAM->DisconnectingTimeout--;
-
- if (STREAM->DisconnectingTimeout)
- return; // Give it a bit longer
-
- // Close has timed out - force a disc, and clear
-
- ForcedCloseProc(TNC, Stream); // Send Tidy Disconnect
-
- goto NotConnected;
- }
-
- // New Disconnect
-
- Debugprintf("New Disconnect Port %d Q %x", TNC->Port, STREAM->BPQtoPACTOR_Q);
-
- if (STREAM->Connected || STREAM->Connecting)
- {
-
- // Need to do a tidy close
-
- STREAM->Connecting = FALSE;
- STREAM->Disconnecting = TRUE;
- STREAM->DisconnectingTimeout = 300; // 30 Secs
-
- if (Stream == 0)
- SetWindowText(TNC->xIDC_TNCSTATE, "Disconnecting");
-
- // Create a traffic record
-
- hookL4SessionDeleted(TNC, STREAM);
-
- if (STREAM->BPQtoPACTOR_Q) // Still data to send?
- return; // Will close when all acked
-
-// if (STREAM->FramesOutstanding && TNC->Hardware == H_UZ7HO)
-// return; // Will close when all acked
-
- TidyCloseProc(TNC, Stream); // Send Tidy Disconnect
-
- return;
- }
-
- // Not connected
-NotConnected:
-
- STREAM->Disconnecting = FALSE;
- STREAM->Attached = FALSE;
- STREAM->Connecting = FALSE;
- STREAM->Connected = FALSE;
-
- if (Stream == 0)
- SetWindowText(TNC->xIDC_TNCSTATE, "Free");
-
- STREAM->FramesQueued = 0;
- STREAM->FramesOutstanding = 0;
-
- CloseComplete(TNC, Stream);
-
- if (TNC->DefaultRXFreq && TNC->RXRadio)
- {
- char Msg[128];
-
- sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->DefaultRXFreq);
- Rig_Command( (TRANSPORTENTRY *) -1, Msg);
- }
-
- if (TNC->DefaultTXFreq && TNC->TXRadio && TNC->TXRadio != TNC->RXRadio)
- {
- char Msg[128];
-
- sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->DefaultTXFreq);
- Rig_Command( (TRANSPORTENTRY *) -1, Msg);
- }
-
- while(STREAM->BPQtoPACTOR_Q)
- {
- buffptr=Q_REM(&STREAM->BPQtoPACTOR_Q);
- ReleaseBuffer(buffptr);
- }
-
- while(STREAM->PACTORtoBPQ_Q)
- {
- buffptr=Q_REM(&STREAM->PACTORtoBPQ_Q);
- ReleaseBuffer(buffptr);
- }
- }
-}
-
-char * CheckAppl(struct TNCINFO * TNC, char * Appl)
-{
- APPLCALLS * APPL;
- BPQVECSTRUC * PORTVEC;
- int Allocated = 0, Available = 0;
- int App, Stream;
- struct TNCINFO * APPLTNC;
-
-// Debugprintf("Checking if %s is running", Appl);
-
- for (App = 0; App < 32; App++)
- {
- APPL=&APPLCALLTABLE[App];
-
- if (_memicmp(APPL->APPLCMD, Appl, 12) == 0)
- {
- int _APPLMASK = 1 << App;
-
- // If App has an alias, assume it is running , unless a CMS alias - then check CMS
-
- if (APPL->APPLHASALIAS)
- {
- if (_memicmp(APPL->APPLCMD, "RELAY ", 6) == 0)
- return APPL->APPLCALL_TEXT; // Assume people using RELAY know what they are doing
-
- if (APPL->APPLPORT && (_memicmp(APPL->APPLCMD, "RMS ", 4) == 0))
- {
- APPLTNC = TNCInfo[APPL->APPLPORT];
- {
- if (APPLTNC)
- {
- if (APPLTNC->TCPInfo && !APPLTNC->TCPInfo->CMSOK && !APPLTNC->TCPInfo->FallbacktoRelay)
- return NULL;
- }
- }
- }
- return APPL->APPLCALL_TEXT;
- }
-
- // See if App is running
-
- PORTVEC = &BPQHOSTVECTOR[0];
-
- for (Stream = 0; Stream < 64; Stream++)
- {
- if (PORTVEC->HOSTAPPLMASK & _APPLMASK)
- {
- Allocated++;
-
- if (PORTVEC->HOSTSESSION == 0 && (PORTVEC->HOSTFLAGS & 3) == 0)
- {
- // Free and no outstanding report
-
- return APPL->APPLCALL_TEXT; // Running
- }
- }
- PORTVEC++;
- }
- }
- }
-
- return NULL; // Not Running
-}
-
-VOID SetApplPorts()
-{
- // If any appl has an alias, get port number
-
- struct APPLCONFIG * App;
- APPLCALLS * APPL;
-
- char C[80];
- char Port[80];
- char Call[80];
-
- int i, n;
-
- App = &xxcfg.C_APPL[0];
-
- for (i=0; i < NumberofAppls; i++)
- {
- APPL=&APPLCALLTABLE[i];
-
- if (APPL->APPLHASALIAS)
- {
- n = sscanf(App->CommandAlias, "%s %s %s", &C[0], &Port[0], &Call[0]);
- if (n == 3)
- APPL->APPLPORT = atoi(Port);
- }
- App++;
- }
-}
-
-
-char Modenames[19][10] = {"WINMOR", "SCS", "KAM", "AEA", "HAL", "TELNET", "TRK",
- "V4", "UZ7HO", "MPSK", "FLDIGI", "UIARQ", "ARDOP", "VARA",
- "SERIAL", "KISSHF", "WINRPR", "HSMODEM", "FREEDATA"};
-
-BOOL ProcessIncommingConnect(struct TNCINFO * TNC, char * Call, int Stream, BOOL SENDCTEXT)
-{
- return ProcessIncommingConnectEx(TNC, Call, Stream, SENDCTEXT, FALSE);
-}
-
-BOOL ProcessIncommingConnectEx(struct TNCINFO * TNC, char * Call, int Stream, BOOL SENDCTEXT, BOOL AllowTR)
-{
- TRANSPORTENTRY * Session;
- int Index = 0;
- PMSGWITHLEN buffptr;
- int Totallen = 0;
- UCHAR * ptr;
- struct PORTCONTROL * PORT = (struct PORTCONTROL *)TNC->PortRecord;
- struct STREAMINFO * STREAM = &TNC->Streams[Stream];
-
- // Stop Scanner
-
- if (Stream == 0 || TNC->Hardware == H_UZ7HO)
- {
- char Msg[80];
-
- sprintf(Msg, "%d SCANSTOP", TNC->Port);
-
- Rig_Command( (TRANSPORTENTRY *) -1, Msg);
-
- UpdateMH(TNC, Call, '+', 'I');
- }
-
- Session = L4TABLE;
-
- // Find a free Circuit Entry
-
- while (Index < MAXCIRCUITS)
- {
- if (Session->L4USER[0] == 0)
- break;
-
- Session++;
- Index++;
- }
-
- if (Index == MAXCIRCUITS)
- return FALSE; // Tables Full
-
- memset(Session, 0, sizeof(TRANSPORTENTRY));
-
- memcpy(STREAM->RemoteCall, Call, 9); // Save Text Callsign
-
- // May be subsequently rejected but a good place to capture calls
-
- hookL4SessionAccepted(STREAM, Call, TNC->TargetCall);
-
- if (AllowTR)
- ConvToAX25Ex(Call, Session->L4USER); // Allow -T and -R SSID's for MPS
- else
- ConvToAX25(Call, Session->L4USER);
- ConvToAX25(MYNODECALL, Session->L4MYCALL);
- Session->CIRCUITINDEX = Index;
- Session->CIRCUITID = NEXTID;
- NEXTID++;
- if (NEXTID == 0) NEXTID++; // Keep non-zero
-
- TNC->PortRecord->ATTACHEDSESSIONS[Stream] = Session;
- STREAM->Attached = TRUE;
-
- Session->L4TARGET.EXTPORT = TNC->PortRecord;
-
- Session->L4CIRCUITTYPE = UPLINK+PACTOR;
- Session->L4WINDOW = L4DEFAULTWINDOW;
- Session->L4STATE = 5;
- Session->SESSIONT1 = L4T1;
- Session->SESSPACLEN = TNC->PortRecord->PORTCONTROL.PORTPACLEN;
- Session->KAMSESSION = Stream;
-
- STREAM->Connected = TRUE; // Subsequent data to data channel
-
- if (LogAllConnects)
- {
- if (TNC->TargetCall[0])
- WriteConnectLog(Call, TNC->TargetCall, Modenames[TNC->Hardware - 1]);
- else
- WriteConnectLog(Call, MYNODECALL, Modenames[TNC->Hardware - 1]);
- }
-
- if (SENDCTEXT == 0)
- return TRUE;
-
- // if Port CTEXT defined, use it
-
- if (PORT->CTEXT)
- {
- Totallen = strlen(PORT->CTEXT);
- ptr = PORT->CTEXT;
- }
- else if (HFCTEXTLEN > 0)
- {
- Totallen = HFCTEXTLEN;
- ptr = HFCTEXT;
- }
- else
- return TRUE;
-
- while (Totallen > 0)
- {
- int sendLen = TNC->PortRecord->ATTACHEDSESSIONS[Stream]->SESSPACLEN;
-
- if (sendLen == 0)
- sendLen = 80;
-
- if (Totallen < sendLen)
- sendLen = Totallen;
-
- buffptr = (PMSGWITHLEN)GetBuff();
- if (buffptr == 0) return TRUE; // No buffers
-
- buffptr->Len = sendLen;
- memcpy(&buffptr->Data[0], ptr, sendLen);
- C_Q_ADD(&TNC->Streams[Stream].BPQtoPACTOR_Q, buffptr);
- Totallen -= sendLen;
- ptr += sendLen;
- }
- return TRUE;
-}
-
-char * Config;
-static char * ptr1, * ptr2;
-
-BOOL ReadConfigFile(int Port, int ProcLine(char * buf, int Port))
-{
- char buf[256],errbuf[256];
-
- if (TNCInfo[Port]) // If restarting, free old config
- free(TNCInfo[Port]);
-
- TNCInfo[Port] = NULL;
-
- Config = PortConfig[Port];
-
- if (Config)
- {
- // Using config from bpq32.cfg
-
- if (strlen(Config) == 0)
- {
- // Empty Config File - OK for most types
-
- struct TNCINFO * TNC = TNCInfo[Port] = zalloc(sizeof(struct TNCINFO));
-
- TNC->InitScript = malloc(2);
- TNC->InitScript[0] = 0;
-
- return TRUE;
- }
-
- ptr1 = Config;
-
- ptr2 = strchr(ptr1, 13);
- while(ptr2)
- {
- memcpy(buf, ptr1, ptr2 - ptr1 + 1);
- buf[ptr2 - ptr1 + 1] = 0;
- ptr1 = ptr2 + 2;
- ptr2 = strchr(ptr1, 13);
-
- strcpy(errbuf,buf); // save in case of error
-
- if (!ProcLine(buf, Port))
- {
- WritetoConsoleLocal("\n");
- WritetoConsoleLocal("Bad config record ");
- WritetoConsoleLocal(errbuf);
- }
- }
- }
- else
- {
- sprintf(buf," ** Error - No Configuration info in bpq32.cfg");
- WritetoConsoleLocal(buf);
- }
-
- return (TRUE);
-}
-int GetLine(char * buf)
-{
-loop:
-
- if (ptr2 == NULL)
- return 0;
-
- memcpy(buf, ptr1, ptr2 - ptr1 + 2);
- buf[ptr2 - ptr1 + 2] = 0;
- ptr1 = ptr2 + 2;
- ptr2 = strchr(ptr1, 13);
-
- if (buf[0] < 0x20) goto loop;
- if (buf[0] == '#') goto loop;
- if (buf[0] == ';') goto loop;
-
- if (buf[strlen(buf)-1] < 0x20) buf[strlen(buf)-1] = 0;
- if (buf[strlen(buf)-1] < 0x20) buf[strlen(buf)-1] = 0;
- buf[strlen(buf)] = 13;
-
- return 1;
-}
-VOID DigiToMultiplePorts(struct PORTCONTROL * PORTVEC, PMESSAGE Msg)
-{
- USHORT Mask=PORTVEC->DIGIMASK;
- int i;
-
- for (i=1; i<=NUMBEROFPORTS; i++)
- {
- if (Mask & 1)
- {
- // Block includes the Msg Header (7/11 bytes), Len Does not!
-
- Msg->PORT = i;
- Send_AX((UCHAR *)&Msg, Msg->LENGTH - MSGHDDRLEN, i);
- Mask>>=1;
- }
- }
-}
-
-int CompareAlias(struct DEST_LIST ** a, struct DEST_LIST ** b)
-{
- return memcmp(a[0]->DEST_ALIAS, b[0]->DEST_ALIAS, 6);
- /* strcmp functions works exactly as expected from comparison function */
-}
-
-
-int CompareNode(struct DEST_LIST ** a, struct DEST_LIST ** b)
-{
- return memcmp(a[0]->DEST_CALL, b[0]->DEST_CALL, 7);
-}
-
-DllExport int APIENTRY CountFramesQueuedOnStream(int Stream)
-{
- BPQVECSTRUC * PORTVEC = &BPQHOSTVECTOR[Stream-1]; // API counts from 1
- TRANSPORTENTRY * L4 = PORTVEC->HOSTSESSION;
-
- int Count = 0;
-
- if (L4)
- {
- if (L4->L4CROSSLINK) // CONNECTED?
- Count = CountFramesQueuedOnSession(L4->L4CROSSLINK);
- else
- Count = CountFramesQueuedOnSession(L4);
- }
- return Count;
-}
-
-DllExport int APIENTRY ChangeSessionCallsign(int Stream, unsigned char * AXCall)
-{
- // Equivalent to "*** linked to" command
-
- memcpy(BPQHOSTVECTOR[Stream-1].HOSTSESSION->L4USER, AXCall, 7);
- return (0);
-}
-
-DllExport int APIENTRY ChangeSessionPaclen(int Stream, int Paclen)
-{
- BPQHOSTVECTOR[Stream-1].HOSTSESSION->SESSPACLEN = Paclen;
- return (0);
-}
-
-DllExport int APIENTRY ChangeSessionIdletime(int Stream, int idletime)
-{
- if (BPQHOSTVECTOR[Stream-1].HOSTSESSION)
- BPQHOSTVECTOR[Stream-1].HOSTSESSION->L4LIMIT = idletime;
- return (0);
-}
-
-DllExport int APIENTRY Get_APPLMASK(int Stream)
-{
- return BPQHOSTVECTOR[Stream-1].HOSTAPPLMASK;
-}
-DllExport int APIENTRY GetStreamPID(int Stream)
-{
- return BPQHOSTVECTOR[Stream-1].STREAMOWNER;
-}
-
-DllExport int APIENTRY GetApplFlags(int Stream)
-{
- return BPQHOSTVECTOR[Stream-1].HOSTAPPLFLAGS;
-}
-
-DllExport int APIENTRY GetApplNum(int Stream)
-{
- return BPQHOSTVECTOR[Stream-1].HOSTAPPLNUM;
-}
-
-DllExport int APIENTRY GetApplMask(int Stream)
-{
- return BPQHOSTVECTOR[Stream-1].HOSTAPPLMASK;
-}
-
-DllExport BOOL APIENTRY GetAllocationState(int Stream)
-{
- return BPQHOSTVECTOR[Stream-1].HOSTFLAGS & 0x80;
-}
-
-VOID Send_AX_Datagram(PDIGIMESSAGE Block, DWORD Len, UCHAR Port);
-
-extern int InitDone;
-extern int SemHeldByAPI;
-extern char pgm[256]; // Uninitialised so per process
-extern int BPQHOSTAPI();
-
-
-VOID POSTSTATECHANGE(BPQVECSTRUC * SESS)
-{
- // Post a message if requested
-#ifndef LINBPQ
- if (SESS->HOSTHANDLE)
- PostMessage(SESS->HOSTHANDLE, BPQMsg, SESS->HOSTSTREAM, 4);
-#endif
- return;
-}
-
-
-DllExport int APIENTRY SessionControl(int stream, int command, int Mask)
-{
- BPQVECSTRUC * SESS;
- TRANSPORTENTRY * L4;
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return (0);
-
- SESS = &BPQHOSTVECTOR[stream];
-
- // Send Session Control command (BPQHOST function 6)
- //; CL=0 CONNECT USING APPL MASK IN DL
- //; CL=1, CONNECT. CL=2 - DISCONNECT. CL=3 RETURN TO NODE
-
- if (command > 1)
- {
- // Disconnect
-
- if (SESS->HOSTSESSION == 0)
- {
- SESS->HOSTFLAGS |= 1; // State Change
- POSTSTATECHANGE(SESS);
- return 0; // NOT CONNECTED
- }
-
- if (command == 3)
- SESS->HOSTFLAGS |= 0x20; // Set Stay
-
- SESS->HOSTFLAGS |= 0x40; // SET 'DISC REQ' FLAG
-
- return 0;
- }
-
- // 0 or 1 - connect
-
- if (SESS->HOSTSESSION) // ALREADY CONNECTED
- {
- SESS->HOSTFLAGS |= 1; // State Change
- POSTSTATECHANGE(SESS);
- return 0;
- }
-
- // SET UP A SESSION FOR THE CONSOLE
-
- SESS->HOSTFLAGS |= 0x80; // SET ALLOCATED BIT
-
- if (command == 1) // Zero is mask supplied by caller
- Mask = SESS->HOSTAPPLMASK; // SO WE GET CORRECT CALLSIGN
-
- L4 = SetupSessionFromHost(SESS, Mask);
-
- if (L4 == 0) // tables Full
- {
- SESS->HOSTFLAGS |= 3; // State Change
- POSTSTATECHANGE(SESS);
- return 0;
- }
-
- SESS->HOSTSESSION = L4;
- L4->L4CIRCUITTYPE = BPQHOST | UPLINK;
- L4->Secure_Session = AuthorisedProgram; // Secure Host Session
-
- SESS->HOSTFLAGS |= 1; // State Change
- POSTSTATECHANGE(SESS);
- return 0; // ALREADY CONNECTED
-}
-
-int FindFreeStreamEx(int GetSem);
-
-int FindFreeStreamNoSem()
-{
- return FindFreeStreamEx(0);
-}
-
-DllExport int APIENTRY FindFreeStream()
-{
- return FindFreeStreamEx(1);
-}
-
-int FindFreeStreamEx(int GetSem)
-{
- int stream, n;
- BPQVECSTRUC * PORTVEC;
-
-// Returns number of first unused BPQHOST stream. If none available,
-// returns 255. See API function 13.
-
- // if init has not yet been run, wait.
-
- while (InitDone == 0)
- {
- Debugprintf("Waiting for init to complete");
- Sleep(1000);
- }
-
- if (InitDone == -1) // Init failed
- exit(0);
-
- if (GetSem)
- GetSemaphore(&Semaphore, 9);
-
- stream = 0;
- n = 64;
-
- while (n--)
- {
- PORTVEC = &BPQHOSTVECTOR[stream++];
- if ((PORTVEC->HOSTFLAGS & 0x80) == 0)
- {
- PORTVEC->STREAMOWNER=GetCurrentProcessId();
- PORTVEC->HOSTFLAGS = 128; // SET ALLOCATED BIT, clear others
- memcpy(&PORTVEC->PgmName[0], pgm, 31);
- if (GetSem)
- FreeSemaphore(&Semaphore);
- return stream;
- }
- }
-
- if (GetSem)
- FreeSemaphore(&Semaphore);
-
- return 255;
-}
-
-DllExport int APIENTRY AllocateStream(int stream)
-{
-// Allocate stream. If stream is already allocated, return nonzero.
-// Otherwise allocate stream, and return zero.
-
- BPQVECSTRUC * PORTVEC = &BPQHOSTVECTOR[stream -1]; // API counts from 1
-
- if ((PORTVEC->HOSTFLAGS & 0x80) == 0)
- {
- PORTVEC->STREAMOWNER=GetCurrentProcessId();
- PORTVEC->HOSTFLAGS = 128; // SET ALLOCATED BIT, clear others
- memcpy(&PORTVEC->PgmName[0], pgm, 31);
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- return 1; // Already allocated
-}
-
-
-DllExport int APIENTRY DeallocateStream(int stream)
-{
- BPQVECSTRUC * PORTVEC;
- UINT * monbuff;
- BOOL GotSem = Semaphore.Flag;
-
-// Release stream.
-
- stream--;
-
- if (stream < 0 || stream > 63)
- return (0);
-
- PORTVEC=&BPQHOSTVECTOR[stream];
-
- PORTVEC->STREAMOWNER=0;
- PORTVEC->PgmName[0] = 0;
- PORTVEC->HOSTAPPLFLAGS=0;
- PORTVEC->HOSTAPPLMASK=0;
- PORTVEC->HOSTHANDLE=0;
-
- // Clear Trace Queue
-
- if (PORTVEC->HOSTSESSION)
- SessionControl(stream + 1, 2, 0);
-
- if (GotSem == 0)
- GetSemaphore(&Semaphore, 0);
-
- while (PORTVEC->HOSTTRACEQ)
- {
- monbuff = Q_REM((void *)&PORTVEC->HOSTTRACEQ);
- ReleaseBuffer(monbuff);
- }
-
- if (GotSem == 0)
- FreeSemaphore(&Semaphore);
-
- PORTVEC->HOSTFLAGS &= 0x60; // Clear Allocated. Must leave any DISC Pending bits
-
- return(0);
-}
-DllExport int APIENTRY SessionState(int stream, int * state, int * change)
-{
- // Get current Session State. Any state changed is ACK'ed
- // automatically. See BPQHOST functions 4 and 5.
-
- BPQVECSTRUC * HOST = &BPQHOSTVECTOR[stream -1]; // API counts from 1
-
- Check_Timer(); // In case Appl doesnt call it often ehough
-
- GetSemaphore(&Semaphore, 20);
-
- // CX = 0 if stream disconnected or CX = 1 if stream connected
- // DX = 0 if no change of state since last read, or DX = 1 if
- // the connected/disconnected state has changed since
- // last read (ie. delta-stream status).
-
- // HOSTFLAGS = Bit 80 = Allocated
- // Bit 40 = Disc Request
- // Bit 20 = Stay Flag
- // Bit 02 and 01 State Change Bits
-
- if ((HOST->HOSTFLAGS & 3) == 0)
- // No Chaange
- *change = 0;
- else
- *change = 1;
-
- if (HOST->HOSTSESSION) // LOCAL SESSION
- // Connected
- *state = 1;
- else
- *state = 0;
-
- HOST->HOSTFLAGS &= 0xFC; // Clear Change Bitd
-
- FreeSemaphore(&Semaphore);
- return 0;
-}
-
-DllExport int APIENTRY SessionStateNoAck(int stream, int * state)
-{
- // Get current Session State. Dont ACK any change
- // See BPQHOST function 4
-
- BPQVECSTRUC * HOST = &BPQHOSTVECTOR[stream -1]; // API counts from 1
-
- Check_Timer(); // In case Appl doesnt call it often ehough
-
- if (HOST->HOSTSESSION) // LOCAL SESSION
- // Connected
- *state = 1;
- else
- *state = 0;
-
- return 0;
-}
-
-
-int SendMsgEx(int stream, char * msg, int len, int GetSem);
-
-int SendMsgNoSem(int stream, char * msg, int len)
-{
- return SendMsgEx(stream, msg, len, 0);
-}
-
-DllExport int APIENTRY SendMsg(int stream, char * msg, int len)
-{
- return SendMsgEx(stream, msg, len, 1);
-}
-
-
-int SendMsgEx(int stream, char * msg, int len, int GetSem)
-{
- // Send message to stream (BPQHOST Function 2)
-
- BPQVECSTRUC * SESS;
- TRANSPORTENTRY * L4;
- TRANSPORTENTRY * Partner;
- PDATAMESSAGE MSG;
-
- Check_Timer();
-
- if (len > 256)
- return 0; // IGNORE
-
- if (stream == 0)
- {
- // Send UNPROTO - SEND FRAME TO ALL RADIO PORTS
-
- // COPY DATA TO A BUFFER IN OUR SEGMENTS - SIMPLFIES THINGS LATER
-
- if (QCOUNT < 50)
- return 0; // Dont want to run out
-
- if (GetSem)
- GetSemaphore(&Semaphore, 10);
-
- if ((MSG = GetBuff()) == 0)
- {
- if (GetSem)
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- MSG->PID = 0xF0; // Normal Data PID
-
- memcpy(&MSG->L2DATA[0], msg, len);
- MSG->LENGTH = (len + MSGHDDRLEN + 1);
-
- SENDUIMESSAGE(MSG);
- ReleaseBuffer(MSG);
- if (GetSem)
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
- SESS = &BPQHOSTVECTOR[stream];
- L4 = SESS->HOSTSESSION;
-
- if (L4 == 0)
- return 0;
-
- if (GetSem)
- GetSemaphore(&Semaphore, 22);
-
- SESS->HOSTFLAGS |= 0x80; // SET ALLOCATED BIT
-
- if (QCOUNT < 40) // PLENTY FREE?
- {
- if (GetSem)
- FreeSemaphore(&Semaphore);
- return 1;
- }
-
- // Dont allow massive queues to form
-
- if (QCOUNT < 100)
- {
- int n = CountFramesQueuedOnStream(stream + 1);
-
- if (n > 100)
- {
- Debugprintf("Stream %d QCOUNT %d Q Len %d - discarding", stream, QCOUNT, n);
- if (GetSem)
- FreeSemaphore(&Semaphore);
- return 1;
- }
- }
-
- if ((MSG = GetBuff()) == 0)
- {
- if (GetSem)
- FreeSemaphore(&Semaphore);
- return 1;
- }
-
- MSG->PID = 0xF0; // Normal Data PID
-
- memcpy(&MSG->L2DATA[0], msg, len);
- MSG->LENGTH = len + MSGHDDRLEN + 1;
-
- // IF CONNECTED, PASS MESSAGE TO TARGET CIRCUIT - FLOW CONTROL AND
- // DELAYED DISC ONLY WORK ON ONE SIDE
-
- Partner = L4->L4CROSSLINK;
-
- L4->L4KILLTIMER = 0; // RESET SESSION TIMEOUT
-
- if (Partner && Partner->L4STATE > 4) // Partner and link up
- {
- // Connected
-
- Partner->L4KILLTIMER = 0; // RESET SESSION TIMEOUT
- C_Q_ADD(&Partner->L4TX_Q, MSG);
- PostDataAvailable(Partner);
- }
- else
- C_Q_ADD(&L4->L4RX_Q, MSG);
-
- if (GetSem)
- FreeSemaphore(&Semaphore);
- return 0;
-}
-DllExport int APIENTRY SendRaw(int port, char * msg, int len)
-{
- struct PORTCONTROL * PORT;
- MESSAGE * MSG;
-
- Check_Timer();
-
- // Send Raw (KISS mode) frame to port (BPQHOST function 10)
-
- if (len > (MAXDATA - (MSGHDDRLEN + 8)))
- return 0;
-
- if (QCOUNT < 50)
- return 1;
-
- // GET A BUFFER
-
- PORT = GetPortTableEntryFromSlot(port);
-
- if (PORT == 0)
- return 0;
-
- GetSemaphore(&Semaphore, 24);
-
- MSG = GetBuff();
-
- if (MSG == 0)
- {
- FreeSemaphore(&Semaphore);
- return 1;
- }
-
- memcpy(MSG->DEST, msg, len);
-
- MSG->LENGTH = len + MSGHDDRLEN;
-
- if (PORT->PROTOCOL == 10 && PORT->TNC && PORT->TNC->Hardware != H_KISSHF) // PACTOR/WINMOR Style
- {
- // Pactor Style. Probably will only be used for Tracker unless we do APRS over V4 or WINMOR
-
- EXTPORTDATA * EXTPORT = (EXTPORTDATA *) PORT;
-
- C_Q_ADD(&EXTPORT->UI_Q, MSG);
-
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- MSG->PORT = PORT->PORTNUMBER;
-
- PUT_ON_PORT_Q(PORT, MSG);
-
- FreeSemaphore(&Semaphore);
- return 0;
-}
-
-DllExport time_t APIENTRY GetRaw(int stream, char * msg, int * len, int * count)
-{
- time_t Stamp;
- BPQVECSTRUC * SESS;
- PMESSAGE MSG;
- int Msglen;
-
- Check_Timer();
-
- *len = 0;
- *count = 0;
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
- SESS = &BPQHOSTVECTOR[stream];
-
- GetSemaphore(&Semaphore, 26);
-
- if (SESS->HOSTTRACEQ == 0)
- {
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- MSG = Q_REM((void *)&SESS->HOSTTRACEQ);
-
- Msglen = MSG->LENGTH;
-
- if (Msglen < 0 || Msglen > 350)
- {
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- Stamp = MSG->Timestamp;
-
- memcpy(msg, MSG, BUFFLEN - sizeof(void *)); // To c
-
- *len = Msglen;
-
- ReleaseBuffer(MSG);
-
- *count = C_Q_COUNT(&SESS->HOSTTRACEQ);
- FreeSemaphore(&Semaphore);
-
- return Stamp;
-}
-
-DllExport int APIENTRY GetMsg(int stream, char * msg, int * len, int * count )
-{
-// Get message from stream. Returns length, and count of frames
-// still waiting to be collected. (BPQHOST function 3)
-// AH = 3 Receive frame into buffer at ES:DI, length of frame returned
-// in CX. BX returns the number of outstanding frames still to
-// be received (ie. after this one) or zero if no more frames
-// (ie. this is last one).
-//
-
- BPQVECSTRUC * SESS;
- TRANSPORTENTRY * L4;
- PDATAMESSAGE MSG;
- int Msglen;
-
- Check_Timer();
-
- *len = 0;
- *count = 0;
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
-
- SESS = &BPQHOSTVECTOR[stream];
- L4 = SESS->HOSTSESSION;
-
- GetSemaphore(&Semaphore, 25);
-
- if (L4 == 0 || L4->L4TX_Q == 0)
- {
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- L4->L4KILLTIMER = 0; // RESET SESSION TIMEOUT
-
- if(L4->L4CROSSLINK)
- L4->L4CROSSLINK->L4KILLTIMER = 0;
-
- MSG = Q_REM((void *)&L4->L4TX_Q);
-
- Msglen = MSG->LENGTH - (MSGHDDRLEN + 1); // Dont want PID
-
- if (Msglen < 0)
- {
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- if (Msglen > 256)
- Msglen = 256;
-
- memcpy(msg, &MSG->L2DATA[0], Msglen);
-
- *len = Msglen;
-
- ReleaseBuffer(MSG);
-
- *count = C_Q_COUNT(&L4->L4TX_Q);
- FreeSemaphore(&Semaphore);
-
- return 0;
-}
-
-
-DllExport int APIENTRY RXCount(int stream)
-{
-// Returns count of packets waiting on stream
-// (BPQHOST function 7 (part)).
-
- BPQVECSTRUC * SESS;
- TRANSPORTENTRY * L4;
-
- Check_Timer();
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
- SESS = &BPQHOSTVECTOR[stream];
- L4 = SESS->HOSTSESSION;
-
- if (L4 == 0)
- return 0; // NOT CONNECTED
-
- return C_Q_COUNT(&L4->L4TX_Q);
-}
-
-DllExport int APIENTRY TXCount(int stream)
-{
-// Returns number of packets on TX queue for stream
-// (BPQHOST function 7 (part)).
-
- BPQVECSTRUC * SESS;
- TRANSPORTENTRY * L4;
-
- Check_Timer();
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
- SESS = &BPQHOSTVECTOR[stream];
- L4 = SESS->HOSTSESSION;
-
- if (L4 == 0)
- return 0; // NOT CONNECTED
-
- L4 = L4->L4CROSSLINK;
-
- if (L4 == 0)
- return 0; // NOTHING ro Q on
-
- return (CountFramesQueuedOnSession(L4));
-}
-
-DllExport int APIENTRY MONCount(int stream)
-{
-// Returns number of monitor frames available
-// (BPQHOST function 7 (part)).
-
- BPQVECSTRUC * SESS;
-
- Check_Timer();
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
- SESS = &BPQHOSTVECTOR[stream];
-
- return C_Q_COUNT(&SESS->HOSTTRACEQ);
-}
-
-
-DllExport int APIENTRY GetCallsign(int stream, char * callsign)
-{
- // Returns call connected on stream (BPQHOST function 8 (part)).
-
- BPQVECSTRUC * SESS;
- TRANSPORTENTRY * L4;
- TRANSPORTENTRY * Partner;
- UCHAR Call[11] = "SWITCH ";
- UCHAR * AXCall = NULL;
- Check_Timer();
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
- SESS = &BPQHOSTVECTOR[stream];
- L4 = SESS->HOSTSESSION;
-
- GetSemaphore(&Semaphore, 26);
-
- if (L4 == 0)
- {
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- Partner = L4->L4CROSSLINK;
-
- if (Partner)
- {
- // CONNECTED OUT - GET TARGET SESSION
-
- if (Partner->L4CIRCUITTYPE & BPQHOST)
- {
- AXCall = &Partner->L4USER[0];
- }
- else if (Partner->L4CIRCUITTYPE & L2LINK)
- {
- struct _LINKTABLE * LINK = Partner->L4TARGET.LINK;
-
- if (LINK)
- AXCall = LINK->LINKCALL;
-
- if (Partner->L4CIRCUITTYPE & UPLINK)
- {
- // IF UPLINK, SHOULD USE SESSION CALL, IN CASE *** LINKED HAS BEEN USED
-
- AXCall = &Partner->L4USER[0];
- }
- }
- else if (Partner->L4CIRCUITTYPE & PACTOR)
- {
- // PACTOR Type - Frames are queued on the Port Entry
-
- EXTPORTDATA * EXTPORT = Partner->L4TARGET.EXTPORT;
-
- if (EXTPORT)
- AXCall = &EXTPORT->ATTACHEDSESSIONS[Partner->KAMSESSION]->L4USER[0];
-
- }
- else
- {
- // MUST BE NODE SESSION
-
- // ANOTHER NODE
-
- // IF THE HOST IS THE UPLINKING STATION, WE NEED THE TARGET CALL
-
- if (L4->L4CIRCUITTYPE & UPLINK)
- {
- struct DEST_LIST *DEST = Partner->L4TARGET.DEST;
-
- if (DEST)
- AXCall = &DEST->DEST_CALL[0];
- }
- else
- AXCall = Partner->L4USER;
- }
- if (AXCall)
- ConvFromAX25(AXCall, Call);
- }
-
- memcpy(callsign, Call, 10);
-
- FreeSemaphore(&Semaphore);
- return 0;
-}
-
-DllExport int APIENTRY GetConnectionInfo(int stream, char * callsign,
- int * port, int * sesstype, int * paclen,
- int * maxframe, int * l4window)
-{
- // Return the Secure Session Flag rather than not connected
-
- BPQVECSTRUC * SESS;
- TRANSPORTENTRY * L4;
- TRANSPORTENTRY * Partner;
- UCHAR Call[11] = "SWITCH ";
- UCHAR * AXCall;
- Check_Timer();
-
- stream--; // API uses 1 - 64
-
- if (stream < 0 || stream > 63)
- return 0;
-
- SESS = &BPQHOSTVECTOR[stream];
- L4 = SESS->HOSTSESSION;
-
- GetSemaphore(&Semaphore, 27);
-
- if (L4 == 0)
- {
- FreeSemaphore(&Semaphore);
- return 0;
- }
-
- Partner = L4->L4CROSSLINK;
-
- // Return the Secure Session Flag rather than not connected
-
- // AL = Radio port on which channel is connected (or zero)
- // AH = SESSION TYPE BITS
- // EBX = L2 paclen for the radio port
- // ECX = L2 maxframe for the radio port
- // EDX = L4 window size (if L4 circuit, or zero) or -1 if not connected
- // ES:DI = CALLSIGN
-
- *port = 0;
- *sesstype = 0;
- *paclen = 0;
- *maxframe = 0;
- *l4window = 0;
- if (L4->SESSPACLEN)
- *paclen = L4->SESSPACLEN;
- else
- *paclen = 256;
-
- if (Partner)
- {
- // CONNECTED OUT - GET TARGET SESSION
-
- *l4window = Partner->L4WINDOW;
- *sesstype = Partner->L4CIRCUITTYPE;
-
- if (Partner->L4CIRCUITTYPE & BPQHOST)
- {
- AXCall = &Partner->L4USER[0];
- }
- else if (Partner->L4CIRCUITTYPE & L2LINK)
- {
- struct _LINKTABLE * LINK = Partner->L4TARGET.LINK;
-
- // EXTRACT PORT AND MAXFRAME
-
- *port = LINK->LINKPORT->PORTNUMBER;
- *maxframe = LINK->LINKWINDOW;
- *l4window = 0;
-
- AXCall = LINK->LINKCALL;
-
- if (Partner->L4CIRCUITTYPE & UPLINK)
- {
- // IF UPLINK, SHOULD USE SESSION CALL, IN CASE *** LINKED HAS BEEN USED
-
- AXCall = &Partner->L4USER[0];
- }
- }
- else if (Partner->L4CIRCUITTYPE & PACTOR)
- {
- // PACTOR Type - Frames are queued on the Port Entry
-
- EXTPORTDATA * EXTPORT = Partner->L4TARGET.EXTPORT;
-
- *port = EXTPORT->PORTCONTROL.PORTNUMBER;
- AXCall = &EXTPORT->ATTACHEDSESSIONS[Partner->KAMSESSION]->L4USER[0];
-
- }
- else
- {
- // MUST BE NODE SESSION
-
- // ANOTHER NODE
-
- // IF THE HOST IS THE UPLINKING STATION, WE NEED THE TARGET CALL
-
- if (L4->L4CIRCUITTYPE & UPLINK)
- {
- struct DEST_LIST *DEST = Partner->L4TARGET.DEST;
-
- AXCall = &DEST->DEST_CALL[0];
- }
- else
- AXCall = Partner->L4USER;
- }
- ConvFromAX25(AXCall, Call);
- }
-
- memcpy(callsign, Call, 10);
-
- FreeSemaphore(&Semaphore);
-
- if (Partner)
- return Partner->Secure_Session;
-
- return 0;
-}
-
-
-DllExport int APIENTRY SetAppl(int stream, int flags, int mask)
-{
-// Sets Application Flags and Mask for stream. (BPQHOST function 1)
-// AH = 1 Set application mask to value in EDX (or even DX if 16
-// applications are ever to be supported).
-//
-// Set application flag(s) to value in CL (or CX).
-// whether user gets connected/disconnected messages issued
-// by the node etc.
-
-
- BPQVECSTRUC * PORTVEC;
- stream--;
-
- if (stream < 0 || stream > 63)
- return (0);
-
- PORTVEC=&BPQHOSTVECTOR[stream];
-
- PORTVEC->HOSTAPPLFLAGS = flags;
- PORTVEC->HOSTAPPLMASK = mask;
-
- // If either is non-zero, set allocated and Process. This gets round problem with
- // stations that don't call allocate stream
-
- if (flags || mask)
- {
- if ((PORTVEC->HOSTFLAGS & 128) == 0) // Not allocated
- {
- PORTVEC->STREAMOWNER=GetCurrentProcessId();
- memcpy(&PORTVEC->PgmName[0], pgm, 31);
- PORTVEC->HOSTFLAGS = 128; // SET ALLOCATED BIT, clear others
- }
- }
-
- return (0);
-}
-
-DllExport struct PORTCONTROL * APIENTRY GetPortTableEntry(int portslot) // Kept for Legacy apps
-{
- struct PORTCONTROL * PORTVEC=PORTTABLE;
-
- if (portslot>NUMBEROFPORTS)
- portslot=NUMBEROFPORTS;
-
- while (--portslot > 0)
- PORTVEC=PORTVEC->PORTPOINTER;
-
- return PORTVEC;
-}
-
-// Proc below renamed to avoid confusion with GetPortTableEntryFromPortNum
-
-DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot)
-{
- struct PORTCONTROL * PORTVEC=PORTTABLE;
-
- if (portslot>NUMBEROFPORTS)
- portslot=NUMBEROFPORTS;
-
- while (--portslot > 0)
- PORTVEC=PORTVEC->PORTPOINTER;
-
- return PORTVEC;
-}
-
-int CanPortDigi(int Port)
-{
- struct PORTCONTROL * PORTVEC = GetPortTableEntryFromPortNum(Port);
- struct TNCINFO * TNC;
-
- if (PORTVEC == NULL)
- return FALSE;
-
- TNC = PORTVEC->TNC;
-
- if (TNC == NULL)
- return TRUE;
-
- if (TNC->Hardware == H_SCS || TNC->Hardware == H_TRK || TNC->Hardware == H_TRKM || TNC->Hardware == H_WINRPR)
- return FALSE;
-
- return TRUE;
-}
-
-struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum)
-{
- struct PORTCONTROL * PORTVEC = PORTTABLE;
-
- do
- {
- if (PORTVEC->PORTNUMBER == portnum)
- return PORTVEC;
-
- PORTVEC=PORTVEC->PORTPOINTER;
- }
- while (PORTVEC);
-
- return NULL;
-}
-
-DllExport UCHAR * APIENTRY GetPortDescription(int portslot, char * Desc)
-{
- struct PORTCONTROL * PORTVEC=PORTTABLE;
-
- if (portslot>NUMBEROFPORTS)
- portslot=NUMBEROFPORTS;
-
- while (--portslot > 0)
- PORTVEC=PORTVEC->PORTPOINTER;
-
- memcpy(Desc, PORTVEC->PORTDESCRIPTION, 30);
- Desc[30]=0;
-
- return 0;
-}
-
-// Standard serial port handling routines, used by lots of modules.
-
-int OpenCOMMPort(struct TNCINFO * conn, char * Port, int Speed, BOOL Quiet)
-{
- if (conn->WEB_COMMSSTATE == NULL)
- conn->WEB_COMMSSTATE = zalloc(100);
-
- if (Port == NULL)
- return (FALSE);
-
- conn->hDevice = OpenCOMPort(Port, Speed, TRUE, TRUE, Quiet, 0);
-
- if (conn->hDevice == 0)
- {
- sprintf(conn->WEB_COMMSSTATE,"%s Open failed - Error %d", Port, GetLastError());
- if (conn->xIDC_COMMSSTATE)
- SetWindowText(conn->xIDC_COMMSSTATE, conn->WEB_COMMSSTATE);
-
- return (FALSE);
- }
-
- sprintf(conn->WEB_COMMSSTATE,"%s Open", Port);
-
- if (conn->xIDC_COMMSSTATE)
- SetWindowText(conn->xIDC_COMMSSTATE, conn->WEB_COMMSSTATE);
-
- return TRUE;
-}
-
-
-
-#ifdef WIN32
-
-HANDLE OpenCOMPort(char * pPort, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet, int Stopbits)
-{
- char szPort[256];
- BOOL fRetVal ;
- COMMTIMEOUTS CommTimeOuts ;
- int Err;
- char buf[100];
- HANDLE fd;
- DCB dcb;
-
- // if Port Name starts COM, convert to \\.\COM or ports above 10 wont work
-
- if (_memicmp(pPort, "COM", 3) == 0)
- {
- char * pp = (char *)pPort;
- int p = atoi(&pp[3]);
- sprintf( szPort, "\\\\.\\COM%d", p);
- }
- else
- strcpy(szPort, pPort);
-
- // open COMM device
-
- fd = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
- 0, // exclusive access
- NULL, // no security attrs
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL );
-
- if (fd == (HANDLE) -1)
- {
- if (Quiet == 0)
- {
- Debugprintf("%s could not be opened %d", pPort, GetLastError());
- }
- return (FALSE);
- }
-
- Err = GetFileType(fd);
-
- // 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 = 0xFFFFFFFF ;
- 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());
-
- WritetoConsoleLocal(buf);
- OutputDebugString(buf);
- CloseHandle(fd);
- return 0;
- }
-
- return fd;
-
-}
-
-int ReadCOMBlockEx(HANDLE fd, char * Block, int MaxLength, BOOL * Error);
-
-int ReadCOMBlock(HANDLE fd, char * Block, int MaxLength)
-{
- BOOL Error;
- return ReadCOMBlockEx(fd, Block, MaxLength, &Error);
-}
-
-// version to pass read error back to caller
-
-int ReadCOMBlockEx(HANDLE fd, char * Block, int MaxLength, BOOL * Error)
-{
- BOOL fReadStat ;
- COMSTAT ComStat ;
- DWORD dwErrorFlags;
- DWORD dwLength;
- BOOL ret;
-
- if (fd == NULL)
- return 0;
-
- // only try to read number of bytes in queue
-
- ret = ClearCommError(fd, &dwErrorFlags, &ComStat);
-
- if (ret == 0)
- {
- int Err = GetLastError();
- *Error = TRUE;
- 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 ) ;
- }
- }
-
- *Error = FALSE;
-
- return dwLength;
-}
-
-
-BOOL WriteCOMBlock(HANDLE fd, char * Block, int BytesToWrite)
-{
- BOOL fWriteStat;
- DWORD BytesWritten;
- DWORD ErrorFlags;
- COMSTAT ComStat;
- DWORD Mask = 0;
- int Err;
-
- Err = GetCommModemStatus(fd, &Mask);
-
-// if ((Mask & MS_CTS_ON) == 0) // trap com0com other end not open
-// return TRUE;
-
- fWriteStat = WriteFile(fd, Block, BytesToWrite,
- &BytesWritten, NULL );
-
- if ((!fWriteStat) || (BytesToWrite != BytesWritten))
- {
- int Err = GetLastError();
- ClearCommError(fd, &ErrorFlags, &ComStat);
- return FALSE;
- }
- return TRUE;
-}
-
-VOID CloseCOMPort(HANDLE fd)
-{
- if (fd == NULL)
- return;
-
- 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);
- fd = NULL;
-}
-
-
-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);
-}
-
-
-#else
-
-static struct speed_struct
-{
- int user_speed;
- speed_t termios_speed;
-} speed_table[] = {
- {300, B300},
- {600, B600},
- {1200, B1200},
- {2400, B2400},
- {4800, B4800},
- {9600, B9600},
- {19200, B19200},
- {38400, B38400},
- {57600, B57600},
- {115200, B115200},
- {-1, B0}
-};
-
-
-HANDLE OpenCOMPort(VOID * pPort, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet, int Stopbits)
-{
- char Port[256];
- char buf[512];
-
- // Linux Version.
-
- int fd;
- int hwflag = 0;
- u_long param=1;
- struct termios term;
- struct speed_struct *s;
-
- if ((uintptr_t)pPort < 256)
- sprintf(Port, "%s/com%d", BPQDirectory, (int)(uintptr_t)pPort);
- else
- strcpy(Port, pPort);
-
- if ((fd = open(Port, O_RDWR | O_NDELAY)) == -1)
- {
- if (Quiet == 0)
- {
- perror("Com Open Failed");
- sprintf(buf," %s could not be opened \n", Port);
- WritetoConsoleLocal(buf);
- Debugprintf(buf);
- }
- return 0;
- }
-
- // Validate Speed Param
-
- for (s = speed_table; s->user_speed != -1; s++)
- if (s->user_speed == speed)
- break;
-
- if (s->user_speed == -1)
- {
- fprintf(stderr, "tty_speed: invalid speed %d\n", speed);
- return FALSE;
- }
-
- if (tcgetattr(fd, &term) == -1)
- {
- perror("tty_speed: tcgetattr");
- return FALSE;
- }
-
- cfmakeraw(&term);
- cfsetispeed(&term, s->termios_speed);
- cfsetospeed(&term, s->termios_speed);
-
- if (tcsetattr(fd, TCSANOW, &term) == -1)
- {
- perror("tty_speed: tcsetattr");
- return FALSE;
- }
-
- ioctl(fd, FIONBIO, ¶m);
-
- Debugprintf("LinBPQ Port %s fd %d", Port, fd);
-
- if (SetDTR)
- {
- COMSetDTR(fd);
- }
- else
- {
- COMClearDTR(fd);
- }
-
- if (SetRTS)
- {
- COMSetRTS(fd);
- }
- else
- {
- COMClearRTS(fd);
- }
- return fd;
-}
-
-int ReadCOMBlockEx(HANDLE fd, char * Block, int MaxLength, BOOL * Error);
-
-int ReadCOMBlock(HANDLE fd, char * Block, int MaxLength)
-{
- BOOL Error;
- return ReadCOMBlockEx(fd, Block, MaxLength, &Error);
-}
-
-// version to pass read error back to caller
-
-int ReadCOMBlockEx(HANDLE fd, char * Block, int MaxLength, BOOL * Error)
-{
- int Length;
-
- if (fd == 0)
- {
- *Error = 1;
- return 0;
- }
-
- errno = 22222; // to catch zero read (?? file closed ??)
-
- Length = read(fd, Block, MaxLength);
-
- *Error = 0;
-
- if (Length == 0 && errno == 22222) // seems to be result of unpluging USB
- {
-// printf("KISS read returned zero len and no errno\n");
- *Error = 1;
- return 0;
- }
-
- if (Length < 0)
- {
- if (errno != 11 && errno != 35) // Would Block
- {
- perror("read");
- printf("Handle %d Errno %d Len %d\n", fd, errno, Length);
- *Error = errno;
- }
- return 0;
- }
-
- return Length;
-}
-
-BOOL WriteCOMBlock(HANDLE fd, char * Block, int BytesToWrite)
-{
- // Some systems seem to have a very small max write size
-
- int ToSend = BytesToWrite;
- int Sent = 0, ret;
- int loops = 100;
-
- while (ToSend && loops-- > 0)
- {
- ret = write(fd, &Block[Sent], ToSend);
-
- if (ret >= ToSend)
- return TRUE;
-
- if (ret == -1)
- {
- if (errno != 11 && errno != 35) // Would Block
- return FALSE;
-
- usleep(10000);
- ret = 0;
- }
-
- Sent += ret;
- ToSend -= ret;
- }
-
-// if (ToSend)
-// {
-// // Send timed out. Close and reopen device
-//
-// }
- return TRUE;
-}
-
-VOID CloseCOMPort(HANDLE fd)
-{
- if (fd == 0)
- return;
-
- close(fd);
- fd = 0;
-}
-
-VOID COMSetDTR(HANDLE fd)
-{
- int status;
-
- ioctl(fd, TIOCMGET, &status);
- status |= TIOCM_DTR;
- ioctl(fd, TIOCMSET, &status);
-}
-
-VOID COMClearDTR(HANDLE fd)
-{
- int status;
-
- ioctl(fd, TIOCMGET, &status);
- status &= ~TIOCM_DTR;
- ioctl(fd, TIOCMSET, &status);
-}
-
-VOID COMSetRTS(HANDLE fd)
-{
- int status;
-
- ioctl(fd, TIOCMGET, &status);
- status |= TIOCM_RTS;
- ioctl(fd, TIOCMSET, &status);
-}
-
-VOID COMClearRTS(HANDLE fd)
-{
- int status;
-
- ioctl(fd, TIOCMGET, &status);
- status &= ~TIOCM_RTS;
- ioctl(fd, TIOCMSET, &status);
-}
-
-#endif
-
-
-int MaxNodes;
-int MaxRoutes;
-int NodeLen;
-int RouteLen;
-struct DEST_LIST * Dests;
-struct ROUTE * Routes;
-
-FILE *file;
-
-int DoRoutes()
-{
- char digis[30] = "";
- int count, len;
- char Normcall[10], Portcall[10];
- char line[80];
-
- for (count=0; countNEIGHBOUR_CALL[0] != 0)
- {
- len=ConvFromAX25(Routes->NEIGHBOUR_CALL,Normcall);
- Normcall[len]=0;
-
- if (Routes->NEIGHBOUR_DIGI1[0] != 0)
- {
- memcpy(digis," VIA ",5);
-
- len=ConvFromAX25(Routes->NEIGHBOUR_DIGI1,Portcall);
- Portcall[len]=0;
- strcpy(&digis[5],Portcall);
-
- if (Routes->NEIGHBOUR_DIGI2[0] != 0)
- {
- len=ConvFromAX25(Routes->NEIGHBOUR_DIGI2,Portcall);
- Portcall[len]=0;
- strcat(digis," ");
- strcat(digis,Portcall);
- }
- }
- else
- digis[0] = 0;
-
- len=sprintf(line,
- "ROUTE ADD %s %d %d %s %d %d %d %d %d\n",
- Normcall,
- Routes->NEIGHBOUR_PORT,
- Routes->NEIGHBOUR_QUAL, digis,
- Routes->NBOUR_MAXFRAME,
- Routes->NBOUR_FRACK,
- Routes->NBOUR_PACLEN,
- Routes->INP3Node | (Routes->NoKeepAlive << 2),
- Routes->OtherendsRouteQual);
-
- fputs(line, file);
- }
-
- Routes+=1;
- }
-
- return (0);
-}
-
-int DoNodes()
-{
- int count, len, cursor, i;
- char Normcall[10], Portcall[10];
- char line[80];
- char Alias[7];
-
- Dests-=1;
-
- for (count=0; countNRROUTE[0].ROUT_NEIGHBOUR == 0)
- continue;
-
- {
- len=ConvFromAX25(Dests->DEST_CALL,Normcall);
- Normcall[len]=0;
-
- memcpy(Alias,Dests->DEST_ALIAS,6);
-
- Alias[6]=0;
-
- for (i=0;i<6;i++)
- {
- if (Alias[i] == ' ')
- Alias[i] = 0;
- }
-
- cursor=sprintf(line,"NODE ADD %s:%s ", Alias,Normcall);
-
- if (Dests->NRROUTE[0].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[0].ROUT_NEIGHBOUR->INP3Node == 0)
- {
- len=ConvFromAX25(
- Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
- Portcall[len]=0;
-
- len=sprintf(&line[cursor],"%s %d %d ",
- Portcall,
- Dests->NRROUTE[0].ROUT_NEIGHBOUR->NEIGHBOUR_PORT,
- Dests->NRROUTE[0].ROUT_QUALITY);
-
- cursor+=len;
-
- if (Dests->NRROUTE[0].ROUT_OBSCOUNT > 127)
- {
- len=sprintf(&line[cursor],"! ");
- cursor+=len;
- }
- }
-
- if (Dests->NRROUTE[1].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[1].ROUT_NEIGHBOUR->INP3Node == 0)
- {
- len=ConvFromAX25(
- Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
- Portcall[len]=0;
-
- len=sprintf(&line[cursor],"%s %d %d ",
- Portcall,
- Dests->NRROUTE[1].ROUT_NEIGHBOUR->NEIGHBOUR_PORT,
- Dests->NRROUTE[1].ROUT_QUALITY);
-
- cursor+=len;
-
- if (Dests->NRROUTE[1].ROUT_OBSCOUNT > 127)
- {
- len=sprintf(&line[cursor],"! ");
- cursor+=len;
- }
- }
-
- if (Dests->NRROUTE[2].ROUT_NEIGHBOUR != 0 && Dests->NRROUTE[2].ROUT_NEIGHBOUR->INP3Node == 0)
- {
- len=ConvFromAX25(
- Dests->NRROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_CALL,Portcall);
- Portcall[len]=0;
-
- len=sprintf(&line[cursor],"%s %d %d ",
- Portcall,
- Dests->NRROUTE[2].ROUT_NEIGHBOUR->NEIGHBOUR_PORT,
- Dests->NRROUTE[2].ROUT_QUALITY);
-
- cursor+=len;
-
- if (Dests->NRROUTE[2].ROUT_OBSCOUNT > 127)
- {
- len=sprintf(&line[cursor],"! ");
- cursor+=len;
- }
- }
-
- if (cursor > 30)
- {
- line[cursor++]='\n';
- line[cursor++]=0;
- fputs(line, file);
- }
- }
- }
- return (0);
-}
-
-void SaveMH()
-{
- char FN[250];
- struct PORTCONTROL * PORT = PORTTABLE;
- FILE *file;
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(FN, "MHSave.txt");
- }
- else
- {
- strcpy(FN,BPQDirectory);
- strcat(FN,"/");
- strcat(FN,"MHSave.txt");
- }
-
- if ((file = fopen(FN, "w")) == NULL)
- return;
-
- while (PORT)
- {
- int Port = 0;
- char * ptr;
-
- MHSTRUC * MH = PORT->PORTMHEARD;
-
- int count = MHENTRIES;
- int n;
- char Normcall[20];
- char From[10];
- char DigiList[100];
- char * Output;
- int len;
- char Digi = 0;
-
-
- // Note that the MHDIGIS field may contain rubbish. You have to check End of Address bit to find
- // how many digis there are
-
- if (MH == NULL)
- continue;
-
- fprintf(file, "Port:%d\n", PORT->PORTNUMBER);
-
- while (count--)
- {
- if (MH->MHCALL[0] == 0)
- break;
-
- Digi = 0;
-
- len = ConvFromAX25(MH->MHCALL, Normcall);
- Normcall[len] = 0;
-
- n = 8; // Max number of digi-peaters
-
- ptr = &MH->MHCALL[6]; // End of Address bit
-
- Output = &DigiList[0];
-
- if ((*ptr & 1) == 0)
- {
- // at least one digi
-
- strcpy(Output, "via ");
- Output += 4;
-
- while ((*ptr & 1) == 0)
- {
- // MORE TO COME
-
- From[ConvFromAX25(ptr + 1, From)] = 0;
- 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++) = '*';
- Digi = '*';
- }
-
- else
- if ((ptr[7] & 0x80) == 0) // Repeased by next?
- {
- *(Output++) = '*'; // No, so need *
- Digi = '*';
- }
-
-
- }
- *(Output++) = ',';
- }
- *(--Output) = 0; // remove last comma
- }
- else
- *(Output) = 0;
-
- // if we used a digi set * on call and display via string
-
-
- if (Digi)
- Normcall[len++] = Digi;
- else
- DigiList[0] = 0; // Dont show list if not used
-
- Normcall[len++] = 0;
-
- ptr = FormatMH(MH, 'U');
-
- ptr[15] = 0;
-
- if (MH->MHDIGI)
- fprintf(file, "%d %6d %-10s%c %s %s|%s|%s\n", (int)MH->MHTIME, MH->MHCOUNT, Normcall, MH->MHDIGI, ptr, DigiList, MH->MHLocator, MH->MHFreq);
- else
- fprintf(file, "%d %6d %-10s%c %s %s|%s|%s\n", (int)MH->MHTIME, MH->MHCOUNT, Normcall, ' ', ptr, DigiList, MH->MHLocator, MH->MHFreq);
-
- MH++;
- }
- PORT = PORT->PORTPOINTER;
- }
-
- fclose(file);
-
- return;
-}
-
-
-int APIENTRY SaveNodes ()
-{
- char FN[250];
-
- Routes = NEIGHBOURS;
- RouteLen = ROUTE_LEN;
- MaxRoutes = MAXNEIGHBOURS;
-
- Dests = DESTS;
- NodeLen = DEST_LIST_LEN;
- MaxNodes = MAXDESTS;
-
- // Set up pointer to BPQNODES file
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(FN,"BPQNODES.dat");
- }
- else
- {
- strcpy(FN,BPQDirectory);
- strcat(FN,"/");
- strcat(FN,"BPQNODES.dat");
- }
-
- if ((file = fopen(FN, "w")) == NULL)
- return FALSE;
-
- DoRoutes();
- DoNodes();
-
- fclose(file);
-
- return (0);
-}
-
-DllExport int APIENTRY ClearNodes ()
-{
- char FN[250];
-
- // Set up pointer to BPQNODES file
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(FN,"BPQNODES.dat");
- }
- else
- {
- strcpy(FN,BPQDirectory);
- strcat(FN,"/");
- strcat(FN,"BPQNODES.dat");
- }
-
- if ((file = fopen(FN, "w")) == NULL)
- return FALSE;
-
- fclose(file);
-
- return (0);
-}
-
-
-static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
-
-char * FormatMH(PMHSTRUC MH, char Format)
-{
- struct tm * TM;
- static char MHTime[50];
- time_t szClock;
- char LOC[7];
-
- memcpy(LOC, MH->MHLocator, 6);
- LOC[6] = 0;
-
- if (Format == 'U' || Format =='L')
- szClock = MH->MHTIME;
- else
- szClock = time(NULL) - MH->MHTIME;
-
- if (Format == 'L')
- TM = localtime(&szClock);
- else
- TM = gmtime(&szClock);
-
- if (Format == 'U' || Format =='L')
- sprintf(MHTime, "%s %02d %.2d:%.2d:%.2d %s %s",
- month[TM->tm_mon], TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec, MH->MHFreq, LOC);
- else
- sprintf(MHTime, "%.2d:%.2d:%.2d:%.2d %s %s",
- TM->tm_yday, TM->tm_hour, TM->tm_min, TM->tm_sec, MH->MHFreq, LOC);
-
- return MHTime;
-
-}
-
-
-Dll VOID APIENTRY CreateOneTimePassword(char * Password, char * KeyPhrase, int TimeOffset)
-{
- // Create a time dependent One Time Password from the KeyPhrase
- // TimeOffset is used when checking to allow for slight variation in clocks
-
- time_t NOW = time(NULL);
- UCHAR Hash[16];
- char Key[1000];
- int i, chr;
-
- NOW = NOW/30 + TimeOffset; // Only Change every 30 secs
-
- sprintf(Key, "%s%x", KeyPhrase, (int)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;
- return;
-}
-
-Dll BOOL APIENTRY CheckOneTimePassword(char * Password, char * KeyPhrase)
-{
- char CheckPassword[17];
- int Offsets[10] = {0, -1, 1, -2, 2, -3, 3, -4, 4};
- int i, Pass;
-
- if (strlen(Password) < 16)
- Pass = atoi(Password);
-
- for (i = 0; i < 9; i++)
- {
- CreateOneTimePassword(CheckPassword, KeyPhrase, Offsets[i]);
-
- if (strlen(Password) < 16)
- {
- // Using a numeric extract
-
- long long Val;
-
- memcpy(&Val, CheckPassword, 8);
- Val = Val %= 1000000;
-
- if (Pass == Val)
- return TRUE;
- }
- else
- if (memcmp(Password, CheckPassword, 16) == 0)
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-DllExport BOOL ConvToAX25Ex(unsigned char * callsign, unsigned char * ax25call)
-{
- // Allows SSID's of 'T and 'R'
-
- int i;
-
- memset(ax25call,0x40,6); // in case short
- ax25call[6]=0x60; // default SSID
-
- for (i=0;i<7;i++)
- {
- if (callsign[i] == '-')
- {
- //
- // process ssid and return
- //
-
- if (callsign[i+1] == 'T')
- {
- ax25call[6]=0x42;
- return TRUE;
- }
-
- if (callsign[i+1] == 'R')
- {
- ax25call[6]=0x44;
- return TRUE;
- }
- i = atoi(&callsign[i+1]);
-
- if (i < 16)
- {
- ax25call[6] |= i<<1;
- return (TRUE);
- }
- return (FALSE);
- }
-
- if (callsign[i] == 0 || callsign[i] == 13 || callsign[i] == ' ' || callsign[i] == ',')
- {
- //
- // End of call - no ssid
- //
- return (TRUE);
- }
-
- ax25call[i] = callsign[i] << 1;
- }
-
- //
- // Too many chars
- //
-
- return (FALSE);
-}
-
-
-DllExport BOOL ConvToAX25(unsigned char * callsign, unsigned char * ax25call)
-{
- int i;
-
- memset(ax25call,0x40,6); // in case short
- ax25call[6]=0x60; // default SSID
-
- for (i=0;i<7;i++)
- {
- if (callsign[i] == '-')
- {
- //
- // process ssid and return
- //
- i = atoi(&callsign[i+1]);
-
- if (i < 16)
- {
- ax25call[6] |= i<<1;
- return (TRUE);
- }
- return (FALSE);
- }
-
- if (callsign[i] == 0 || callsign[i] == 13 || callsign[i] == ' ' || callsign[i] == ',')
- {
- //
- // End of call - no ssid
- //
- return (TRUE);
- }
-
- ax25call[i] = callsign[i] << 1;
- }
-
- //
- // Too many chars
- //
-
- return (FALSE);
-}
-
-
-DllExport int ConvFromAX25(unsigned char * incall,unsigned char * outcall)
-{
- int in,out=0;
- unsigned char chr;
-
- memset(outcall,0x20,10);
-
- for (in=0;in<6;in++)
- {
- chr=incall[in];
- if (chr == 0x40)
- break;
- chr >>= 1;
- outcall[out++]=chr;
- }
-
- chr=incall[6]; // ssid
-
- if (chr == 0x42)
- {
- outcall[out++]='-';
- outcall[out++]='T';
- return out;
- }
-
- if (chr == 0x44)
- {
- outcall[out++]='-';
- outcall[out++]='R';
- return out;
- }
-
- chr >>= 1;
- chr &= 15;
-
- if (chr > 0)
- {
- outcall[out++]='-';
- if (chr > 9)
- {
- chr-=10;
- outcall[out++]='1';
- }
- chr+=48;
- outcall[out++]=chr;
- }
- return (out);
-}
-
-unsigned short int compute_crc(unsigned char *buf, int txlen);
-
-SOCKADDR_IN reportdest = {0};
-
-SOCKET ReportSocket = 0;
-
-SOCKADDR_IN Chatreportdest = {0};
-
-extern char LOCATOR[]; // Locator for Reporting - may be Maidenhead or LAT:LON
-extern char MAPCOMMENT[]; // Locator for Reporting - may be Maidenhead or LAT:LON
-extern char LOC[7]; // Maidenhead Locator for Reporting
-extern char ReportDest[7];
-
-
-VOID SendReportMsg(char * buff, int txlen)
-{
- unsigned short int crc = compute_crc(buff, txlen);
-
- crc ^= 0xffff;
-
- buff[txlen++] = (crc&0xff);
- buff[txlen++] = (crc>>8);
-
- sendto(ReportSocket, buff, txlen, 0, (struct sockaddr *)&reportdest, sizeof(reportdest));
-
-}
-VOID SendLocation()
-{
- MESSAGE AXMSG = {0};
- PMESSAGE AXPTR = &AXMSG;
- char Msg[512];
- int Len;
-
- Len = sprintf(Msg, "%s %s %s", LOCATOR, VersionString, MAPCOMMENT);
-
-#ifdef LINBPQ
- Len = sprintf(Msg, "%s L%s %s", LOCATOR, VersionString, MAPCOMMENT);
-#endif
-#ifdef MACBPQ
- Len = sprintf(Msg, "%s M%s %s", LOCATOR, VersionString, MAPCOMMENT);
-#endif
-#ifdef FREEBSD
- Len = sprintf(Msg, "%s F%s %s", LOCATOR, VersionString, MAPCOMMENT);
-#endif
-
- if (Len > 256)
- Len = 256;
-
- // Block includes the Msg Header (7 bytes), Len Does not!
-
- memcpy(AXPTR->DEST, ReportDest, 7);
- memcpy(AXPTR->ORIGIN, MYCALL, 7);
- AXPTR->DEST[6] &= 0x7e; // Clear End of Call
- AXPTR->DEST[6] |= 0x80; // set Command Bit
-
- AXPTR->ORIGIN[6] |= 1; // Set End of Call
- AXPTR->CTL = 3; //UI
- AXPTR->PID = 0xf0;
- memcpy(AXPTR->L2DATA, Msg, Len);
-
- SendReportMsg((char *)&AXMSG.DEST, Len + 16);
-
- if (M0LTEMap)
- SendDataToPktMap();
-
- return;
-
-}
-
-
-
-VOID SendMH(struct TNCINFO * TNC, char * call, char * freq, char * LOC, char * Mode)
-{
- MESSAGE AXMSG;
- PMESSAGE AXPTR = &AXMSG;
- char Msg[100];
- int Len;
-
- if (ReportSocket == 0 || LOCATOR[0] == 0)
- return;
-
- Len = sprintf(Msg, "MH %s,%s,%s,%s", call, freq, LOC, Mode);
-
- // Block includes the Msg Header (7 bytes), Len Does not!
-
- memcpy(AXPTR->DEST, ReportDest, 7);
-
- if (TNC && TNC->PortRecord->PORTCONTROL.PORTCALL[0])
- memcpy(AXPTR->ORIGIN, TNC->PortRecord->PORTCONTROL.PORTCALL, 7);
- else
- memcpy(AXPTR->ORIGIN, MYCALL, 7);
- AXPTR->DEST[6] &= 0x7e; // Clear End of Call
- AXPTR->DEST[6] |= 0x80; // set Command Bit
-
- AXPTR->ORIGIN[6] |= 1; // Set End of Call
- AXPTR->CTL = 3; //UI
- AXPTR->PID = 0xf0;
- memcpy(AXPTR->L2DATA, Msg, Len);
-
- SendReportMsg((char *)&AXMSG.DEST, Len + 16) ;
-
- return;
-
-}
-
-time_t TimeLastNRRouteSent = 0;
-
-char NRRouteMessage[256];
-int NRRouteLen = 0;
-
-
-VOID SendNETROMRoute(struct PORTCONTROL * PORT, unsigned char * axcall)
-{
- // Called to update Link Map when a NODES Broadcast is received
- // Batch to reduce Load
-
- MESSAGE AXMSG;
- PMESSAGE AXPTR = &AXMSG;
- char Msg[300];
- int Len;
- char Call[10];
- char Report[16];
- time_t Now = time(NULL);
- int NeedSend = FALSE;
-
-
- if (ReportSocket == 0 || LOCATOR[0] == 0)
- return;
-
- Call[ConvFromAX25(axcall, Call)] = 0;
-
- sprintf(Report, "%s,%d,", Call, PORT->PORTTYPE);
-
- if (Now - TimeLastNRRouteSent > 60)
- NeedSend = TRUE;
-
- if (strstr(NRRouteMessage, Report) == 0) // reported recently
- strcat(NRRouteMessage, Report);
-
- if (strlen(NRRouteMessage) > 230 || NeedSend)
- {
- Len = sprintf(Msg, "LINK %s", NRRouteMessage);
-
- // Block includes the Msg Header (7 bytes), Len Does not!
-
- memcpy(AXPTR->DEST, ReportDest, 7);
- memcpy(AXPTR->ORIGIN, MYCALL, 7);
- AXPTR->DEST[6] &= 0x7e; // Clear End of Call
- AXPTR->DEST[6] |= 0x80; // set Command Bit
-
- AXPTR->ORIGIN[6] |= 1; // Set End of Call
- AXPTR->CTL = 3; //UI
- AXPTR->PID = 0xf0;
- memcpy(AXPTR->L2DATA, Msg, Len);
-
- SendReportMsg((char *)&AXMSG.DEST, Len + 16) ;
-
- TimeLastNRRouteSent = Now;
- NRRouteMessage[0] = 0;
- }
-
- return;
-
-}
-
-DllExport char * APIENTRY GetApplCall(int Appl)
-{
- if (Appl < 1 || Appl > NumberofAppls ) return NULL;
-
- return (UCHAR *)(&APPLCALLTABLE[Appl-1].APPLCALL_TEXT);
-}
-DllExport char * APIENTRY GetApplAlias(int Appl)
-{
- if (Appl < 1 || Appl > NumberofAppls ) return NULL;
-
- return (UCHAR *)(&APPLCALLTABLE[Appl-1].APPLALIAS_TEXT);
-}
-
-DllExport int32_t APIENTRY GetApplQual(int Appl)
-{
- if (Appl < 1 || Appl > NumberofAppls ) return 0;
-
- return (APPLCALLTABLE[Appl-1].APPLQUAL);
-}
-
-char * GetApplCallFromName(char * App)
-{
- int i;
- char PaddedAppl[13] = " ";
-
- memcpy(PaddedAppl, App, (int)strlen(App));
-
- for (i = 0; i < NumberofAppls; i++)
- {
- if (memcmp(&APPLCALLTABLE[i].APPLCMD, PaddedAppl, 12) == 0)
- return &APPLCALLTABLE[i].APPLCALL_TEXT[0];
- }
- return NULL;
-}
-
-
-DllExport char * APIENTRY GetApplName(int Appl)
-{
- if (Appl < 1 || Appl > NumberofAppls ) return NULL;
-
- return (UCHAR *)(&APPLCALLTABLE[Appl-1].APPLCMD);
-}
-
-DllExport int APIENTRY GetNumberofPorts()
-{
- return (NUMBEROFPORTS);
-}
-
-DllExport int APIENTRY GetPortNumber(int portslot)
-{
- struct PORTCONTROL * PORTVEC=PORTTABLE;
-
- if (portslot>NUMBEROFPORTS)
- portslot=NUMBEROFPORTS;
-
- while (--portslot > 0)
- PORTVEC=PORTVEC->PORTPOINTER;
-
- return PORTVEC->PORTNUMBER;
-
-}
-
-DllExport char * APIENTRY GetVersionString()
-{
-// return ((char *)&VersionStringWithBuild);
- return ((char *)&VersionString);
-}
-
-#ifdef MACBPQ
-
-//Fiddle till I find a better solution
-
-#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060
-int __sync_lock_test_and_set(int * ptr, int val)
-{
- *ptr = val;
- return 0;
-}
-#endif // __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
-#endif // MACBPQ
-
-
-#define GetSemaphore(Semaphore,ID) _GetSemaphore(Semaphore, ID, __FILE__, __LINE__)
-
-
-void _GetSemaphore(struct SEM * Semaphore, int ID, char * File, int Line)
-{
- //
- // Wait for it to be free
- //
-
- if (Semaphore->Flag != 0)
- {
- Semaphore->Clashes++;
- }
-
-loop1:
-
- while (Semaphore->Flag != 0)
- {
- Sleep(10);
- }
-
- //
- // try to get semaphore
- //
-
-#ifdef WIN32
-
- {
- if (InterlockedExchange(&Semaphore->Flag, 1) != 0) // Failed to get it
- goto loop1; // try again;;
- }
-
-#else
-
- if (__sync_lock_test_and_set(&Semaphore->Flag, 1) != 0)
-
- // Failed to get it
- goto loop1; // try again;
-
-#endif
-
- //Ok. got it
-
- Semaphore->Gets++;
- Semaphore->SemProcessID = GetCurrentProcessId();
- Semaphore->SemThreadID = GetCurrentThreadId();
- SemHeldByAPI = ID;
- Semaphore->Line = Line;
- strcpy(Semaphore->File, File);
-
- return;
-}
-
-void FreeSemaphore(struct SEM * Semaphore)
-{
- if (Semaphore->Flag == 0)
- Debugprintf("Free Semaphore Called when Sem not held");
-
- Semaphore->Rels++;
- Semaphore->Flag = 0;
-
- return;
-}
-
-#ifdef WIN32
-
-#include "DbgHelp.h"
-/*
-USHORT WINAPI RtlCaptureStackBackTrace(
- __in ULONG FramesToSkip,
- __in ULONG FramesToCapture,
- __out PVOID *BackTrace,
- __out_opt PULONG BackTraceHash
-);
-*/
-#endif
-
-void printStack(void)
-{
-#ifdef WIN32
-#ifdef _DEBUG // So we can use on 98/2K
-
- unsigned int i;
- void * stack[ 100 ];
- unsigned short frames;
- SYMBOL_INFO * symbol;
- HANDLE process;
-
- Debugprintf("Stack Backtrace");
-
- process = GetCurrentProcess();
-
- SymInitialize( process, NULL, TRUE );
-
- frames = RtlCaptureStackBackTrace( 0, 60, stack, NULL );
- symbol = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
- symbol->MaxNameLen = 255;
- symbol->SizeOfStruct = sizeof( SYMBOL_INFO );
-
- for( i = 0; i < frames; i++ )
- {
- SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );
-
- Debugprintf( "%i: %s - %p", frames - i - 1, symbol->Name, symbol->Address );
- }
-
- free(symbol);
-
-#endif
-#endif
-}
-
-pthread_t ResolveUpdateThreadId = 0;
-
-char NodeMapServer[80] = "update.g8bpq.net";
-char ChatMapServer[80] = "chatupdate.g8bpq.net";
-
-VOID ResolveUpdateThread(void * Unused)
-{
- struct hostent * HostEnt1;
- struct hostent * HostEnt2;
-
- ResolveUpdateThreadId = GetCurrentThreadId();
-
- while (TRUE)
- {
- if (pthread_equal(ResolveUpdateThreadId, GetCurrentThreadId()) == FALSE)
- {
- Debugprintf("Resolve Update thread %x redundant - closing", GetCurrentThreadId());
- return;
- }
-
- // Resolve name to address
-
- Debugprintf("Resolving %s", NodeMapServer);
- HostEnt1 = gethostbyname (NodeMapServer);
-// HostEnt1 = gethostbyname ("192.168.1.64");
-
- if (HostEnt1)
- memcpy(&reportdest.sin_addr.s_addr,HostEnt1->h_addr,4);
-
- Debugprintf("Resolving %s", ChatMapServer);
- HostEnt2 = gethostbyname (ChatMapServer);
-// HostEnt2 = gethostbyname ("192.168.1.64");
-
- if (HostEnt2)
- memcpy(&Chatreportdest.sin_addr.s_addr,HostEnt2->h_addr,4);
-
- if (HostEnt1 && HostEnt2)
- {
- Sleep(1000 * 60 * 30);
- continue;
- }
-
- Debugprintf("Resolve Failed for update.g8bpq.net or chatmap.g8bpq.net");
- Sleep(1000 * 60 * 5);
- }
-}
-
-
-VOID OpenReportingSockets()
-{
- u_long param=1;
- BOOL bcopt=TRUE;
-
- if (LOCATOR[0])
- {
- // Enable Node Map Reports
-
- ReportTimer = 1200; // 2 mins - Give Rigcontrol time to start
-
- ReportSocket = socket(AF_INET,SOCK_DGRAM,0);
-
- if (ReportSocket == INVALID_SOCKET)
- {
- Debugprintf("Failed to create Reporting socket");
- ReportSocket = 0;
- return;
- }
-
- ioctlsocket (ReportSocket, FIONBIO, ¶m);
- setsockopt (ReportSocket, SOL_SOCKET, SO_BROADCAST, (const char FAR *)&bcopt,4);
-
- reportdest.sin_family = AF_INET;
- reportdest.sin_port = htons(81);
- ConvToAX25("DUMMY-1", ReportDest);
- }
-
- // Set up Chat Report even if no LOCATOR reportdest.sin_family = AF_INET;
- // Socket must be opened in MailChat Process
-
- Chatreportdest.sin_family = AF_INET;
- Chatreportdest.sin_port = htons(81);
-
- _beginthread(ResolveUpdateThread, 0, NULL);
-
- printf("MQTT Enabled %d\n", MQTT);
-
- if (MQTT)
- MQTTConnect(MQTT_HOST, MQTT_PORT, MQTT_USER, MQTT_PASS);
-}
-
-VOID WriteMiniDumpThread();
-
-time_t lastMiniDump = 0;
-
-void WriteMiniDump()
-{
-#ifdef WIN32
-
- _beginthread(WriteMiniDumpThread, 0, 0);
- Sleep(3000);
-}
-
-VOID WriteMiniDumpThread()
-{
- HANDLE hFile;
- BOOL ret;
- char FN[256];
- struct tm * TM;
- time_t Now = time(NULL);
-
- if (lastMiniDump == Now) // Not more than one per second
- {
- Debugprintf("minidump suppressed");
- return;
- }
-
- lastMiniDump = Now;
-
- TM = gmtime(&Now);
-
- sprintf(FN, "%s/Logs/MiniDump%d%02d%02d%02d%02d%02d.dmp", BPQDirectory,
- TM->tm_year + 1900, TM->tm_mon +1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec);
-
- hFile = CreateFile(FN, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
- if((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
- {
- // Create the minidump
-
- ret = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
- hFile, MiniDumpNormal, 0, 0, 0 );
-
- if(!ret)
- Debugprintf("MiniDumpWriteDump failed. Error: %u", GetLastError());
- else
- Debugprintf("Minidump %s created.", FN);
- CloseHandle(hFile);
- }
-#endif
-}
-
-// UI Util Code
-
-#pragma pack(1)
-
-typedef struct _MESSAGEX
-{
-// BASIC LINK LEVEL MESSAGE BUFFER LAYOUT
-
- struct _MESSAGEX * CHAIN;
-
- UCHAR PORT;
- USHORT LENGTH;
-
- UCHAR DEST[7];
- UCHAR ORIGIN[7];
-
-// MAY BE UP TO 56 BYTES OF DIGIS
-
- UCHAR CTL;
- UCHAR PID;
- UCHAR DATA[256];
- UCHAR PADDING[56]; // In case he have Digis
-
-}MESSAGEX, *PMESSAGEX;
-
-#pragma pack()
-
-
-int PortNum[MaxBPQPortNo + 1] = {0}; // Tab nunber to port
-
-char * UIUIDigi[MaxBPQPortNo + 1]= {0};
-char * UIUIDigiAX[MaxBPQPortNo + 1] = {0}; // ax.25 version of digistring
-int UIUIDigiLen[MaxBPQPortNo + 1] = {0}; // Length of AX string
-
-char UIUIDEST[MaxBPQPortNo + 1][11] = {0}; // Dest for Beacons
-
-char UIAXDEST[MaxBPQPortNo + 1][7] = {0};
-
-
-UCHAR FN[MaxBPQPortNo + 1][256]; // Filename
-int Interval[MaxBPQPortNo + 1]; // Beacon Interval (Mins)
-int MinCounter[MaxBPQPortNo + 1]; // Interval Countdown
-
-BOOL SendFromFile[MaxBPQPortNo + 1];
-char Message[MaxBPQPortNo + 1][1000]; // Beacon Text
-
-VOID SendUIBeacon(int Port);
-
-BOOL RunUI = TRUE;
-
-VOID UIThread(void * Unused)
-{
- int Port, MaxPorts = GetNumberofPorts();
-
- Sleep(60000);
-
- while (RunUI)
- {
- int sleepInterval = 60000;
-
- for (Port = 1; Port <= MaxPorts; Port++)
- {
- if (MinCounter[Port])
- {
- MinCounter[Port]--;
-
- if (MinCounter[Port] == 0)
- {
- MinCounter[Port] = Interval[Port];
- SendUIBeacon(Port);
-
- // pause beteen beacons but adjust sleep interval to suit
-
- Sleep(10000);
- sleepInterval -= 10000;
- }
- }
- }
-
- while (sleepInterval <= 0) // just in case we have a crazy config
- sleepInterval += 60000;
-
- Sleep(sleepInterval);
- }
-}
-
-int UIRemoveLF(char * Message, int len)
-{
- // Remove lf chars
-
- char * ptr1, * ptr2;
-
- ptr1 = ptr2 = Message;
-
- while (len-- > 0)
- {
- *ptr2 = *ptr1;
-
- if (*ptr1 == '\r')
- if (*(ptr1+1) == '\n')
- {
- ptr1++;
- len--;
- }
- ptr1++;
- ptr2++;
- }
-
- return (int)(ptr2 - Message);
-}
-
-
-
-
-VOID UISend_AX_Datagram(UCHAR * Msg, DWORD Len, UCHAR Port, UCHAR * HWADDR, BOOL Queue)
-{
- MESSAGEX AXMSG;
- PMESSAGEX AXPTR = &AXMSG;
- int DataLen = Len;
- struct PORTCONTROL * PORT = GetPortTableEntryFromSlot(Port);
-
- // Block includes the Msg Header (7 or 11 bytes), Len Does not!
-
- memcpy(AXPTR->DEST, HWADDR, 7);
-
- // Get BCALL or PORTCALL if set
-
- if (PORT && PORT->PORTBCALL[0])
- memcpy(AXPTR->ORIGIN, PORT->PORTBCALL, 7);
- else if (PORT && PORT->PORTCALL[0])
- memcpy(AXPTR->ORIGIN, PORT->PORTCALL, 7);
- else
- memcpy(AXPTR->ORIGIN, MYCALL, 7);
-
- AXPTR->DEST[6] &= 0x7e; // Clear End of Call
- AXPTR->DEST[6] |= 0x80; // set Command Bit
-
- if (UIUIDigi[Port])
- {
- // This port has a digi string
-
- int DigiLen = UIUIDigiLen[Port];
- UCHAR * ptr;
-
- memcpy(&AXPTR->CTL, UIUIDigiAX[Port], DigiLen);
-
- ptr = (UCHAR *)AXPTR;
- ptr += DigiLen;
- AXPTR = (PMESSAGEX)ptr;
-
- Len += DigiLen;
- }
-
- AXPTR->ORIGIN[6] |= 1; // Set End of Call
- AXPTR->CTL = 3; //UI
- AXPTR->PID = 0xf0;
- memcpy(AXPTR->DATA, Msg, DataLen);
-
-// if (Queue)
-// QueueRaw(Port, &AXMSG, Len + 16);
-// else
- SendRaw(Port, (char *)&AXMSG.DEST, Len + 16);
-
- return;
-
-}
-
-
-
-VOID SendUIBeacon(int Port)
-{
- char UIMessage[1024];
- int Len = (int)strlen(Message[Port]);
- int Index = 0;
-
- if (SendFromFile[Port])
- {
- FILE * hFile;
-
- hFile = fopen(FN[Port], "rb");
-
- if (hFile == 0)
- return;
-
- Len = (int)fread(UIMessage, 1, 1024, hFile);
-
- fclose(hFile);
-
- }
- else
- strcpy(UIMessage, Message[Port]);
-
- Len = UIRemoveLF(UIMessage, Len);
-
- while (Len > 256)
- {
- UISend_AX_Datagram(&UIMessage[Index], 256, Port, UIAXDEST[Port], TRUE);
- Index += 256;
- Len -= 256;
- Sleep(2000);
- }
- UISend_AX_Datagram(&UIMessage[Index], Len, Port, UIAXDEST[Port], TRUE);
-}
-
-#ifndef LINBPQ
-
-typedef struct tag_dlghdr
-{
- HWND hwndTab; // tab control
- HWND hwndDisplay; // current child dialog box
- RECT rcDisplay; // display rectangle for the tab control
-
- DLGTEMPLATE *apRes[MaxBPQPortNo + 1];
-
-} DLGHDR;
-
-DLGTEMPLATE * WINAPI DoLockDlgRes(LPCSTR lpszResName);
-
-#endif
-
-HWND hwndDlg;
-int PageCount;
-int CurrentPage=0; // Page currently on show in tabbed Dialog
-
-
-VOID WINAPI OnSelChanged(HWND hwndDlg);
-VOID WINAPI OnChildDialogInit(HWND hwndDlg);
-
-#define ICC_STANDARD_CLASSES 0x00004000
-
-HWND hwndDisplay;
-
-#define ID_TEST 102
-#define IDD_DIAGLOG1 103
-#define IDC_FROMFILE 1022
-#define IDC_EDIT1 1054
-#define IDC_FILENAME 1054
-#define IDC_EDIT2 1055
-#define IDC_MESSAGE 1055
-#define IDC_EDIT3 1056
-#define IDC_INTERVAL 1056
-#define IDC_EDIT4 1057
-#define IDC_UIDEST 1057
-#define IDC_FILE 1058
-#define IDC_TAB1 1059
-#define IDC_UIDIGIS 1059
-#define IDC_PORTNAME 1060
-
-extern HKEY REGTREE;
-HBRUSH bgBrush;
-
-VOID SetupUI(int Port)
-{
- char DigiString[100], * DigiLeft;
-
- ConvToAX25(UIUIDEST[Port], &UIAXDEST[Port][0]);
-
- UIUIDigiLen[Port] = 0;
-
- if (UIUIDigi[Port])
- {
- UIUIDigiAX[Port] = zalloc(100);
- strcpy(DigiString, UIUIDigi[Port]);
- DigiLeft = strlop(DigiString,',');
-
- while(DigiString[0])
- {
- ConvToAX25(DigiString, &UIUIDigiAX[Port][UIUIDigiLen[Port]]);
- UIUIDigiLen[Port] += 7;
-
- if (DigiLeft)
- {
- memmove(DigiString, DigiLeft, (int)strlen(DigiLeft) + 1);
- DigiLeft = strlop(DigiString,',');
- }
- else
- DigiString[0] = 0;
- }
- }
-}
-
-#ifndef LINBPQ
-
-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 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);
-
-}
-
-#endif
-
-config_t cfg;
-
-VOID SaveUIConfig()
-{
- config_setting_t *root, *group, *UIGroup;
- int Port, MaxPort = GetNumberofPorts();
- char ConfigName[256];
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(ConfigName,"UIUtil.cfg");
- }
- else
- {
- strcpy(ConfigName,BPQDirectory);
- strcat(ConfigName,"/");
- strcat(ConfigName,"UIUtil.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);
-
- UIGroup = config_setting_add(group, "UIUtil", CONFIG_TYPE_GROUP);
-
- for (Port = 1; Port <= MaxPort; Port++)
- {
- char Key[20];
-
- sprintf(Key, "Port%d", Port);
- group = config_setting_add(UIGroup, Key, CONFIG_TYPE_GROUP);
-
- SaveStringValue(group, "UIDEST", &UIUIDEST[Port][0]);
- SaveStringValue(group, "FileName", &FN[Port][0]);
- SaveStringValue(group, "Message", &Message[Port][0]);
- SaveStringValue(group, "Digis", UIUIDigi[Port]);
-
- SaveIntValue(group, "Interval", Interval[Port]);
- SaveIntValue(group, "SendFromFile", SendFromFile[Port]);
- }
-
- if(!config_write_file(&cfg, ConfigName))
- {
- fprintf(stderr, "Error while writing file.\n");
- config_destroy(&cfg);
- return;
- }
-
- config_destroy(&cfg);
-}
-
-int GetRegConfig();
-
-VOID GetUIConfig()
-{
- char Key[100];
- char CfgFN[256];
- char Digis[100];
- struct stat STAT;
-
- config_t cfg;
- config_setting_t *group;
- int Port, MaxPort = GetNumberofPorts();
-
- memset((void *)&cfg, 0, sizeof(config_t));
-
- config_init(&cfg);
-
- if (BPQDirectory[0] == 0)
- {
- strcpy(CfgFN,"UIUtil.cfg");
- }
- else
- {
- strcpy(CfgFN,BPQDirectory);
- strcat(CfgFN,"/");
- strcat(CfgFN,"UIUtil.cfg");
- }
-
- if (stat(CfgFN, &STAT) == -1)
- {
- // No file. If Windows try to read from registy
-
-#ifndef LINBPQ
- GetRegConfig();
-#else
- Debugprintf("UIUtil Config File not found\n");
-#endif
- return;
- }
-
- if(!config_read_file(&cfg, CfgFN))
- {
- fprintf(stderr, "UI Util Config Error Line %d - %s\n", config_error_line(&cfg), config_error_text(&cfg));
-
- config_destroy(&cfg);
- return;
- }
-
- group = config_lookup(&cfg, "main");
-
- if (group)
- {
- for (Port = 1; Port <= MaxPort; Port++)
- {
- sprintf(Key, "main.UIUtil.Port%d", Port);
-
- group = config_lookup (&cfg, Key);
-
- if (group)
- {
- GetStringValue(group, "UIDEST", &UIUIDEST[Port][0], 11);
- GetStringValue(group, "FileName", &FN[Port][0], 256);
- GetStringValue(group, "Message", &Message[Port][0], 1000);
- GetStringValue(group, "Digis", Digis, 100);
- UIUIDigi[Port] = _strdup(Digis);
-
- Interval[Port] = GetIntValue(group, "Interval");
- MinCounter[Port] = Interval[Port];
-
- SendFromFile[Port] = GetIntValue(group, "SendFromFile");
-
- SetupUI(Port);
- }
- }
- }
-
-
- _beginthread(UIThread, 0, NULL);
-
-}
-
-#ifndef LINBPQ
-
-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;
-}
-
-BOOL GetStringValue(config_setting_t * group, char * name, char * value, int maxlen)
-{
- char * str;
- config_setting_t *setting;
-
- setting = config_setting_get_member (group, name);
- if (setting)
- {
- str = (char *)config_setting_get_string(setting);
-
- if (strlen(str) > maxlen)
- {
- Debugprintf("Suspect config record %s", str);
- str[maxlen] = 0;
- }
- strcpy(value, str);
- return TRUE;
- }
- value[0] = 0;
- return FALSE;
-}
-
-int GetRegConfig()
-{
- int retCode, Vallen, Type, i;
- char Key[80];
- char Size[80];
- HKEY hKey;
- RECT Rect;
-
- wsprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\UIUtil");
-
- retCode = RegOpenKeyEx (REGTREE, Key, 0, KEY_QUERY_VALUE, &hKey);
-
- if (retCode == ERROR_SUCCESS)
- {
- Vallen=80;
-
- retCode = RegQueryValueEx(hKey,"Size",0,
- (ULONG *)&Type,(UCHAR *)&Size,(ULONG *)&Vallen);
-
- if (retCode == ERROR_SUCCESS)
- sscanf(Size,"%d,%d,%d,%d",&Rect.left,&Rect.right,&Rect.top,&Rect.bottom);
-
- RegCloseKey(hKey);
- }
-
- for (i=1; i<=32; i++)
- {
- wsprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\UIUtil\\UIPort%d", i);
-
- retCode = RegOpenKeyEx (REGTREE,
- Key,
- 0,
- KEY_QUERY_VALUE,
- &hKey);
-
- if (retCode == ERROR_SUCCESS)
- {
- Vallen=0;
- RegQueryValueEx(hKey,"Digis",0,
- (ULONG *)&Type, NULL, (ULONG *)&Vallen);
-
- if (Vallen)
- {
- UIUIDigi[i] = malloc(Vallen);
- RegQueryValueEx(hKey,"Digis",0,
- (ULONG *)&Type, UIUIDigi[i], (ULONG *)&Vallen);
- }
-
- Vallen=4;
- retCode = RegQueryValueEx(hKey, "Interval", 0,
- (ULONG *)&Type, (UCHAR *)&Interval[i], (ULONG *)&Vallen);
-
- MinCounter[i] = Interval[i];
-
- Vallen=4;
- retCode = RegQueryValueEx(hKey, "SendFromFile", 0,
- (ULONG *)&Type, (UCHAR *)&SendFromFile[i], (ULONG *)&Vallen);
-
-
- Vallen=10;
- retCode = RegQueryValueEx(hKey, "UIDEST", 0, &Type, &UIUIDEST[i][0], &Vallen);
-
- Vallen=255;
- retCode = RegQueryValueEx(hKey, "FileName", 0, &Type, &FN[i][0], &Vallen);
-
- Vallen=999;
- retCode = RegQueryValueEx(hKey, "Message", 0, &Type, &Message[i][0], &Vallen);
-
- SetupUI(i);
-
- RegCloseKey(hKey);
- }
- }
-
- SaveUIConfig();
-
- return TRUE;
-}
-
-INT_PTR CALLBACK ChildDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
-{
-// This processes messages from controls on the tab subpages
- int Command;
-
- int retCode, disp;
- char Key[80];
- HKEY hKey;
- BOOL OK;
- OPENFILENAME ofn;
- char Digis[100];
-
- int Port = PortNum[CurrentPage];
-
-
- switch (message)
- {
- case WM_NOTIFY:
-
- switch (((LPNMHDR)lParam)->code)
- {
- case TCN_SELCHANGE:
- OnSelChanged(hDlg);
- return TRUE;
- // More cases on WM_NOTIFY switch.
- case NM_CHAR:
- return TRUE;
- }
-
- break;
- case WM_INITDIALOG:
- OnChildDialogInit( hDlg);
- return (INT_PTR)TRUE;
-
- case WM_CTLCOLORDLG:
-
- return (LONG)bgBrush;
-
- case WM_CTLCOLORSTATIC:
- {
- HDC hdcStatic = (HDC)wParam;
- SetTextColor(hdcStatic, RGB(0, 0, 0));
- SetBkMode(hdcStatic, TRANSPARENT);
- return (LONG)bgBrush;
- }
-
-
- case WM_COMMAND:
-
- Command = LOWORD(wParam);
-
- if (Command == 2002)
- return TRUE;
-
- switch (Command)
- {
- case IDC_FILE:
-
- memset(&ofn, 0, sizeof (OPENFILENAME));
- ofn.lStructSize = sizeof (OPENFILENAME);
- ofn.hwndOwner = hDlg;
- ofn.lpstrFile = &FN[Port][0];
- ofn.nMaxFile = 250;
- ofn.lpstrTitle = "File to send as beacon";
- ofn.lpstrInitialDir = BPQDirectory;
-
- if (GetOpenFileName(&ofn))
- SetDlgItemText(hDlg, IDC_FILENAME, &FN[Port][0]);
-
- break;
-
-
- case IDOK:
-
- GetDlgItemText(hDlg, IDC_UIDEST, &UIUIDEST[Port][0], 10);
-
- if (UIUIDigi[Port])
- {
- free(UIUIDigi[Port]);
- UIUIDigi[Port] = NULL;
- }
-
- if (UIUIDigiAX[Port])
- {
- free(UIUIDigiAX[Port]);
- UIUIDigiAX[Port] = NULL;
- }
-
- GetDlgItemText(hDlg, IDC_UIDIGIS, Digis, 99);
-
- UIUIDigi[Port] = _strdup(Digis);
-
- GetDlgItemText(hDlg, IDC_FILENAME, &FN[Port][0], 255);
- GetDlgItemText(hDlg, IDC_MESSAGE, &Message[Port][0], 1000);
-
- Interval[Port] = GetDlgItemInt(hDlg, IDC_INTERVAL, &OK, FALSE);
-
- MinCounter[Port] = Interval[Port];
-
- SendFromFile[Port] = IsDlgButtonChecked(hDlg, IDC_FROMFILE);
-
- wsprintf(Key, "SOFTWARE\\G8BPQ\\BPQ32\\UIUtil\\UIPort%d", PortNum[CurrentPage]);
-
- retCode = RegCreateKeyEx(REGTREE,
- Key, 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, &disp);
-
- if (retCode == ERROR_SUCCESS)
- {
- retCode = RegSetValueEx(hKey, "UIDEST", 0, REG_SZ,(BYTE *)&UIUIDEST[Port][0], (int)strlen(&UIUIDEST[Port][0]));
- retCode = RegSetValueEx(hKey, "FileName", 0, REG_SZ,(BYTE *)&FN[Port][0], (int)strlen(&FN[Port][0]));
- retCode = RegSetValueEx(hKey, "Message", 0, REG_SZ,(BYTE *)&Message[Port][0], (int)strlen(&Message[Port][0]));
- retCode = RegSetValueEx(hKey, "Interval", 0, REG_DWORD,(BYTE *)&Interval[Port], 4);
- retCode = RegSetValueEx(hKey, "SendFromFile", 0, REG_DWORD,(BYTE *)&SendFromFile[Port], 4);
- retCode = RegSetValueEx(hKey, "Digis",0, REG_SZ, Digis, (int)strlen(Digis));
-
- RegCloseKey(hKey);
- }
-
- SetupUI(Port);
-
- SaveUIConfig();
-
- return (INT_PTR)TRUE;
-
-
- case IDCANCEL:
-
- EndDialog(hDlg, LOWORD(wParam));
- return (INT_PTR)TRUE;
-
- case ID_TEST:
-
- SendUIBeacon(Port);
- return TRUE;
-
- }
- break;
-
- }
- return (INT_PTR)FALSE;
-}
-
-
-
-VOID WINAPI OnTabbedDialogInit(HWND hDlg)
-{
- DLGHDR *pHdr = (DLGHDR *) LocalAlloc(LPTR, sizeof(DLGHDR));
- DWORD dwDlgBase = GetDialogBaseUnits();
- int cxMargin = LOWORD(dwDlgBase) / 4;
- int cyMargin = HIWORD(dwDlgBase) / 8;
-
- TC_ITEM tie;
- RECT rcTab;
-
- int i, pos, tab = 0;
- INITCOMMONCONTROLSEX init;
-
- char PortNo[60];
- struct _EXTPORTDATA * PORTVEC;
-
- hwndDlg = hDlg; // Save Window Handle
-
- // Save a pointer to the DLGHDR structure.
-
-#define GWL_USERDATA (-21)
-
- SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) pHdr);
-
- // Create the tab control.
-
-
- init.dwICC = ICC_STANDARD_CLASSES;
- init.dwSize=sizeof(init);
- i=InitCommonControlsEx(&init);
-
- pHdr->hwndTab = CreateWindow(WC_TABCONTROL, "", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
- 0, 0, 100, 100, hwndDlg, NULL, hInstance, NULL);
-
- if (pHdr->hwndTab == NULL) {
-
- // handle error
-
- }
-
- // Add a tab for each of the child dialog boxes.
-
- tie.mask = TCIF_TEXT | TCIF_IMAGE;
-
- tie.iImage = -1;
-
- for (i = 1; i <= NUMBEROFPORTS; i++)
- {
- // Only allow UI on ax.25 ports
-
- PORTVEC = (struct _EXTPORTDATA * )GetPortTableEntryFromSlot(i);
-
- if (PORTVEC->PORTCONTROL.PORTTYPE == 16) // EXTERNAL
- if (PORTVEC->PORTCONTROL.PROTOCOL == 10) // Pactor/WINMOR
- if (PORTVEC->PORTCONTROL.UICAPABLE == 0)
- continue;
-
- wsprintf(PortNo, "Port %2d", GetPortNumber(i));
- PortNum[tab] = i;
-
- tie.pszText = PortNo;
- TabCtrl_InsertItem(pHdr->hwndTab, tab, &tie);
-
- pHdr->apRes[tab++] = DoLockDlgRes("PORTPAGE");
- }
-
- PageCount = tab;
-
- // Determine the bounding rectangle for all child dialog boxes.
-
- SetRectEmpty(&rcTab);
-
- for (i = 0; i < PageCount; i++)
- {
- if (pHdr->apRes[i]->cx > rcTab.right)
- rcTab.right = pHdr->apRes[i]->cx;
-
- if (pHdr->apRes[i]->cy > rcTab.bottom)
- rcTab.bottom = pHdr->apRes[i]->cy;
-
- }
-
- MapDialogRect(hwndDlg, &rcTab);
-
-// rcTab.right = rcTab.right * LOWORD(dwDlgBase) / 4;
-
-// rcTab.bottom = rcTab.bottom * HIWORD(dwDlgBase) / 8;
-
- // Calculate how large to make the tab control, so
-
- // the display area can accomodate all the child dialog boxes.
-
- TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
-
- OffsetRect(&rcTab, cxMargin - rcTab.left, cyMargin - rcTab.top);
-
- // Calculate the display rectangle.
-
- CopyRect(&pHdr->rcDisplay, &rcTab);
-
- TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay);
-
- // Set the size and position of the tab control, buttons,
-
- // and dialog box.
-
- SetWindowPos(pHdr->hwndTab, NULL, rcTab.left, rcTab.top, rcTab.right - rcTab.left, rcTab.bottom - rcTab.top, SWP_NOZORDER);
-
- // Move the Buttons to bottom of page
-
- pos=rcTab.left+cxMargin;
-
-
- // Size the dialog box.
-
- SetWindowPos(hwndDlg, NULL, 0, 0, rcTab.right + cyMargin + 2 * GetSystemMetrics(SM_CXDLGFRAME),
- rcTab.bottom + 2 * cyMargin + 2 * GetSystemMetrics(SM_CYDLGFRAME) + GetSystemMetrics(SM_CYCAPTION),
- SWP_NOMOVE | SWP_NOZORDER);
-
- // Simulate selection of the first item.
-
- OnSelChanged(hwndDlg);
-
-}
-
-// DoLockDlgRes - loads and locks a dialog template resource.
-
-// Returns a pointer to the locked resource.
-
-// lpszResName - name of the resource
-
-DLGTEMPLATE * WINAPI DoLockDlgRes(LPCSTR lpszResName)
-{
- HRSRC hrsrc = FindResource(hInstance, lpszResName, RT_DIALOG);
- HGLOBAL hglb = LoadResource(hInstance, hrsrc);
-
- return (DLGTEMPLATE *) LockResource(hglb);
-}
-
-//The following function processes the TCN_SELCHANGE notification message for the main dialog box. The function destroys the dialog box for the outgoing page, if any. Then it uses the CreateDialogIndirect function to create a modeless dialog box for the incoming page.
-
-// OnSelChanged - processes the TCN_SELCHANGE notification.
-
-// hwndDlg - handle of the parent dialog box
-
-VOID WINAPI OnSelChanged(HWND hwndDlg)
-{
- char PortDesc[40];
- int Port;
-
- DLGHDR *pHdr = (DLGHDR *) GetWindowLong(hwndDlg, GWL_USERDATA);
-
- CurrentPage = TabCtrl_GetCurSel(pHdr->hwndTab);
-
- // Destroy the current child dialog box, if any.
-
- if (pHdr->hwndDisplay != NULL)
-
- DestroyWindow(pHdr->hwndDisplay);
-
- // Create the new child dialog box.
-
- pHdr->hwndDisplay = CreateDialogIndirect(hInstance, pHdr->apRes[CurrentPage], hwndDlg, ChildDialogProc);
-
- hwndDisplay = pHdr->hwndDisplay; // Save
-
- Port = PortNum[CurrentPage];
- // Fill in the controls
-
- GetPortDescription(PortNum[CurrentPage], PortDesc);
-
- SetDlgItemText(hwndDisplay, IDC_PORTNAME, PortDesc);
-
- CheckDlgButton(hwndDisplay, IDC_FROMFILE, SendFromFile[Port]);
-
- SetDlgItemInt(hwndDisplay, IDC_INTERVAL, Interval[Port], FALSE);
-
- SetDlgItemText(hwndDisplay, IDC_UIDEST, &UIUIDEST[Port][0]);
- SetDlgItemText(hwndDisplay, IDC_UIDIGIS, UIUIDigi[Port]);
-
-
-
- SetDlgItemText(hwndDisplay, IDC_FILENAME, &FN[Port][0]);
- SetDlgItemText(hwndDisplay, IDC_MESSAGE, &Message[Port][0]);
-
- ShowWindow(pHdr->hwndDisplay, SW_SHOWNORMAL);
-
-}
-
-
-//The following function processes the WM_INITDIALOG message for each of the child dialog boxes. You cannot specify the position of a dialog box created using the CreateDialogIndirect function. This function uses the SetWindowPos function to position the child dialog within the tab control's display area.
-
-// OnChildDialogInit - Positions the child dialog box to fall
-
-// within the display area of the tab control.
-
-VOID WINAPI OnChildDialogInit(HWND hwndDlg)
-{
- HWND hwndParent = GetParent(hwndDlg);
- DLGHDR *pHdr = (DLGHDR *) GetWindowLong(hwndParent, GWL_USERDATA);
-
- SetWindowPos(hwndDlg, HWND_TOP, pHdr->rcDisplay.left, pHdr->rcDisplay.top, 0, 0, SWP_NOSIZE);
-}
-
-
-
-LRESULT CALLBACK UIWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- int wmId, wmEvent;
- HKEY hKey=0;
-
- switch (message) {
-
- case WM_INITDIALOG:
- OnTabbedDialogInit(hWnd);
- return (INT_PTR)TRUE;
-
- case WM_NOTIFY:
-
- switch (((LPNMHDR)lParam)->code)
- {
- case TCN_SELCHANGE:
- OnSelChanged(hWnd);
- return TRUE;
- // More cases on WM_NOTIFY switch.
- case NM_CHAR:
- return TRUE;
- }
-
- break;
-
-
- case WM_CTLCOLORDLG:
- return (LONG)bgBrush;
-
- case WM_CTLCOLORSTATIC:
- {
- HDC hdcStatic = (HDC)wParam;
- SetTextColor(hdcStatic, RGB(0, 0, 0));
- SetBkMode(hdcStatic, TRANSPARENT);
-
- return (LONG)bgBrush;
- }
-
- case WM_COMMAND:
-
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
-
- switch (wmId) {
-
- case IDOK:
-
- return TRUE;
-
- default:
-
- return 0;
- }
-
-
- case WM_SYSCOMMAND:
-
- wmId = LOWORD(wParam); // Remember, these are...
- wmEvent = HIWORD(wParam); // ...different for Win32!
-
- switch (wmId)
- {
- case SC_RESTORE:
-
- return (DefWindowProc(hWnd, message, wParam, lParam));
-
- 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:
- return(DestroyWindow(hWnd));
-
- default:
- return (DefWindowProc(hWnd, message, wParam, lParam));
-
- }
-
- return (0);
-}
-
-#endif
-
-extern struct DATAMESSAGE * REPLYBUFFER;
-char * __cdecl Cmdprintf(TRANSPORTENTRY * Session, char * Bufferptr, const char * format, ...);
-
-void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struct CMDX * CMD)
-{
- char FN[250];
- FILE *hFile;
- struct stat STAT;
- struct PORTCONTROL * PORT = PORTTABLE;
- char PortList[256] = "";
-
- while (PORT)
- {
- if (PORT->CTEXT)
- {
- free(PORT->CTEXT);
- PORT->CTEXT = 0;
- }
-
- if (BPQDirectory[0] == 0)
- sprintf(FN, "Port%dCTEXT.txt", PORT->PORTNUMBER);
- else
- sprintf(FN, "%s/Port%dCTEXT.txt", BPQDirectory, PORT->PORTNUMBER);
-
- if (stat(FN, &STAT) == -1)
- {
- PORT = PORT->PORTPOINTER;
- continue;
- }
-
- hFile = fopen(FN, "rb");
-
- if (hFile)
- {
- char * ptr;
-
- PORT->CTEXT = zalloc(STAT.st_size + 1);
- fread(PORT->CTEXT , 1, STAT.st_size, hFile);
- fclose(hFile);
-
- // convert CRLF or LF to CR
-
- while (ptr = strstr(PORT->CTEXT, "\r\n"))
- memmove(ptr, ptr + 1, strlen(ptr));
-
- // Now has LF
-
- while (ptr = strchr(PORT->CTEXT, '\n'))
- *ptr = '\r';
-
-
- sprintf(PortList, "%s,%d", PortList, PORT->PORTNUMBER);
- }
-
- PORT = PORT->PORTPOINTER;
- }
-
- if (Session)
- {
- Bufferptr = Cmdprintf(Session, Bufferptr, "CTEXT Read for ports %s\r", &PortList[1]);
- SendCommandReply(Session, REPLYBUFFER, (int)(Bufferptr - (char *)REPLYBUFFER));
- }
- else
- Debugprintf("CTEXT Read for ports %s\r", &PortList[1]);
-}
-
-// Get the current frequency for a port. This can get a bit complicated, especially if looking for centre freq
-// rather than dial freq (as this depends on mode).
-//
-// Used for various reporting functions - MH, Maps, BBS New User message,
-
-// I think I'll try PORT "PortFreq" setting first then if that isn't available via rigcontrol.
-//
-// For now at least will report dial freq if using RIGCONTROL
-
-DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqString)
-{
- struct PORTCONTROL * PORT = GetPortTableEntryFromPortNum(PortNo);
- double freq = 0.0;
- uint64_t freqint = 0;
-
- char * ptr;
- int n = 3;
-
- FreqString[0] = 0;
-
- if (PORT == 0)
- return 0;
-
- if (PORT->PortFreq)
- {
- freqint = PORT->PortFreq;
- freq = freqint / 1000000.0;
- }
- else
- {
- // Try rigcontrol
-
-
- struct TNCINFO * TNC;
- struct RIGINFO * RIG = 0;
-
- if (PORT->RIGPort)
- TNC = TNCInfo[PORT->RIGPort];
- else
- TNC = TNCInfo[PortNo];
-
- if (TNC)
- RIG = TNC->RIG;
-
- if (RIG == 0)
- return 0;
-
- // Frequency should be in valchar
-
- if (RIG->Valchar[0] == 0)
- return 0;
-
- freq = atof(TNC->RIG->Valchar);
- freqint = (int64_t)(freq * 1000000.0);
- }
-
- sprintf(FreqString, "%.6f", freq);
-
- // Return 3 digits after . (KHz) unless more are significant
-
- ptr = &FreqString[strlen(FreqString) - 1];
-
- while (n-- && *(ptr) == '0')
- *ptr-- = 0;
-
- return freqint;
-}
-
-SOCKET OpenHTTPSock(char * Host)
-{
- SOCKET sock = 0;
- struct sockaddr_in destaddr;
- struct sockaddr_in sinx;
- int addrlen=sizeof(sinx);
- struct hostent * HostEnt;
- int err;
- u_long param=1;
- BOOL bcopt=TRUE;
-
- destaddr.sin_family = AF_INET;
- destaddr.sin_port = htons(80);
-
- // Resolve name to address
-
- HostEnt = gethostbyname (Host);
-
- if (!HostEnt)
- {
- err = WSAGetLastError();
-
- Debugprintf("Resolve Failed for %s %d %x", Host, err, err);
- return 0 ; // Resolve failed
- }
-
- memcpy(&destaddr.sin_addr.s_addr,HostEnt->h_addr,4);
-
- // Allocate a Socket entry
-
- sock = socket(AF_INET,SOCK_STREAM,0);
-
- if (sock == INVALID_SOCKET)
- return 0;
-
- setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4);
-
- sinx.sin_family = AF_INET;
- sinx.sin_addr.s_addr = INADDR_ANY;
- sinx.sin_port = 0;
-
- if (bind(sock, (struct sockaddr *) &sinx, addrlen) != 0 )
- return FALSE;
-
- if (connect(sock,(struct sockaddr *) &destaddr, sizeof(destaddr)) != 0)
- {
- err=WSAGetLastError();
- closesocket(sock);
- return 0;
- }
-
- return sock;
-}
-
-static char HeaderTemplate[] = "POST %s HTTP/1.1\r\n"
- "Accept: app N B lication/json\r\n"
-// "Accept-Encoding: gzip,deflate,gzip, deflate\r\n"
- "Content-Type: application/json\r\n"
- "Host: %s:%d\r\n"
- "Content-Length: %d\r\n"
- "User-Agent: %s%s\r\n"
-// "Expect: 100-continue\r\n"
- "\r\n";
-
-
-DllExport VOID WINAPI SendWebRequest(char * Host, char * Request, char * Params, char * Return)
-{
- SOCKET sock;
- int InputLen = 0;
- int inptr = 0;
- char Buffer[4096];
- char Header[256];
- char * ptr, * ptr1;
- int Sent;
- int Len = strlen(Params);
-
- if (M0LTEMap == 0)
- return;
-
- sock = OpenHTTPSock(Host);
-
- if (sock == 0)
- return;
-
-#ifdef LINBPQ
- sprintf(Header, HeaderTemplate, Request, Host, 80, Len, "linbpq/", VersionString, Params);
-#else
- sprintf(Header, HeaderTemplate, Request, Host, 80, Len, "bpq32/", VersionString, Params);
-#endif
- Sent = send(sock, Header, (int)strlen(Header), 0);
- Sent = send(sock, Params, (int)strlen(Params), 0);
-
- if (Sent == -1)
- {
- int Err = WSAGetLastError();
- Debugprintf("Error %d from Web Update send()", Err);
- closesocket(sock);
- return;
- }
-
- while (InputLen != -1)
- {
- InputLen = recv(sock, &Buffer[inptr], 4095 - inptr, 0);
-
- if (InputLen == -1 || InputLen == 0)
- {
- int Err = WSAGetLastError();
- Debugprintf("Error %d from Web Update recv()", Err);
- closesocket(sock);
- return;
- }
-
- inptr += InputLen;
-
- Buffer[inptr] = 0;
-
- ptr = strstr(Buffer, "\r\n\r\n");
-
- if (ptr)
- {
- // got header
-
- int Hddrlen = (int)(ptr - Buffer);
-
- ptr1 = strstr(Buffer, "Content-Length:");
-
- if (ptr1)
- {
- // Have content length
-
- int ContentLen = atoi(ptr1 + 16);
-
- if (ContentLen + Hddrlen + 4 == inptr)
- {
- // got whole response
-
- if (strstr(Buffer, " 200 OK"))
- {
- if (Return)
- {
- memcpy(Return, ptr + 4, ContentLen);
- Return[ContentLen] = 0;
- }
- else
- Debugprintf("Map Database update ok");
-
- }
- else
- {
- strlop(Buffer, 13);
- Debugprintf("Map Update failed - %s", Buffer);
- }
- closesocket(sock);
- return;
- }
- }
- else
- {
- ptr1 = strstr(_strlwr(Buffer), "transfer-encoding:");
-
- if (ptr1)
- {
- // Just accept anything until I've sorted things with Lee
-
- closesocket(sock);
- Debugprintf("Web Database update ok");
- return;
- }
- }
- }
- }
-}
-
-// https://packetnodes.spots.radio/api/NodeData/{callsign}
-
-//SendHTTPRequest(sock, "/account/exists", Message, Len, Response);
-
-#include "kiss.h"
-
-extern char MYALIASLOPPED[10];
-extern int MasterPort[MAXBPQPORTS+1];
-
-
-// G7TAJ //
-/*
- {"mheard": [
- {
- "Callsign": "GB7CIP-7",
- "Port": "VHF",
- "Packets": 70369,
- "LastHeard": "2024-12-29 20:26:32"
- },
-*/
-
-void BuildPortMH(char * MHJSON, struct PORTCONTROL * PORT)
-{
- struct tm * TM;
- static char MHTIME[50];
- time_t szClock;
- MHSTRUC * MH = PORT->PORTMHEARD;
- int count = MHENTRIES;
- char Normcall[20];
- int len;
- char * ptr;
- char mhstr[400];
- int i;
- char c;
-
- if (MH == NULL)
- return;
-
- while (count--)
- {
- if (MH->MHCALL[0] == 0)
- break;
-
- len = ConvFromAX25(MH->MHCALL, Normcall);
- Normcall[len] = 0;
-
- ptr = &MH->MHCALL[6]; // End of Address bit
-
- if ((*ptr & 1) == 0)
- {
- // at least one digi - which we are not going to include
- MH++;
- continue;
- }
-
- // validate call to prevent corruption of json
-
- for (i=0; i < len; i++)
- {
- c = Normcall[i];
-
- if (!isalnum(c) && !(c == '#') && !(c == ' ') && !(c == '-'))
- goto skipit;
- }
-
-
- //format TIME
-
- szClock = MH->MHTIME;
- TM = gmtime(&szClock);
- sprintf(MHTIME, "%d-%d-%d %02d:%02d:%02d",
- TM->tm_year+1900, TM->tm_mon + 1, TM->tm_mday, TM->tm_hour, TM->tm_min, TM->tm_sec);
-
- sprintf(mhstr, "{\"callSign\": \"%s\", \"port\": \"%d\", \"packets\": %d, \"lastHeard\": \"%s\" },\r\n" ,
- Normcall, PORT->PORTNUMBER, MH->MHCOUNT, MHTIME);
-
- strcat( MHJSON, mhstr );
-skipit:
- MH++;
- }
-}
-
-void SendDataToPktMapThread();
-
-void SendDataToPktMap()
-{
- _beginthread(SendDataToPktMapThread,2048000,0);
-}
-
-void SendDataToPktMapThread()
-{
- char Return[256] = "";
- char Request[64];
- char Params[50000];
-
- struct PORTCONTROL * PORT = PORTTABLE;
- struct PORTCONTROL * SAVEPORT;
- struct ROUTE * Routes = NEIGHBOURS;
- int MaxRoutes = MAXNEIGHBOURS;
-
- int PortNo;
- int Active;
- uint64_t Freq;
- int Baud;
- int Bitrate;
- char * Mode;
- char * Use;
- char * Type;
- char * Modulation;
- char * Usage;
-
- char locked[] = " ! ";
- int Percent = 0;
- int Port = 0;
- char Normcall[10];
- char Copy[20];
- char ID[33];
-
- char * ptr = Params;
-
-// G7TAJ //
- char MHJSON[50000];
- char * mhptr;
- char * b4Routesptr;
-
- MHJSON[0]=0;
-// G7TAJ //
-
-// printf("Sending to new map\n");
-
- sprintf(Request, "/api/NodeData/%s", MYNODECALL);
-
-// https://packetnodes.spots.radio/swagger/index.html
-
- // This builds the request and sends it
-
- // Minimum header seems to be
-
- // "nodeAlias": "BPQ",
- // "location": {"locator": "IO68VL"},
- // "software": {"name": "BPQ32","version": "6.0.24.3"},
-
- ptr += sprintf(ptr, "{\"nodeAlias\": \"%s\",\r\n", MYALIASLOPPED);
-
- if (strlen(LOCATOR) == 6)
- ptr += sprintf(ptr, "\"location\": {\"locator\": \"%s\"},\r\n", LOCATOR);
- else
- {
- // Lat Lon
-
- double myLat, myLon;
- char LocCopy[80];
- char * context;
-
- strcpy(LocCopy, LOCATOR);
-
- myLat = atof(strtok_s(LocCopy, ",:; ", &context));
- myLon = atof(context);
-
- ptr += sprintf(ptr, "\"location\": {\"coords\": {\"lat\": %f, \"lon\": %f}},\r\n",
- myLat, myLon);
-
- }
-
-#ifdef LINBPQ
- ptr += sprintf(ptr, "\"software\": {\"name\": \"LINBPQ\",\"version\": \"%s\"},\r\n", VersionString);
-#else
- ptr += sprintf(ptr, "\"software\": {\"name\": \"BPQ32\",\"version\": \"%s\"},\r\n", VersionString);
-#endif
- ptr += sprintf(ptr, "\"source\": \"ReportedByNode\",\r\n");
-
-// G7TAJ //
- sprintf(MHJSON, ",\"mheard\": [");
-// G7TAJ //
-
-
- //Ports
-
- ptr += sprintf(ptr, "\"ports\": [");
-
- // Get active ports
-
- while (PORT)
- {
- PortNo = PORT->PORTNUMBER;
-
- if (PORT->Hide)
- {
- PORT = PORT->PORTPOINTER;
- continue;
- }
-
- if (PORT->SendtoM0LTEMap == 0)
- {
- PORT = PORT->PORTPOINTER;
- continue;
- }
-
- // Try to get port status - may not be possible with some
-
- if (PORT->PortStopped)
- {
- PORT = PORT->PORTPOINTER;
- continue;
- }
-
- Active = 0;
- Freq = 0;
- Baud = 0;
- Mode = "ax.25";
- Use = "";
- Type = "RF";
- Bitrate = 0;
- Modulation = "FSK";
- Usage = "Access";
-
- if (PORT->PortFreq)
- Freq = PORT->PortFreq;
-
- if (PORT->PORTTYPE == 0)
- {
- struct KISSINFO * KISS = (struct KISSINFO *)PORT;
- NPASYINFO Port;
-
- SAVEPORT = PORT;
-
- if (KISS->FIRSTPORT && KISS->FIRSTPORT != KISS)
- {
- // Not first port on device
-
- PORT = (struct PORTCONTROL *)KISS->FIRSTPORT;
- Port = KISSInfo[PortNo];
- }
-
- Port = KISSInfo[PORT->PORTNUMBER];
-
- if (Port)
- {
- // KISS like - see if connected
-
- if (PORT->PORTIPADDR.s_addr || PORT->KISSSLAVE)
- {
- // KISS over UDP or TCP
-
- if (PORT->KISSTCP)
- {
- if (Port->Connected)
- Active = 1;
- }
- else
- Active = 1; // UDP - Cant tell
- }
- else
- if (Port->idComDev) // Serial port Open
- Active = 1;
-
- PORT = SAVEPORT;
- }
- }
- else if (PORT->PORTTYPE == 14) // Loopback
- Active = 0;
-
- else if (PORT->PORTTYPE == 16) // External
- {
- if (PORT->PROTOCOL == 10) // 'HF' Port
- {
- struct TNCINFO * TNC = TNCInfo[PortNo];
- struct AGWINFO * AGW;
-
- if (TNC == NULL)
- {
- PORT = PORT->PORTPOINTER;
- continue;
- }
-
- if (Freq == 0 && TNC->RIG)
- Freq = TNC->RIG->RigFreq * 1000000;
-
- switch (TNC->Hardware) // Hardware Type
- {
- case H_KAM:
- case H_AEA:
- case H_HAL:
- case H_SERIAL:
-
- // Serial
-
- if (TNC->hDevice)
- Active = 1;
-
- break;
-
- case H_SCS:
- case H_TRK:
- case H_WINRPR:
-
- if (TNC->HostMode)
- Active = 1;
-
- break;
-
-
- case H_UZ7HO:
-
- if (TNCInfo[MasterPort[PortNo]]->CONNECTED)
- Active = 1;
-
- // Try to get mode and frequency
-
- AGW = TNC->AGWInfo;
-
- if (AGW && AGW->isQTSM)
- {
- if (AGW->ModemName[0])
- {
- char * ptr1, * ptr2, *Context;
-
- strcpy(Copy, AGW->ModemName);
- ptr1 = strtok_s(Copy, " ", & Context);
- ptr2 = strtok_s(NULL, " ", & Context);
-
- if (Context)
- {
- Modulation = Copy;
-
- if (strstr(ptr1, "BPSK") || strstr(ptr1, "AFSK"))
- {
- Baud = Bitrate = atoi(Context);
- }
- else if (strstr(ptr1, "QPSK"))
- {
- Modulation = "QPSK";
- Bitrate = atoi(Context);
- Baud = Bitrate /2;
- }
- }
- }
- }
-
- break;
-
- case H_KISSHF:
-
- // Try to get mode from ID then drop through
-
- if (stristr(PORT->PORTDESCRIPTION, "BPSK"))
- {
- Modulation = "BPSK";
- }
-
- case H_WINMOR:
- case H_V4:
-
- case H_MPSK:
- case H_FLDIGI:
- case H_UIARQ:
- case H_ARDOP:
- case H_VARA:
-
- case H_FREEDATA:
-
- // TCP
-
- Mode = Modenames[TNC->Hardware - 1];
-
- if (TNC->CONNECTED)
- Active = 1;
-
- break;
-
- case H_TELNET:
-
- Active = 1;
- Type = "Internet";
- Mode = "";
- }
- }
- else
- {
- // External but not HF - AXIP, BPQETHER VKISS, ??
-
- struct _EXTPORTDATA * EXTPORT = (struct _EXTPORTDATA *)PORT;
- Type = "Internet";
- Active = 1;
- }
- }
-
- if (Active)
- {
- char * ptr2 = &ID[29];
- strcpy(ID, PORT->PORTDESCRIPTION);
- while (*(ptr2) == ' ' && ptr2 != ID)
- *(ptr2--) = 0;
-
- if (PORT->M0LTEMapInfo)
- {
- // Override with user configured values - RF,7.045,BPSK,300,300,Access
-
- char param[256];
- char *p1, *p2, *p3, *p4, *p5;
-
- strcpy(param, PORT->M0LTEMapInfo);
-
- p1 = strlop(param, ',');
- p2 = strlop(p1, ',');
- p3 = strlop(p2, ',');
- p4 = strlop(p3, ',');
- p5 = strlop(p4, ',');
-
- // int n = sscanf(PORT->M0LTEMapInfo, "%s,%s,%s,%s,%s,%s", &p1, &p2, &p3, &p4, &p5, &p6);
-
- if (p5)
- {
- if (param[0]) Type = param;
-
- if (p1[0])
- {
- // if set to DIAL+=n and frequency set from config or rigcontrol modify it
-
- uint64_t offset = 0;
-
- if (_memicmp(p1, "DIAL+", 5) == 0)
- offset = atoi(&p1[5]);
- else if (_memicmp(p1, "DIAL-", 5) == 0)
- offset = -atoi(&p1[5]);
- else
- Freq = atof(p1) * 1000000;
-
- if (Freq != 0)
- Freq += offset;
-
- }
-
- if (p2[0]) Modulation = p2;
- if (p3[0]) Baud = atoi(p3);
- if (p4[0]) Bitrate = atoi(p4);
- if (p5[0]) Usage = p5;
- }
- }
-
- ptr += sprintf(ptr, "{\"id\": \"%d\",\"linkType\": \"%s\","
- "\"freq\": \"%lld\",\"mode\": \"%s\",\"modulation\": \"%s\","
- "\"baud\": \"%d\",\"bitrate\": \"%d\",\"usage\": \"%s\",\"comment\": \"%s\"},\r\n",
- PortNo, Type,
- Freq, Mode, Modulation,
- Baud, Bitrate, Usage, ID);
-
-// G7TAJ //
- // make MH list to be added later
- BuildPortMH(MHJSON, PORT);
-
-// G7TAJ //
-
-
- }
-
- PORT = PORT->PORTPOINTER;
- }
-
- ptr -= 3;
- ptr += sprintf(ptr, "],\r\n");
-
- // Neighbours
-
-// G7TAJ //
- b4Routesptr = ptr-3;
-// G7TAJ //
-
- ptr += sprintf(ptr, "\"neighbours\": [\r\n");
-
- while (MaxRoutes--)
- {
- if (Routes->NEIGHBOUR_CALL[0] != 0)
- if (Routes->NEIGHBOUR_LINK && Routes->NEIGHBOUR_LINK->L2STATE >= 5)
- {
- ConvFromAX25(Routes->NEIGHBOUR_CALL, Normcall);
- strlop(Normcall, ' ');
-
- ptr += sprintf(ptr,
- "{\"node\": \"%s\", \"port\": \"%d\", \"quality\": \"%d\"},\r\n",
- Normcall, Routes->NEIGHBOUR_PORT, Routes->NEIGHBOUR_QUAL);
- }
-
- Routes++;
- }
-
-// G7TAJ //
-
- // if !strstr quality, then there are none, so remove neighbours portion
- if ( strstr(Params, "quality") == NULL ) {
- ptr = b4Routesptr;
- } else {
- ptr -= 3;
- ptr += sprintf(ptr, "]");
- }
-
- if ( strlen(MHJSON) > 15 ) {
- mhptr = MHJSON + strlen(MHJSON);
- mhptr -= 3;
- sprintf(mhptr, "]\r\n");
- ptr += sprintf(ptr, "\r\n%s", MHJSON);
-
- }
-
- ptr += sprintf(ptr, "}");
-
-
-
-// G7TAJ //
-
-
-/*
-{
- "nodeAlias": "BPQ",
- "location": {"locator": "IO92KX"},
- "software": {"name": "BPQ32","version": "6.0.24.11 Debug Build "},
- "contact": "G8BPQ",
- "sysopComment": "Testing",
- "source": "ReportedByNode"
-}
-
- "ports": [
- {
- "id": "string",
- "linkType": "RF",
- "freq": 0,
- "mode": "string",
- "modulation": "string",
- "baud": 0,
- "bitrate": 0,
- "usage": "Access",
- "comment": "string"
- }
- ],
-
-*/
- // "contact": "string",
- // "neighbours": [{"node": "G7TAJ","port": "30"}]
-
- SendWebRequest("packetnodes.spots.radio", Request, Params, 0);
-}
-
-// ="{\"neighbours\": [{\"node\": \"G7TAJ\",\"port\": \"30\"}]}";
-
-//'POST' \
-// 'https://packetnodes.spots.radio/api/NodeData/GM8BPQ' \
-// -H 'accept: */*' \
-// -H 'Content-Type: application/json' \
-// -d '{
-// "nodeAlias": "BPQ",
-// "location": {"locator": "IO68VL"},
-// "software": {"name": "BPQ32","version": "6.0.24.3"},
-// "contact": "string",
-// "neighbours": [{"node": "G7TAJ","port": "30"}]
-//}'
-
-
-
-
-
-
-
-
-
diff --git a/CommonCode.c b/CommonCode.c
index 18d412c..0866980 100644
--- a/CommonCode.c
+++ b/CommonCode.c
@@ -18,7 +18,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/
-
// General C Routines common to bpq32 and linbpq. Mainly moved from BPQ32.c
#pragma data_seg("_BPQDATA")
@@ -914,7 +913,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');
}
@@ -1493,8 +1492,8 @@ int SendMsgEx(int stream, char * msg, int len, int GetSem)
if (QCOUNT < 50)
return 0; // Dont want to run out
- if (GetSem)
- GetSemaphore(&Semaphore, 10);
+ if (GetSem)
+ GetSemaphore(&Semaphore, 10);
if ((MSG = GetBuff()) == 0)
{
@@ -1623,7 +1622,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,6 +2686,14 @@ int DoRoutes()
{
if (Routes->NEIGHBOUR_CALL[0] != 0)
{
+ // Dont save routes from config file here or they are difficult to get rid of
+
+ if (Routes->NEIGHBOUR_FLAG & LOCKEDBYCONFIG)
+ {
+ Routes++;
+ continue;
+ }
+
len=ConvFromAX25(Routes->NEIGHBOUR_CALL,Normcall);
Normcall[len]=0;
@@ -2710,7 +2717,7 @@ int DoRoutes()
digis[0] = 0;
len=sprintf(line,
- "ROUTE ADD %s %d %d %s %d %d %d %d %d\n",
+ "ROUTE ADD %s %d %d %s %d %d %d %d %d %c\n",
Normcall,
Routes->NEIGHBOUR_PORT,
Routes->NEIGHBOUR_QUAL, digis,
@@ -2718,7 +2725,8 @@ int DoRoutes()
Routes->NBOUR_FRACK,
Routes->NBOUR_PACLEN,
Routes->INP3Node | (Routes->NoKeepAlive << 2),
- Routes->OtherendsRouteQual);
+ Routes->OtherendsRouteQual,
+ (Routes->NEIGHBOUR_FLAG & LOCKEDBYSYSOP)?'!':' ');
fputs(line, file);
}
diff --git a/FLDigi.c b/FLDigi.c
index 480a443..8c97113 100644
--- a/FLDigi.c
+++ b/FLDigi.c
@@ -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;
diff --git a/FreeDATA.c b/FreeDATA.c
index 66ff40a..0af1375 100644
--- a/FreeDATA.c
+++ b/FreeDATA.c
@@ -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);
diff --git a/HALDriver.c b/HALDriver.c
index a914a38..408ff97 100644
--- a/HALDriver.c
+++ b/HALDriver.c
@@ -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)
{
diff --git a/HFCommon.c b/HFCommon.c
index c0f82d7..1ecd775 100644
--- a/HFCommon.c
+++ b/HFCommon.c
@@ -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;
diff --git a/HSMODEM.c b/HSMODEM.c
index 4efdb80..d3430d7 100644
--- a/HSMODEM.c
+++ b/HSMODEM.c
@@ -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
diff --git a/HTTPcode-skigdebian.c b/HTTPcode-skigdebian.c
deleted file mode 100644
index ac0a3ff..0000000
--- a/HTTPcode-skigdebian.c
+++ /dev/null
@@ -1,5175 +0,0 @@
-/*
-Copyright 2001-2022 John Wiseman G8BPQ
-
-This file is part of LinBPQ/BPQ32.
-
-LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-LinBPQ/BPQ32 is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
-*/
-
-
-//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
-
-#define _CRT_SECURE_NO_DEPRECATE
-
-#define DllImport
-
-#include "cheaders.h"
-#include
-
-#include "tncinfo.h"
-#include "time.h"
-#include "bpq32.h"
-#include "telnetserver.h"
-
-// This is needed to link with a lib built from source
-
-#ifdef WIN32
-#define ZEXPORT __stdcall
-#endif
-
-#include
-
-#define CKernel
-#include "httpconnectioninfo.h"
-
-extern int MAXBUFFS, QCOUNT, MINBUFFCOUNT, NOBUFFCOUNT, BUFFERWAITS, L3FRAMES;
-extern int NUMBEROFNODES, MAXDESTS, L4CONNECTSOUT, L4CONNECTSIN, L4FRAMESTX, L4FRAMESRX, L4FRAMESRETRIED, OLDFRAMES;
-extern int STATSTIME;
-extern TRANSPORTENTRY * L4TABLE;
-extern BPQVECSTRUC BPQHOSTVECTOR[];
-extern BOOL APRSApplConnected;
-extern char VersionString[];
-VOID FormatTime3(char * Time, time_t cTime);
-DllExport int APIENTRY Get_APPLMASK(int Stream);
-VOID SaveUIConfig();
-int ProcessNodeSignon(SOCKET sock, struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, int LOCAL);
-VOID SetupUI(int Port);
-VOID SendUIBeacon(int Port);
-VOID GetParam(char * input, char * key, char * value);
-VOID ARDOPAbort(struct TNCINFO * TNC);
-VOID WriteMiniDump();
-BOOL KillTNC(struct TNCINFO * TNC);
-BOOL RestartTNC(struct TNCINFO * TNC);
-int GetAISPageInfo(char * Buffer, int ais, int adsb);
-int GetAPRSPageInfo(char * Buffer, double N, double S, double W, double E, int aprs, int ais, int adsb);
-unsigned char * Compressit(unsigned char * In, int Len, int * OutLen);
-char * stristr (char *ch1, char *ch2);
-int GetAPRSIcon(unsigned char * _REPLYBUFFER, char * NodeURL);
-char * GetStandardPage(char * FN, int * Len);
-BOOL SHA1PasswordHash(char * String, char * Hash);
-char * byte_base64_encode(char *str, int len);
-int APIProcessHTTPMessage(char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE);
-int RHPProcessHTTPMessage(struct ConnectionInfo * conn, char * response, char * Method, char * URL, char * request, BOOL LOCAL, BOOL COOKIE);
-
-extern struct ROUTE * NEIGHBOURS;
-extern int ROUTE_LEN;
-extern int MAXNEIGHBOURS;
-
-extern struct DEST_LIST * DESTS; // NODE LIST
-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 * RigWebPage;
-extern COLORREF Colours[256];
-
-extern BOOL IncludesMail;
-extern BOOL IncludesChat;
-
-extern BOOL APRSWeb;
-extern BOOL RigActive;
-
-extern HKEY REGTREE;
-
-extern BOOL APRSActive;
-
-extern UCHAR LogDirectory[];
-
-extern struct RIGPORTINFO * PORTInfo[34];
-extern int NumberofPorts;
-
-extern UCHAR ConfigDirectory[260];
-
-VOID sendandcheck(SOCKET sock, const char * Buffer, int Len);
-int CompareNode(const void *a, const void *b);
-int CompareAlias(const void *a, const void *b);
-void ProcessMailHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen, int InputLen, char * Token);
-void ProcessChatHTTPMessage(struct HTTPConnectionInfo * Session, char * Method, char * URL, char * input, char * Reply, int * RLen);
-struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot);
-int SetupNodeMenu(char * Buff, int SYSOP);
-int StatusProc(char * Buff);
-int ProcessMailSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL);
-int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, BOOL WebMail, int LOCAL);
-int ProcessChatSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * Reply, struct HTTPConnectionInfo ** Session, int LOCAL);
-VOID APRSProcessHTTPMessage(SOCKET sock, char * MsgPtr, BOOL LOCAL, BOOL COOKIE);
-
-
-static struct HTTPConnectionInfo * SessionList; // active term mode sessions
-
-char Mycall[10];
-
-char MAILPipeFileName[] = "\\\\.\\pipe\\BPQMAILWebPipe";
-char CHATPipeFileName[] = "\\\\.\\pipe\\BPQCHATWebPipe";
-
-char Index[] = "%s's BPQ32 Web Server