diff --git a/AGWAPI.c b/AGWAPI.c index bf4c7da..dcf3494 100644 --- a/AGWAPI.c +++ b/AGWAPI.c @@ -1142,6 +1142,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) int con,conport; int AGWYReply = 0; int state, change; + int n; // if we have hidden some ports then the port in the AGW packet will be an index into the visible ports, // not the real port number @@ -1196,7 +1197,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) conport=GetPortNumber(VisiblePortToRealPort[key[0]-48]); - sprintf(ConnectMsg,"C %d %s",conport,ToCall); + n = sprintf(ConnectMsg,"C %d %s",conport,ToCall); // if 'v' command add digis @@ -1211,7 +1212,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) while(nDigis--) { - sprintf(ConnectMsg, "%s, %s", ConnectMsg, Digis); + n += sprintf(&ConnectMsg[n], " %s", Digis); Digis += 10; } } diff --git a/AISCommon.c b/AISCommon.c index f0b6a6a..e123bb2 100644 --- a/AISCommon.c +++ b/AISCommon.c @@ -760,7 +760,7 @@ void SaveVesselDataBase() void LoadNavAidDataBase() { - int i; + int i, n, count; FILE *file; char buf[256]; @@ -793,10 +793,12 @@ void LoadNavAidDataBase() NavRecords = (struct NAVAIDRECORD **)malloc(NavAidCount * sizeof(void *)); + count = 0; + for (i = 0; i < NavAidCount; i++) { navptr = (struct NAVAIDRECORD *)malloc(sizeof(struct NAVAIDRECORD)); - NavRecords[i] = navptr; + NavRecords[count] = navptr; memset(navptr, 0, sizeof(struct NAVAIDRECORD)); fgets(buf, 255, file); @@ -807,6 +809,19 @@ void LoadNavAidDataBase() token = strtok(NULL, "|\n" ); strcpy(&navptr->name[0],token); + for (n = 0; n < 20; n++) + { + char c = navptr->name[n]; + + if (!isalpha(c) && !isdigit(c) && c != ' ' && c != '_') + { + count--; + break; + } + } + + count++; + token = strtok(NULL, "|\n" ); navptr->lat = atof(token); @@ -820,6 +835,7 @@ void LoadNavAidDataBase() navptr->TimeLastUpdated = atoi(token); } + NavAidCount = count; fclose(file); } diff --git a/APRSCode.c b/APRSCode.c index 7255c7a..2ee3b5f 100644 --- a/APRSCode.c +++ b/APRSCode.c @@ -553,6 +553,8 @@ int APRSWriteLog(char * msg) UCHAR Value[MAX_PATH]; time_t T; struct tm * tm; + int n; + if (LogAPRSIS == 0) return 0; @@ -574,8 +576,9 @@ int APRSWriteLog(char * msg) strcat(Value, "logs/APRS_"); } - sprintf(Value, "%s%02d%02d%02d.log", Value, - tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); + n = strlen(Value); + + sprintf(&Value[n], "%02d%02d%02d.log", tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); if ((file = fopen(Value, "ab")) == NULL) return FALSE; diff --git a/ARDOP.c b/ARDOP.c index 8cae151..a46fe3e 100644 --- a/ARDOP.c +++ b/ARDOP.c @@ -1494,7 +1494,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, cmd); if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { @@ -5955,8 +5958,8 @@ VOID ARAXINIT(struct PORTCONTROL * PORT) char Msg[80] = ""; memcpy(Msg, PORT->PORTDESCRIPTION, 30); - sprintf(Msg, "%s\n", Msg); - + strcat(Msg, "\n); + WritetoConsoleLocal(Msg); } diff --git a/BBSUtilities.c b/BBSUtilities.c index 8e7c10a..72a2371 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -5810,12 +5810,12 @@ VOID ProcessMsgLine(CIRCUIT * conn, struct UserInfo * user, char* Buffer, int ms } else { - ToLen = sprintf(ToString, "%sTo: %s\r\n", ToString, Addr); + ToLen = sprintf(&ToString[strlen(ToString)], "To: %s\r\n", Addr); continue; } } - ToLen = sprintf(ToString, "%sTo: %s@%s\r\n", ToString, Addr, Via); + ToLen = sprintf(&ToString[strlen(ToString)], "To: %s@%s\r\n", Addr, Via); continue; } @@ -5833,7 +5833,7 @@ VOID ProcessMsgLine(CIRCUIT * conn, struct UserInfo * user, char* Buffer, int ms } else { - ToLen = sprintf(ToString, "%sTo: %s\r\n", ToString, Addr); + ToLen = sprintf(&ToString[strlen(ToString)], "To: %s\r\n", Addr); // Add to B2 Message for RMS diff --git a/Bpq32.c b/Bpq32.c index 944010b..3bccd2f 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1253,6 +1253,9 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Fix problem using SENDRAW from BPQMail (63) // Fix compatibility with latest ardopcf (64) // Fix bug in RHP socket timeout code (65) +// Fix L4 RTT (66) +// Fix RigConrol with Chanxx but no other settings (66) + #define CKernel @@ -6117,13 +6120,14 @@ DllExport BOOL APIENTRY SaveReg(char * KeyIn, HANDLE hFile) { if (len > 76) { - len = sprintf(RegLine, "%s\\\r\n", RegLine); + len += sprintf(&RegLine[len], "\\\r\n", RegLine); + strcat(RegLine, "\\\r\n"); WriteFile(hFile, RegLine, len, &written, NULL); strcpy(RegLine, " "); len = 2; } - len = sprintf(RegLine, "%s%02x,", RegLine, Value[k]); + len += sprintf(&RegLine[len], "%02x,", Value[k]); } RegLine[--len] = 0x0d; RegLine[++len] = 0x0a; @@ -6149,19 +6153,20 @@ DllExport BOOL APIENTRY SaveReg(char * KeyIn, HANDLE hFile) { if (len > 76) { - len = sprintf(RegLine, "%s\\\r\n", RegLine); + len += sprintf(RegLine[len], "\\\r\n"); WriteFile(hFile, RegLine, len, &written, NULL); strcpy(RegLine, " "); len = 2; } - len = sprintf(RegLine, "%s%02x,", RegLine, Value[k]); + + len += sprintf(&RegLine[len], "%02x,", Value[k]); if (len > 76) { - len = sprintf(RegLine, "%s\\\r\n", RegLine); + len += sprintf(RegLine[len], "\\\r\n"); WriteFile(hFile, RegLine, len, &written, NULL); strcpy(RegLine, " "); } - len = sprintf(RegLine, "%s00,", RegLine); + len += sprintf(&RegLine[len], "00,"); } RegLine[--len] = 0x0d; diff --git a/Cmd.c b/Cmd.c index 9ff56fe..6b1db1a 100644 --- a/Cmd.c +++ b/Cmd.c @@ -1733,6 +1733,7 @@ VOID LISTENCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc char * ptr, *Context; struct PORTCONTROL * PORT = NULL; char ListenPortList[128] = ""; + int len = 0; ptr = strtok_s(CmdTail, " ,", &Context); @@ -1785,7 +1786,7 @@ VOID LISTENCMD(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, struc } } - sprintf(ListenPortList, "%s %d", ListenPortList, Port); + len += sprintf(&ListenPortList[len], " %d", Port); ListenMask |= ((uint64_t)1 << (Port - 1)); } diff --git a/CommonCode.c b/CommonCode.c index 0866980..f00b8f6 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -4792,6 +4792,7 @@ void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, st struct stat STAT; struct PORTCONTROL * PORT = PORTTABLE; char PortList[256] = ""; + int len = 0; while (PORT) { @@ -4833,7 +4834,7 @@ void GetPortCTEXT(TRANSPORTENTRY * Session, char * Bufferptr, char * CmdTail, st *ptr = '\r'; - sprintf(PortList, "%s,%d", PortList, PORT->PORTNUMBER); + len += sprintf(&PortList[len], ",%d", PORT->PORTNUMBER); } PORT = PORT->PORTPOINTER; diff --git a/FLDigi.c b/FLDigi.c index 8c97113..59d9008 100644 --- a/FLDigi.c +++ b/FLDigi.c @@ -538,8 +538,12 @@ pollloop: if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, cmd); + + if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { } diff --git a/FLDigi64.c b/FLDigi64.c deleted file mode 100644 index 4ca0a8d..0000000 --- a/FLDigi64.c +++ /dev/null @@ -1,3860 +0,0 @@ -/* -Copyright 2001-2018 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - -// -// FLARQ Emulator/FLDIGI Interface for BPQ32 -// - -#define _CRT_SECURE_NO_DEPRECATE - -#include "CHeaders.h" - -int (WINAPI FAR *GetModuleFileNameExPtr)(); -int (WINAPI FAR *EnumProcessesPtr)(); - - -#include -#include - -#include "tncinfo.h" - -#include "bpq32.h" - -#define VERSION_MAJOR 2 -#define VERSION_MINOR 0 - -#define SD_RECEIVE 0x00 -#define SD_SEND 0x01 -#define SD_BOTH 0x02 - -#define DLE 0x10 -#define SOH 1 -#define STX 2 -#define EOT 4 - -#define FEND 0xC0 -#define FESC 0xDB -#define TFEND 0xDC -#define TFESC 0xDD - -#define TIMESTAMP 352 - -#define CONTIMEOUT 1200 - -#define AGWHDDRLEN sizeof(struct AGWHEADER) - -extern int (WINAPI FAR *GetModuleFileNameExPtr)(); - -//int ResetExtDriver(int num); -extern char * PortConfig[33]; -int SemHeldByAPI; - -struct TNCINFO * TNCInfo[34]; // Records are Malloc'd - -static void ConnecttoFLDigiThread(void * portptr); - -void CreateMHWindow(); -int Update_MH_List(struct in_addr ipad, char * call, char proto); - -static int ConnecttoFLDigi(); -static int ProcessReceivedData(int bpqport); -static int ProcessLine(char * buf, int Port); -int KillTNC(struct TNCINFO * TNC); -static int RestartTNC(struct TNCINFO * TNC); -VOID ProcessFLDigiPacket(struct TNCINFO * TNC, char * Message, int Len); -VOID ProcessFLDigiKISSPacket(struct TNCINFO * TNC, char * Message, int Len); -struct TNCINFO * GetSessionKey(char * key, struct TNCINFO * TNC); -VOID SendARQData(struct TNCINFO * TNC, UINT * Buffer); -static VOID DoMonitorHddr(struct TNCINFO * TNC, struct AGWHEADER * RXHeader, UCHAR * Msg); -VOID SendRPBeacon(struct TNCINFO * TNC); -VOID FLReleaseTNC(struct TNCINFO * TNC); -unsigned int CalcCRC(UCHAR * ptr, int Len); -VOID ARQTimer(struct TNCINFO * TNC); -VOID QueueAndSend(struct TNCINFO * TNC, struct ARQINFO * ARQ, SOCKET sock, char * Msg, int MsgLen); -VOID SaveAndSend(struct TNCINFO * TNC, struct ARQINFO * ARQ, SOCKET sock, char * Msg, int MsgLen); -VOID ProcessARQStatus(struct TNCINFO * TNC, struct ARQINFO * ARQ, char *Input); -VOID SendXMLPoll(struct TNCINFO * TNC); -static int ProcessXMLData(int port); -VOID CheckFLDigiData(struct TNCINFO * TNC); -VOID SendPacket(struct TNCINFO * TNC, UCHAR * Msg, int MsgLen); -int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len); -VOID SendXMLCommand(struct TNCINFO * TNC, char * Command, char * Value, char ParamType); -VOID FLSlowTimer(struct TNCINFO * TNC); -VOID SendKISSCommand(struct TNCINFO * TNC, char * Msg); - -int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len); -VOID SuspendOtherPorts(struct TNCINFO * ThisTNC); -VOID ReleaseOtherPorts(struct TNCINFO * ThisTNC); - -char * strlop(char * buf, char delim); - -extern UCHAR BPQDirectory[]; - -#define MAXBPQPORTS 32 -#define MAXMPSKPORTS 16 - -//LOGFONT LFTTYFONT ; - -//HFONT hFont ; - -static int MPSKChannel[MAXBPQPORTS+1]; // BPQ Port to MPSK Port -static int BPQPort[MAXMPSKPORTS][MAXBPQPORTS+1]; // MPSK Port and Connection to BPQ Port -//static int MPSKtoBPQ_Q[MAXBPQPORTS+1]; // Frames for BPQ, indexed by BPQ Port -//static int BPQtoMPSK_Q[MAXBPQPORTS+1]; // Frames for MPSK. indexed by MPSK port. Only used it TCP session is blocked - -// Each port may be on a different machine. We only open one connection to each MPSK instance - -static char * MPSKSignon[MAXBPQPORTS+1]; // Pointer to message for secure signin - -static unsigned int MPSKInst = 0; -static int AttachedProcesses=0; - -static HWND hResWnd,hMHWnd; -static BOOL GotMsg; - -static HANDLE STDOUT=0; - -//SOCKET sock; - -static SOCKADDR_IN sinx; -static SOCKADDR_IN rxaddr; -static SOCKADDR_IN destaddr[MAXBPQPORTS+1]; - -static int addrlen=sizeof(sinx); - -//static short MPSKPort=0; - -static time_t ltime,lasttime[MAXBPQPORTS+1]; - -static BOOL CONNECTING[MAXBPQPORTS+1]; -static BOOL CONNECTED[MAXBPQPORTS+1]; - -//HANDLE hInstance; - -static char WindowTitle[] = "FLDIGI"; -static char ClassName[] = "FLDIGISTATUS"; -static int RigControlRow = 165; - -static fd_set readfs; -static fd_set writefs; -static fd_set errorfs; -static struct timeval timeout; - -int Blocksizes[10] = {0,2,4,8,16,32,64,128,256,512}; - - -static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) -{ - PMSGWITHLEN buffptr; - char txbuff[500]; - unsigned int txlen=0; - struct TNCINFO * TNC = TNCInfo[port]; - int Stream = 0; - struct STREAMINFO * STREAM; - int TNCOK; - - if (TNC == NULL) - return 0; // Port not defined - - // Look for attach on any call - -// for (Stream = 0; Stream <= 1; Stream++) - { - STREAM = &TNC->Streams[Stream]; - - if (TNC->PortRecord->ATTACHEDSESSIONS[Stream] && TNC->Streams[Stream].Attached == 0) - { - char Cmd[80]; - - // New Attach - - int calllen; - STREAM->Attached = TRUE; - - TNC->FLInfo->RAW = FALSE; - - calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4USER, STREAM->MyCall); - STREAM->MyCall[calllen] = 0; - STREAM->FramesOutstanding = 0; - - SuspendOtherPorts(TNC); // Dont allow connects on interlocked ports - - // Stop Scanning - - sprintf(Cmd, "%d SCANSTOP", TNC->Port); - Rig_Command(-1, Cmd); - - sprintf(TNC->WEB_TNCSTATE, "In Use by %s", TNC->Streams[0].MyCall); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - -/* len = sprintf(Cmd, "%cSTOP_BEACON_ARQ_FAE\x1b", '\x1a'); - - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Cmd); // Savde till not transmitting - else - SendPacket(TNC->TCPDataSock, Cmd, len, 0); -*/ - } - } - - switch (fn) - { - case 7: - - // 100 mS Timer. - - // See if waiting for busy to clear before sending a connect - - if (TNC->BusyDelay) - { - // Still Busy? - - if (InterlockedCheckBusy(TNC) == FALSE) - { - // No, so send connect - - struct ARQINFO * ARQ = TNC->ARQInfo; - int SendLen; - char Reply[80]; - - SendLen = sprintf(Reply, "c%s:42 %s:24 %c 7 T60R5W10", - STREAM->MyCall, STREAM->RemoteCall, ARQ->OurStream); - - strcpy(TNC->WEB_PROTOSTATE, "Connecting"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - ARQ->ARQState = ARQ_ACTIVE; - - ARQ->ARQTimerState = ARQ_CONNECTING; - SaveAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - - STREAM->Connecting = TRUE; - - sprintf(TNC->WEB_TNCSTATE, "%s Connecting to %s", STREAM->MyCall, STREAM->RemoteCall); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - strcpy(TNC->WEB_PROTOSTATE, "Connecting"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - TNC->BusyDelay = 0; - } - else - { - // Wait Longer - - TNC->BusyDelay--; - - if (TNC->BusyDelay == 0) - { - // Timed out - Send Error Response - - UINT * buffptr = GetBuff(); - - if (buffptr == 0) return (0); // No buffers, so ignore - - buffptr[1]=39; - memcpy(buffptr+2,"Sorry, Can't Connect - Channel is busy\r", 39); - - C_Q_ADD(&TNC->Streams[0].PACTORtoBPQ_Q, buffptr); - free(TNC->ConnectCmd); - - sprintf(TNC->WEB_TNCSTATE, "In Use by %s", TNC->Streams[0].MyCall); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - } - } - } - - - - if (STREAM->NeedDisc) - { - STREAM->NeedDisc--; - - if (STREAM->NeedDisc == 0) - { - // Send the DISCONNECT - - TidyClose(TNC, 0); - } - } - - ARQTimer(TNC); - SendXMLPoll(TNC); - - TNC->SlowTimer--; - - if (TNC->SlowTimer < 0) - { - TNC->SlowTimer = 100; - FLSlowTimer(TNC); // 10 Secs - } - - return 0; - - case 1: // poll - - if (TNC->CONNECTED == FALSE && TNC->CONNECTING == FALSE && TNC->FLInfo->KISSMODE == FALSE) - { - // See if time to reconnect - - time( <ime ); - if (ltime-lasttime[port] >9 ) - { - ConnecttoFLDigi(port); - lasttime[port]=ltime; - } - } - - FD_ZERO(&readfs); - - if (TNC->CONNECTED) - if (TNC->TCPSock) - FD_SET(TNC->TCPSock,&readfs); - - if (TNC->CONNECTED || TNC->FLInfo->KISSMODE) - FD_SET(TNC->TCPDataSock,&readfs); - - -// FD_ZERO(&writefs); - -// if (TNC->BPQtoWINMOR_Q) FD_SET(TNC->TCPDataSock,&writefs); // Need notification of busy clearing - - FD_ZERO(&errorfs); - - if (TNC->CONNECTED) - if (TNC->TCPSock) - FD_SET(TNC->TCPSock,&errorfs); - - if (TNC->CONNECTED || TNC->FLInfo->KISSMODE) - FD_SET(TNC->TCPDataSock,&errorfs); - - - if (select((int)TNC->TCPDataSock + 1, &readfs, &writefs, &errorfs, &timeout) > 0) - { - // See what happened - - if (FD_ISSET(TNC->TCPDataSock,&readfs)) - { - // data available - - ProcessReceivedData(port); - } - - if (FD_ISSET(TNC->TCPSock,&readfs)) - { - // data available - - ProcessXMLData(port); - } - - - if (FD_ISSET(TNC->TCPDataSock,&writefs)) - { - // Connect success - - TNC->CONNECTED = TRUE; - TNC->CONNECTING = FALSE; - - sprintf(TNC->WEB_COMMSSTATE, "Connected to FLDIGI"); - SetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); - - // If required, send signon - -// SendPacket(TNC->TCPDataSock,"\x1a", 1, 0); -// SendPacket(TNC->TCPDataSock,"DIGITAL MODE ?", 14, 0); -// SendPacket(TNC->TCPDataSock,"\x1b", 1, 0); - -// EnumWindows(EnumTNCWindowsProc, (LPARAM)TNC); - } - - if (FD_ISSET(TNC->TCPDataSock,&errorfs) || FD_ISSET(TNC->TCPSock,&errorfs)) - { - // if connecting, then failed, if connected then has just disconnected - -// if (CONNECTED[port]) -// if (!CONNECTING[port]) -// { -// i=sprintf(ErrMsg, "MPSK Connection lost for BPQ Port %d\r\n", port); -// WritetoConsole(ErrMsg); -// } - - CONNECTING[port]=FALSE; - CONNECTED[port]=FALSE; - - } - - } - - - - // See if any frames for this port - - for (Stream = 0; Stream <= 1; Stream++) - { - STREAM = &TNC->Streams[Stream]; - - - if (STREAM->Attached) - CheckForDetach(TNC, Stream, STREAM, TidyClose, ForcedClose, CloseComplete); - - if (STREAM->ReportDISC) - { - STREAM->ReportDISC = FALSE; - buff->PORT = Stream; - - return -1; - } - - // if Busy, send buffer status poll - - if (STREAM->PACTORtoBPQ_Q == 0) - { - if (STREAM->DiscWhenAllSent) - { - STREAM->DiscWhenAllSent--; - if (STREAM->DiscWhenAllSent == 0) - STREAM->ReportDISC = TRUE; // Dont want to leave session attached. Causes too much confusion - } - } - else - { - int datalen; - - buffptr=Q_REM(&STREAM->PACTORtoBPQ_Q); - - datalen = (int)buffptr->Len; - - buff->PORT = Stream; // Compatibility with Kam Driver - buff->PID = 0xf0; - memcpy(&buff->L2DATA, &buffptr->Data[0], datalen); // Data goes to + 7, but we have an extra byte - datalen += sizeof(void *) + 4; - - PutLengthinBuffer(buff, datalen); - - ReleaseBuffer(buffptr); - - return (1); - } - } - - if (TNC->PortRecord->UI_Q) - { - struct _MESSAGE * buffptr; - int SendLen; - char Reply[256]; - int UILen; - char * UIMsg; - - buffptr = Q_REM(&TNC->PortRecord->UI_Q); - - UILen = buffptr->LENGTH; - UILen -= 23; - UIMsg = buffptr->L2DATA; - - UIMsg[UILen] = 0; - - if (UILen < 129 && TNC->Streams[0].Attached == FALSE) // Be sensible! - { - // >00uG8BPQ:72 TestA - SendLen = sprintf(Reply, "u%s:72 %s", TNC->NodeCall, UIMsg); - SendPacket(TNC, Reply, SendLen); - } - ReleaseBuffer(buffptr); - } - - return (0); - - case 2: // send - - - if (!TNC->CONNECTED) return 0; // Don't try if not connected to TNC - - Stream = buff->PORT; - - STREAM = &TNC->Streams[Stream]; - -// txlen=(buff[6]<<8) + buff[5] - 8; - - txlen = GetLengthfromBuffer((PDATAMESSAGE)buff) - 8; - - if (STREAM->Connected) - { - buffptr = GetBuff(); - - if (buffptr == 0) return (0); // No buffers, so ignore - - buffptr->Len = txlen; - memcpy(buffptr->Data, buff->L2DATA, txlen); - - C_Q_ADD(&TNC->Streams[Stream].BPQtoPACTOR_Q, buffptr); - - return (0); - } - else - { - buff->L2DATA[txlen] = 0; - _strupr(&buff->L2DATA[0]); - - if (_memicmp(&buff->L2DATA[0], "D\r", 2) == 0) - { - if (STREAM->Connected) - TidyClose(TNC, buff->PORT); - - STREAM->ReportDISC = TRUE; // Tell Node - - TNC->FLInfo->MCASTMODE = FALSE; - - return 0; - } - - // See if Local command (eg RADIO) - - if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) - { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); - - if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK->CIRCUITINDEX, &buff->L2DATA[0])) - { - } - else - { - PMSGWITHLEN buffptr = (PMSGWITHLEN)GetBuff(); - - if (buffptr == 0) return 1; // No buffers, so ignore - - buffptr->Len = sprintf((UCHAR *)&buffptr->Data[0], "%s", &buff->L2DATA[0]); - C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); - - } - return 1; - } - - if (_memicmp(&buff->L2DATA[0], "MODEM ", 6) == 0) - { - buff->L2DATA[txlen -1] = 0; - _strupr(&buff->L2DATA[0]); - - // If in KISS mode, send as a KISS command Frame - - if (TNC->FLInfo->KISSMODE) - { - sprintf(txbuff, "MODEM:%s MODEM:", &buff->L2DATA[6]); - SendKISSCommand(TNC, txbuff); - } - else - { - SendXMLCommand(TNC, "modem.set_by_name", &buff->L2DATA[6], 'S'); - } - - TNC->InternalCmd = TRUE; - return 1; - } - - if (_memicmp(buff->L2DATA, "FREQ ", 5) == 0) - { - buff->L2DATA[txlen - 1] = 0; - _strupr(&buff->L2DATA[0]); - - // If in KISS mode, send as a KISS command Frame - - if (TNC->FLInfo->KISSMODE) - { - sprintf(txbuff, "WFF:%s WFF:", &buff->L2DATA[5]); - SendKISSCommand(TNC, txbuff); - } - else - { - SendXMLCommand(TNC, "modem.set_carrier", atoi(&buff->L2DATA[5]), 'I'); - } - - TNC->InternalCmd = TRUE; - return 1; - } - - if (_memicmp(buff->L2DATA, "SQUELCH ", 8) == 0) - { - buff->L2DATA[txlen - 1] = 0; - _strupr(&buff->L2DATA[0]); - - // Only works in KISS - - if (TNC->FLInfo->KISSMODE) - { - if (_memicmp(&buff->L2DATA[8], "ON", 2) == 0) - sprintf(txbuff, "KPSQL:ON KPSQL:"); - - else if (_memicmp(&buff->L2DATA[8], "OFF", 3) == 0) - sprintf(txbuff, "KPSQL:OFF KPSQL:"); - else - txlen = sprintf(txbuff, "KPSQLS:%s KPSQLS:", &buff->L2DATA[8]); - - SendKISSCommand(TNC, txbuff); - TNC->InternalCmd = TRUE; - } - return 1; - } - - if (_memicmp(buff->L2DATA, "KPSATT ", 7) == 0) - { - buff->L2DATA[txlen - 1] = 0; - _strupr(&buff->L2DATA[0]); - - // If in KISS mode, send as a KISS command Frame - - if (TNC->FLInfo->KISSMODE) - { - sprintf(txbuff, "KPSATT:%s KPSATT:", &buff->L2DATA[7]); - - SendKISSCommand(TNC, txbuff); - TNC->InternalCmd = TRUE; - } - - return 1; - } - - if (STREAM->Connecting && _memicmp(buff->L2DATA, "ABORT", 5) == 0) - { -// len = sprintf(Command,"%cSTOP_SELECTIVE_CALL_ARQ_FAE\x1b", '\x1a'); - -// if (TNC->MPSKInfo->TX) -// TNC->CmdSet = TNC->CmdSave = _strdup(Command); // Save till not transmitting -// else -// SendPacket(TNC->TCPDataSock, Command, len, 0); - -// TNC->InternalCmd = TRUE; - return (0); - } - - if (_memicmp(&buff->L2DATA[0], "MODE", 4) == 0) - { - PMSGWITHLEN buffptr = GetBuff(); - - buff->L2DATA[txlen - 1] = 0; // Remove CR - - if (strstr(&buff->L2DATA[0], "RAW")) - TNC->FLInfo->RAW = TRUE; - else if (strstr(&buff->L2DATA[0], "KISS")) - TNC->FLInfo->RAW = FALSE; - else - { - buffptr->Len = sprintf(&buffptr->Data[0], "FLDigi} Error - Invalid Mode\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - return 1; - } - - buffptr->Len = sprintf(&buffptr->Data[0], "FLDigi} Ok - Mode is %s\r", - (TNC->FLInfo->RAW)?"RAW":"KISS"); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - return 1; - } - - if (_memicmp(&buff->L2DATA[0], "MCAST", 5) == 0) - { - UINT * buffptr = GetBuff(); - - TNC->FLInfo->MCASTMODE = TRUE; - - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "FLDigi} Ok\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - return 1; - } - - if (_memicmp(&buff->L2DATA[0], "INUSE?", 6) == 0) - { - // Return Error if in use, OK if not - - UINT * buffptr = GetBuff(); - int s = 0; - - while(s <= 1) - { - if (s != Stream) - { - if (TNC->PortRecord->ATTACHEDSESSIONS[s]) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "FLDig} Error - In use\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - return 1; // Busy - } - } - s++; - } - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "FLDigi} Ok - Not in use\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - return 1; - } - - // See if a Connect Command. - - if (toupper(buff->L2DATA[0]) == 'C' && buff->L2DATA[1] == ' ' && txlen > 2) // Connect - { - char * ptr; - char * context; - struct ARQINFO * ARQ = TNC->ARQInfo; - int SendLen; - char Reply[80]; - - buff->L2DATA[txlen] = 0; - _strupr(&buff->L2DATA[0]); - - memset(ARQ, 0, sizeof(struct ARQINFO)); // Reset ARQ State - ARQ->TXSeq = ARQ->TXLastACK = 63; // Last Sent - ARQ->RXHighest = ARQ->RXNoGaps = 63; // Last Received - ARQ->OurStream = (rand() % 78) + 49; // To give some protection against other stuff on channel - ARQ->FarStream = 48; // Not yet defined - TNC->FLInfo->FLARQ = FALSE; - - memset(STREAM->RemoteCall, 0, 10); - - ptr = strtok_s(&buff->L2DATA[2], " ,\r", &context); - strcpy(STREAM->RemoteCall, ptr); - - // See if Busy - - if (InterlockedCheckBusy(TNC)) - { - // Channel Busy. Unless override set, wait - - if (TNC->OverrideBusy == 0) - { - // Save Command, and wait up to 10 secs - - sprintf(TNC->WEB_TNCSTATE, "Waiting for clear channel"); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - TNC->BusyDelay = TNC->BusyWait * 10; // BusyWait secs - return 0; - } - } - - TNC->OverrideBusy = FALSE; - -//00cG8BPQ:1025 G8BPQ:24 0 7 T60R5W10FA36 - - SendLen = sprintf(Reply, "c%s:42 %s:24 %c 7 T60R5W10", - STREAM->MyCall, STREAM->RemoteCall, ARQ->OurStream); - - strcpy(TNC->WEB_PROTOSTATE, "Connecting"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - ARQ->ARQState = ARQ_ACTIVE; - - ARQ->ARQTimerState = ARQ_CONNECTING; - SaveAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - - STREAM->Connecting = TRUE; - - sprintf(TNC->WEB_TNCSTATE, "%s Connecting to %s", STREAM->MyCall, STREAM->RemoteCall); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - strcpy(TNC->WEB_PROTOSTATE, "Connecting"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - return 0; - } - - // Send any other command to FLDIGI - - buff->L2DATA[txlen - 1] = 0; - _strupr(&buff->L2DATA[0]); - - // If in KISS mode, send as a KISS command Frame - - if (TNC->FLInfo->KISSMODE) - { - char outbuff[1000]; - int newlen; - - buff->L2DATA[-1] = 6; // KISS Control - - newlen = KissEncode(&buff->L2DATA[-1], outbuff, txlen); - sendto(TNC->TCPDataSock, outbuff, newlen, 0, (struct sockaddr *)&TNC->Datadestaddr, sizeof(struct sockaddr)); - } - else - { - SendXMLCommand(TNC, "modem.set_by_name", &buff->L2DATA[0], 'S'); - } - - TNC->InternalCmd = TRUE; - } - - return (0); - - case 3: - - Stream = (int)(size_t)buff; - - TNCOK = TNC->CONNECTED; - - STREAM = &TNC->Streams[Stream]; - { - // Busy if TX Window reached - - struct ARQINFO * ARQ = TNC->ARQInfo; - int Outstanding; - - Outstanding = ARQ->TXSeq - ARQ->TXLastACK; - - if (Outstanding < 0) - Outstanding += 64; - - TNC->PortRecord->FramesQueued = Outstanding + C_Q_COUNT(&TNC->Streams[0].BPQtoPACTOR_Q); // Save for Appl Level Queued Frames - - if (Outstanding > ARQ->TXWindow) - return (1 | TNCOK << 8 | STREAM->Disconnecting << 15); // 3rd Nibble is frames unacked - else - return TNCOK << 8 | STREAM->Disconnecting << 15; - - } - return TNCOK << 8 | STREAM->Disconnecting << 15; // OK, but lock attach if disconnecting - - case 4: // reinit - - shutdown(TNC->TCPSock, SD_BOTH); - shutdown(TNC->TCPDataSock, SD_BOTH); - Sleep(100); - - closesocket(TNC->TCPSock); - closesocket(TNC->TCPDataSock); - TNC->CONNECTED = FALSE; - - if (TNC->WeStartedTNC) - { - KillTNC(TNC); - RestartTNC(TNC); - } - - return (0); - - case 5: // Close - - shutdown(TNC->TCPSock, SD_BOTH); - shutdown(TNC->TCPDataSock, SD_BOTH); - Sleep(100); - - closesocket(TNC->TCPSock); - closesocket(TNC->TCPDataSock); - - if (TNC->WeStartedTNC) - { - KillTNC(TNC); - } - - return 0; - } - - return 0; -} - -#ifndef LINBPQ - -int FindFLDIGI(char * Path) -{ - HANDLE hProc; - char ExeName[256] = ""; - char FLDIGIName[256]; - DWORD Pid = 0; - DWORD Processes[1024], Needed, Count; - unsigned int i; - - if (EnumProcessesPtr == NULL) - return 0; // Cant get PID - - if (!EnumProcessesPtr(Processes, sizeof(Processes), &Needed)) - return TRUE; - - // Path is to .bat, so need to strip extension of both names - - strcpy(FLDIGIName, Path); - strlop(FLDIGIName, '.'); - - // Calculate how many process identifiers were returned. - - Count = Needed / sizeof(DWORD); - - for (i = 0; i < Count; i++) - { - if (Processes[i] != 0) - { - hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Processes[i]); - - if (hProc) - { - GetModuleFileNameExPtr(hProc, 0, ExeName, 255); - CloseHandle(hProc); - - strlop(ExeName, '.'); - - if (_stricmp(ExeName, FLDIGIName) == 0) - return Processes[i]; - - } - } - } - return 0; -} - - -static KillTNC(struct TNCINFO * TNC) -{ - HANDLE hProc; - - if (TNC->PTTMode) - Rig_PTT(TNC->RIG, FALSE); // Make sure PTT is down - - if (TNC->ProgramPath) - TNC->PID = FindFLDIGI(TNC->ProgramPath); - - if (TNC->PID == 0) return 0; - - hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, TNC->PID); - - if (hProc) - { - TerminateProcess(hProc, 0); - CloseHandle(hProc); - } - - TNC->WeStartedTNC = 0; // So we don't try again - - return 0; -} - -#endif - -static int RestartTNC(struct TNCINFO * TNC) -{ - if (TNC->ProgramPath == NULL) - return 0; - - _strlwr(TNC->ProgramPath); - - if (_memicmp(TNC->ProgramPath, "REMOTE:", 7) == 0) - { - int n; - - // Try to start TNC on a remote host - - SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); - struct sockaddr_in destaddr; - - Debugprintf("trying to restart FLDIGI %s", TNC->ProgramPath); - - if (sock == INVALID_SOCKET) - return 0; - - destaddr.sin_family = AF_INET; - destaddr.sin_addr.s_addr = inet_addr(TNC->HostName); - destaddr.sin_port = htons(8500); - - if (destaddr.sin_addr.s_addr == INADDR_NONE) - { - // Resolve name to address - - struct hostent * HostEnt = gethostbyname (TNC->HostName); - - if (!HostEnt) - return 0; // Resolve failed - - memcpy(&destaddr.sin_addr.s_addr,HostEnt->h_addr,4); - } - - n = sendto(sock, TNC->ProgramPath, (int)strlen(TNC->ProgramPath), 0, (struct sockaddr *)&destaddr, sizeof(destaddr)); - - Debugprintf("Restart FLDIGI - sento returned %d", n); - - Sleep(100); - closesocket(sock); - - return 1; // Cant tell if it worked, but assume ok - } -#ifndef LINBPQ - { - STARTUPINFO SInfo; // pointer to STARTUPINFO - PROCESS_INFORMATION PInfo; // pointer to PROCESS_INFORMATION - char HomeDir[MAX_PATH]; - int i, ret; - - SInfo.cb=sizeof(SInfo); - SInfo.lpReserved=NULL; - SInfo.lpDesktop=NULL; - SInfo.lpTitle=NULL; - SInfo.dwFlags=0; - SInfo.cbReserved2=0; - SInfo.lpReserved2=NULL; - - if (TNC->ProgramPath) - { - strcpy(HomeDir, TNC->ProgramPath); - i = strlen(HomeDir); - - while(--i) - { - if (HomeDir[i] == '/' || HomeDir[i] == '\\') - { - HomeDir[i] = 0; - break; - } - } - - // for some reason the program name must be lower case - - _strlwr(TNC->ProgramPath); - - ret = CreateProcess(TNC->ProgramPath, NULL, NULL, NULL, FALSE,0 ,NULL , NULL, &SInfo, &PInfo); - return ret; - } - } -#endif - return 0; -} - - -static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL) -{ - int Len = sprintf(Buff, "" - "" - "FLDigi Status" - "

FLDIGI Status

"); - - - Len += sprintf(&Buff[Len], ""); - - Len += sprintf(&Buff[Len], "", TNC->WEB_COMMSSTATE); - Len += sprintf(&Buff[Len], "", TNC->WEB_TNCSTATE); - Len += sprintf(&Buff[Len], "", TNC->WEB_MODE); - Len += sprintf(&Buff[Len], "", TNC->WEB_CHANSTATE); - Len += sprintf(&Buff[Len], "", TNC->WEB_PROTOSTATE); - Len += sprintf(&Buff[Len], "", TNC->WEB_TRAFFIC); -// Len += sprintf(&Buff[Len], "", TNC->WEB_RESTARTS); - Len += sprintf(&Buff[Len], "
Comms State%s
TNC State%s
Mode%s
Channel State%s
Proto State%s
Traffic%s
TNC Restarts
"); - - Len += sprintf(&Buff[Len], "", TNC->WebBuffer); - Len = DoScanLine(TNC, Buff, Len); - - return Len; -} - -VOID FLDIGISuspendPort(struct TNCINFO * TNC) -{ - TNC->FLInfo->CONOK = FALSE; -} - -VOID FLDIGIReleasePort(struct TNCINFO * TNC) -{ - TNC->FLInfo->CONOK = TRUE; -} - -VOID SendKISSCommand(struct TNCINFO * TNC, char * Msg) -{ - int txlen, rc; - char txbuff[256]; - char outbuff[256]; - - txlen = sprintf(txbuff, "%c%s", 6, Msg); - txlen = KissEncode(txbuff, outbuff, txlen); - rc = sendto(TNC->TCPDataSock, outbuff, txlen, 0, (struct sockaddr *)&TNC->Datadestaddr, sizeof(struct sockaddr)); -} - -VOID * FLDigiExtInit(EXTPORTDATA * PortEntry) -{ - int i, port; - char Msg[255]; - struct TNCINFO * TNC; - char * ptr; - - // - // The Socket to connect to is in IOBASE - // - - srand((unsigned int)time(NULL)); - - port = PortEntry->PORTCONTROL.PORTNUMBER; - - ReadConfigFile(port, ProcessLine); - - TNC = TNCInfo[port]; - - if (TNC == NULL) - { - // Not defined in Config file - - sprintf(Msg," ** Error - no info in BPQ32.cfg for this port\n"); - WritetoConsole(Msg); - - return ExtProc; - } - - TNC->Port = port; - - TNC->PortRecord = PortEntry; - - if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) - memcpy(TNC->NodeCall, MYNODECALL, 10); - else - ConvFromAX25(&PortEntry->PORTCONTROL.PORTCALL[0], TNC->NodeCall); - - TNC->Interlock = PortEntry->PORTCONTROL.PORTINTERLOCK; - - - PortEntry->PORTCONTROL.PROTOCOL = 10; - PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream - PortEntry->PORTCONTROL.UICAPABLE = 1; // Can send beacons - PortEntry->PORTCONTROL.PORTQUALITY = 0; - PortEntry->SCANCAPABILITIES = NONE; // Scan Control - None - - TNC->FLInfo->CONOK = TRUE; - - if (PortEntry->PORTCONTROL.PORTPACLEN == 0 || PortEntry->PORTCONTROL.PORTPACLEN > 128) - PortEntry->PORTCONTROL.PORTPACLEN = 64; - - TNC->SuspendPortProc = FLDIGISuspendPort; - TNC->ReleasePortProc = FLDIGIReleasePort; - - ptr=strchr(TNC->NodeCall, ' '); - if (ptr) *(ptr) = 0; // Null Terminate - - TNC->Hardware = H_FLDIGI; - - if (TNC->BusyWait == 0) - TNC->BusyWait = 10; - - MPSKChannel[port] = PortEntry->PORTCONTROL.CHANNELNUM-65; - - PortEntry->MAXHOSTMODESESSIONS = 1; - - i=sprintf(Msg,"FLDigi Host %s Port %d \n", - TNC->HostName, TNC->TCPPort); - - WritetoConsole(Msg); - -#ifndef LINBPQ - - if (TNC->ProgramPath) - TNC->PID = FindFLDIGI(TNC->ProgramPath); - - if (TNC->PID == 0) // Not running -#endif - TNC->WeStartedTNC = RestartTNC(TNC); // Always try if Linux - - if (TNC->FLInfo->KISSMODE) - { - // Open Datagram port - - SOCKET sock; - u_long param=1; - BOOL bcopt=TRUE; - struct sockaddr_in sinx; - struct hostent * HostEnt = NULL; - - TNC->FLInfo->CmdControl = 5; //Send params immediately - - TNC->Datadestaddr.sin_addr.s_addr = inet_addr(TNC->HostName); - - if (TNC->Datadestaddr.sin_addr.s_addr == INADDR_NONE) - { - // Resolve name to address - - HostEnt = gethostbyname (TNC->HostName); - - if (HostEnt) - { - memcpy(&TNC->Datadestaddr.sin_addr.s_addr,HostEnt->h_addr,4); - } - } - - TNC->TCPDataSock = sock = socket(AF_INET,SOCK_DGRAM,0); - - ioctl(sock, FIONBIO, ¶m); - - setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char FAR *)&bcopt,4); - - sinx.sin_family = AF_INET; - sinx.sin_addr.s_addr = INADDR_ANY; - sinx.sin_port = htons(TNC->TCPPort + 1); - - if (bind(sock, (struct sockaddr *) &sinx, sizeof(sinx)) != 0 ) - { - // Bind Failed - - int err = WSAGetLastError(); - Consoleprintf("Bind Failed for UDP port %d - error code = %d", TNC->TCPPort, err); - } - - TNC->Datadestaddr.sin_family = AF_INET; - TNC->Datadestaddr.sin_port = htons(TNC->TCPPort); - } - else - ConnecttoFLDigi(port); - - time(&lasttime[port]); // Get initial time value - - PortEntry->PORTCONTROL.TNC = TNC; - - TNC->WebWindowProc = WebProc; - TNC->WebWinX = 520; - TNC->WebWinY = 500; - TNC->WebBuffer = zalloc(5000); - - TNC->WEB_COMMSSTATE = zalloc(100); - TNC->WEB_TNCSTATE = zalloc(100); - TNC->WEB_CHANSTATE = zalloc(100); - TNC->WEB_BUFFERS = zalloc(100); - TNC->WEB_PROTOSTATE = zalloc(100); - TNC->WEB_RESTARTTIME = zalloc(100); - TNC->WEB_RESTARTS = zalloc(100); - - TNC->WEB_MODE = zalloc(50); - TNC->WEB_TRAFFIC = zalloc(100); - - -#ifndef LINBPQ - - CreatePactorWindow(TNC, ClassName, WindowTitle, RigControlRow, PacWndProc, 500, 450, ForcedClose); - - CreateWindowEx(0, "STATIC", "Comms State", WS_CHILD | WS_VISIBLE, 10,6,120,20, TNC->hDlg, NULL, hInstance, NULL); - TNC->xIDC_COMMSSTATE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,6,386,20, TNC->hDlg, NULL, hInstance, NULL); - - CreateWindowEx(0, "STATIC", "TNC State", WS_CHILD | WS_VISIBLE, 10,28,106,20, TNC->hDlg, NULL, hInstance, NULL); - TNC->xIDC_TNCSTATE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,28,520,20, TNC->hDlg, NULL, hInstance, NULL); - - CreateWindowEx(0, "STATIC", "Mode/CF", WS_CHILD | WS_VISIBLE, 10,50,80,20, TNC->hDlg, NULL, hInstance, NULL); - TNC->xIDC_MODE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,50,200,20, TNC->hDlg, NULL, hInstance, NULL); - - CreateWindowEx(0, "STATIC", "Channel State", WS_CHILD | WS_VISIBLE, 10,72,110,20, TNC->hDlg, NULL, hInstance, NULL); - TNC->xIDC_CHANSTATE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,72,144,20, TNC->hDlg, NULL, hInstance, NULL); - - CreateWindowEx(0, "STATIC", "Proto State", WS_CHILD | WS_VISIBLE,10,94,80,20, TNC->hDlg, NULL, hInstance, NULL); - TNC->xIDC_PROTOSTATE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE,116,94,374,20 , TNC->hDlg, NULL, hInstance, NULL); - - CreateWindowEx(0, "STATIC", "Traffic", WS_CHILD | WS_VISIBLE,10,116,80,20, TNC->hDlg, NULL, hInstance, NULL); - TNC->xIDC_TRAFFIC = CreateWindowEx(0, "STATIC", "RX 0 TX 0 ACKED 0 Resent 0", WS_CHILD | WS_VISIBLE,116,116,374,20 , TNC->hDlg, NULL, hInstance, NULL); - - TNC->hMonitor= CreateWindowEx(0, "LISTBOX", "", WS_CHILD | WS_VISIBLE | LBS_NOINTEGRALHEIGHT | - LBS_DISABLENOSCROLL | WS_HSCROLL | WS_VSCROLL, - 0,170,250,300, TNC->hDlg, NULL, hInstance, NULL); - - TNC->ClientHeight = 450; - TNC->ClientWidth = 500; - - TNC->hMenu = CreatePopupMenu(); - - AppendMenu(TNC->hMenu, MF_STRING, WINMOR_KILL, "Kill FLDigi"); - AppendMenu(TNC->hMenu, MF_STRING, WINMOR_RESTART, "Kill and Restart FLDigi"); - AppendMenu(TNC->hMenu, MF_STRING, ARDOP_ABORT, "Abort Current Session"); - - MoveWindows(TNC); -#endif - - return ExtProc; - -} - - -static int ProcessLine(char * buf, int Port) -{ - UCHAR * ptr,* p_cmd; - char * p_ipad = 0; - char * p_port = 0; - unsigned short WINMORport = 0; - int BPQport; - int len=510; - struct TNCINFO * TNC; - struct ARQINFO * ARQ; - struct FLINFO * FL; - - char errbuf[256]; - - strcpy(errbuf, buf); - - ptr = strtok(buf, " \t\n\r"); - - if(ptr == NULL) return (TRUE); - - if(*ptr =='#') return (TRUE); // comment - - if(*ptr ==';') return (TRUE); // comment - - if (_stricmp(buf, "ADDR")) - return FALSE; // Must start with ADDR - - ptr = strtok(NULL, " \t\n\r"); - - BPQport = Port; - p_ipad = ptr; - - TNC = TNCInfo[BPQport] = zalloc(sizeof(struct TNCINFO)); - - ARQ = TNC->ARQInfo = zalloc(sizeof(struct ARQINFO)); - FL = TNC->FLInfo = zalloc(sizeof(struct FLINFO)); - - TNC->Timeout = 50; // Default retry = 5 seconds - TNC->Retries = 6; // Default Retries - TNC->Window = 16; - - TNC->FLInfo->KISSMODE = TRUE; // Default to KISS - - TNC->InitScript = malloc(1000); - TNC->InitScript[0] = 0; - - if (p_ipad == NULL) - p_ipad = strtok(NULL, " \t\n\r"); - - if (p_ipad == NULL) return (FALSE); - - p_port = strtok(NULL, " \t\n\r"); - - if (p_port == NULL) return (FALSE); - - TNC->TCPPort = atoi(p_port); - - TNC->destaddr.sin_family = AF_INET; - TNC->destaddr.sin_port = htons(TNC->TCPPort + 40); // Defaults XML 7362 ARQ 7322 - - TNC->Datadestaddr.sin_family = AF_INET; - TNC->Datadestaddr.sin_port = htons(TNC->TCPPort); - - TNC->HostName = malloc(strlen(p_ipad)+1); - - if (TNC->HostName == NULL) return TRUE; - - strcpy(TNC->HostName,p_ipad); - - ptr = strtok(NULL, " \t\n\r"); - - if (ptr) - { - if (_memicmp(ptr, "PATH", 4) == 0) - { - p_cmd = strtok(NULL, "\n\r"); - if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); - } - } - - // Read Initialisation lines - - while(TRUE) - { - if (GetLine(buf) == 0) - return TRUE; - - strcpy(errbuf, buf); - - if (memcmp(buf, "****", 4) == 0) - return TRUE; - - ptr = strchr(buf, ';'); - if (ptr) - { - *ptr++ = 13; - *ptr = 0; - } - - if (_memicmp(buf, "TIMEOUT", 7) == 0) - TNC->Timeout = atoi(&buf[8]) * 10; - else - if (_memicmp(buf, "RETRIES", 7) == 0) - TNC->Retries = atoi(&buf[8]); - else - if (_memicmp(buf, "WINDOW", 6) == 0) - TNC->Window = atoi(&buf[7]); - else - if (_memicmp(buf, "ARQMODE", 7) == 0) - TNC->FLInfo->KISSMODE = FALSE; - else - if (_memicmp(buf, "DEFAULTMODEM", 12) == 0) // Send Beacon after each session - { - // Check that freq is also specified - - char * Freq = strchr(&buf[13], '/'); - - if (Freq) - { - *(Freq++) = 0; - strcpy(TNC->FLInfo->DefaultMode, &buf[13]); - TNC->FLInfo->DefaultFreq = atoi(Freq); - } - } - else - - strcat (TNC->InitScript, buf); - } - - - return (TRUE); -} - -static int ConnecttoFLDigi(int port) -{ - _beginthread(ConnecttoFLDigiThread, 0, (void *)(size_t)port); - - return 0; -} - -static VOID ConnecttoFLDigiThread(void * portptr) -{ - int port = (int)(size_t)portptr; - char Msg[255]; - int err,i; - u_long param=1; - BOOL bcopt=TRUE; - struct hostent * HostEnt = NULL; - struct TNCINFO * TNC = TNCInfo[port]; - - Sleep(5000); // Allow init to complete - - TNC->destaddr.sin_addr.s_addr = inet_addr(TNC->HostName); - TNC->Datadestaddr.sin_addr.s_addr = inet_addr(TNC->HostName); - - if (TNC->destaddr.sin_addr.s_addr == INADDR_NONE) - { - // Resolve name to address - - HostEnt = gethostbyname (TNC->HostName); - - if (!HostEnt) return; // Resolve failed - - memcpy(&TNC->destaddr.sin_addr.s_addr,HostEnt->h_addr,4); - memcpy(&TNC->Datadestaddr.sin_addr.s_addr,HostEnt->h_addr,4); - } - - if (TNC->TCPSock) - { - Debugprintf("FLDIGI Closing Sock %d", TNC->TCPSock); - closesocket(TNC->TCPSock); - } - - TNC->TCPSock = 0; - - - TNC->TCPSock=socket(AF_INET,SOCK_STREAM,0); - - if (TNC->TCPSock == INVALID_SOCKET) - { - i=sprintf(Msg, "Socket Failed for FLDigi Control socket - error code = %d\n", WSAGetLastError()); - WritetoConsole(Msg); - return; - } - - setsockopt (TNC->TCPSock, 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; - - TNC->CONNECTING = TRUE; - - if (connect(TNC->TCPSock,(LPSOCKADDR) &TNC->destaddr,sizeof(TNC->destaddr)) == 0) - { - // - // Connected successful - // - } - else - { - if (TNC->Alerted == FALSE) - { - err=WSAGetLastError(); - i=sprintf(Msg, "Connect Failed for FLDigi Control socket - error code = %d\n", err); - WritetoConsole(Msg); - - sprintf(TNC->WEB_COMMSSTATE, "Connection to TNC failed"); - MySetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); - TNC->Alerted = TRUE; - } - - closesocket(TNC->TCPSock); - TNC->TCPSock = 0; - TNC->CONNECTING = FALSE; - return; - } - - TNC->LastFreq = 0; - - if (TNC->TCPDataSock) - closesocket(TNC->TCPDataSock); - - TNC->TCPDataSock = 0; - - TNC->TCPDataSock=socket(AF_INET,SOCK_STREAM,0); - - setsockopt (TNC->TCPDataSock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4); - - if (TNC->TCPDataSock == INVALID_SOCKET) - { - i=sprintf(Msg, "Socket Failed for FLDigi socket - error code = %d\r\n", WSAGetLastError()); - WritetoConsole(Msg); - - closesocket(TNC->TCPSock); - closesocket(TNC->TCPDataSock); - TNC->TCPSock = 0; - TNC->CONNECTING = FALSE; - - return; - } - - if (bind(TNC->TCPDataSock, (LPSOCKADDR) &sinx, addrlen) != 0 ) - { - // - // Bind Failed - // - - i=sprintf(Msg, "Bind Failed for FLDigi Data socket - error code = %d\r\n", WSAGetLastError()); - WritetoConsole(Msg); - - closesocket(TNC->TCPSock); - closesocket(TNC->TCPDataSock); - TNC->TCPSock = 0; - TNC->TCPDataSock = 0; - TNC->CONNECTING = FALSE; - return; - } - - if (connect(TNC->TCPDataSock,(LPSOCKADDR) &TNC->Datadestaddr,sizeof(TNC->Datadestaddr)) == 0) - { - ioctlsocket (TNC->TCPDataSock,FIONBIO,¶m); // Set nonblocking - TNC->CONNECTED = TRUE; - TNC->CONNECTING = FALSE; - - TNC->Alerted = TRUE; - - sprintf(TNC->WEB_COMMSSTATE, "Connected to FLDIGI"); - SetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); - } - else - { - sprintf(Msg, "Connect Failed for FLDigi Data socket Port %d - error code = %d\r\n", port, WSAGetLastError()); - WritetoConsole(Msg); - - closesocket(TNC->TCPSock); - closesocket(TNC->TCPDataSock); - TNC->TCPSock = 0; - TNC->TCPDataSock = 0; - TNC->CONNECTING = FALSE; - } - - return; -} - -VOID UpdateStatsLine(struct TNCINFO * TNC, struct STREAMINFO * STREAM) -{ - sprintf(TNC->WEB_TRAFFIC, "RX %d TX %d ACKED %d Resent %d Queued %d", - STREAM->BytesRXed, STREAM->BytesTXed, STREAM->BytesAcked, STREAM->BytesResent, STREAM->BytesOutstanding); - SetWindowText(TNC->xIDC_TRAFFIC, TNC->WEB_TRAFFIC); -} - -VOID SendPacket(struct TNCINFO * TNC, UCHAR * Msg, int MsgLen) -{ - if (TNC->FLInfo->KISSMODE) - { - char KissMsg[1000]; - char outbuff[1000]; - int newlen; - - if (TNC->FLInfo->RAW) - { - // KISS RAW - - // Add CRC and Send - - unsigned short CRC; - char crcstring[6]; - - KissMsg[0] = 7; // KISS Raw - KissMsg[1] = 1; // SOH - KissMsg[2] = '0'; // Version - KissMsg[3] = TNC->ARQInfo->FarStream; - - Msg[MsgLen] = 0; - - memcpy(&KissMsg[4], Msg, MsgLen +1 ); // Get terminating NULL - - CRC = CalcCRC(KissMsg + 1, MsgLen + 3); - - sprintf(crcstring, "%04X%c", CRC, 4); - - strcat(KissMsg, crcstring); - MsgLen += 9; - } - else - { - // Normal KISS - - KissMsg[0] = 0; // KISS Control - KissMsg[1] = TNC->ARQInfo->FarStream; - memcpy(&KissMsg[2], Msg, MsgLen); - MsgLen += 2; - } - - newlen = KissEncode(KissMsg, outbuff, MsgLen); - sendto(TNC->TCPDataSock, outbuff, newlen, 0, (struct sockaddr *)&TNC->Datadestaddr, sizeof(struct sockaddr)); - - SendKISSCommand(TNC, "TXBUF:"); - - } - else - { - // ARQ Scoket - - // Add Header, CRC and Send - - unsigned short CRC; - char crcstring[6]; - char outbuff[1000]; - - outbuff[0] = 1; // SOH - outbuff[1] = '0'; // Version - outbuff[2] = TNC->ARQInfo->FarStream; - - Msg[MsgLen] = 0; - - memcpy(&outbuff[3], Msg, MsgLen + 1); - - CRC = CalcCRC(outbuff , MsgLen + 3); - - sprintf(crcstring, "%04X%c", CRC, 4); - - strcat(outbuff, crcstring); - MsgLen += 8; - - send(TNC->TCPDataSock, outbuff, MsgLen, 0); - } -} - -VOID ProcessFLDigiData(struct TNCINFO * TNC, UCHAR * Input, int Len, char Channel, BOOL RAW); - -static int ProcessReceivedData(int port) -{ - int bytes, used, bytesleft; - int i; - char ErrMsg[255]; - unsigned char MessageBuff[1500]; - unsigned char * Message = MessageBuff; - unsigned char * MessageBase = MessageBuff; - - struct TNCINFO * TNC = TNCInfo[port]; - struct FLINFO * FL = TNC->FLInfo; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - - // If using KISS/UDP interface use recvfrom - - if (FL->KISSMODE) - { - struct sockaddr_in rxaddr; - int addrlen = sizeof(struct sockaddr_in); - unsigned char * KissEnd; - - bytesleft = recvfrom(TNC->TCPDataSock, Message, 1500, 0, (struct sockaddr *)&rxaddr, &addrlen); - - if (bytesleft < 0) - { - int err = WSAGetLastError(); - // if (err != 11) - // printf("KISS Error %d %d\n", nLength, err); - bytes = 0; - } - - while (bytesleft > 0) - { - unsigned char * in; - unsigned char * out; - unsigned char c; - - if (bytesleft < 3) - return 0; - - if (Message[0] != FEND) - return 0; // Duff - - Message = MessageBase; - in = out = &Message[2]; - - // We may have more than one KISS message in a packet - - KissEnd = memchr(&Message[2], FEND, bytesleft ); - - if (KissEnd == 0) - return 0; // Duff - - *(KissEnd) = 0; - - used = (int)(KissEnd - Message + 1); - - bytesleft -= used; - bytes = used; - - MessageBase += used; - - if (Message[1] == 6) // KISS Command - { - UCHAR * ptr = strchr(&Message[2], FEND); - - if (ptr) *ptr = 0; // Null Terminate - - if (bytes > 250) - Message[250] = 0; - - FL->Responding = 5; - - if (TNC->TNCOK == 0) - { - TNC->TNCOK = TRUE; - TNC->CONNECTED = TRUE; - - sprintf(TNC->WEB_COMMSSTATE, "Connected to FLDIGI"); - SetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); - } - - // Trap BUSY fiest - there are lots of them, and they are likely to be confused - // with tesponses to Interactive commands - - if (memcmp(&Message[2], "BUSY", 4) == 0) - { - BOOL Changed = FALSE; - - if (Message[7] == 'T' && FL->Busy == FALSE) - { - TNC->Busy = FL->Busy = TRUE; - Changed = TRUE; - } - else - { - if (Message[7] == 'F' && FL->Busy == TRUE) - { - TNC->Busy = FL->Busy = FALSE; - Changed = TRUE; - } - } - - if (Changed) - { - if (FL->TX) - strcpy(TNC->WEB_CHANSTATE, "TX"); - else - if (FL->Busy) - strcpy(TNC->WEB_CHANSTATE, "Busy"); - else - strcpy(TNC->WEB_CHANSTATE, "Idle"); - - SetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE); - } - - continue; - } - - if (TNC->InternalCmd) - { - ULONG * buffptr = GetBuff(); - - TNC->InternalCmd = FALSE; - - if (buffptr) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "FLDIGI} Ok %s\r", &Message[2]); - C_Q_ADD(&TNC->Streams[0].PACTORtoBPQ_Q, buffptr); - } - - // Drop through in case need to extract info from command - } - - // Auto Command - -// Debugprintf("%d %s", TNC->PortRecord->PORTCONTROL.PORTNUMBER, &Message[2]); - - if (memcmp(&Message[2], "FLSTAT", 4) == 0) - { - if (strstr(&Message[2], "FLSTAT:INIT")) - { - // FLDIGI Reloaded - set parmas - SendKISSCommand(TNC, "RSIDBCAST:ON TRXSBCAST:ON TXBEBCAST:ON KISSRAW:ON"); - } - continue; - } - - if (memcmp(&Message[2], "TRXS", 4) == 0) - { - char * ptr1, * context; - BOOL Changed = FALSE; - - ptr1 = strtok_s(&Message[7], ",", &context); - - if (strstr(ptr1, "TX")) - { - if (TNC->FLInfo->TX == FALSE) - { - TNC->FLInfo->TX = TRUE; - Changed = TRUE; - } - } - else - { - if (TNC->FLInfo->TX) - { - TNC->FLInfo->TX = FALSE; - Changed = TRUE; - } - } - - if (Changed) - { - if (FL->TX) - strcpy(TNC->WEB_CHANSTATE, "TX"); - else - if (FL->Busy) - strcpy(TNC->WEB_CHANSTATE, "Busy"); - else - strcpy(TNC->WEB_CHANSTATE, "Idle"); - - SetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE); - } - - continue; - } - - if (memcmp(&Message[2], "TXBUF:", 6) == 0) - { - char * ptr1, * context; - - ptr1 = strtok_s(&Message[8], ",", &context); - STREAM->BytesOutstanding = atoi(ptr1); - UpdateStatsLine(TNC, STREAM); - continue; - } - - if (memcmp(&Message[2], "TXBE:", 5) == 0) - { - STREAM->BytesOutstanding = 0; - UpdateStatsLine(TNC, STREAM); - continue; - } - - if (memcmp(&Message[2], "RSIDN:", 6) == 0) - { - char * ptr1, * context; - - ptr1 = strtok_s(&Message[8], ",", &context); - - TNC->FLInfo->CenterFreq = atoi(ptr1); - ptr1 = strtok_s(NULL, ",", &context); - if (strlen(ptr1) > 19) - ptr1[19] = 0; - - strcpy(TNC->FLInfo->CurrentMode, ptr1); - } - - if (memcmp(&Message[2], "MODEM:", 6) == 0) - { - char * ptr1, * context; - - ptr1 = strtok_s(&Message[8], ",", &context); - if (strlen(ptr1) > 19) - ptr1[19] = 0; - - strcpy(TNC->FLInfo->CurrentMode, ptr1); - } - - if (memcmp(&Message[2], "WFF:", 4) == 0) - { - char * ptr1, * context; - - ptr1 = strtok_s(&Message[6], ",", &context); - TNC->FLInfo->CenterFreq = atoi(ptr1); - } - - sprintf(TNC->WEB_MODE, "%s/%d", TNC->FLInfo->CurrentMode, TNC->FLInfo->CenterFreq); - SetWindowText(TNC->xIDC_MODE, TNC->WEB_MODE); - - continue; - } - - if (Message[1] == 7) // Not Normal Data - { - // "RAW" Mode. Just process as if received from TCP Socket Interface - - ProcessFLDigiPacket(TNC, &Message[2] , bytes - 3); // Data may be for another port - continue; - } - - bytes -= 3; // Two FEND and Control - - // Undo KISS - - while (bytes) - { - bytes--; - - c = *(in++); - - if (c == FESC) - { - c = *(in++); - bytes--; - - if (c == TFESC) - c = FESC; - else if (c == TFEND) - c = FEND; - } - *(out++) = c; - } - ProcessFLDigiData(TNC, &Message[3], (int)(out - &Message[3]), Message[2], FALSE); // KISS not RAW - } - return 0; - } - - // Need to extract messages from byte stream - - bytes = recv(TNC->TCPDataSock, Message, 500, 0); - - if (bytes == SOCKET_ERROR) - { -// i=sprintf(ErrMsg, "Read Failed for MPSK socket - error code = %d\r\n", WSAGetLastError()); -// WritetoConsole(ErrMsg); - - closesocket(TNC->TCPDataSock); - - TNC->CONNECTED = FALSE; - if (TNC->Streams[0].Attached) - TNC->Streams[0].ReportDISC = TRUE; - - return (0); - } - - if (bytes == 0) - { - // zero bytes means connection closed - - i=sprintf(ErrMsg, "FlDigi Connection closed for BPQ Port %d\n", port); - WritetoConsole(ErrMsg); - - TNC->CONNECTED = FALSE; - if (TNC->Streams[0].Attached) - TNC->Streams[0].ReportDISC = TRUE; - - return (0); - } - - // Have some data - - ProcessFLDigiPacket(TNC, Message, bytes); // Data may be for another port - - return (0); - -} - - -VOID ProcessFLDigiPacket(struct TNCINFO * TNC, char * Message, int Len) -{ - char * MPTR = Message; - char c; - struct FLINFO * FL = TNC->FLInfo; - - - if (TNC->FLInfo->MCASTMODE) - { - if (TNC->Streams[0].Attached == 0) - return; - - while(Len) - { - c = *(MPTR++); - - if (TNC->InPacket) - { - TNC->DataBuffer[TNC->DataLen++] = c; - - // Sanity Check - - if (TNC->DataLen == 6) - { - char * ptr = &TNC->DataBuffer[1]; - - if (memcmp(ptr, "DATA ", 5) == 0 || - memcmp(ptr, "PROG ", 5) == 0 || - memcmp(ptr, "FILE ", 5) == 0 || - memcmp(ptr, "SIZE ", 5) == 0 || - memcmp(ptr, "DESC ", 5) == 0 || - memcmp(ptr, "CNTL ", 5) == 0 || - memcmp(ptr, "ID ", 3) == 0) - - { - } - else - { - // False Trigger, try again - - TNC->InPacket = FALSE; - } - - } - else - { - if (TNC->InData) - { - if (--TNC->MCASTLen == 0) - { - // Got a packet - - UINT * buffptr; - int Stream = 0; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - - buffptr = GetBuff(); - - if (buffptr) - { - TNC->DataBuffer[TNC->DataLen++] = 13; // Keep Tidy - - buffptr[1] = TNC->DataLen; - memcpy(&buffptr[2], &TNC->DataBuffer[0], TNC->DataLen); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - - TNC->InPacket = FALSE; - } - } - else - { - // Looking for > - - if (TNC->DataLen == 16) - { - // Not found it - - TNC->InPacket = FALSE; - } - else - { - if (c == '>') - { - // Got Header - extract Length - - char * ptr; - int len; - - ptr = strchr(TNC->DataBuffer, ' '); - - if (ptr) - { - len = atoi(ptr); - - if (len) - { - TNC->InData = TRUE; - TNC->MCASTLen = len; - } - } - } - } - } - } - - if (TNC->DataLen > 520) - TNC->DataLen--; // Protect Buffer - } - else - { - // Look for '<' - - if (c == '<') - { - TNC->DataBuffer[0] = c; - TNC->DataLen = 1; - TNC->InPacket = TRUE; - TNC->InData = FALSE; - } - } - Len--; - } - return; - } - // Look for SOH/EOT delimiters. May Have several SOH before EOTTNC->FL - - while(Len) - { - c = *(MPTR++); - - switch (c) - { - case 01: // New Packet - - if (TNC->InPacket) - CheckFLDigiData(TNC); - - TNC->DataBuffer[0] = 1; - TNC->DataLen = 1; - TNC->InPacket = TRUE; - break; - - case 04: - - if (TNC->InPacket) - CheckFLDigiData(TNC); - TNC->DataLen = 0; - TNC->InPacket = FALSE; - - break; - - default: - - if (TNC->InPacket) - { - if (TNC->DataLen == 1) - { - if (c != '0' && c != '1') - { - // Drop if not Protocol '0' or '1' - this should eliminate almost all noise packets - - TNC->InPacket = 0; - break; - } - } - TNC->DataBuffer[TNC->DataLen++] = c; - } - - if (TNC->DataLen > 520) - TNC->DataLen--; // Protect Buffer - - } - Len--; - } -} -VOID CheckFLDigiData(struct TNCINFO * TNC) -{ - UCHAR * Input = &TNC->DataBuffer[0]; - int Len = TNC->DataLen - 4; // Not including CRC - unsigned short CRC; - char crcstring[6]; - - if (Len < 0) - return; - - TNC->DataBuffer[TNC->DataLen] = 0; - - // RAW format message, either from ARQ Scoket or RAW KISS - - // Check Checksum - - CRC = CalcCRC(Input , Len); - - sprintf(crcstring, "%04X", CRC); - - if (memcmp(&Input[Len], crcstring, 4) !=0) - { - // CRC Error - could just be noise - -// Debugprintf("%s %s", crcstring, Input); - return; - } - ProcessFLDigiData(TNC, &Input[3], Len - 3, Input[2], TRUE); // From RAW -} -/* -VOID ProcessARQPacket(struct PORTCONTROL * PORT, MESSAGE * Buffer) -{ - // ARQ Packet from KISS-Like Hardware - - struct TNCINFO * TNC = TNCInfo[PORT->PORTNUMBER]; - UCHAR * Input; - int Len; - - if (TNC == NULL) - { - // Set up TNC info - - TNC = TNCInfo[PORT->PORTNUMBER] = zalloc(sizeof(struct TNCINFO)); - TNC->ARQInfo = zalloc(sizeof(struct ARQINFO)); - TNC->FLInfo = zalloc(sizeof(struct FLINFO)); - - TNC->Timeout = 50; // Default retry = 10 seconds - TNC->Retries = 6; // Default Retries - TNC->Window = 16; - } - - Input = &Buffer->DEST[0]; - Len = Buffer->LENGTH - 7; // Not including CRC - - // Look for attach on any call - - ProcessFLDigiData(TNC, Input, Len); -} -*/ -static int Stuff(UCHAR * inbuff, UCHAR * outbuff, int len) -{ - int i, txptr = 0; - UCHAR c; - UCHAR * ptr = inbuff; - - // DLE Escape DLE, SOH, EOT - - for (i = 0; i < len; i++) - { - c = *(ptr++); - -// if (c == 0 || c == DLE || c == SOH || c == EOT) - if (c < 32 && c != 10 && c != 13 && c != 8) - { - outbuff[txptr++] = DLE; - - // if between 0 and 0x1F, Add 40, - // if > x80 and less than 0xa0 subtract 20 - - c += 0x40; - } - outbuff[txptr++]=c; - } - - return txptr; -} - - -static int UnStuff(UCHAR * inbuff, int len) -{ - int i, txptr = 0; - UCHAR c; - UCHAR * outbuff = inbuff; - UCHAR * ptr = inbuff; - - // This unstuffs into the input buffer - - for (i = 0; i < len; i++) - { - c = *(ptr++); - - if (c == DLE) - { - c = *(ptr++); - i++; - - // if between 0x40 and 0x5F, subtract 0x40, - // else add 0x20 (so we can send chars 80-9f without a double DLE) - - if (c < 0x60) - c -= 0x40; - else - c += 0x20; - } - outbuff[txptr++] = c; - } - - return txptr; -} - -unsigned int crcval = 0xFFFF; - -void update(char c) -{ - int i; - - crcval ^= c & 255; - for (i = 0; i < 8; ++i) - { - if (crcval & 1) - crcval = (crcval >> 1) ^ 0xA001; - else - crcval = (crcval >> 1); - } -} - -unsigned int CalcCRC(UCHAR * ptr, int Len) -{ - int i; - - crcval = 0xFFFF; - for (i = 0; i < Len; i++) - { - update(*ptr++); - } - return crcval; -} -/* - -00cG8BPQ:1025 G8BPQ:24 0 8 T60R6W108E06 -00kG8BPQ:24 G8BPQ 4 85F9B - -00cG8BPQ:1025 GM8BPQ:24 0 7 T60R5W1051D5 (128, 5) - -,00cG8BPQ:1025 G8BPQ:24 0 7 T60R5W10FA36 -00kG8BPQ:24 G8BPQ 5 89FCA - -First no sees to be a connection counter. Next may be stream - - -08s___ABFC -08tG8BPQ:73 xxx 33FA -00tG8BPQ:73 yyy 99A3 -08dG8BPQ:90986C -00bG8BPQ:911207 - -call:90 for dis 91 for dis ack 73 for chat) - -08pG8BPQ?__645E -00s_??4235 - -08pG8BPQ?__645E -00s_??4235 - -i Ident -c Connect -k Connect Ack -r Connect NAK -d Disconnect req -s Data Ack/ Retransmit Req )status) -p Poll -f Format Fail -b dis ack -t talk - -a Abort -o Abort ACK - - -00cG8BPQ:1025 G8BPQ:24 0 7 T60R5W10FA36 -00kG8BPQ:24 G8BPQ 6 49A3A -08s___ABFC -08 ARQ:FILE::flarqmail-1.eml -ARQ:EMAIL:: -ARQ:SIZE::90 -ARQ::STX -//FLARQ COMPOSER -Date: 09/01/2014 23:24:42 -To: gm8bpq -From: -SubjectA0E0 -08!: Test - -Test Message - -ARQ::ETX -F0F2 -08pG8BPQ!__623E -08pG8BPQ!__623E -08pG8BPQ!__623E - - - - -*/ -VOID ProcessFLDigiData(struct TNCINFO * TNC, UCHAR * Input, int Len, char Channel, BOOL RAW) -{ - UINT * buffptr; - int Stream = 0; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - char CTRL = Input[0]; - struct ARQINFO * ARQ = TNC->ARQInfo; - struct FLINFO * FL = TNC->FLInfo; - - int SendLen; - char Reply[80]; - - - // Process Message - - // This processes eitrher message from the KISS or RAW interfaces. - // Headers and RAW checksum have been removed, so packet starts with Control Byte - - // Only a connect request is allowed with no session, so check first - - if (CTRL == 'c') - { - // Connect Request - - char * call1; - char * call2; - char * port1; - char * port2; - char * ptr; - char * context; - char FarStream = 0; - int BlockSize = 6; // 64 default - int Window = TNC->Window; - APPLCALLS * APPL; - char * ApplPtr = APPLS; - int App; - char Appl[10]; - struct WL2KInfo * WL2K = TNC->WL2K; - TRANSPORTENTRY * SESS; - - if (FL->CONOK == FALSE) - return; - - call1 = strtok_s(&Input[1], " ", &context); - call2 = strtok_s(NULL, " ", &context); - - port1 = strlop(call1, ':'); - port2 = strlop(call2, ':'); - - // See if for us - - for (App = 0; App < 32; App++) - { - APPL=&APPLCALLTABLE[App]; - memcpy(Appl, APPL->APPLCALL_TEXT, 10); - ptr=strchr(Appl, ' '); - - if (ptr) *ptr = 0; - - if (_stricmp(call2, Appl) == 0) - break; - } - - if (App > 31) - if (strcmp(TNC->NodeCall, call2) !=0) - return; // Not Appl or Port/Node Call - - ptr = strtok_s(NULL, " ", &context); - FarStream = *ptr; - ptr = strtok_s(NULL, " ", &context); - BlockSize = atoi(ptr); - - if (ARQ->ARQState) - { - // We have already received a connect request - just ACK it - - goto AckConnectRequest; - } - - // Get a Session - - SuspendOtherPorts(TNC); - - ProcessIncommingConnect(TNC, call1, 0, FALSE); - - SESS = TNC->PortRecord->ATTACHEDSESSIONS[0]; - - strcpy(STREAM->MyCall, call2); - STREAM->ConnectTime = time(NULL); - STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0; - - if (TNC->RIG && TNC->RIG != &TNC->DummyRig && strcmp(TNC->RIG->RigName, "PTT")) - { - sprintf(TNC->WEB_TNCSTATE, "%s Connected to %s Inbound Freq %s", TNC->Streams[0].RemoteCall, call2, TNC->RIG->Valchar); - SESS->Frequency = (atof(TNC->RIG->Valchar) * 1000000.0) + 1500; // Convert to Centre Freq - SESS->Mode = TNC->WL2KMode; - } - else - { - sprintf(TNC->WEB_TNCSTATE, "%s Connected to %s Inbound", TNC->Streams[0].RemoteCall, call2); - if (WL2K) - { - SESS->Frequency = WL2K->Freq; - SESS->Mode = WL2K->mode; - } - } - - if (WL2K) - strcpy(SESS->RMSCall, WL2K->RMSCall); - - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - strcpy(TNC->WEB_PROTOSTATE, "Connect Pending"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - memset(ARQ, 0, sizeof(struct ARQINFO)); // Reset ARQ State - ARQ->FarStream = FarStream; - ARQ->TXSeq = ARQ->TXLastACK = 63; // Last Sent - ARQ->RXHighest = ARQ->RXNoGaps = 63; // Last Received - ARQ->ARQState = ARQ_ACTIVE; - ARQ->OurStream = (rand() % 78) + 49; // To give some protection against other stuff on channel - ARQ->FarStream = FarStream; // Not Yet defined - if (strcmp(port1, "1025") == 0) - { - FL->FLARQ = TRUE; // From FLARQ - ARQ->OurStream = '8'; // FLARQ Ignores what we send - } - else - FL->FLARQ = FALSE; // From other app (eg BPQ) - - FL->RAW = RAW; - - STREAM->NeedDisc = 0; - - if (App < 32) - { - char AppName[13]; - - memcpy(AppName, &ApplPtr[App * sizeof(CMDX)], 12); - AppName[12] = 0; - - // Make sure app is available - - if (CheckAppl(TNC, AppName)) - { - char Buffer[32]; - int MsgLen = sprintf(Buffer, "%s\r", AppName); - - buffptr = GetBuff(); - - if (buffptr == 0) - { - return; // No buffers, so ignore - } - - buffptr[1] = MsgLen; - memcpy(buffptr+2, Buffer, MsgLen); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - TNC->SwallowSignon = TRUE; - - // Save Appl Call in case needed for - - } - else - { - STREAM->NeedDisc = 50; // 1 sec - } - } - - ARQ->TXWindow = Window; - - if (BlockSize < 4) BlockSize = 4; - if (BlockSize < 9) BlockSize = 9; - - ARQ->MaxBlock = Blocksizes[BlockSize]; - - - ARQ->ARQTimer = 10; // To force CTEXT to be Queued - - if (App == 32) - { - // Connect to Node - send CTEXT - - if (HFCTEXTLEN > 1) - { - buffptr = GetBuff(); - if (buffptr) - { - buffptr[1] = HFCTEXTLEN; - memcpy(&buffptr[2], HFCTEXT, HFCTEXTLEN); - SendARQData(TNC, buffptr); - } - } - } - - if (STREAM->NeedDisc) - { - // Send Not Avail - - buffptr = GetBuff(); - if (buffptr) - { - buffptr[1] = sprintf((char *)&buffptr[2], "Application Not Available\n"); - SendARQData(TNC, buffptr); - } - } - -AckConnectRequest: - - SendLen = sprintf(Reply, "k%s:24 %s %c 7", call2, call1, ARQ->OurStream); - - SaveAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - ARQ->ARQTimerState = ARQ_CONNECTACK; - - return; - } - - // All others need a session - -// if (!STREAM->Connected && !STREAM->Connecting) -// return; - - if (CTRL == 'k') - { - // Connect ACK - - char * call1; - char * call2; - char * port1; - char * port2; - char * ptr; - char * context; - char FarStream = 0; - int BlockSize = 6; // 64 default - int Window = 16; - - char Reply[80]; - int ReplyLen; - - call1 = strtok_s(&Input[1], " ", &context); - call2 = strtok_s(NULL, " ", &context); - - port1 = strlop(call1, ':'); - port2 = strlop(call2, ':'); - - if (strcmp(call1, STREAM->RemoteCall) != 0) - return; - - if (Channel != ARQ->OurStream) - return; // Wrong Session - - ptr = strtok_s(NULL, " ", &context); - if (ptr) - FarStream = *ptr; - ptr = strtok_s(NULL, " ", &context); - if (ptr) - BlockSize = atoi(ptr); - - if (STREAM->Connected) - goto SendKReply; // Repeated ACK - - STREAM->ConnectTime = time(NULL); - STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = STREAM->BytesResent = 0; - STREAM->Connected = TRUE; - - ARQ->ARQTimerState = 0; - ARQ->ARQTimer = 0; - - if (TNC->RIG) - sprintf(TNC->WEB_TNCSTATE, "%s Connected to %s Outbound Freq %s", STREAM->MyCall, STREAM->RemoteCall, TNC->RIG->Valchar); - else - sprintf(TNC->WEB_TNCSTATE, "%s Connected to %s Outbound", STREAM->MyCall, STREAM->RemoteCall); - - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - UpdateMH(TNC, STREAM->RemoteCall, '+', 'Z'); - - ARQ->ARQTimerState = 0; - ARQ->FarStream = FarStream; - ARQ->TXWindow = TNC->Window; - ARQ->MaxBlock = Blocksizes[BlockSize]; - - ARQ->ARQState = ARQ_ACTIVE; - - STREAM->NeedDisc = 0; - - buffptr = GetBuff(); - - if (buffptr) - { - ReplyLen = sprintf(Reply, "*** Connected to %s\r", STREAM->RemoteCall); - - buffptr[1] = ReplyLen; - memcpy(buffptr+2, Reply, ReplyLen); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - - strcpy(TNC->WEB_PROTOSTATE, "Connected"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - -SendKReply: - - // Reply with status - - SendLen = sprintf(Reply, "s%c%c%c", ARQ->TXSeq + 32, ARQ->RXNoGaps + 32, ARQ->RXHighest + 32); - - if (ARQ->RXHighest != ARQ->RXNoGaps) - { - int n = ARQ->RXNoGaps + 1; - n &= 63; - - while (n != ARQ->RXHighest) - { - if (ARQ->RXHOLDQ[n] == 0) // Dont have it - SendLen += sprintf(&Reply[SendLen], "%c", n + 32); - - n++; - n &= 63; - } - } - - QueueAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - return; - } - - // All others need a session - - //if (!STREAM->Connected) - // return; - - - if (CTRL == 's') - { - // Status - - if (Channel != ARQ->OurStream) - return; // Wrong Session - - ARQ->ARQTimer = 0; // Stop retry timer - Input[Len] = 0; - ProcessARQStatus(TNC, ARQ, &Input[1]); - - return; - } - - if (CTRL == 'p') - { - // Poll - - char * call1; - char * context; - - call1 = strtok_s(&Input[1], " \x1A", &context); - - if (strcmp(call1, STREAM->RemoteCall) != 0) - return; - - if (Channel != ARQ->OurStream) - return; // Wrong Session - - SendLen = sprintf(Reply, "s%c%c%c", ARQ->TXSeq + 32, ARQ->RXNoGaps + 32, ARQ->RXHighest + 32); - - if (ARQ->RXHighest != ARQ->RXNoGaps) - { - int n = ARQ->RXNoGaps + 1; - n &= 63; - - while (n != ARQ->RXHighest) - { - if (ARQ->RXHOLDQ[n] == 0) // Dont have it - SendLen += sprintf(&Reply[SendLen], "%c", n + 32); - - n++; - n &= 63; - } - } - else - ARQ->TurnroundTimer = 15; // Allow us to send it all acked - - QueueAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - - return; - } - - - if (CTRL == 'a') - { - // Abort. Send Abort ACK - same as - - char * call1; - char * context; - - call1 = strtok_s(&Input[1], " :", &context); - - if (strcmp(call1, STREAM->RemoteCall) != 0) - return; - - if (Channel != ARQ->OurStream) - return; // Wrong Session - - SendLen = sprintf(Reply, "o%c%c%c", ARQ->TXSeq + 32, ARQ->RXNoGaps + 32, ARQ->RXHighest + 32); - - if (ARQ->RXHighest != ARQ->RXNoGaps) - { - int n = ARQ->RXNoGaps + 1; - n &= 63; - - while (n != ARQ->RXHighest) - { - if (ARQ->RXHOLDQ[n] == 0) // Dont have it - SendLen += sprintf(&Reply[SendLen], "%c", n + 32); - - n++; - n &= 63; - } - } - - QueueAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - return; - } - - if (CTRL == 'i') - { - // Ident - - return; - } - - if (CTRL == 't') - { - // Talk - not sure what to do with these - - return; - } - - if (CTRL == 'd') - { - // Disconnect Request - - char * call1; - char * context; - - call1 = strtok_s(&Input[1], " ", &context); - strlop(call1, ':'); - - if (strcmp(STREAM->RemoteCall, call1)) - return; - - if (Channel != ARQ->OurStream) - return; // Wrong Session - - - // As the Disc ACK isn't repeated, we have to clear session now - - STREAM->Connected = FALSE; - STREAM->Connecting = FALSE; - STREAM->ReportDISC = TRUE; - - strcpy(TNC->WEB_PROTOSTATE, "Disconncted"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - ARQ->ARQState = 0; - - SendLen = sprintf(Reply, "b%s:91", STREAM->MyCall); - - ARQ->ARQTimerState = ARQ_WAITACK; - SaveAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - ARQ->Retries = 2; - return; - } - - if (CTRL == 'b') - { - // Disconnect ACK - - char * call1; - char * context; - - call1 = strtok_s(&Input[1], " ", &context); - strlop(call1, ':'); - - if (strcmp(STREAM->RemoteCall, call1)) - return; - - if (Channel != ARQ->OurStream) - return; // Wrong Session - - ARQ->ARQTimer = 0; - ARQ->ARQTimerState = 0; - ARQ->ARQState = 0; - - if (STREAM->Connected) - { - // Create a traffic record - - char logmsg[120]; - time_t Duration; - - Duration = time(NULL) - STREAM->ConnectTime; - - if (Duration == 0) - Duration = 1; - - sprintf(logmsg,"Port %2d %9s Bytes Sent %d BPS %d Bytes Received %d BPS %d Time %d Seconds", - TNC->Port, STREAM->RemoteCall, - STREAM->BytesTXed, (int)(STREAM->BytesTXed/Duration), - STREAM->BytesRXed, (int)(STREAM->BytesRXed/Duration), (int)Duration); - - Debugprintf(logmsg); - } - - STREAM->Connecting = FALSE; - STREAM->Connected = FALSE; // Back to Command Mode - STREAM->ReportDISC = TRUE; // Tell Node - - if (STREAM->Disconnecting) // - FLReleaseTNC(TNC); - - STREAM->Disconnecting = FALSE; - - strcpy(TNC->WEB_PROTOSTATE, "Disconncted"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - return; - } - - if (CTRL == 'u') - { - // Beacon - - //>00uGM8BPQ:72 GM8BPQ TestingAD67 - - char * Call = &Input[1]; - strlop(Call, ':'); - - UpdateMH(TNC, Call, '!', 0); - return; - } - - if (STREAM->Connected) - { - if (Channel != ARQ->OurStream) - return; // Wrong Session - - if (CTRL >= ' ' && CTRL < 96) - { - // ARQ Data - - int Seq = CTRL - 32; - int Work; - -// if (rand() % 5 == 2) -// { -// Debugprintf("Dropping %d", Seq); -// return; -// } - - buffptr = GetBuff(); - - if (buffptr == NULL) - return; // Sould never run out, but cant do much else - - // Remove any DLE transparency - - if (TNC->FLInfo->KISSMODE) - Len -= 1; - else - Len = UnStuff(&Input[1], Len - 1); - - buffptr[1] = Len; - memcpy(&buffptr[2], &Input[1], Len); - STREAM->BytesRXed += Len; - - UpdateStatsLine(TNC, STREAM); - - // Safest always to save, then see what we can process - - if (ARQ->RXHOLDQ[Seq]) - { - // Wot! Shouldn't happen - - ReleaseBuffer(ARQ->RXHOLDQ[Seq]); -// Debugprintf("ARQ Seq %d Duplicate"); - } - - ARQ->RXHOLDQ[Seq] = buffptr; -// Debugprintf("ARQ saving %d", Seq); - - // If this is higher that highest received, save. But beware of wrap' - - // Hi = 2, Seq = 60 dont save s=h = 58 - // Hi = 10 Seq = 12 save s-h = 2 - // Hi = 14 Seq = 10 dont save s-h = -4 - // Hi = 60 Seq = 2 save s-h = -58 - - Work = Seq - ARQ->RXHighest; - - if ((Work > 0 && Work < 32) || Work < -32) - ARQ->RXHighest = Seq; - - // We may now be able to process some - - Work = (ARQ->RXNoGaps + 1) & 63; // The next one we need - - while (ARQ->RXHOLDQ[Work]) - { - // We have it - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, ARQ->RXHOLDQ[Work]); -// ReleaseBuffer(ARQ->RXHOLDQ[Work]); - - ARQ->RXHOLDQ[Work] = NULL; -// Debugprintf("Processing %d from Q", Work); - - ARQ->RXNoGaps = Work; - Work = (Work + 1) & 63; // The next one we need - } - - ARQ->TurnroundTimer = 200; // Delay before allowing reply. Will normally be reset by the poll following data - return; - } - } -} - - -VOID SendARQData(struct TNCINFO * TNC, UINT * Buffer) -{ - // Send Data, saving a copy until acked. - - struct ARQINFO * ARQ = TNC->ARQInfo; - struct FLINFO * FL = TNC->FLInfo; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - - - UCHAR TXBuffer[300]; - SOCKET sock = TNC->TCPDataSock; - int SendLen; - UCHAR * ptr; - int Origlen = Buffer[1]; - int Stuffedlen; - - ARQ->TXSeq++; - ARQ->TXSeq &= 63; - - SendLen = sprintf(TXBuffer, "%c", ARQ->TXSeq + 32); - - ptr = (UCHAR *)&Buffer[2]; // Start of data; - - ptr[Buffer[1]] = 0; - - if (memcmp(ptr, "ARQ:", 4) == 0) - { - // FLARQ Mail/FIle transfer. Turn off CR > LF translate (used for terminal mode) - - FL->FLARQ = FALSE; - } - - if (FL->FLARQ) - { - // Terminal Mode. Need to convert CR to LF so it displays in FLARQ Window - - ptr = strchr(ptr, 13); - - while (ptr) - { - *(ptr++) = 10; // Replace CR with LF - ptr = strchr(ptr, 13); - } - } - - if (TNC->FLInfo->KISSMODE) - { - memcpy(&TXBuffer[SendLen], (UCHAR *)&Buffer[2], Origlen); - SendLen += Origlen; - } - else - { - Stuffedlen = Stuff((UCHAR *)&Buffer[2], &TXBuffer[SendLen], Origlen); - SendLen += Stuffedlen; - } - - TXBuffer[SendLen] = 0; - -// if (rand() % 5 == 2) -// Debugprintf("Dropping %d", ARQ->TXSeq); -// else - - ARQ->TXHOLDQ[ARQ->TXSeq] = Buffer; - - STREAM->BytesTXed += Origlen; - - UpdateStatsLine(TNC, STREAM); - - // if waiting for ack, don't send, just queue. Will be sent when ack received - - if (ARQ->ARQTimer == 0 || ARQ->ARQTimerState == ARQ_WAITDATA) - { - SendPacket(TNC, TXBuffer, SendLen); - ARQ->ARQTimer = 15; // wait up to 1.5 sec for more data before polling - ARQ->Retries = 1; - ARQ->ARQTimerState = ARQ_WAITDATA; - } - else - STREAM->BytesResent -= Origlen; // So wont be included in resent bytes -} - -VOID TidyClose(struct TNCINFO * TNC, int Stream) -{ - char Reply[80]; - int SendLen; - - struct ARQINFO * ARQ = TNC->ARQInfo; - - SendLen = sprintf(Reply, "d%s:90", TNC->Streams[0].MyCall); - - SaveAndSend(TNC, ARQ, TNC->TCPDataSock, Reply, SendLen); - ARQ->ARQTimerState = ARQ_DISC; - - strcpy(TNC->WEB_PROTOSTATE, "Disconncting"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); -} - -VOID ForcedClose(struct TNCINFO * TNC, int Stream) -{ - TidyClose(TNC, Stream); // I don't think Hostmode has a DD -} - -VOID CloseComplete(struct TNCINFO * TNC, int Stream) -{ - FLReleaseTNC(TNC); -} - -VOID FLReleaseTNC(struct TNCINFO * TNC) -{ - // Set mycall back to Node or Port Call, and Start Scanner - - UCHAR TXMsg[1000]; - - strcpy(TNC->WEB_TNCSTATE, "Free"); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - // if a default Modem is defined, select it - - if (TNC->FLInfo->DefaultMode[0]) - { - char txbuff[80]; - - if (TNC->FLInfo->KISSMODE) - { - sprintf(txbuff, "WFF:%d MODEM:%s MODEM: WFF:", TNC->FLInfo->DefaultFreq, TNC->FLInfo->DefaultMode); - SendKISSCommand(TNC, txbuff); - } - else - { - SendXMLCommand(TNC, "modem.set_by_name", TNC->FLInfo->DefaultMode, 'S'); - SendXMLCommand(TNC, "modem.set_carrier", (char *)TNC->FLInfo->DefaultFreq, 'I'); - } - } - // Start Scanner - - sprintf(TXMsg, "%d SCANSTART 15", TNC->Port); - - Rig_Command(-1, TXMsg); - - ReleaseOtherPorts(TNC); - -} -VOID QueueAndSend(struct TNCINFO * TNC, struct ARQINFO * ARQ, SOCKET sock, char * Msg, int MsgLen) -{ - // Queue to be sent after TXDELAY - - memcpy(ARQ->TXMsg, Msg, MsgLen + 1); - ARQ->TXLen = MsgLen; - ARQ->TXDelay = 15; // Try 1500 ms -} - -VOID SaveAndSend(struct TNCINFO * TNC, struct ARQINFO * ARQ, SOCKET sock, char * Msg, int MsgLen) -{ - // Used for Messages that need a reply. Save, send and set timeout - - memcpy(ARQ->LastMsg, Msg, MsgLen + 1); // Include Null - ARQ->LastLen = MsgLen; - - // Delay the send for a short while Just use the timeout code - -// SendPacket(sock, Msg, MsgLen, 0); - ARQ->ARQTimer = 1; // Try 500 ms - ARQ->Retries = TNC->Retries + 1; // First timout is rthe real send - - return; -} - - -VOID ARQTimer(struct TNCINFO * TNC) -{ - struct ARQINFO * ARQ = TNC->ARQInfo; - UINT * buffptr; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - int SendLen; - char Reply[80]; - struct FLINFO * FL = TNC->FLInfo; - - //Send frames, unless held by TurnroundTimer or Window - - int Outstanding; - - // Use new BUSY: poll to detect busy state - - if (FL->TX == FALSE) - if (TNC->FLInfo->KISSMODE) - SendKISSCommand(TNC, "BUSY:"); // Send every poll for now - may need to optimize later - - -/* -// Use Received chars as a rough channel active indicator - - FL->BusyTimer++; - - if (FL->BusyTimer > 4) - { - FL->BusyTimer = 0; - - if (FL->BusyCounter > 2) // 2 chars in last .3 secs - FL->Busy = TRUE; - else - FL->Busy = FALSE; - - if (FL->TX) - strcpy(TNC->WEB_CHANSTATE, "TX"); - else - if (FL->Busy) - strcpy(TNC->WEB_CHANSTATE, "Busy"); - else - strcpy(TNC->WEB_CHANSTATE, "Idle"); - - FL->BusyCounter = 0; - - SetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE); - } - -*/ // TXDelay is used as a turn round delay for frames that don't have to be retried. It doesn't - // need to check for busy (or anything else (I think!) - - if (ARQ->TXDelay) - { - ARQ->TXDelay--; - - if (ARQ->TXDelay) - return; - - SendPacket(TNC, ARQ->TXMsg, ARQ->TXLen); - } - - // if We are alredy sending (State = ARQ_WAITDATA) we should allow it to send more (and the Poll at end) - - if (ARQ->ARQTimerState == ARQ_WAITDATA) - { - while (STREAM->BPQtoPACTOR_Q) - { - Outstanding = ARQ->TXSeq - ARQ->TXLastACK; - - if (Outstanding < 0) - Outstanding += 64; - - TNC->PortRecord->FramesQueued = Outstanding + C_Q_COUNT(&STREAM->BPQtoPACTOR_Q); // Save for Appl Level Queued Frames - - if (Outstanding > ARQ->TXWindow) - break; - - buffptr = Q_REM(&STREAM->BPQtoPACTOR_Q); - SendARQData(TNC, buffptr); - } - - ARQ->ARQTimer--; - - if (ARQ->ARQTimer > 0) - return; // Timer Still Running - - // No more data available - send poll - - SendLen = sprintf(Reply, "p%s", TNC->Streams[0].MyCall); - - ARQ->ARQTimerState = ARQ_WAITACK; - - // This is one message that should not be queued so it is sent straiget after data - -// Debugprintf("Sending Poll"); - - memcpy(ARQ->LastMsg, Reply, SendLen + 1); - ARQ->LastLen = SendLen; - - SendPacket(TNC, Reply, SendLen); - - ARQ->ARQTimer = TNC->Timeout; - ARQ->Retries = TNC->Retries; - - strcpy(TNC->WEB_PROTOSTATE, "Wait ACK"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - return; - - } - - // TrunroundTimer is used to allow time for far end to revert to RX - - if (ARQ->TurnroundTimer && !FL->Busy) - ARQ->TurnroundTimer--; - - if (ARQ->TurnroundTimer == 0) - { - while (STREAM->BPQtoPACTOR_Q) - { - Outstanding = ARQ->TXSeq - ARQ->TXLastACK; - - if (Outstanding < 0) - Outstanding += 64; - - TNC->PortRecord->FramesQueued = Outstanding + C_Q_COUNT(&STREAM->BPQtoPACTOR_Q) + 1; // Make sure busy is reported to BBS - - if (Outstanding > ARQ->TXWindow) - break; - - buffptr = Q_REM(&STREAM->BPQtoPACTOR_Q); - SendARQData(TNC, buffptr); - } - } - - if (ARQ->ARQTimer) - { - if (FL->TX || FL->Busy) - { - // Only decrement if running send poll timer - - if (ARQ->ARQTimerState != ARQ_WAITDATA) - return; - } - - ARQ->ARQTimer--; - { - if (ARQ->ARQTimer) - return; // Timer Still Running - } - - ARQ->Retries--; - - if (ARQ->Retries) - { - // Retry Current Message - - SendPacket(TNC, ARQ->LastMsg, ARQ->LastLen); - ARQ->ARQTimer = TNC->Timeout + (rand() % 30); - - return; - } - - // Retried out. - - switch (ARQ->ARQTimerState) - { - case ARQ_WAITDATA: - - // No more data available - send poll - - SendLen = sprintf(Reply, "p%s", TNC->Streams[0].MyCall); - - ARQ->ARQTimerState = ARQ_WAITACK; - - // This is one message that should not be queued so it is sent straiget after data - - memcpy(ARQ->LastMsg, Reply, SendLen + 1); - ARQ->LastLen = SendLen; - - SendPacket(TNC, Reply, SendLen); - - ARQ->ARQTimer = TNC->Timeout; - ARQ->Retries = TNC->Retries; - - strcpy(TNC->WEB_PROTOSTATE, "Wait ACK"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - return; - - case ARQ_CONNECTING: - - // Report Connect Failed, and drop back to command mode - - buffptr = GetBuff(); - - if (buffptr) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "FLDigi} Failure with %s\r", STREAM->RemoteCall); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - - // Send Disc to TNC in case it got the Connects, but we missed the ACKs - - TidyClose(TNC, 0); - ARQ->Retries = 2; // First timout is the real send, only send once - STREAM->Connecting = FALSE; // Back to Command Mode - ARQ->ARQState = FALSE; - - break; - - case ARQ_WAITACK: - case ARQ_CONNECTACK: - case ARQ_DISC: - - STREAM->Connected = FALSE; // Back to Command Mode - STREAM->ReportDISC = TRUE; - ARQ->ARQState = FALSE; - - while (STREAM->PACTORtoBPQ_Q) - ReleaseBuffer(Q_REM(&STREAM->PACTORtoBPQ_Q)); - - while (STREAM->BPQtoPACTOR_Q) - ReleaseBuffer(Q_REM(&STREAM->BPQtoPACTOR_Q)); - - strcpy(TNC->WEB_TNCSTATE, "Free"); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - strcpy(TNC->WEB_PROTOSTATE, "Disconncted"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - break; - - } - } -} - -VOID ProcessARQStatus(struct TNCINFO * TNC, struct ARQINFO * ARQ, char * Input) -{ - // Release any acked frames and resend any outstanding - - int LastInSeq = Input[1] - 32; - int LastRXed = Input[2] - 32; - int FirstUnAcked = ARQ->TXLastACK; - int n = (int)strlen(Input) - 3; - char * ptr; - int NexttoResend; - int First, Last, Outstanding; - UINT * Buffer; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - int Acked = 0; - - // First status is an ack of Connect ACK - - if (ARQ->ARQTimerState == ARQ_CONNECTACK) - { - ARQ->Retries = 0; - ARQ->ARQTimer = 0; - ARQ->ARQTimerState = 0; - - strcpy(TNC->WEB_PROTOSTATE, "Connected"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - } - - // Release all up to LastInSeq - - while (FirstUnAcked != LastInSeq) - { - FirstUnAcked++; - FirstUnAcked &= 63; - - Buffer = ARQ->TXHOLDQ[FirstUnAcked]; - - if (Buffer) - { -// Debugprintf("Acked %d", FirstUnAcked); - STREAM->BytesAcked += Buffer[1]; - ReleaseBuffer(Buffer); - ARQ->TXHOLDQ[FirstUnAcked] = NULL; - Acked++; - } - } - - ARQ->TXLastACK = FirstUnAcked; - - Outstanding = ARQ->TXSeq - ARQ->TXLastACK; - - if (Outstanding < 0) - Outstanding += 64; - - TNC->PortRecord->FramesQueued = Outstanding + C_Q_COUNT(&STREAM->BPQtoPACTOR_Q); // Save for Appl Level Queued Frames - - if (FirstUnAcked == ARQ->TXSeq) - { - UpdateStatsLine(TNC, STREAM); - ARQ->NoAckRetries = 0; - - strcpy(TNC->WEB_PROTOSTATE, "Connected"); - SetWindowText(TNC->xIDC_PROTOSTATE, TNC->WEB_PROTOSTATE); - - return; // All Acked - } - // Release any not in retry list up to LastRXed. - - ptr = &Input[3]; - - while (n) - { - NexttoResend = *(ptr++) - 32; - - FirstUnAcked++; - FirstUnAcked &= 63; - - while (FirstUnAcked != NexttoResend) - { - Buffer = ARQ->TXHOLDQ[FirstUnAcked]; - - if (Buffer) - { -// Debugprintf("Acked %d", FirstUnAcked); - STREAM->BytesAcked += Buffer[1]; - ReleaseBuffer(Buffer); - ARQ->TXHOLDQ[FirstUnAcked] = NULL; - Acked++; - } - - FirstUnAcked++; - FirstUnAcked &= 63; - } - - // We don't ACK this one. Process any more resend values, then release up to LastRXed. - - n--; - } - - // Release rest up to LastRXed - - while (FirstUnAcked != LastRXed) - { - FirstUnAcked++; - FirstUnAcked &= 63; - - Buffer = ARQ->TXHOLDQ[FirstUnAcked]; - - if (Buffer) - { -// Debugprintf("Acked %d", FirstUnAcked); - STREAM->BytesAcked += Buffer[1]; - ReleaseBuffer(Buffer); - ARQ->TXHOLDQ[FirstUnAcked] = NULL; - Acked++; - } - } - - // Resend anything in TX Buffer (From LastACK to TXSeq - - Last = ARQ->TXSeq + 1; - Last &= 63; - - First = LastInSeq; - - while (First != Last) - { - First++; - First &= 63; - - if(ARQ->TXHOLDQ[First]) - { - UINT * Buffer = ARQ->TXHOLDQ[First]; - UCHAR TXBuffer[300]; - SOCKET sock = TNC->TCPDataSock; - int SendLen; - -// Debugprintf("Resend %d", First); - - STREAM->BytesResent += Buffer[1]; - - SendLen = sprintf(TXBuffer, "%c", First + 32); - - if (TNC->FLInfo->KISSMODE) - { - memcpy(&TXBuffer[SendLen], (UCHAR *)&Buffer[2], Buffer[1]); - SendLen += Buffer[1]; - } - else - SendLen += Stuff((UCHAR *)&Buffer[2], &TXBuffer[SendLen], Buffer[1]); - - TXBuffer[SendLen] = 0; - - SendPacket(TNC, TXBuffer, SendLen); - - ARQ->ARQTimer = 10; // wait up to 1 sec for more data before polling - ARQ->Retries = 1; - ARQ->ARQTimerState = ARQ_WAITDATA; - - if (Acked == 0) - { - // Nothing acked by this statis message - - Acked = 0; // Dont count more thna once - ARQ->NoAckRetries++; - if (ARQ->NoAckRetries > TNC->Retries) - { - // Too many retries - just disconnect - - TidyClose(TNC, 0); - return; - } - } - } - } - - UpdateStatsLine(TNC, STREAM); -} - -VOID FLSlowTimer(struct TNCINFO * TNC) -{ - struct FLINFO * FL = TNC->FLInfo; - - // Entered every 10 secs - - // if in MCAST mode, clear KILL timer (MCAST RX can run for a long time - - if (TNC->FLInfo->MCASTMODE) - { - TRANSPORTENTRY * SESS = TNC->PortRecord->ATTACHEDSESSIONS[0]; - - if (SESS) - SESS->L4KILLTIMER = 0; - } - - if (FL->KISSMODE) - { - if (FL->Responding) - FL->Responding--; - - if (FL->Responding == 0) - { - TNC->TNCOK = FALSE; - TNC->CONNECTED = FALSE; - - sprintf(TNC->WEB_COMMSSTATE, "Connection to FLDIGI lost"); - SetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); - - // Set basic params till it responds - } - - FL->CmdControl++; - - if (FL->CmdControl > 5) // Every Minute - { - FL->CmdControl = 0; - - SendKISSCommand(TNC, "FLSTAT: MODEM: WFF:"); - } - - SendKISSCommand(TNC, "TRXS: TXBUF:"); // In case TX/RX report is missed - } -} - -static int ProcessXMLData(int port) -{ - unsigned int bytes; - int i; - char ErrMsg[255]; - char Message[500]; - struct TNCINFO * TNC = TNCInfo[port]; - struct FLINFO * FL = TNC->FLInfo; - char * ptr1, * ptr2, *ptr3; - - // Need to extract messages from byte stream - - bytes = recv(TNC->TCPSock,(char *)&Message, 500, 0); - - if (bytes == SOCKET_ERROR) - { -// i=sprintf(ErrMsg, "Read Failed for FLDigi socket - error code = %d\r\n", WSAGetLastError()); -// WritetoConsole(ErrMsg); - - closesocket(TNC->TCPSock); - - TNC->CONNECTED = FALSE; - if (TNC->Streams[0].Attached) - TNC->Streams[0].ReportDISC = TRUE; - - return (0); - } - - if (bytes == 0) - { - // zero bytes means connection closed - - i=sprintf(ErrMsg, "FlDigi Connection closed for BPQ Port %d\n", port); - WritetoConsole(ErrMsg); - - TNC->CONNECTED = FALSE; - if (TNC->Streams[0].Attached) - TNC->Streams[0].ReportDISC = TRUE; - - return (0); - } - - // Have some data. Assume for now we get a whole packet - - if (TNC->InternalCmd) - { - ULONG * buffptr = GetBuff(); - - TNC->InternalCmd = FALSE; - - ptr1 = strstr(Message, ""); - - if (ptr1) - { - ptr1 += 7; - ptr2 = strstr(ptr1, ""); - if (ptr2) *ptr2 = 0; - - ptr3 = strstr(ptr1, ""); - - if (ptr3) - { - ptr1 = ptr3 + 4; - ptr2 = strstr(ptr1, ""); - if (ptr2) *ptr2 = 0; - } - - if (buffptr) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "FLDIGI} Ok Was %s\r", ptr1); - C_Q_ADD(&TNC->Streams[0].PACTORtoBPQ_Q, buffptr); - } - } - - return 0; - } - - - ptr1 = strstr(Message, ""); - - if (ptr1) - { - ptr1 += 7; - ptr2 = strstr(ptr1, ""); - if (ptr2) *ptr2 = 0; - - ptr2 = strstr(ptr1, ""); - - if (ptr2) - { - ptr2 += 8; - ptr1 = ptr2; - ptr2 = strstr(ptr1, ""); - if (ptr2) *ptr2 = 0; - } - - if (strcmp(FL->LastXML, "modem.get_name") == 0) - { - strcpy(TNC->WEB_MODE, ptr1); - SetWindowText(TNC->xIDC_MODE, ptr1); - } - else if (strcmp(FL->LastXML, "main.get_trx_state") == 0) - { - if (strcmp(ptr1, "TX") == 0) - FL->TX = TRUE; - else - FL->TX = FALSE; - - - if (FL->TX) - strcpy(TNC->WEB_CHANSTATE, "TX"); - else - if (FL->Busy) - strcpy(TNC->WEB_CHANSTATE, "Busy"); - else - strcpy(TNC->WEB_CHANSTATE, "Idle"); - - SetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE); - } - else if (strcmp(FL->LastXML, "main.get_squelch") == 0) - { -/* - if (_memicmp(Buffer, "BUSY TRUE", 9) == 0) - { - TNC->BusyFlags |= CDBusy; - TNC->Busy = TNC->BusyHold * 10; // BusyHold delay - - SetWindowText(TNC->xIDC_CHANSTATE, "Busy"); - strcpy(TNC->WEB_CHANSTATE, "Busy"); - - TNC->WinmorRestartCodecTimer = time(NULL); -*/ - return 0; - } -/* - if (_memicmp(Buffer, "BUSY FALSE", 10) == 0) - { - TNC->BusyFlags &= ~CDBusy; - if (TNC->BusyHold) - strcpy(TNC->WEB_CHANSTATE, "BusyHold"); - else - strcpy(TNC->WEB_CHANSTATE, "Clear"); - - SetWindowText(TNC->xIDC_CHANSTATE, TNC->WEB_CHANSTATE); - TNC->WinmorRestartCodecTimer = time(NULL); - return; - } -*/ - - } - - return (0); - -} - - - -char MsgHddr[] = "POST /RPC2 HTTP/1.1\r\n" - "User-Agent: XMLRPC++ 0.8\r\n" - "Host: 127.0.0.1:7362\r\n" - "Content-Type: text/xml\r\n" - "Content-length: %d\r\n" - "\r\n%s"; - -char Req[] = "\r\n" - "%s\r\n" - "%s" - "\r\n"; - - -VOID SendXMLCommand(struct TNCINFO * TNC, char * Command, char * Value, char ParamType) -{ - int Len; - char ReqBuf[512]; - char SendBuff[512]; - struct FLINFO * FL = TNC->FLInfo; - struct ARQINFO * ARQ = TNC->ARQInfo; - char ValueString[256] =""; - - if (!TNC->CONNECTED || TNC->FLInfo->KISSMODE) - return; - - if (Value) - if (ParamType == 'S') - sprintf(ValueString, "%s", Value); - else - sprintf(ValueString, "%d", Value); - - strcpy(FL->LastXML, Command); - Len = sprintf(ReqBuf, Req, FL->LastXML, ValueString); - Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf); - send(TNC->TCPSock, SendBuff, Len, 0); - return; -} - -VOID SendXMLPoll(struct TNCINFO * TNC) -{ - int Len; - char ReqBuf[256]; - char SendBuff[256]; - struct FLINFO * FL = TNC->FLInfo; - struct ARQINFO * ARQ = TNC->ARQInfo; - - if (!TNC->CONNECTED) - return; - - if (TNC->FLInfo->KISSMODE) - return; - - if (ARQ->ARQTimer) - { - // if timer is running, poll fot TX State - - strcpy(FL->LastXML, "main.get_trx_state"); - Len = sprintf(ReqBuf, Req, FL->LastXML, ""); - Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf); - send(TNC->TCPSock, SendBuff, Len, 0); - return; - } - - FL->XMLControl++; - - - if (FL->XMLControl > 9) - { - FL->XMLControl = 0; - strcpy(FL->LastXML, "modem.get_name"); - } - else - { - if (FL->XMLControl == 5) - strcpy(FL->LastXML, "main.get_trx_state"); - else - return; - } - - Len = sprintf(ReqBuf, Req, FL->LastXML, ""); - Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf); - send(TNC->TCPSock, SendBuff, Len, 0); -} - -// sudo add-apt-repository ppa:kamalmostafa/fldigi - - diff --git a/FreeDATA.c b/FreeDATA.c index 0af1375..9e4b349 100644 --- a/FreeDATA.c +++ b/FreeDATA.c @@ -740,7 +740,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, cmd); if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { @@ -4139,7 +4142,7 @@ void buildParamString(struct TNCINFO * TNC, char * line) FDI->TuningRange * -1.0, FDI->TuningRange * 1.0, FDI->TXLevel); if (FDI->hamlibHost) - sprintf(line, "%s --rigctld_ip %s --rigctld_port %d", line, FDI->hamlibHost, FDI->hamlibPort); + sprintf(&line[strlen(line)], " --rigctld_ip %s --rigctld_port %d", FDI->hamlibHost, FDI->hamlibPort); if (FDI->LimitBandWidth) strcat(line, " --500hz"); diff --git a/HALDriver64.c b/HALDriver64.c deleted file mode 100644 index 7c60f9f..0000000 --- a/HALDriver64.c +++ /dev/null @@ -1,1907 +0,0 @@ -/* -Copyright 2001-2018 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - -// -// DLL to inteface HAL Communications Corp Clover/Pacor controllers to BPQ32 switch -// -// Uses BPQ EXTERNAL interface -// - -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_DEPRECATE - -#include "time.h" - -#include "CHeaders.h" -#include "tncinfo.h" - -#include "bpq32.h" - -#define HAL 1 - -#define SetMYCALL 0x13 -#define ConnectEnable 0x52 -#define ConnectDisable 0x42 -#define SetEAS 0x59 // Echo as Sent -#define SetTones 0xec -#define ClearOnDisc 0x57 - -static char ClassName[]="HALSTATUS"; - -static char WindowTitle[] = "HAL"; -static int RigControlRow = 185; - -struct TNCINFO * TNCInfo[34]; // Records are Malloc'd - -#define SOH 0x01 // CONTROL CODES -#define ETB 0x17 -#define DLE 0x10 - -//int MaxStreams = 0; - -#ifndef LINBPQ -extern HFONT hFont; -#endif - -static char status[23][50] = {"IDLE", "TFC", "RQ", "ERR", "PHS", "OVER", "FSK TX", - "FSK RX", "P-MODE100", "P-MODE200", "HUFMAN ON", "HUFMAN OFF", "P-MODE SBY(LISTEN ON)", - "P-MODE SBY(LISTEN OFF)", "ISS", "IRS", - "AMTOR SBY(LISTEN ON)", "AMTOR SBY(LISTEN OFF)", "AMTOR FEC TX", "AMTOR FEC RX", "P-MODE FEC TX", - "FREE SIGNAL TX (AMTOR)", "FREE SIGNAL TX TIMED OUT (AMTOR)"}; - -struct TNCINFO * CreateTTYInfo(int port, int speed); -BOOL OpenConnection(int); -BOOL SetupConnection(int); -static BOOL WriteCommBlock(struct TNCINFO * TNC); -static void CheckRX(struct TNCINFO * TNC); -VOID HALPoll(int Port); -VOID ProcessDEDFrame(struct TNCINFO * TNC, UCHAR * rxbuff, int len); -VOID ProcessTermModeResponse(struct TNCINFO * TNC); -static VOID DoTNCReinit(struct TNCINFO * TNC); -VOID DoTermModeTimeout(struct TNCINFO * TNC); -VOID ProcessHALBuffer(struct TNCINFO * TNC, int Length); -VOID ProcessHALCmd(struct TNCINFO * TNC); -VOID ProcessHALData(struct TNCINFO * TNC); -VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * rxbuffer, int Len); -VOID ProcessKNormCommand(struct TNCINFO * TNC, UCHAR * rxbuffer); -VOID ProcessHostFrame(struct TNCINFO * TNC, UCHAR * rxbuffer, int Len); -VOID DoMonitor(struct TNCINFO * TNC, UCHAR * Msg, int Len); - -BOOL HALConnected(struct TNCINFO * TNC, char * Call); -VOID HALDisconnected(struct TNCINFO * TNC); - -static VOID EncodeAndSend(struct TNCINFO * TNC, UCHAR * txbuffer, int Len); -VOID SendCmd(struct TNCINFO * TNC, UCHAR * txbuffer, int Len); -int DLEEncode(UCHAR * inbuff, UCHAR * outbuff, int len); -int DLEDecode(UCHAR * inbuff, UCHAR * outbuff, int len); - -VOID COMClearDTR(HANDLE fd); -VOID COMClearRTS(HANDLE fd); -int DoScanLine(struct TNCINFO * TNC, char * Buff, int Len); - - - -//static HANDLE LogHandle[4] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; - -//char * Logs[4] = {"1", "2", "3", "4"}; - -//char BaseDir[]="c:"; - -static VOID CloseLogfile(int Flags) -{ -// CloseHandle(LogHandle[Flags]); -// LogHandle[Flags] = INVALID_HANDLE_VALUE; -} - -static VOID OpenLogfile(int Flags) -{ -/* -UCHAR FN[MAX_PATH]; - time_t T; - struct tm * tm; - - T = time(NULL); - tm = gmtime(&T); - - sprintf(FN,"%s\\HALLog_%02d%02d%02d_%s.bin", BaseDir, tm->tm_mday, tm->tm_hour, tm->tm_min, Logs[Flags]); - - LogHandle[Flags] = CreateFile(FN, - GENERIC_WRITE, - FILE_SHARE_READ, - NULL, - OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - - SetFilePointer(LogHandle[Flags], 0, 0, FILE_END); - - return (LogHandle[Flags] != INVALID_HANDLE_VALUE); -*/ -} - -static void WriteLogLine(int Flags, char * Msg, int MsgLen) -{ -// int cnt; -// WriteFile(LogHandle[Flags] ,Msg , MsgLen, &cnt, NULL); -} - - - -int ProcessLine(char * buf, int Port) -{ - UCHAR * ptr,* p_cmd; - char * p_ipad = 0; - char * p_port = 0; - unsigned short WINMORport = 0; - int BPQport; - int len=510; - struct TNCINFO * TNC; - char errbuf[256]; - - strcpy(errbuf, buf); - - ptr = strtok(buf, " \t\n\r"); - - if(ptr == NULL) return (TRUE); - - if(*ptr =='#') return (TRUE); // comment - - if(*ptr ==';') return (TRUE); // comment - - ptr = strtok(NULL, " \t\n\r"); - - if (_stricmp(buf, "APPL") == 0) // Using BPQ32 COnfig - { - BPQport = Port; - p_cmd = ptr; - } - else - if (_stricmp(buf, "PORT") != 0) // Using Old Config - { - // New config without a PORT or APPL - this is a Config Command - - strcpy(buf, errbuf); - strcat(buf, "\r"); - - BPQport = Port; - - TNC = TNCInfo[BPQport] = zalloc(sizeof(struct TNCINFO)); - - TNC->InitScript = malloc(1000); - TNC->InitScript[0] = 0; - goto ConfigLine; - } - else - - { - - // Old Config from file - - BPQport=0; - BPQport = atoi(ptr); - - p_cmd = strtok(NULL, " \t\n\r"); - - if (Port && Port != BPQport) - { - // Want a particular port, and this isn't it - - while(TRUE) - { - if (GetLine(buf) == 0) - return TRUE; - - if (memcmp(buf, "****", 4) == 0) - return TRUE; - - } - } - } - if(BPQport > 0 && BPQport < 33) - { - TNC = TNCInfo[BPQport] = zalloc(sizeof(struct TNCINFO)); - TNC->InitScript = malloc(1000); - TNC->InitScript[0] = 0; - - if (p_cmd != NULL) - { - if (p_cmd[0] != ';' && p_cmd[0] != '#') - TNC->ApplCmd=_strdup(p_cmd); - } - - // Read Initialisation lines - - while(TRUE) - { - if (GetLine(buf) == 0) - return TRUE; -ConfigLine: - strcpy(errbuf, buf); - - if (memcmp(buf, "****", 4) == 0) - return TRUE; - - ptr = strchr(buf, ';'); - if (ptr) - { - *ptr++ = 13; - *ptr = 0; - } - - if (_memicmp(buf, "WL2KREPORT", 10) == 0) - { - TNC->WL2K = DecodeWL2KReportLine(buf); - continue; - } - if (_memicmp(buf, "NEEDXONXOFF", 10) == 0) - { - TNC->XONXOFF = TRUE; - continue; - } - - if (_memicmp(buf, "TONES", 5) == 0) - { - int tone1 = 0, tone2 = 0; - - ptr = strtok(&buf[6], " ,/\t\n\r"); - if (ptr) - { - tone1 = atoi(ptr); - ptr = strtok(NULL, " ,/\t\n\r"); - if (ptr) - { - tone2 = atoi(ptr); - ptr = &TNC->InitScript[TNC->InitScriptLen]; - - // Try putting into FSK mode first - - *(ptr++) = 0x84; - *(ptr++) = SetTones; // Set Tones (Mark, Space HI byte first) - *(ptr++) = tone1 >> 8; - *(ptr++) = tone1 & 0xff; - *(ptr++) = tone2 >> 8; - *(ptr++) = tone2 & 0xff; - - TNC->InitScriptLen += 6; - - continue; - } - } - goto BadLine; - } - if (_memicmp(buf, "DEFAULTMODE ", 12) == 0) - { - - ptr = strtok(&buf[12], " ,\t\n\r"); - if (ptr) - { - if (_stricmp(ptr, "CLOVER") == 0) - TNC->DefaultMode = Clover; - else if (_stricmp(ptr, "PACTOR") == 0) - TNC->DefaultMode = Pactor; - else if (_stricmp(ptr, "AMTOR") == 0) - TNC->DefaultMode = AMTOR; - else goto BadLine; - - continue; - } - goto BadLine; - } - } - BadLine: - WritetoConsole(" Bad config record "); - WritetoConsole(errbuf); - WritetoConsole("\r\n"); - } - - return (TRUE); -} - -static size_t ExtProc(int fn, int port , PDATAMESSAGE buff) -{ - int txlen = 0; - PMSGWITHLEN buffptr; - struct TNCINFO * TNC = TNCInfo[port]; - struct STREAMINFO * STREAM; - int Stream; - - if (TNC == NULL) - return 0; - - if (fn < 4 || fn > 5) - if (TNC->hDevice == 0) - return 0; // Port not open - - STREAM = &TNC->Streams[0]; - - switch (fn) - { - case 1: // poll - - while (TNC->PortRecord->UI_Q) // Release anything accidentally put on UI_Q - { - buffptr = Q_REM(&TNC->PortRecord->UI_Q); - ReleaseBuffer(buffptr); - } - - //for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (STREAM->ReportDISC) - { - STREAM->ReportDISC = FALSE; - buff->PORT = 0; - - return -1; - } - } - - CheckRX(TNC); - HALPoll(port); - - //for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (STREAM->PACTORtoBPQ_Q !=0) - { - int datalen; - - buffptr=Q_REM(&STREAM->PACTORtoBPQ_Q); - - datalen = (int)buffptr->Len; - - buff->PORT = 0; // Compatibility with Kam Driver - buff->PID = 0xf0; - memcpy(&buff->L2DATA, &buffptr->Data[0], datalen); // Data goes to + 7, but we have an extra byte - datalen += sizeof(void *) + 4; - - PutLengthinBuffer(buff, datalen); - - - ReleaseBuffer(buffptr); - - return (1); - } - } - - return 0; - - case 2: // send - - buffptr = GetBuff(); - - if (buffptr == 0) return (0); // No buffers, so ignore - - // Find TNC Record - - Stream = buff->PORT; - - if (!TNC->TNCOK) - { - // Send Error Response - - PMSGWITHLEN buffptr = (PMSGWITHLEN)GetBuff(); - - if (buffptr == 0) return (0); // No buffers, so ignore - - buffptr->Len = 27; - memcpy(&buffptr->Data[0], "No Connection to PACTOR TNC\r", 27); - - C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); - return 0; - } - - txlen = GetLengthfromBuffer(buff) - (sizeof(void *) + 4); - - buffptr->Len = txlen; - memcpy(&buffptr->Data[0], &buff->L2DATA[0], txlen); - - C_Q_ADD(&STREAM->BPQtoPACTOR_Q, buffptr); - - STREAM->FramesQueued++; - - return (0); - - - case 3: // CHECK IF OK TO SEND. Also used to check if TNC is responding - - Stream = (int)(size_t)buff; - - if (STREAM->FramesQueued > 4) - return (1 | TNC->HostMode << 8); - - return TNC->HostMode << 8 | STREAM->Disconnecting << 15; // OK, but lock attach if disconnecting - - case 4: // reinit - - return (0); - - case 5: // Close - - CloseCOMPort(TNCInfo[port]->hDevice); - return (0); - - case 6: // Scan Control - - return 0; // None Yet - - } - return 0; - -} - -static int WebProc(struct TNCINFO * TNC, char * Buff, BOOL LOCAL) -{ - int Len = sprintf(Buff, "" - "HAL Status

HAL Status

"); - - Len += sprintf(&Buff[Len], ""); - - Len += sprintf(&Buff[Len], "", TNC->WEB_COMMSSTATE); - Len += sprintf(&Buff[Len], "", TNC->WEB_TNCSTATE); - Len += sprintf(&Buff[Len], "", TNC->WEB_MODE); - Len += sprintf(&Buff[Len], "", TNC->WEB_STATE); - Len += sprintf(&Buff[Len], "", TNC->WEB_TXRX); - Len += sprintf(&Buff[Len], "", TNC->WEB_TRAFFIC); - Len += sprintf(&Buff[Len], ""); - Len += sprintf(&Buff[Len], "", TNC->WEB_LEDS); - Len += sprintf(&Buff[Len], "
Comms State%s
TNC State%s
Mode%s
Status%s
TX/RX State%s
Traffic%s
LEDSSTBY CALL LINK ERROR TX RX
%s
"); - - Len = DoScanLine(TNC, Buff, Len); - - return Len; -} - - -VOID * HALExtInit(EXTPORTDATA * PortEntry) -{ - char msg[500]; - struct TNCINFO * TNC; - int port; - char * ptr; - int len; - char Msg[80]; -#ifndef LINBPQ - HWND x; -#endif - // - // Will be called once for each Pactor Port - // The COM port number is in IOBASE - // - - sprintf(msg,"HAL Driver %s", PortEntry->PORTCONTROL.SerialPortName); - WritetoConsole(msg); - - port=PortEntry->PORTCONTROL.PORTNUMBER; - - ReadConfigFile(port, ProcessLine); - TNC = TNCInfo[port]; - - if (TNC == NULL) - { - // Not defined in Config file - - sprintf(msg," ** Error - no info in BPQ32.cfg for this port"); - WritetoConsole(msg); - - return ExtProc; - } - - TNC->Port = port; - - TNC->Hardware = H_HAL; - - TNC->Interlock = PortEntry->PORTCONTROL.PORTINTERLOCK; - - PortEntry->MAXHOSTMODESESSIONS = 1; // Default - - TNC->PortRecord = PortEntry; - - if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) - { - memcpy(TNC->NodeCall, MYNODECALL, 10); - } - else - { - ConvFromAX25(&PortEntry->PORTCONTROL.PORTCALL[0], TNC->NodeCall); - } - - PortEntry->PORTCONTROL.PROTOCOL = 10; - PortEntry->PORTCONTROL.PORTQUALITY = 0; - - if (PortEntry->PORTCONTROL.PORTPACLEN == 0) - PortEntry->PORTCONTROL.PORTPACLEN = 100; - - ptr=strchr(TNC->NodeCall, ' '); - if (ptr) *(ptr) = 0; // Null Terminate - - if (TNC->DefaultMode) - TNC->CurrentMode = TNC->DefaultMode; - else - TNC->CurrentMode = Clover; - - TNC->PollDelay = 999999999; - - // Set Disable +?, ExpandedStatus , Channel Stats Off, ClearOnDisc, EAS and MYCALL - - len = sprintf(Msg, "%c%c%c%c%c%c%s", 0xcc, 0x56, 0x41, ClearOnDisc, SetEAS, SetMYCALL, TNC->NodeCall); - len++; // We include the NULL - - memcpy(&TNC->InitScript[TNC->InitScriptLen], Msg, len); - TNC->InitScriptLen += len; - - PortEntry->PORTCONTROL.TNC = TNC; - - TNC->WebWindowProc = WebProc; - TNC->WebWinX = 510; - TNC->WebWinY = 280; - - TNC->WEB_COMMSSTATE = zalloc(100); - TNC->WEB_TNCSTATE = zalloc(100); - strcpy(TNC->WEB_TNCSTATE, "Free"); - TNC->WEB_MODE = zalloc(100); - TNC->WEB_TRAFFIC = zalloc(100); - TNC->WEB_BUFFERS = zalloc(100); - TNC->WEB_STATE = zalloc(100); - TNC->WEB_TXRX = zalloc(100); - TNC->WEB_LEDS = zalloc(100); - strcpy(TNC->WEB_LEDS, " X X X X X X"); - -#ifndef LINBPQ - - CreatePactorWindow(TNC, ClassName, WindowTitle, RigControlRow, PacWndProc, 500, 233, ForcedClose); - - x = CreateWindowEx(0, "STATIC", "Comms State", WS_CHILD | WS_VISIBLE, 10,6,120,20, TNC->hDlg, NULL, hInstance, NULL); - x = TNC->xIDC_COMMSSTATE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,6,386,20, TNC->hDlg, NULL, hInstance, NULL); - - x = CreateWindowEx(0, "STATIC", "TNC State", WS_CHILD | WS_VISIBLE, 10,28,106,20, TNC->hDlg, NULL, hInstance, NULL); - x = TNC->xIDC_TNCSTATE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,28,520,20, TNC->hDlg, NULL, hInstance, NULL); - - x = CreateWindowEx(0, "STATIC", "Mode", WS_CHILD | WS_VISIBLE, 10,50,80,20, TNC->hDlg, NULL, hInstance, NULL); - x = TNC->xIDC_MODE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,50,200,20, TNC->hDlg, NULL, hInstance, NULL); - - x = CreateWindowEx(0, "STATIC", "Status", WS_CHILD | WS_VISIBLE, 10,72,110,20, TNC->hDlg, NULL, hInstance, NULL); - x = TNC->xIDC_STATE = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE, 116,72,144,20, TNC->hDlg, NULL, hInstance, NULL); - - x = CreateWindowEx(0, "STATIC", "TX/RX State", WS_CHILD | WS_VISIBLE,10,94,80,20, TNC->hDlg, NULL, hInstance, NULL); - x = TNC->xIDC_TXRX = CreateWindowEx(0, "STATIC", "", WS_CHILD | WS_VISIBLE,116,94,374,20 , TNC->hDlg, NULL, hInstance, NULL); - - x = CreateWindowEx(0, "STATIC", "Traffic", WS_CHILD | WS_VISIBLE,10,116,80,20, TNC->hDlg, NULL, hInstance, NULL); - x = TNC->xIDC_TRAFFIC = CreateWindowEx(0, "STATIC", "RX 0 TX 0 ACKED 0", WS_CHILD | WS_VISIBLE,116,116,374,20 , TNC->hDlg, NULL, hInstance, NULL); - - x = CreateWindowEx(0, "STATIC", "LEDS", WS_CHILD | WS_VISIBLE,10,138,60,20, TNC->hDlg, NULL, hInstance, NULL); - SendMessage(x, WM_SETFONT, (WPARAM)hFont, 0); - x = CreateWindowEx(0, "STATIC", "STBY CALL LINK ERROR TX RX", WS_CHILD | WS_VISIBLE,116,138,280,20, TNC->hDlg, NULL, hInstance, NULL); - SendMessage(x, WM_SETFONT, (WPARAM)hFont, 0); - x = TNC->xIDC_LEDS = CreateWindowEx(0, "STATIC", " X X X X X X", WS_CHILD | WS_VISIBLE,116,158,280,20 , TNC->hDlg, NULL, hInstance, NULL); - SendMessage(x, WM_SETFONT, (WPARAM)hFont, 0); - - TNC->ClientHeight = 233; - TNC->ClientWidth = 500; - - MoveWindows(TNC); -#endif - - OpenCOMMPort(TNC, PortEntry->PORTCONTROL.SerialPortName, PortEntry->PORTCONTROL.BAUDRATE, FALSE); - - SendCmd(TNC, "\x09" , 1); // Reset - - WritetoConsole("\n"); - - return ExtProc; -} - - - -static VOID KISSCLOSE(int Port) -{ - struct TNCINFO * conn = TNCInfo[Port]; - - // drop DTR and RTS - - COMClearDTR(conn->hDevice); - COMClearRTS(conn->hDevice); - - // purge any outstanding reads/writes and close device handle - - CloseCOMPort(conn->hDevice); - - return; -} - - -static void CheckRX(struct TNCINFO * TNC) -{ - int Length, Len; - UCHAR * Xptr; - - // only try to read number of bytes in queue - - if (TNC->RXLen == 500) - TNC->RXLen = 0; - - Len = ReadCOMBlock(TNC->hDevice, &TNC->RXBuffer[TNC->RXLen], 500 - TNC->RXLen); - - if (Len == 0) - return; - - TNC->RXLen += Len; - - Length = TNC->RXLen; - - // We need to konw whether data is received or echoed, so we can't split commands and data here. - // Pass everything to the Command Handler. It will check that there are enough bytes for the command, - // and wait for more if not. - - // The USB version also uses 0x91 0x31 to eacape 0x11, 0x91 0x33 for 0x13 and 0x91 0xB1 for 0x91 - - // If USB version, we might get unescaped xon and xoff, which we must ignore - - if (TNC->XONXOFF) - { - Xptr = memchr(&TNC->RXBuffer, 0x11, Length); - - while(Xptr) - { - Debugprintf("XON Port %d", TNC->Port); - memmove(Xptr, Xptr + 1, Length-- - (TNC->RXBuffer - Xptr)); - Xptr = memchr(&TNC->RXBuffer, 0x11, Length); - } - - Xptr = memchr(&TNC->RXBuffer, 0x13, Length); - - while(Xptr) - { - Debugprintf("XOFF Port %d", TNC->Port); - memmove(Xptr, Xptr + 1, Length-- - (TNC->RXBuffer - Xptr)); - Xptr = memchr(&TNC->RXBuffer, 0x13, Length); - } - - Xptr = memchr(&TNC->RXBuffer, 0x91, Length); // See if packet contains 0x91 escape - - if (Xptr) - - // Make sure we have the escaped char as well - - if ((Xptr - &TNC->RXBuffer[0]) == Length - 1) // x91 is last char - return; - } - - ProcessHALBuffer(TNC, Length); - - TNC->RXLen = 0; - - return; - -} - - - -static BOOL WriteCommBlock(struct TNCINFO * TNC) -{ - WriteCOMBlock(TNC->hDevice, TNC->TXBuffer, TNC->TXLen); - return TRUE; -} - -VOID HALPoll(int Port) -{ - struct TNCINFO * TNC = TNCInfo[Port]; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - - UCHAR * Poll = TNC->TXBuffer; - char Status[80]; - UCHAR TXMsg[1000]; - int datalen; - - if (TNC->Timeout) - { - TNC->Timeout--; - - if (TNC->Timeout) // Still waiting - return; - - // Timed Out - - TNC->TNCOK = FALSE; - TNC->HostMode = 0; - - sprintf(TNC->WEB_COMMSSTATE,"%s Open but TNC not responding", TNC->PortRecord->PORTCONTROL.SerialPortName); - MySetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); - - //for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (TNC->PortRecord->ATTACHEDSESSIONS[0]) // Connected - { - STREAM->Connected = FALSE; // Back to Command Mode - STREAM->ReportDISC = TRUE; // Tell Node - } - } - - } - - // if we have just restarted or TNC appears to be in terminal mode, run Initialisation Sequence - - if (TNC->TNCOK) - if (!TNC->HostMode) - { - DoTNCReinit(TNC); - return; - } - - if (TNC->PortRecord->ATTACHEDSESSIONS[0] && STREAM->Attached == 0) - { - // New Attach - - int calllen; - char Msg[80]; - - STREAM->Attached = TRUE; - - STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = 0; - - calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4USER, STREAM->MyCall); - STREAM->MyCall[calllen] = 0; - - datalen = sprintf(TXMsg, "%c%s", SetMYCALL, STREAM->MyCall); - SendCmd(TNC, TXMsg, datalen + 1); // Send the NULL - - sprintf(TNC->WEB_TNCSTATE, "In Use by %s", STREAM->MyCall); - MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - // Stop Scanning - - sprintf(Msg, "%d SCANSTOP", TNC->Port); - - Rig_Command(-1, Msg); - - SendCmd(TNC, "\x42", 1); // Connect Enable off - - return; - - } - - //for (Stream = 0; Stream <= MaxStreams; Stream++) - - if (STREAM->Attached) - CheckForDetach(TNC, 0, STREAM, TidyClose, ForcedClose, CloseComplete); - - if (TNC->NeedPACTOR) - { - TNC->NeedPACTOR--; - - if (TNC->NeedPACTOR == 0) - { - int datalen; - - UCHAR TXMsg[80]; - - datalen = sprintf(TXMsg, "%c%s", SetMYCALL, TNC->NodeCall); - SendCmd(TNC, TXMsg, datalen + 1); // Send the NULL - - // Set Listen Mode - - switch (TNC->CurrentMode) - { - case Pactor: - - SendCmd(TNC, "\x84", 1); // FSK - SendCmd(TNC, "\x83", 1); // Select P-MODE Standby - SendCmd(TNC, "\x58", 1); // Listen - - break; - - case Clover: - - SendCmd(TNC, "\x80", 1); // Clover - SendCmd(TNC, "\x54", 1); // Enable adaptive Clover format - SendCmd(TNC, "\x41", 1); // No Statistics - SendCmd(TNC, "\x60\x09", 2); // Robust Retries - SendCmd(TNC, "\x61\x09", 2); // Normal Retries - - break; - } - - SendCmd(TNC, "\x52", 1); // ConnectEnable - - // Restart Scanning - - sprintf(Status, "%d SCANSTART 15", TNC->Port); - - Rig_Command(-1, Status); - - return; - } - } - -#define MAXHALTX 256 - - //for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (TNC->TNCOK && STREAM->BPQtoPACTOR_Q && (STREAM->BytesTXed - STREAM->BytesAcked < 600)) - { - int datalen; - UINT * buffptr; - UCHAR * MsgPtr; - unsigned char TXMsg[500]; - - buffptr = (UINT * )STREAM->BPQtoPACTOR_Q; - datalen=buffptr[1]; - MsgPtr = (UCHAR *)&buffptr[2]; - - if (STREAM->Connected) - { - if (TNC->SwallowSignon) - { - TNC->SwallowSignon = FALSE; - if (strstr(MsgPtr, "Connected")) // Discard *** connected - { - ReleaseBuffer(buffptr); - STREAM->FramesQueued--; - return; - } - } - - // Must send data in small chunks - the Hal has limited buffer space - - // If in IRS force a turnround - - if (TNC->TXRXState == 'R' && TNC->CurrentMode != Clover) - { - if (TNC->TimeInRX++ > 15) - SendCmd(TNC, "\x87", 1); // Changeover to ISS - else - goto Poll; - } - - TNC->TimeInRX = 0; - - EncodeAndSend(TNC, MsgPtr, datalen); - buffptr=Q_REM(&STREAM->BPQtoPACTOR_Q); - ReleaseBuffer(buffptr); - WriteLogLine(2, MsgPtr, datalen); - - STREAM->BytesTXed += datalen; - STREAM->FramesQueued--; - - ShowTraffic(TNC); - - return; - } - else - { - buffptr=Q_REM(&STREAM->BPQtoPACTOR_Q); - STREAM->FramesQueued--; - - // Command. Do some sanity checking and look for things to process locally - - datalen--; // Exclude CR - MsgPtr[datalen] = 0; // Null Terminate - _strupr(MsgPtr); - - if (memcmp(MsgPtr, "RADIO ", 6) == 0) - { - sprintf(&MsgPtr[40], "%d %s", TNC->Port, &MsgPtr[6]); - if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK->CIRCUITINDEX, &MsgPtr[40])) - { - ReleaseBuffer(buffptr); - } - else - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "%s", &MsgPtr[40]); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - return; - } - - if (memcmp(MsgPtr, "MODE CLOVER", 11) == 0) - { - TNC->CurrentMode = Clover; - buffptr[1] = sprintf((UCHAR *)&buffptr[2],"HAL} Ok\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - MySetWindowText(TNC->xIDC_MODE, "Clover"); - strcpy(TNC->WEB_MODE, "Clover"); - - SendCmd(TNC, "\x80", 1); // Clover - SendCmd(TNC, "\x54", 1); // Enable adaptive Clover format - SendCmd(TNC, "\x41", 1); // No Statistics - - return; - } - - if (memcmp(MsgPtr, "MODE PACTOR", 11) == 0) - { - TNC->CurrentMode = Pactor; - buffptr[1] = sprintf((UCHAR *)&buffptr[2],"HAL} Ok\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - SendCmd(TNC, "\x84", 1); // FSK - SendCmd(TNC, "\x83", 1); // Select P-MODE Standby - SendCmd(TNC, "\x48", 1); // Listen Off - - return; - } - if (memcmp(MsgPtr, "MODE AMTOR", 11) == 0) - { - TNC->CurrentMode = AMTOR; - buffptr[1] = sprintf((UCHAR *)&buffptr[2],"HAL} Ok\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - return; - } - - if (MsgPtr[0] == 'C' && MsgPtr[1] == ' ' && datalen > 2) // Connect - { - memcpy(STREAM->RemoteCall, &MsgPtr[2], 9); - - switch (TNC->CurrentMode) - { - case Pactor: - - SendCmd(TNC, "\x84", 1); // FSK - SendCmd(TNC, "\x83", 1); // Select P-MODE Standby - - datalen = sprintf(TXMsg, "\x19%s", STREAM->RemoteCall); - - sprintf(TNC->WEB_TNCSTATE, "%s Connecting to %s - PACTOR", STREAM->MyCall, STREAM->RemoteCall); - - // DOnt set connecting till we get the 19 response so we can trap listen as a fail - break; - - case Clover: - - SendCmd(TNC, "\x54", 1); // Enable adaptive Clover format - SendCmd(TNC, "\x57", 1); // Enable TX buffer clear on disconnect - - datalen = sprintf(TXMsg, "\x11%s", STREAM->RemoteCall); - - sprintf(TNC->WEB_TNCSTATE, "%s Connecting to %s - CLOVER", STREAM->MyCall, STREAM->RemoteCall); - - break; - } - - MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - SendCmd(TNC, TXMsg, datalen + 1); // Include NULL - - ReleaseBuffer(buffptr); - - return; - } - - if (memcmp(MsgPtr, "CLOVER ", 7) == 0) - { - memcpy(STREAM->RemoteCall, &MsgPtr[2], 9); - - SendCmd(TNC, "\x54", 1); // Enable adaptive Clover format - SendCmd(TNC, "\x57", 1); // Enable TX buffer clear on disconnect - - datalen = sprintf(TXMsg, "\x11%s", STREAM->RemoteCall); - SendCmd(TNC, TXMsg, datalen + 1); // Include NULL - - sprintf(TNC->WEB_TNCSTATE, "%s Connecting to %s - CLOVER", - STREAM->MyCall, STREAM->RemoteCall); - MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - ReleaseBuffer(buffptr); - - return; - } - - if (memcmp(MsgPtr, "DISCONNECT", datalen) == 0) // Disconnect - { - SendCmd(TNC, "\x07", 1); // Normal Disconnect - TNC->NeedPACTOR = 50; - - STREAM->Connecting = FALSE; - STREAM->ReportDISC = TRUE; - ReleaseBuffer(buffptr); - - return; - } - - // Other Command ?? Treat as HEX string - - datalen = sscanf(MsgPtr, "%X %X %X %X %X %X %X %X %X %X %X %X %X %X %X %X", - (UINT *)&TXMsg[0], (UINT *)&TXMsg[1], (UINT *)&TXMsg[2], (UINT *)&TXMsg[3], (UINT *)&TXMsg[4], - (UINT *)&TXMsg[5], (UINT *)&TXMsg[6], (UINT *)&TXMsg[7], (UINT *)&TXMsg[8], (UINT *)&TXMsg[9], - (UINT *)&TXMsg[10], (UINT *)&TXMsg[11], (UINT *)&TXMsg[12], (UINT *)&TXMsg[13], - (UINT *)&TXMsg[14], (UINT *)&TXMsg[15]); - -// SendCmd(TNC, TXMsg, datalen); - ReleaseBuffer(buffptr); - TNC->InternalCmd = 0; - } - } - } -Poll: - // Nothing doing - send Poll (but not too often) - - TNC->PollDelay++; - - if (TNC->PollDelay < 20) - return; - - TNC->PollDelay = 0; - - if (TNC->TNCOK) - SendCmd(TNC, "\x7d" , 1); // Use Get LEDS as Poll - else - SendCmd(TNC, "\x09" , 1); // Reset - - TNC->Timeout = 100; - - return; -} - -static VOID DoTNCReinit(struct TNCINFO * TNC) -{ - // TNC Has Restarted, send init commands (can probably send all at once) - -// TNC->TXBuffer[0] = 0x1b; -// TNC->TXLen = 1; - - WriteCommBlock(TNC); - - SendCmd(TNC, TNC->InitScript, TNC->InitScriptLen); - - TNC->HostMode = TRUE; // Should now be in Host Mode - TNC->NeedPACTOR = 20; // Need to set Calls and start scan - - TNC->DataMode = RXDATA; // Start with RX Data - - SendCmd(TNC, "\x7d" , 1); // Use Get LEDS as Poll -// SendCmd(TNC, "\xc9" , 1); // Huffman Off - SendCmd(TNC, "\x57", 1); // Enable TX buffer clear on disconnect - - SendCmd(TNC, "\x60\x06", 2); // Robust Mode Retries - -// SendCmd(TNC, "\x6f\x03" , 2); // Undocumented XON/XOFF On - used to see if old or new style modem - - TNC->Timeout = 50; - - return; - -} - -VOID ProcessHALData(struct TNCINFO * TNC) -{ - // Received Data just pass to Appl - - UINT * buffptr; - int Len = TNC->DataLen; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - - TNC->DataLen = 0; - - if (TNC->DataMode == TXDATA) - { - STREAM->BytesAcked += Len; -// Debugprintf("Acked %d", Len); - - if (STREAM->BytesAcked > STREAM->BytesTXed) - Debugprintf("Too Much Acked"); - - if ((STREAM->BPQtoPACTOR_Q == 0) && STREAM->BytesAcked >= STREAM->BytesTXed) - { - // All sent - - if (STREAM->Disconnecting) - TidyClose(TNC, 0); - else - if (TNC->CurrentMode != Clover) - - // turn round link - - SendCmd(TNC, "\x0c" , 1); // Turnround - - } - } - else - { - if (TNC->DataMode == RXDATA) - { -// Debugprintf("RXed %d", Len); - buffptr = GetBuff(); - if (buffptr == NULL) - return; // No buffers, so ignore - - buffptr[1] = Len; // Length - - WriteLogLine(1, TNC->DataBuffer, Len); - - STREAM->BytesRXed += Len; - - memcpy(&buffptr[2], TNC->DataBuffer, Len); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - } - - ShowTraffic(TNC); - - return; -} - - - -VOID ProcessHALBuffer(struct TNCINFO * TNC, int Length) -{ - UCHAR Char; - UCHAR * inptr; - UCHAR * cmdptr; - UCHAR * dataptr; - BOOL CmdEsc, DataEsc; - - inptr = TNC->RXBuffer; - - cmdptr = &TNC->CmdBuffer[TNC->CmdLen]; - dataptr = &TNC->DataBuffer[TNC->DataLen]; - CmdEsc = TNC->CmdEsc; - DataEsc = TNC->DataEsc; - - // HAL uses HEX 80 as a command escape, 81 to ESCAPE 80 and 81 - - // The USB version also uses 0x91 0x31 to eacape 0x11, 0x91 0x33 for 0x13 and 0x91 0xB1 for 0x91 - - // Command Responses can be variable length - - // Command Handler will check for each command/response if it has enough - if not it will wait till more arrives - - while(Length--) - { - Char = *(inptr++); - - if (CmdEsc) - { - CmdEsc = FALSE; - - if (TNC->XONXOFF && Char == 0x91) - { - // XON/XOFF escape. We ensured above that data follows so we can process it inline - - Length--; - Char = *(inptr++) - 0x20; - } - *(cmdptr++) = Char; - } - else if (DataEsc) - { - DataEsc = FALSE; - goto DataChar; - } - else -NotData: - if (Char == 0x80) // Next Char is Command - CmdEsc = TRUE; - else if (Char == 0x81) // Next Char is escaped data (80 or 81) - DataEsc = TRUE; - else - { - // This is a Data Char. We must process any Commands received so far, so we know the type of data - - DataChar: - - TNC->CmdLen = (int)(cmdptr - TNC->CmdBuffer); - ProcessHALCmd(TNC); - cmdptr = &TNC->CmdBuffer[TNC->CmdLen]; - dataptr = &TNC->DataBuffer[TNC->DataLen]; - - *(dataptr++) = Char; // Normal Data - - // Now process any other data chars - - while(Length--) - { - Char = *(inptr++); - - if (TNC->XONXOFF && Char == 0x91) - { - // XON/XOFF escape within data. We ensured above that data follows so we - // can process it here - - Length--; - Char = *(inptr++) - 0x20; - } - - if (Char == 0x80 || Char == 0x81) - { - // Process any data we have, then loop back - - TNC->DataLen = (int)(dataptr - TNC->DataBuffer); - ProcessHALData(TNC); - - goto NotData; - } - *(dataptr++) = Char; // Normal Data - } - - // Used all data - - TNC->DataLen = (int)(dataptr - TNC->DataBuffer); - - ProcessHALData(TNC); - TNC->CmdEsc = CmdEsc; - TNC->DataEsc = DataEsc; - - return; - } - } - - // Save State - - TNC->CmdLen = (int)(cmdptr - TNC->CmdBuffer); - - TNC->CmdEsc = CmdEsc; - TNC->DataEsc = DataEsc; - - if (TNC->DataLen) - ProcessHALData(TNC); - - if (TNC->CmdLen) - ProcessHALCmd(TNC); -} - -VOID mySetWindowText(struct TNCINFO * TNC, char * Msg) -{ - MySetWindowText(TNC->xIDC_STATE, Msg); - strcpy(TNC->WEB_STATE, Msg); -} - -VOID ProcessHALCmd(struct TNCINFO * TNC) -{ - char * Call; - int Stream = 0; - int Opcode; - int StatusByte; - int Leds; - int Len; - int Used; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - -CmdLoop: - - Opcode = TNC->CmdBuffer[0]; - Len = TNC->CmdLen; - - if (Len == 0) - return; - - TNC->TNCOK = TRUE; - TNC->Timeout = 0; - - sprintf(TNC->WEB_COMMSSTATE,"%s TNC link OK", TNC->PortRecord->PORTCONTROL.SerialPortName); - MySetWindowText(TNC->xIDC_COMMSSTATE, TNC->WEB_COMMSSTATE); - - // We may have more than one response in the buffer, and only each cmd/response decoder knows how many it needs - - switch(Opcode) - { - case 0x09: //Hardware Reset - equivalent to power on reset - - // Hardware has reset - need to reinitialise - - TNC->HostMode = 0; // Force Reinit - - Used = 1; - break; - - case 0x7a: // FSK Modes Status - - // Mixture of mode and state - eg listen huffman on/off irs/iss, so cant just display - - if (Len < 2) return; // Wait for more - - StatusByte = TNC->CmdBuffer[1]; - - switch (StatusByte) - { - case 0x06: // FSK TX (RTTY) - case 0x07: // FSK RX (RTTY) - case 0x10: // AMTOR STANDBY (LISTEN ON) - case 0x11: // AMTOR STANDBY (LISTEN OFF) - case 0x12: // AMTOR FEC TX (AMTOR) - case 0x13: // AMTOR FEC RX (AMTOR) - case 0x14: // P-MODE FEC TX (P-MODE) - case 0x15: // FREE SIGNAL TX (AMTOR) - case 0x16: // FREE SIGNAL TX TIMED OUT (AMTOR) - - // Diaplay Linke Status - - MySetWindowText(TNC->xIDC_MODE, status[StatusByte]); - strcpy(TNC->WEB_MODE, status[StatusByte]); - - break; - - case 0x0C: // P-MODE STANDBY (LISTEN ON) - case 0x0D: // P-MODE STANDBY (LISTEN OFF) - - // if we were connecting, this means connect failed. - - MySetWindowText(TNC->xIDC_MODE, status[StatusByte]); - strcpy(TNC->WEB_MODE, status[StatusByte]); - - if (STREAM->Connecting) - HALDisconnected(TNC); - - break; - - case 0x0E: // ISS (AMTOR/P-MODE) - - MySetWindowText(TNC->xIDC_TXRX,"ISS"); - strcpy(TNC->WEB_TXRX, "ISS"); - TNC->TXRXState = 'S'; - break; - - case 0x0F: // IRS (AMTOR/P-MODE) - - MySetWindowText(TNC->xIDC_TXRX,"IRS"); - strcpy(TNC->WEB_TXRX, "IRS"); - TNC->TXRXState = 'R'; - break; - - case 0x00: // IDLE (AMTOR/P-MODE) - case 0x01: // TFC (AMTOR/P-MODE) - case 0x02: // RQ (AMTOR/P-MODE) - case 0x03: // ERR (AMTOR/P-MODE) - case 0x04: // PHS (AMTOR/P-MODE) - case 0x05: // OVER (AMTOR/P-MODE) (not implemented) - - MySetWindowText(TNC->xIDC_STATE, status[StatusByte]); - strcpy(TNC->WEB_MODE, status[StatusByte]); - - - -//$807A $8008 P-MODE100 (P-MODE) -//$807A $8009 P-MODE200 (P-MODE) -//$807A $800A HUFFMAN ON (P-MODE) -//$807A $800B HUFFMAN OFF (P-MODE) - ; - } - Used = 2; - break; - - - case 0x7d: // Get LED Status - - // We use Get LED Status as a Poll - - if (Len < 2) return; // Wait for more - - Leds = TNC->CmdBuffer[1]; - sprintf(TNC->WEB_LEDS," %c %c %c %c %c %c ", - (Leds & 0x20)? 'X' : ' ', - (Leds & 0x10)? 'X' : ' ', - (Leds & 0x08)? 'X' : ' ', - (Leds & 0x04)? 'X' : ' ', - (Leds & 0x02)? 'X' : ' ', - (Leds & 0x01)? 'X' : ' '); - -// STBY CALL LINK ERROR TX RX - MySetWindowText(TNC->xIDC_LEDS, TNC->WEB_LEDS); - - Used = 2; - break; - - case 0x21: // Monitored FEC CCB - case 0x22: // Monitored ARQ CCB - - // As the reply is variable, make sure we have the terminating NULL - - if (memchr(TNC->CmdBuffer, 0, Len) == NULL) - return; // Wait for more - - Call = &TNC->CmdBuffer[1]; - Used = (int)strlen(Call) + 2; // Opcode and Null - - UpdateMH(TNC, Call, '!', 0); - - break; - - case 0x27: // Clover ARQ LINK REQUEST status message - - //indicates an incoming link request to either MYCALL ($8027 $8000), or MYALTCALL ($8027 $8001). - - if (Len < 2) return; // Wait for more - - // Don't need to do anything (but may eventally use ALTCALL as an APPLCALL - Used = 2; - break; - - case 0x2D: // FSK ARQ Link Request status message - - // $802D $8001 $8000 CLOVER Link Request (not implemented) - // $802D $8002 $8000 AMTOR CCIR-476 Link Request - // $802D $8003 $8000 AMTOR CCIR-625 Link Request - // $802D $8004 $8000 P-MODE Link Request - - if (Len < 3) return; // Wait for more - - // Don't need to do anything (but may save Session type later - - Used = 3; - break; - - - case 0x28: // Monitored Call - - // As the reply is variable, make sure we have the terminating NULL - - if (memchr(TNC->CmdBuffer, 0, Len) == NULL) - return; // Wait for more - - Call = &TNC->CmdBuffer[1]; - Used = strlen(Call) + 2; // Opcode and Null - - // Could possibly be used for APPLCALLS by changing MYCALL when we see a call to one of our calls - - break; - - - case 0x20: // Clover Linked with - Call Connected - case 0x29: // The Linked 476 message indicates the start of a CCIR 476 linked session. - case 0x2A: // The Linked 625 message indicates the start of a CCIR 625 linked session to . - case 0x2B: // P-MODE link to - - // As the reply is variable, make sure we have the terminating NULL - - if (memchr(TNC->CmdBuffer, 0, Len) == NULL) - return; // Wait for more - - Call = &TNC->CmdBuffer[1]; - Used = (int)strlen(Call) + 2; // Opcode and Null - - HALConnected(TNC, Call); - - break; - - case 0x23: // Normal Disconnected - followed by $8000 - case 0x24: // Link failed (any of the link errors) - case 0x25: // Signal Lost (LOS) - - if (Len < 2) return; // Wait for more - - HALDisconnected(TNC); - - Used = 2; - break; - - - // Stream Switch Reports - we will need to do something with these if Echo as Sent is set - // or we do something with the secondary port - - case 0x30: // Switch to Receive Data characters - case 0x31: // Switch to Transmit Data characters - case 0x32: // Switch to RX data from secondary port - - TNC->DataMode = Opcode; - Used = 1; - break; - - case 0x33: // Send TX data to modem - case 0x34: // Send TX data to secondary port - - TNC->TXMode = Opcode; - Used = 1; - break; - - case 0x70: // Channel Spectra Data - // $807F $80xx $8030 Invalid or unimplemented command code - if (Len < 9) return; // Wait for more - - Used = 9; - break; - - case 0x71: // SelCall On/Off - - if (Len < 2) return; // Wait for more - - Used = 2; - break; - - case 0x72: // Channel Spectra Data - // $807F $80xx $8030 Invalid or unimplemented command code - if (Len < 15) return; // Wait for more - - Used = 15; - break; - - case 0x73: // Clover Link state - - if (Len < 2) return; // Wait for more - - StatusByte = TNC->CmdBuffer[1]; - - switch (StatusByte) - { - case 0x00: mySetWindowText(TNC, "Channel idle"); break; - case 0x01: mySetWindowText(TNC, "Channel occupied with non-Clover signal"); break; - case 0x42: mySetWindowText(TNC, "Linked stations monitored"); break; - case 0x64: mySetWindowText(TNC, "Attempting normal link"); break; - case 0x65: mySetWindowText(TNC, "Attempting robust link"); break; - case 0x66: mySetWindowText(TNC, "Calling ARQ CQ"); break; - case 0x78: mySetWindowText(TNC, "Clover Control Block (CCB) send retry"); break; - case 0x79: mySetWindowText(TNC, "Clover Control Block (CCB) receive retry"); break; - case 0x7D: mySetWindowText(TNC, "Clover Control Block (CCB) received successfully"); break; - case 0x8A: mySetWindowText(TNC, "TX data block sent"); break; - case 0x8B: mySetWindowText(TNC, "RX data block received ok (precedes data block)"); break; - case 0x8C: mySetWindowText(TNC, "TX data block re-sent"); break; - case 0x8D: mySetWindowText(TNC, "RX data block decode failed (precedes data block)"); break; - case 0x8E: mySetWindowText(TNC, "TX idle"); break; - case 0x8F: mySetWindowText(TNC, "RX idle"); break; - case 0x9C: mySetWindowText(TNC, "Link failed: CCB send retries exceeded"); break; - case 0x9D: mySetWindowText(TNC, "Link failed: CCB receive retries exceeded"); break; - case 0x9E: mySetWindowText(TNC, "Link failed: protocol error"); break; - case 0xA0: mySetWindowText(TNC, "Receiving FEC SYNC sequence"); break; - } - - Used = 2; - break; - - case 0x75: // Clover waveform format - - if (Len < 5) return; // Wait for more - - Used = 5; - break; - - case 0x7F: // Error $80xx $80yy Error in command $80xx of type $80yy - // $807F $80xx $8030 Invalid or unimplemented command code - // $807F $80xx $8031 Invalid parameter value - // $807F $80xx $8032 Not allowed when connected - // $807F $80xx $8033 Not allowed when disconnected - // $807F $80xx $8034 Not valid in this mode - // $807F $80xx $8035 Not valid in this code - // $807F $8096 $8036 EEPROM write error - - if (Len < 3) return; // Wait for more - - if (TNC->CmdBuffer[1] == 0x6f && TNC->CmdBuffer[2] == 0x31) - { - // Reject of XON/XOFF enable - -// TNC->XONXOFF = FALSE; -// Debugprintf("BPQ32 HAL Port %d - Disabling XON/XOFF mode", TNC->Port); - } - else - Debugprintf("HAL Port %d Command Error Cmd %X Error %X", TNC->Port, TNC->CmdBuffer[1], TNC->CmdBuffer[2]); - - Used = 3; - break; - - // Following are all immediate commands - response is echo of command - - case 0x6f: // XON/XOFF on - -// TNC->XONXOFF = TRUE; // And drop through -// Debugprintf("BPQ32 HAL Port %d - Enabling XON/XOFF mode", TNC->Port); - - case 0x19: // Call P-MODE to - case 0x10: // Robust Link to using MYCALL - case 0x11: // Normal Link to using MYCALL - - STREAM->Connecting = TRUE; - - case 0x00: // P Load LOD file - case 0x01: // P Load S28 file - case 0x02: //Check Unit Error Status - case 0x03: //F Check System Clock - case 0x04: //C Close PTT and transmit Clover waveform - case 0x05: //Open PTT and stop transmit test - case 0x06: //Immediate Abort (Panic Kill) - case 0x07: //Normal disconnect (wait for ACK) - case 0x08: //Software reset - restore all program defaults - case 0x0A: //Send CW ID - case 0x0B: //Close PTT and transmit Single Tone - case 0x0C: //F Normal OVER (AMTOR,P-MODE) - case 0x0D: //F Force RTTY TX (Baudot/ASCII) - case 0x0E: //F Go to RTTY RX (Baudot/ASCII) - case 0x0F: //Go to LOD/S28 file loader - case SetMYCALL: // Set MYCALL Response - - case 0x1E: // Set MYALTCALL Response - - case 0x41: - case 0x42: - case 0x46: - case 0x47: - case 0x48: - case 0x4d: - case 0x52: // Enable adaptive Clover format - case 0x54: // Enable adaptive Clover format - - case 0x56: // Expanded Link State Reports OFF/ON - case 0x57: // Clear buffers on disc - case 0x58: - case 0x59: - case 0x60: // Robust Mode Retries - case 0x61: // Normal Mode Retries - case 0x80: //Switch to CLOVER mode - case 0x81: //Select AMTOR Standby - case 0x82: //Select AMTOR FEC - case 0x83: //Select P-MODE Standby - case 0x84: //Switch to FSK modes - case 0x85: //Select Baudot - case 0x86: //Select ASCII - case 0x87: //Forced OVER (AMTOR, P-MODE) - case 0x88: //Forced END (AMTOR, P-MODE) - case 0x89: //Force LTRS shift - case 0x8A: //Force FIGS shift - case 0x8B: //Send MARK tone - case 0x8C: //Send SPACE tone - case 0x8D: //Send MARK/SPACE tones - case 0x8E: //Received first character on line - case 0x8F: //Close PTT only (no tones) - - case 0xC9: //Huffman Off/On - case 0xCC: - case 0xD9: //Close PTT only (no tones) - - case SetTones: - - Used = 1; - break; - - case 0x91: // ???? - -// if (Len < 2) return; // Wait for more - - Used = 1; - break; - - default: - - // We didn't recognise command, so don't know how long it is - disaster! - - Debugprintf("HAL Port %d Unrecognised Command %x", TNC->Port, Opcode); - TNC->CmdLen = 0; - - return; - } - - if (Used == Len) - { - // All used - most likely case - - TNC->CmdLen = 0; - return; - } - - // Move Command Down buffer, and reenter - - TNC->CmdLen -= Used; - - memmove(TNC->CmdBuffer, &TNC->CmdBuffer[Used], TNC->CmdLen); - - goto CmdLoop; - - -} - - -VOID HALDisconnected(struct TNCINFO * TNC) -{ - struct STREAMINFO * STREAM = &TNC->Streams[0]; - - CloseLogfile(0); - CloseLogfile(1); - CloseLogfile(2); - - if ((STREAM->Connecting | STREAM->Connected) == 0) - { - // Not connected or Connecting. Probably response to going into Pactor Listen Mode - - return; - } - - if (STREAM->Connecting && STREAM->Disconnecting == FALSE) - { - UINT * buffptr; - - // Connect Failed - actually I think HAL uses another code for connect failed, but leave here for now - - buffptr = GetBuff(); - - if (buffptr) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "*** Failure with %s\r", STREAM->RemoteCall); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - - STREAM->Connecting = FALSE; - STREAM->Connected = FALSE; // In case! - STREAM->FramesQueued = 0; - - sprintf(TNC->WEB_TNCSTATE, "In Use by %s", STREAM->MyCall); - MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - return; - } - - // Connected, or Disconnecting - Release Session - - STREAM->Connecting = FALSE; - STREAM->Connected = FALSE; // Back to Command Mode - STREAM->FramesQueued = 0; - - if (STREAM->Disconnecting == FALSE) - STREAM->ReportDISC = TRUE; // Tell Node - - STREAM->Disconnecting = FALSE; - - // Need to reset Pactor Call in case it was changed - - TNC->NeedPACTOR = 20; -} - -BOOL HALConnected(struct TNCINFO * TNC, char * Call) -{ - char Msg[80]; - UINT * buffptr; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - char CallCopy[80]; - - strcpy(CallCopy, Call); - strcat(CallCopy, " "); // Some routines expect 10 char calls - - STREAM->BytesRXed = STREAM->BytesTXed = STREAM->BytesAcked = 0; - STREAM->ConnectTime = time(NULL); - - // Stop Scanner - - sprintf(Msg, "%d SCANSTOP", TNC->Port); - - Rig_Command(-1, Msg); - - ShowTraffic(TNC); - - TNC->DataMode = RXDATA; - - OpenLogfile(0); - OpenLogfile(1); - OpenLogfile(2); - - if (TNC->PortRecord->ATTACHEDSESSIONS[0] == 0) - { - // Incoming Connect - - ProcessIncommingConnect(TNC, CallCopy, 0, TRUE); - - sprintf(TNC->WEB_TNCSTATE, "%s Connected to %s Inbound", STREAM->RemoteCall, TNC->NodeCall); - MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - if (TNC->CurrentMode != Clover) - SendCmd(TNC, "\x87", 1); // Changeover to ISS - - // If an autoconnect APPL is defined, send it - - if (TNC->ApplCmd) - { - buffptr = GetBuff(); - if (buffptr == 0) return TRUE; // No buffers, so ignore - - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "%s\r", TNC->ApplCmd); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - TNC->SwallowSignon = TRUE; - - return TRUE; - } - - if (FULL_CTEXT && HFCTEXTLEN == 0) - { - EncodeAndSend(TNC, CTEXTMSG, CTEXTLEN); - WriteLogLine(2, CTEXTMSG, CTEXTLEN); - - STREAM->BytesTXed += CTEXTLEN; - } - return TRUE; - } - - // Connect Complete - - buffptr = GetBuff(); - if (buffptr == 0) return TRUE; // No buffers, so ignore - - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "*** Connected to %s\r", Call);; - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - STREAM->Connecting = FALSE; - STREAM->Connected = TRUE; // Subsequent data to data channel - - sprintf(TNC->WEB_TNCSTATE, "%s Connected to %s Outbound", TNC->NodeCall, STREAM->RemoteCall); - MySetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - - UpdateMH(TNC, CallCopy, '+', 'O'); - - - return TRUE; -} - - -static VOID EncodeAndSend(struct TNCINFO * TNC, UCHAR * txbuffer, int Len) -{ - // Send A Packet With DLE Encoding Encoding - - TNC->TXLen = DLEEncode(txbuffer, TNC->TXBuffer, Len); - - WriteCommBlock(TNC); -} - -VOID SendCmd(struct TNCINFO * TNC, UCHAR * txbuffer, int Len) -{ - // Send A Packet With Command Encoding (preceed each with 0x80 - - int i,txptr=0; - UCHAR * outbuff = TNC->TXBuffer; - - for (i=0; iTXLen = txptr; - WriteCommBlock(TNC); -} - -int DLEEncode(UCHAR * inbuff, UCHAR * outbuff, int len) -{ - int i, txptr = 0; - UCHAR c; - - // Escape x80 and x81 with x81 - -// outbuff[0] = 0x80; -// outbuff[1] = 0x33; // Send data to modem - - for (i=0;iNeedPACTOR = 30; -} - - - - diff --git a/HSMODEM.c b/HSMODEM.c index d3430d7..7b44895 100644 --- a/HSMODEM.c +++ b/HSMODEM.c @@ -648,8 +648,12 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, cmd); + + if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { } diff --git a/HTTPcode.c b/HTTPcode.c index f3f0d22..245ab3d 100644 --- a/HTTPcode.c +++ b/HTTPcode.c @@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses */ + //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define _CRT_SECURE_NO_DEPRECATE @@ -4379,7 +4380,7 @@ int ProcessMailAPISignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char if (user && user[0] && password && password[0]) { - sprintf(MsgPtr, "%s?%s&%s", MsgPtr, user, password); + sprintf(&MsgPtr[strlen(MsgPtr)], "?%s&%s", user, password); } } diff --git a/HanksRT.c b/HanksRT.c index e8f5ffd..89e03e2 100644 --- a/HanksRT.c +++ b/HanksRT.c @@ -1860,7 +1860,7 @@ static void cn_dec(ChatCIRCUIT *circuit, CHATNODE *node) __try { #endif - len = sprintf(line, "%s %p %s", line, cn->node, cn->node->alias); + len += sprintf(&line[len], " %p %s", cn->node, cn->node->alias); if (len > 80) { Debugprintf("%s", line); @@ -2821,7 +2821,7 @@ static void show_circuits(ChatCIRCUIT *conn, char Flag) CHATNODE *node; LINK *link; char line[1000]; - int len; + int len = 0; CN *cn; int i = 0; @@ -2836,16 +2836,16 @@ static void show_circuits(ChatCIRCUIT *conn, char Flag) nprintf(conn, "%d Node(s)\r", i); if (Flag == 'c') - sprintf(line, "Here %-6.6s <-", OurNode); + len = sprintf(line, "Here %-6.6s <-", OurNode); else - sprintf(line, "Here %-6.6s <-", OurAlias); + len = sprintf(line, "Here %-6.6s <-", OurAlias); for (node = node_hd; node; node = node->next) if (node->refcnt) { if (Flag == 'c') - len = sprintf(line, "%s %s", line, node->call); + len += sprintf(&line[len], " %s", node->call); else - len = sprintf(line, "%s %s", line, node->alias); + len += sprintf(&line[len], " %s", node->alias); if (len > 80) { nprintf(conn, "%s\r", line); @@ -2873,9 +2873,9 @@ static void show_circuits(ChatCIRCUIT *conn, char Flag) __try { if (Flag == 'c') - len = sprintf(line, "%s %s", line, cn->node->call); + len += sprintf(&line[len], " %s", cn->node->call); else - len = sprintf(line, "%s %s", line, cn->node->alias); + len += sprintf(&line[len], " %s", cn->node->alias); if (len > 80) { nprintf(conn, "%s\r", line); @@ -2883,23 +2883,23 @@ static void show_circuits(ChatCIRCUIT *conn, char Flag) } } __except(EXCEPTION_EXECUTE_HANDLER) - {len = sprintf(line, "%s *PE* Corrupt Rec %x %x", line, cn, cn->node);} + {len += sprintf(&line[len], " *PE* Corrupt Rec %x %x", cn, cn->node);} } else - len = sprintf(line, "%s Corrupt Rec %x %x ", line, cn, cn->node); + len = sprintf(&line[len], " Corrupt Rec %x %x ", cn, cn->node); } } __except(EXCEPTION_EXECUTE_HANDLER) - {len = sprintf(line, "%s *PE* Corrupt Rec %x %x ", line, cn, cn->node);} + {len += sprintf(&line[len], " *PE* Corrupt Rec %x %x ", cn, cn->node);} #else for (cn = circuit->hnode; cn; cn = cn->next) { if (cn->node && cn->node->alias) { if (Flag == 'c') - len = sprintf(line, "%s %s", line, cn->node->call); + len += sprintf(&line[len], " %s", cn->node->call); else - len = sprintf(line, "%s %s", line, cn->node->alias); + len += sprintf(&line[len], " %s", cn->node->alias); if (len > 80) { nprintf(conn, "%s\r", line); @@ -2907,7 +2907,7 @@ static void show_circuits(ChatCIRCUIT *conn, char Flag) } } else - len = sprintf(line, "%s Corrupt Rec %p %p ", line, cn, cn->node); + len += sprintf(&line[len], " Corrupt Rec %p %p ", cn, cn->node); } #endif nprintf(conn, "%s\r", line); @@ -3682,7 +3682,7 @@ VOID SendChatLinkStatus() } } - len = sprintf(Msg, "%s%s %c ", Msg, link->call, '0' + link->flags); + len += sprintf(&Msg[len], "%s %c ", link->call, '0' + link->flags); if (len > 240) break; diff --git a/KISSHF.c b/KISSHF.c index ec2d29a..59fd3ec 100644 --- a/KISSHF.c +++ b/KISSHF.c @@ -458,8 +458,12 @@ ok: if (_memicmp(txbuff, "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &txbuff[6]); + char cmd[56]; + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, cmd); + + if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { } diff --git a/L4Code.c b/L4Code.c index 99ac4b3..1c92cb4 100644 --- a/L4Code.c +++ b/L4Code.c @@ -38,22 +38,22 @@ extern BPQVECSTRUC BPQHOSTVECTOR[]; #define BPQHOSTSTREAMS 64 #define IPHOSTVECTOR BPQHOSTVECTOR[BPQHOSTSTREAMS + 3] -VOID CLOSECURRENTSESSION(TRANSPORTENTRY * Session); -VOID SENDL4DISC(TRANSPORTENTRY * Session); -int C_Q_COUNT(VOID * Q); +void CLOSECURRENTSESSION(TRANSPORTENTRY * Session); +void SENDL4DISC(TRANSPORTENTRY * Session); +int C_Q_COUNT(void * Q); TRANSPORTENTRY * SetupSessionForL2(struct _LINKTABLE * LINK); -VOID InformPartner(struct _LINKTABLE * LINK, int Reason); -VOID IFRM150(TRANSPORTENTRY * Session, PDATAMESSAGE Buffer); -VOID SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG); +void InformPartner(struct _LINKTABLE * LINK, int Reason); +void IFRM150(TRANSPORTENTRY * Session, PDATAMESSAGE Buffer); +void SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG); BOOL FINDCIRCUIT(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY ** REQL4, int * NewIndex); int GETBUSYBIT(TRANSPORTENTRY * L4); BOOL cATTACHTOBBS(TRANSPORTENTRY * Session, UINT Mask, int Paclen, int * AnySessions); VOID SETUPNEWCIRCUIT(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, char * BPQPARAMS, int ApplMask, int * BPQNODE); extern char * ALIASPTR; -VOID SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER * L3MSG, BOOL BPQNODE, UINT Applmask, UCHAR * ApplCall); -VOID L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG); -VOID L4TIMEOUT(TRANSPORTENTRY * L4); +void SendConACK(struct _LINKTABLE * LINK, TRANSPORTENTRY * L4, L3MESSAGEBUFFER * L3MSG, BOOL BPQNODE, UINT Applmask, UCHAR * ApplCall); +void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG); +void L4TIMEOUT(TRANSPORTENTRY * L4); struct DEST_LIST * CHECKL3TABLES(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * Msg); int CHECKIFBUSYL4(TRANSPORTENTRY * L4); VOID AUTOTIMER(TRANSPORTENTRY * L4); @@ -1776,7 +1776,7 @@ int FINDCIRCUIT(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY ** REQL4, int * NewIndex return FALSE; } -VOID L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG) +void L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG) { // EXCHANGE ORIGIN AND DEST @@ -1791,7 +1791,7 @@ VOID L3SWAPADDRESSES(L3MESSAGEBUFFER * L3MSG) L3MSG->L3SRCE[6] |= 1; // Set Last Call } -VOID SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) +void SendConNAK(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG) { L3MSG->L4FLAGS = L4CACK | L4BUSY; // REJECT L3MSG->L4DATA[0] = 0; // WINDOW @@ -1965,7 +1965,7 @@ VOID FRAMEFORUS(struct _LINKTABLE * LINK, L3MESSAGEBUFFER * L3MSG, int ApplMask, { // INTERNODE LINK - TRANSPORTENTRY * L4 = 0; + TRANSPORTENTRY * L4; struct DEST_LIST * DEST; int Opcode; char Nodename[20]; @@ -2489,13 +2489,14 @@ VOID ACKFRAMES(L3MESSAGEBUFFER * L3MSG, TRANSPORTENTRY * L4, int NR) RTT = GetTickCount() - L4->RTT_TIMER; - if (RTT < 180) // Sanity Check + if (RTT < 180000) // Sanity Check { if (DEST->DEST_RTT == 0) DEST->DEST_RTT = RTT; else DEST->DEST_RTT = ((DEST->DEST_RTT * 9) + RTT) /10; // 90% Old + New } + L4->RTT_TIMER = 0; } } diff --git a/MULTIPSK.c b/MULTIPSK.c index 3fb81c1..59e389f 100644 --- a/MULTIPSK.c +++ b/MULTIPSK.c @@ -407,7 +407,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) if (_memicmp(buff->L2DATA, "RADIO ", 6) == 0) { - sprintf(buff->L2DATA, "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + + strcpy(cmd, &buff->L2DATA[6]); + sprintf(buff->L2DATA, "%d %s", TNC->Port, cmd); if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, buff->L2DATA)) { @@ -1539,7 +1542,7 @@ VOID CloseComplete(struct TNCINFO * TNC, int Stream) sprintf(Cmd, "%cDIGITAL MODE %s\x1b", '\x1a', TNC->MPSKInfo->DefaultMode); if (TNC->MPSKInfo->Beacon) - sprintf(Cmd, "%s%cBEACON_ARQ_FAE\x1b", Cmd, '\x1a'); + sprintf(&Cmd[strlen(Cmd)], "%cBEACON_ARQ_FAE\x1b", '\x1a'); Len = strlen(Cmd); diff --git a/MULTIPSK64.c b/MULTIPSK64.c deleted file mode 100644 index 8fe6a84..0000000 --- a/MULTIPSK64.c +++ /dev/null @@ -1,1543 +0,0 @@ -/* -Copyright 2001-2018 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - -// -// DLL to provide interface to allow G8BPQ switch to use MultoPSK ALE400 Mode -// -// Uses BPQ EXTERNAL interface -// - - -#define _CRT_SECURE_NO_DEPRECATE - -#define _CRT_SECURE_NO_DEPRECATE - -#include "CHeaders.h" -#include -#include - -#include "tncinfo.h" - -#include "bpq32.h" - -#define VERSION_MAJOR 2 -#define VERSION_MINOR 0 - -#define SD_RECEIVE 0x00 -#define SD_SEND 0x01 -#define SD_BOTH 0x02 - -#define TIMESTAMP 352 - -#define CONTIMEOUT 1200 - - - -#define AGWHDDRLEN sizeof(struct AGWHEADER) - -extern int (WINAPI FAR *GetModuleFileNameExPtr)(); - -//int ResetExtDriver(int num); -extern char * PortConfig[33]; - -struct TNCINFO * TNCInfo[34]; // Records are Malloc'd - -static void ConnecttoMPSKThread(void * portptr); - -void CreateMHWindow(); -int Update_MH_List(struct in_addr ipad, char * call, char proto); - -static int ConnecttoMPSK(); -static int ProcessReceivedData(int bpqport); -static int ProcessLine(char * buf, int Port); -int KillTNC(struct TNCINFO * TNC); -int RestartTNC(struct TNCINFO * TNC); -VOID ProcessMPSKPacket(struct TNCINFO * TNC, char * Message, int Len); -struct TNCINFO * GetSessionKey(char * key, struct TNCINFO * TNC); -static VOID SendData(struct TNCINFO * TNC, char * Msg, int MsgLen); -static VOID DoMonitorHddr(struct TNCINFO * TNC, struct AGWHEADER * RXHeader, UCHAR * Msg); -VOID SendRPBeacon(struct TNCINFO * TNC); - -char * strlop(char * buf, char delim); - -extern UCHAR BPQDirectory[]; - -#define MAXBPQPORTS 32 -#define MAXMPSKPORTS 16 - -//LOGFONT LFTTYFONT ; - -//HFONT hFont ; - -static int MPSKChannel[MAXBPQPORTS+1]; // BPQ Port to MPSK Port -static int BPQPort[MAXMPSKPORTS][MAXBPQPORTS+1]; // MPSK Port and Connection to BPQ Port - -static int MasterPort[MAXBPQPORTS+1]; // Pointer to first BPQ port for a specific MPSK host - -// Each port may be on a different machine. We only open one connection to each MPSK instance - -static char * MPSKSignon[MAXBPQPORTS+1]; // Pointer to message for secure signin - -static unsigned int MPSKInst = 0; -static int AttachedProcesses=0; - -static HWND hResWnd,hMHWnd; -static BOOL GotMsg; - -static HANDLE STDOUT=0; - -//SOCKET sock; - -static SOCKADDR_IN sinx; -static SOCKADDR_IN rxaddr; -static SOCKADDR_IN destaddr[MAXBPQPORTS+1]; - -static int addrlen=sizeof(sinx); - -//static short MPSKPort=0; - -static time_t ltime,lasttime[MAXBPQPORTS+1]; - -static BOOL CONNECTING[MAXBPQPORTS+1]; -static BOOL CONNECTED[MAXBPQPORTS+1]; - -//HANDLE hInstance; - - -static fd_set readfs; -static fd_set writefs; -static fd_set errorfs; -static struct timeval timeout; - -#ifndef LINBPQ - -static BOOL CALLBACK EnumTNCWindowsProc(HWND hwnd, LPARAM lParam) -{ - char wtext[200]; - struct TNCINFO * TNC = (struct TNCINFO *)lParam; - UINT ProcessId; - char FN[MAX_PATH] = ""; - - if (TNC->ProgramPath == NULL) - return FALSE; - - GetWindowText(hwnd, wtext, 199); - - if (strstr(wtext,"* MULTIPSK")) - { - GetWindowThreadProcessId(hwnd, &ProcessId); - - TNC->PID = ProcessId; - return FALSE; - } - - return (TRUE); -} - -#endif - -static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) -{ - PMSGWITHLEN buffptr; - - unsigned int txlen=0; - struct TNCINFO * TNC = TNCInfo[port]; - int Stream = 0; - struct STREAMINFO * STREAM; - int TNCOK; - - if (TNC == NULL) - return 0; // Port not defined - - // Look for attach on any call - - for (Stream = 0; Stream <= TNC->MPSKInfo->MaxSessions; Stream++) - { - STREAM = &TNC->Streams[Stream]; - - if (TNC->PortRecord->ATTACHEDSESSIONS[Stream] && TNC->Streams[Stream].Attached == 0) - { - char Cmd[80]; - int len; - - // New Attach - - int calllen; - STREAM->Attached = TRUE; - - calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4USER, STREAM->MyCall); - STREAM->MyCall[calllen] = 0; - STREAM->FramesOutstanding = 0; - - // Stop Scanning - - sprintf(Cmd, "%d SCANSTOP", TNC->Port); - Rig_Command(-1, Cmd); - - len = sprintf(Cmd, "%cSTOP_BEACON_ARQ_FAE\x1b", '\x1a'); - - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Cmd); // Savde till not transmitting - else - send(TNC->TCPSock, Cmd, len, 0); - - } - } - - switch (fn) - { - case 1: // poll - - if (MasterPort[port] == port) - { - // Only on first port using a host - - if (TNC->CONNECTED == FALSE && TNC->CONNECTING == FALSE) - { - // See if time to reconnect - - time( <ime ); - if (ltime-lasttime[port] >9 ) - { - ConnecttoMPSK(port); - lasttime[port]=ltime; - } - } - - FD_ZERO(&readfs); - - if (TNC->CONNECTED) FD_SET(TNC->TCPSock,&readfs); - - - FD_ZERO(&writefs); - - if (TNC->CONNECTING) FD_SET(TNC->TCPSock,&writefs); // Need notification of Connect - - if (TNC->BPQtoWINMOR_Q) FD_SET(TNC->TCPSock,&writefs); // Need notification of busy clearing - - - - FD_ZERO(&errorfs); - - if (TNC->CONNECTING ||TNC->CONNECTED) FD_SET(TNC->TCPSock,&errorfs); - - if (select((int)TNC->TCPSock+ 1, &readfs, &writefs, &errorfs, &timeout) > 0) - { - // See what happened - - if (FD_ISSET(TNC->TCPSock,&readfs)) - { - // data available - - ProcessReceivedData(port); - } - - if (FD_ISSET(TNC->TCPSock,&writefs)) - { - // Connect success - - TNC->CONNECTED = TRUE; - TNC->CONNECTING = FALSE; - - // If required, send signon - - send(TNC->TCPSock,"\x1a", 1, 0); - send(TNC->TCPSock,"DIGITAL MODE ?", 14, 0); - send(TNC->TCPSock,"\x1b", 1, 0); - -// EnumWindows(EnumTNCWindowsProc, (LPARAM)TNC); - } - - if (FD_ISSET(TNC->TCPSock,&errorfs)) - { - - // if connecting, then failed, if connected then has just disconnected - -// if (CONNECTED[port]) -// if (!CONNECTING[port]) -// { -// i=sprintf(ErrMsg, "MPSK Connection lost for BPQ Port %d\r\n", port); -// WritetoConsole(ErrMsg); -// } - - CONNECTING[port]=FALSE; - CONNECTED[port]=FALSE; - - } - - } - - } - - // See if any frames for this port - - for (Stream = 0; Stream <= TNC->MPSKInfo->MaxSessions; Stream++) - { - STREAM = &TNC->Streams[Stream]; - - // Have to time out connects, as TNC doesn't report failure - - if (STREAM->Connecting) - { - STREAM->Connecting--; - - if (STREAM->Connecting == 0) - { - // Report Connect Failed, and drop back to command mode - - buffptr = GetBuff(); - - if (buffptr) - { - buffptr->Len = sprintf(buffptr->Data, "MPSK} Failure with %s\r", STREAM->RemoteCall); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - - STREAM->Connected = FALSE; // Back to Command Mode - STREAM->DiscWhenAllSent = 10; - - // Send Disc to TNC - - TidyClose(TNC, Stream); - } - } - - if (STREAM->Attached) - CheckForDetach(TNC, Stream, STREAM, TidyClose, ForcedClose, CloseComplete); - - if (STREAM->ReportDISC) - { - STREAM->ReportDISC = FALSE; - buff->PORT = Stream; - - return -1; - } - - // if Busy, send buffer status poll - - if (STREAM->PACTORtoBPQ_Q == 0) - { - if (STREAM->DiscWhenAllSent) - { - STREAM->DiscWhenAllSent--; - if (STREAM->DiscWhenAllSent == 0) - STREAM->ReportDISC = TRUE; // Dont want to leave session attached. Causes too much confusion - } - } - else - { - int datalen; - - buffptr=Q_REM(&STREAM->PACTORtoBPQ_Q); - - datalen = buffptr->Len; - - buff->PORT = Stream; - buff->PID = 0xf0; - memcpy(buff->L2DATA, buffptr->Data, datalen); // Data goes to +7, but we have an extra byte - datalen += MSGHDDRLEN + 1; - - PutLengthinBuffer((PDATAMESSAGE)buff, datalen); - - ReleaseBuffer(buffptr); - - return (1); - } - } - - if (TNC->PortRecord->UI_Q) - { - struct _MESSAGE * buffptr; - - SOCKET Sock; - buffptr = Q_REM(&TNC->PortRecord->UI_Q); - - Sock = TNCInfo[MasterPort[port]]->TCPSock; - - ReleaseBuffer((UINT *)buffptr); - } - - - return (0); - - - - case 2: // send - - - if (!TNCInfo[MasterPort[port]]->CONNECTED) return 0; // Don't try if not connected to TNC - - Stream = buff->PORT; - - STREAM = &TNC->Streams[Stream]; - -// txlen=(buff[6]<<8) + buff[5] - 8; - - txlen = GetLengthfromBuffer((PDATAMESSAGE)buff) - 8; - - if (STREAM->Connected) - { - SendData(TNC, buff->L2DATA, txlen); - } - else - { - char Command[80]; - int len; - - buff->L2DATA[txlen] = 0; - _strupr(buff->L2DATA); - - if (_memicmp(&buff[8], "D\r", 2) == 0) - { - TidyClose(TNC, buff->PORT); - STREAM->ReportDISC = TRUE; // Tell Node - return 0; - } - - // See if Local command (eg RADIO) - - if (_memicmp(buff->L2DATA, "RADIO ", 6) == 0) - { - sprintf(buff->L2DATA, "%d %s", TNC->Port, &buff->L2DATA[6]); - - if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK->CIRCUITINDEX, buff->L2DATA)) - { - } - else - { - buffptr = (PMSGWITHLEN)GetBuff(); - - if (buffptr == 0) return 1; // No buffers, so ignore - - buffptr->Len= sprintf((UCHAR *)&buffptr->Data, "%s", buff->L2DATA); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - return 1; - } - - if (STREAM->Connecting && _memicmp(&buff[8], "ABORT", 5) == 0) - { - len = sprintf(Command,"%cSTOP_SELECTIVE_CALL_ARQ_FAE\x1b", '\x1a'); - - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Command); // Save till not transmitting - else - send(TNC->TCPSock, Command, len, 0); - - TNC->InternalCmd = TRUE; - return (0); - } - - if (_memicmp(&buff[8], "MODE", 4) == 0) - { - buff->L2DATA[txlen - 1] = 0; // Remove CR - - len = sprintf(Command,"%cDIGITAL MODE %s\x1b", '\x1a', &buff->L2DATA[5]); - - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Command); // Save till not transmitting - else - send(TNC->TCPSock, Command, len, 0); - - TNC->InternalCmd = TRUE; - return (0); - } - - - if (_memicmp(&buff[8], "INUSE?", 6) == 0) - { - // Return Error if in use, OK if not - - UINT * buffptr = GetBuff(); - int s = 0; - - while(s <= TNC->MPSKInfo->MaxSessions) - { - if (s != Stream) - { - if (TNC->PortRecord->ATTACHEDSESSIONS[s]) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "MPSK} Error - In use\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - return 1; // Busy - } - } - s++; - } - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "MPSK} Ok - Not in use\r"); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - return 1; - } - - // See if a Connect Command. - - if (toupper(buff->L2DATA[0]) == 'C' && buff->L2DATA[1] == ' ' && txlen > 2) // Connect - { - char * ptr; - char * context; - - buff->L2DATA[txlen] = 0; - _strupr(buff->L2DATA); - - memset(STREAM->RemoteCall, 0, 10); - - ptr = strtok_s(&buff->L2DATA[2], " ,\r", &context); - strcpy(STREAM->RemoteCall, ptr); - - len = sprintf(Command,"%cCALLSIGN_TO_CALL_ARQ_FAE %s%c%cSELECTIVE_CALL_ARQ_FAE\x1b", - '\x1a', STREAM->RemoteCall, '\x1b', '\x1a'); - - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Command); // Save till not transmitting - else - send(TNC->TCPSock, Command, len, 0); - - STREAM->Connecting = TNC->MPSKInfo->ConnTimeOut; // It doesn't report failure - -// sprintf(Status, "%s Connecting to %s", TNC->Streams[0].MyCall, TNC->Streams[0].RemoteCall); -// SetDlgItemText(TNC->hDlg, IDC_TNCSTATE, Status); - - return 0; - } - - // Send any other command to Multipsk - - buff->L2DATA[txlen - 1] = 0; - _strupr(&buff->L2DATA[0]); - - len = sprintf(Command,"%c%s\x1b", '\x1a', buff->L2DATA); - - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Command); // Save till not transmitting - else - send(TNC->TCPSock, Command, len, 0); - - TNC->InternalCmd = TRUE; - - } - - return (0); - - case 3: - - Stream = buff->PORT; - - TNCOK = TNCInfo[MasterPort[port]]->CONNECTED; - - STREAM = &TNC->Streams[Stream]; - - if (STREAM->FramesOutstanding > 8) - return (1 | TNCOK << 8 | STREAM->Disconnecting << 15); - - return TNCOK << 8 | STREAM->Disconnecting << 15; // OK, but lock attach if disconnecting - - break; - - case 4: // reinit - - shutdown(TNC->TCPSock, SD_BOTH); - Sleep(100); - - closesocket(TNC->TCPSock); - TNC->CONNECTED = FALSE; - - if (TNC->PID && TNC->WeStartedTNC) - { - KillTNC(TNC); - RestartTNC(TNC); - } - - return (0); - - case 5: // Close - - shutdown(TNC->TCPSock, SD_BOTH); - Sleep(100); - - closesocket(TNC->TCPSock); - - if (TNC->PID && TNC->WeStartedTNC) - { - KillTNC(TNC); - } - - return 0; - } - - return 0; -} - -#ifndef LINBPQ - -static KillTNC(struct TNCINFO * TNC) -{ - HANDLE hProc; - - if (TNC->PTTMode) - Rig_PTT(TNC->RIG, FALSE); // Make sure PTT is down - - if (TNC->PID == 0) return 0; - - hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, TNC->PID); - - if (hProc) - { - TerminateProcess(hProc, 0); - CloseHandle(hProc); - } - - TNC->PID = 0; // So we don't try again - - return 0; -} - -static RestartTNC(struct TNCINFO * TNC) -{ - STARTUPINFO SInfo; // pointer to STARTUPINFO - PROCESS_INFORMATION PInfo; // pointer to PROCESS_INFORMATION - char HomeDir[MAX_PATH]; - int i, ret; - - SInfo.cb=sizeof(SInfo); - SInfo.lpReserved=NULL; - SInfo.lpDesktop=NULL; - SInfo.lpTitle=NULL; - SInfo.dwFlags=0; - SInfo.cbReserved2=0; - SInfo.lpReserved2=NULL; - - if (TNC->ProgramPath) - { - strcpy(HomeDir, TNC->ProgramPath); - i = strlen(HomeDir); - - while(--i) - { - if (HomeDir[i] == '/' || HomeDir[i] == '\\') - { - HomeDir[i] = 0; - break; - } - } - ret = CreateProcess(TNC->ProgramPath, "MultiPSK TCP_IP_ON", NULL, NULL, FALSE,0 ,NULL ,HomeDir, &SInfo, &PInfo); - - if (ret) - TNC->PID = PInfo.dwProcessId; - - return ret; - } - return 0; -} -#endif - -UINT MPSKExtInit(EXTPORTDATA * PortEntry) -{ - int i, port; - char Msg[255]; - struct TNCINFO * TNC; - char * ptr; - - // - // Will be called once for each MPSK port to be mapped to a BPQ Port - // The MPSK port number is in CHANNEL - A=0, B=1 etc - // - // The Socket to connect to is in IOBASE - // - - port = PortEntry->PORTCONTROL.PORTNUMBER; - - ReadConfigFile(port, ProcessLine); - - TNC = TNCInfo[port]; - - if (TNC == NULL) - { - // Not defined in Config file - - sprintf(Msg," ** Error - no info in BPQ32.cfg for this port\n"); - WritetoConsole(Msg); - - return ExtProc; - } - - TNC->Port = port; - - TNC->PortRecord = PortEntry; - - if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) - memcpy(TNC->NodeCall, MYNODECALL, 10); - else - ConvFromAX25(&PortEntry->PORTCONTROL.PORTCALL[0], TNC->NodeCall); - - TNC->Interlock = PortEntry->PORTCONTROL.PORTINTERLOCK; - - PortEntry->PORTCONTROL.PROTOCOL = 10; - PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream - PortEntry->PORTCONTROL.PORTQUALITY = 0; - PortEntry->SCANCAPABILITIES = NONE; // Scan Control - None - - if (PortEntry->PORTCONTROL.PORTPACLEN == 0) - PortEntry->PORTCONTROL.PORTPACLEN = 64; - - ptr=strchr(TNC->NodeCall, ' '); - if (ptr) *(ptr) = 0; // Null Terminate - - TNC->Hardware = H_MPSK; - - MPSKChannel[port] = PortEntry->PORTCONTROL.CHANNELNUM-65; - - PortEntry->MAXHOSTMODESESSIONS = 1; - - i=sprintf(Msg,"MPSK Host %s Port %d \n", - TNC->HostName, TNC->TCPPort); - - WritetoConsole(Msg); - - // See if we already have a port for this host - - MasterPort[port] = port; - - for (i = 1; i < port; i++) - { - if (i == port) continue; - - if (TNCInfo[i] && TNCInfo[i]->TCPPort == TNC->TCPPort && - _stricmp(TNCInfo[i]->HostName, TNC->HostName) == 0) - { - MasterPort[port] = i; - break; - } - } - - BPQPort[PortEntry->PORTCONTROL.CHANNELNUM-65][MasterPort[port]] = port; - -#ifndef LINBPQ - if (MasterPort[port] == port) - { - if (EnumWindows(EnumTNCWindowsProc, (LPARAM)TNC)) - if (TNC->ProgramPath) - TNC->WeStartedTNC = RestartTNC(TNC); - - ConnecttoMPSK(port); - } -#endif - time(&lasttime[port]); // Get initial time value - -// SendMessage(0x40eaa, WM_COMMAND, 0x03000eaa, 0x40eaa); - - return ExtProc; - -} - - -static int ProcessLine(char * buf, int Port) -{ - UCHAR * ptr,* p_cmd; - char * p_ipad = 0; - char * p_port = 0; - unsigned short WINMORport = 0; - int BPQport; - int len=510; - struct TNCINFO * TNC; - struct MPSKINFO * AGW; - - char errbuf[256]; - - strcpy(errbuf, buf); - - ptr = strtok(buf, " \t\n\r"); - - if(ptr == NULL) return (TRUE); - - if(*ptr =='#') return (TRUE); // comment - - if(*ptr ==';') return (TRUE); // comment - - if (_stricmp(buf, "ADDR")) - return FALSE; // Must start with ADDR - - ptr = strtok(NULL, " \t\n\r"); - - BPQport = Port; - p_ipad = ptr; - - TNC = TNCInfo[BPQport] = zalloc(sizeof(struct TNCINFO)); - AGW = TNC->MPSKInfo = zalloc(sizeof(struct MPSKINFO)); // AGW Sream Mode Specific Data - - AGW->MaxSessions = 10; - AGW->ConnTimeOut = CONTIMEOUT; - - TNC->InitScript = malloc(1000); - TNC->InitScript[0] = 0; - - if (p_ipad == NULL) - p_ipad = strtok(NULL, " \t\n\r"); - - if (p_ipad == NULL) return (FALSE); - - p_port = strtok(NULL, " \t\n\r"); - - if (p_port == NULL) return (FALSE); - - TNC->TCPPort = atoi(p_port); - - TNC->destaddr.sin_family = AF_INET; - TNC->destaddr.sin_port = htons(TNC->TCPPort); - TNC->HostName = malloc(strlen(p_ipad)+1); - - if (TNC->HostName == NULL) return TRUE; - - strcpy(TNC->HostName,p_ipad); - - ptr = strtok(NULL, " \t\n\r"); - - if (ptr) - { - if (_memicmp(ptr, "PATH", 4) == 0) - { - p_cmd = strtok(NULL, "\n\r"); - if (p_cmd) TNC->ProgramPath = _strdup(p_cmd); - } - } - - // Read Initialisation lines - - while(TRUE) - { - if (GetLine(buf) == 0) - return TRUE; - - strcpy(errbuf, buf); - - if (memcmp(buf, "****", 4) == 0) - return TRUE; - - ptr = strchr(buf, ';'); - if (ptr) - { - *ptr++ = 13; - *ptr = 0; - } - - if (_memicmp(buf, "CONTIMEOUT", 10) == 0) - AGW->ConnTimeOut = atoi(&buf[11]) * 10; - else - if (_memicmp(buf, "UPDATEMAP", 9) == 0) - TNC->PktUpdateMap = TRUE; - else - if (_memicmp(buf, "ALEBEACON", 9) == 0) // Send Beacon after each session - TNC->MPSKInfo->Beacon = TRUE; - else - if (_memicmp(buf, "DEFAULTMODE", 11) == 0) // Send Beacon after each session - strcpy(TNC->MPSKInfo->DefaultMode, &buf[12]); - else - - strcat (TNC->InitScript, buf); - } - - - return (TRUE); -} - -static int ConnecttoMPSK(int port) -{ - _beginthread(ConnecttoMPSKThread, 0, (void *)(size_t)port); - - return 0; -} - -VOID ConnecttoMPSKThread(void * portptr) -{ - - int port = (int)(size_t)portptr; - char Msg[255]; - int err,i; - u_long param=1; - BOOL bcopt=TRUE; - struct hostent * HostEnt; - struct TNCINFO * TNC = TNCInfo[port]; - - Sleep(5000); // Allow init to complete - - TNC->destaddr.sin_addr.s_addr = inet_addr(TNC->HostName); - - if (TNC->destaddr.sin_addr.s_addr == INADDR_NONE) - { - // Resolve name to address - - HostEnt = gethostbyname (TNC->HostName); - - if (!HostEnt) return; // Resolve failed - - memcpy(&TNC->destaddr.sin_addr.s_addr,HostEnt->h_addr,4); - memcpy(&TNC->Datadestaddr.sin_addr.s_addr,HostEnt->h_addr,4); - - } - - if (TNC->TCPSock) - closesocket(TNC->TCPSock); - - TNC->TCPSock = 0; - - TNC->TCPSock=socket(AF_INET,SOCK_STREAM,0); - - if (TNC->TCPSock == INVALID_SOCKET) - { - i=sprintf(Msg, "Socket Failed for MPSK socket - error code = %d\n", WSAGetLastError()); - WritetoConsole(Msg); - - return; - } - - sinx.sin_family = AF_INET; - sinx.sin_addr.s_addr = INADDR_ANY; - sinx.sin_port = 0; - - TNC->CONNECTING = TRUE; - - if (connect(TNC->TCPSock,(LPSOCKADDR) &TNC->destaddr,sizeof(TNC->destaddr)) == 0) - { - // - // Connected successful - // - - TNC->CONNECTED=TRUE; - } - else - { - if (TNC->Alerted == FALSE) - { - err=WSAGetLastError(); - i=sprintf(Msg, "Connect Failed for MPSK socket - error code = %d\n", err); - WritetoConsole(Msg); - MySetWindowText(TNC->xIDC_COMMSSTATE, "Connection to TNC failed"); - - TNC->Alerted = TRUE; - } - - TNC->CONNECTING = FALSE; - return; - } - - TNC->LastFreq = 0; // so V4 display will be updated - - MySetWindowText(TNC->xIDC_COMMSSTATE, "Connected to MPSK TNC"); - - return; - -} - -static int ProcessReceivedData(int port) -{ - unsigned int bytes; - int i; - char ErrMsg[255]; - char Message[500]; - struct TNCINFO * TNC = TNCInfo[port]; - - // Need to extract messages from byte stream - - bytes = recv(TNC->TCPSock,(char *)&Message, 500, 0); - - if (bytes == SOCKET_ERROR) - { -// i=sprintf(ErrMsg, "Read Failed for MPSK socket - error code = %d\r\n", WSAGetLastError()); -// WritetoConsole(ErrMsg); - - closesocket(TNC->TCPSock); - - TNC->CONNECTED = FALSE; - if (TNC->Streams[0].Attached) - TNC->Streams[0].ReportDISC = TRUE; - - return (0); - } - - if (bytes == 0) - { - // zero bytes means connection closed - - i=sprintf(ErrMsg, "MPSK Connection closed for BPQ Port %d\n", port); - WritetoConsole(ErrMsg); - - TNC->CONNECTED = FALSE; - if (TNC->Streams[0].Attached) - TNC->Streams[0].ReportDISC = TRUE; - - return (0); - } - - // Have some data - - ProcessMPSKPacket(TNC, Message, bytes); // Data may be for another port - - return (0); - -} - -VOID ProcessMSPKCmd(struct TNCINFO * TNC); -VOID ProcessMSPKComment(struct TNCINFO * TNC); -VOID ProcessMSPKData(struct TNCINFO * TNC); - -VOID ProcessMPSKPacket(struct TNCINFO * TNC, char * Message, int Len) -{ - char * MPTR = Message; - -/* -3) each text character transmitted by the client to the server (for the Multipsk TX text editor) must be preceded by the character CHR(25) or CHR(22) in the case of a special link (KISS in Packet or Pax, for example). - -4) each command string transmitted by the client to the server must be preceded by the character CHR(26) and finished by CHR(27), - -5) each character effectively transmitted by Multipsk to the transceiver and transmitted to the client is preceded by the character CHR(28), - -6) each character received by Multipsk and transmitted to the client is preceded by the character CHR(29), - -7) each command string transmitted by the server to the client must be preceded by the character CHR(30) and finished by CHR(31), - -8) all commands (written in readable text ) will have an answer (see further for details), - -9) each server comment (Call ID or RS ID reception, switch to RX or to TX) string transmitted by the server to the client must be preceded by a string: "CHR(23)RX CALL ID=", "CHR(23)RX RS ID=", "CHR(23)SWITCH=RX", "CHR(23) SWITCH=TX", and finished by CHR(24). - -10) each server command, for the transceiver control, transmitted by the server to the client must be preceded by the string "CHR(23) XCVR=" and finished by CHR(24). - -Data - -End of TX] ARQ FAE CQ[End of TX] ARQ FAE CQ[End of TX] call "THIS I[End of TX] end of link to GM8BPQ[End of TX] sounding "THIS WAS"[End of TX] ARQ FAE CQ[End of TX] ARQ FAE CQ[End of TX] ARQ FAE CQ[End of TX] ARQ FAE CQFAE BEACON OH5RM Kouvola KP30JR -[End of TX] ARQ FAE selective callGM8BPQ DE OH5RM - -[Connection made with OH5RM] - - -18103 but I have to go out to change antenna - -[End of connection with OH5RM]FAE BEACON OH5RM Kouvola KP30JR -S" to GM8BPQ - -10:23:55 AM Comment: SWITCH=RX -10:24:00 AM Comment: RX RS ID=10:24:00 UTC ALE400 1609 Hz 0 MHz -10:24:19 AM Comment: RX RS ID=10:24:19 UTC ALE400 1604 Hz 0 MHz -10:25:04 AM Comment: SWITCH=TX -10:25:07 AM Comment: SWITCH=RX -10:25:15 AM Comment: SWITCH=TX -:30:22 AM Comment: SWITCH=RX -10:30:25 AM Comment: SWITCH=TX -10:30:27 AM Comment: SWITCH=RX -10:30:35 AM Comment: RX RS ID=10:30:35 UTC ALE400 1598 Hz 0 MHz - - -*/ - - // Reuse the HAL CMD and Data Buffers to build messages from TCP stream - - // See if sequence split over a packet boundary - - if (TNC->CmdEsc == 23) - { - TNC->CmdEsc = 0; - goto CommentEsc; - } - - if (TNC->CmdEsc == 29) - { - TNC->CmdEsc = 0; - goto DataEsc; - } - - if (TNC->CmdEsc == 30) - { - TNC->CmdEsc = 0; - goto CmdEsc; - } - - // No Split - - while(Len) - { - switch (*(MPTR++)) - { - case 29: // Data Char - - Len--; - DataEsc: - if (Len) - { - TNC->DataBuffer[TNC->DataLen++] = *MPTR; - MPTR++; - Len--; - goto OuterLoop; - } - - TNC->CmdEsc = 29; - - if (TNC->DataLen) - ProcessMSPKData(TNC); - - - return; // Nothing left - - case 30: - - Len --; - CmdEsc: - while (Len) - { - if (*MPTR == 31) // End of String - { - ProcessMSPKCmd(TNC); - TNC->CmdLen = 0; - - // Process any data left in buffer - - MPTR++; - Len--; - goto OuterLoop; - } - - TNC->CmdBuffer[TNC->CmdLen++] = *MPTR; - MPTR++; - Len--; - } - - TNC->CmdEsc = 30; - return; // Nothing left - - case 23: // Server Comment - - Len --; - CommentEsc: - while (Len) - { - if (*MPTR == 24) // End of String - { - // Process Comment - - ProcessMSPKCmd(TNC); - TNC->CmdLen = 0; - - // Process any data left in buffer - - MPTR++; - Len--; - goto OuterLoop; - } - - TNC->CmdBuffer[TNC->CmdLen++] = *MPTR; - MPTR++; - Len--; - } - - TNC->CmdEsc = 23; - return; // Nothing left - - default: - - Len--; - - } -OuterLoop:; - } - - if (TNC->DataLen) - ProcessMSPKData(TNC); -} - -VOID ProcessMSPKCmd(struct TNCINFO * TNC) -{ - TNC->CmdBuffer[TNC->CmdLen] = 0; - - if (strcmp(TNC->CmdBuffer, "SWITCH=TX") == 0) - TNC->MPSKInfo->TX = TRUE; - else - { - if (strcmp(TNC->CmdBuffer, "SWITCH=RX") == 0) - { - TNC->MPSKInfo->TX = FALSE; - - // See if a command was queued while busy - - if (TNC->CmdSet) - { - send(TNC->TCPSock, TNC->CmdSet, (int)strlen(TNC->CmdSet), 0); - free (TNC->CmdSet); - TNC->CmdSet = NULL; - } - } - else - { - Debugprintf("MPSK CMD %s", TNC->CmdBuffer); - - if (TNC->InternalCmd) - { - ULONG * buffptr = GetBuff(); - char * ptr = strstr(TNC->CmdBuffer, "OK"); - - if (ptr) - *(ptr+2) = 0; // Convert OKn to OK for BBS Connect Script - - TNC->InternalCmd = FALSE; - - if (buffptr) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "MPSK} %s\r", TNC->CmdBuffer); - C_Q_ADD(&TNC->Streams[0].PACTORtoBPQ_Q, buffptr); - } - - if (strstr(TNC->CmdBuffer, "STOP_SELECTIVE_CALL_ARQ_FAE OK")) - TNC->Streams[0].Connecting = FALSE; - - } - } - } -} - -VOID ProcessMSPKComment(struct TNCINFO * TNC) -{ - TNC->CmdBuffer[TNC->CmdLen] = 0; - Debugprintf("MPSK Comment %s", TNC->CmdBuffer); -} - -static int UnStuff(UCHAR * inbuff, int len) -{ - int i,txptr=0; - UCHAR c; - UCHAR * outbuff = inbuff; - - for (i = 0; i < len; i++) - { - c = inbuff[i]; - - if (c == 0xc0) - c = inbuff[++i] - 0x20; - - outbuff[txptr++]=c; - } - - return txptr; -} - -VOID ProcessMSPKData(struct TNCINFO * TNC) -{ - UINT * buffptr; - int Stream = 0; - struct STREAMINFO * STREAM = &TNC->Streams[0]; - char * ptr; - int Len = TNC->DataLen; - - TNC->DataBuffer[TNC->DataLen] = 0; - - // Process Data - - if (STREAM->Connected) - { - ptr = strstr(TNC->DataBuffer, "[End of connection"); - - if (ptr) - { - // Disconnect - - TNC->DataLen = 0; - - if (STREAM->DiscWhenAllSent) - return; // Already notified - - if (STREAM->Connecting) - { - // Report Connect Failed, and drop back to command mode - - STREAM->Connecting = FALSE; - buffptr = GetBuff(); - - if (buffptr == 0) return; // No buffers, so ignore - - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "MPSK} Failure with %s\r", STREAM->RemoteCall); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - STREAM->DiscWhenAllSent = 10; - - return; - } - - // Release Session - - STREAM->Connecting = FALSE; - STREAM->Connected = FALSE; // Back to Command Mode - STREAM->ReportDISC = TRUE; // Tell Node - - STREAM->Disconnecting = FALSE; - STREAM->DiscWhenAllSent = 10; - STREAM->FramesOutstanding = 0; - - return; - } - - // Pass to Application. Remove any transparency (hex 0xc0 used as an escape) - - buffptr = GetBuff(); - - if (TNC->DataBuffer[TNC->DataLen - 1] == 0xc0) - return; // Last char is an escape, so wait for the escaped char to arrive - - if (buffptr) - { - if (memchr(TNC->DataBuffer, 0xc0, TNC->DataLen)) - TNC->DataLen = UnStuff(TNC->DataBuffer, TNC->DataLen); - - buffptr[1] = TNC->DataLen; - memcpy(&buffptr[2], TNC->DataBuffer, TNC->DataLen); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - STREAM->BytesRXed += TNC->DataLen; - } - - TNC->DataLen = 0; - return; - } - - // Not Connected. We get various status messages, including Connection made, - // but they may be split across packets, or have more that one to a packet. - // I think they are all CR/LF terminated . No they aren't! - - // Look for [] this seems to be what is important - -DataLoop: - - if (memcmp(TNC->DataBuffer, "[End of TX] ARQ FAE CQ", 22) == 0) - { - // Remove string from buffer - - if (Len == 22) // Most Likely - { - TNC->DataLen = 0; - return; - } - - TNC->DataLen -= 22; - memmove(TNC->DataBuffer, &TNC->DataBuffer[22], Len - 21); //Copy Null - Len -= 22; - goto DataLoop; - - } - - ptr = strchr(TNC->DataBuffer, '['); - - if (ptr) - { - // Start of a significant Message - - char * eptr = strchr(TNC->DataBuffer, ']'); - char CallFrom[20]; - char * cptr ; - - if (eptr == 0) - return; // wait for matching [] - - cptr = strstr(TNC->DataBuffer, "[Connection made with "); - - // TNC->DataLen -= LineLen; - // memmove(TNC->DataBuffer, &TNC->DataBuffer[LineLen], 1 + Len - LineLen); //Copy Null - // Len -= LineLen; - // goto DataLoop; - - - if (cptr) // Have a connection - { - - // Connected - - memcpy(CallFrom, &cptr[22], 18); - cptr = strchr(CallFrom, ']'); - if (cptr) - *cptr = 0; - - if (STREAM->Connecting) - { - // Connect Complete - - STREAM->Connected = TRUE; - STREAM->Connecting = FALSE; - STREAM->ConnectTime = time(NULL); - STREAM->BytesRXed = STREAM->BytesTXed = 0; - - buffptr = GetBuff(); - if (buffptr) - { - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "*** Connected to %s\r", CallFrom); - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - } - } - else - { - // Incoming. Look for a free Stream - - STREAM->Connected = TRUE; - STREAM->ConnectTime = time(NULL); - STREAM->BytesRXed = STREAM->BytesTXed = 0; - - UpdateMH(TNC, CallFrom, '+', 'I'); - - ProcessIncommingConnect(TNC, CallFrom, Stream, FALSE); - - if (HFCTEXTLEN) - { - if (HFCTEXTLEN > 1) - SendData(TNC, HFCTEXT, HFCTEXTLEN); - } - else - { - if (FULL_CTEXT) - { - int Len = CTEXTLEN, CTPaclen = 50; - int Next = 0; - - while (Len > CTPaclen) // CTEXT Paclen - { - SendData(TNC, &CTEXTMSG[Next], CTPaclen); - Next += CTPaclen; - Len -= CTPaclen; - } - SendData(TNC, &CTEXTMSG[Next], Len); - } - } - } - } - - } - - // Doesnt contain [ - just discard - - TNC->DataLen = 0; - Debugprintf(TNC->DataBuffer); - return; - -} - - - -/* - buffptr = GetBuff(); - if (buffptr == 0) return; // No buffers, so ignore - - buffptr[1] = RXHeader->DataLength; - memcpy(&buffptr[2], Message, RXHeader->DataLength); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - return; - - return; - - - case 'd': // Disconnected - - - - case 'C': - - // Connect. Can be Incoming or Outgoing - - // "*** CONNECTED To Station [CALLSIGN]" When the other station starts the connection - // "*** CONNECTED With [CALLSIGN]" When we started the connection - - */ - - -VOID SendData(struct TNCINFO * TNC, char * Msg, int MsgLen) -{ - // Preceed each data byte with 25 (decimal) - - char * NewMsg = malloc (MsgLen * 4); - int n; - UCHAR c; - int ExtraLen = 0; - char * ptr = NewMsg; - char * inptr = Msg; - SOCKET sock = TNCInfo[MasterPort[TNC->Port]]->TCPSock; - - TNC->Streams[0].BytesTXed += MsgLen; - - for (n = 0; n < MsgLen; n++) - { - *(ptr++) = 25; - c = *inptr++; - - if (c < 0x20 || c == 0xc0) - { - if (c != 0x0d) - { - *ptr++ = 0x0c0; - *(ptr++) = 25; - *ptr++ = c + 0x20; - ExtraLen += 2; - continue; - } - } - - *ptr++ = c; - } - - send(sock, NewMsg, MsgLen * 2 + ExtraLen, 0); - - free(NewMsg); -} - -VOID TidyClose(struct TNCINFO * TNC, int Stream) -{ - char Command[80]; - int len; - - len = sprintf(Command,"%cSTOP_SELECTIVE_CALL_ARQ_FAE\x1b", '\x1a'); - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Command); // Savde till not transmitting - else - send(TNC->TCPSock, Command, len, 0); -} - -VOID ForcedClose(struct TNCINFO * TNC, int Stream) -{ - TidyClose(TNC, Stream); // I don't think Hostmode has a DD -} - -VOID CloseComplete(struct TNCINFO * TNC, int Stream) -{ - char Cmd[80]; - int Len; - - sprintf(Cmd, "%d SCANSTART 15", TNC->Port); - Rig_Command(-1, Cmd); - - Cmd[0] = 0; - - if (TNC->MPSKInfo->DefaultMode[0]) - sprintf(Cmd, "%cDIGITAL MODE %s\x1b", '\x1a', TNC->MPSKInfo->DefaultMode); - - if (TNC->MPSKInfo->Beacon) - sprintf(Cmd, "%s%cBEACON_ARQ_FAE\x1b", Cmd, '\x1a'); - - Len = (int)strlen(Cmd); - - if(Len) - { - if (TNC->MPSKInfo->TX) - TNC->CmdSet = TNC->CmdSave = _strdup(Cmd); // Savde till not transmitting - else - send(TNC->TCPSock, Cmd, Len, 0); - } -} - diff --git a/MailTCP.c b/MailTCP.c index 91ddc3f..289fb62 100644 --- a/MailTCP.c +++ b/MailTCP.c @@ -1570,12 +1570,12 @@ VOID ProcessSMTPServerMessage(SocketConn * sockptr, char * Buffer, int Len) if (CheckifLocalRMSUser(Addr)) // if local RMS - Leave Here continue; - ToLen = sprintf(ToString, "%sTo: %s\r\n", ToString, &Addr[4]); + ToLen = sprintf(&ToString[strlen(ToString)], "To: %s\r\n", &Addr[4]); *sockptr->RecpTo[i] = 0; // So we dont create individual one later continue; } - ToLen = sprintf(ToString, "%sTo: %s@%s\r\n", ToString, &Addr[4], Via); + ToLen = sprintf(&ToString[strlen(ToString)], "To: %s@%s\r\n", &Addr[4], Via); *sockptr->RecpTo[i] = 0; // So we dont create individual one later continue; } @@ -1591,7 +1591,7 @@ VOID ProcessSMTPServerMessage(SocketConn * sockptr, char * Buffer, int Len) if (CheckifLocalRMSUser(Addr)) // if local RMS - Leave Here continue; - ToLen = sprintf(ToString, "%sTo: %s\r\n", ToString, Addr); + ToLen = sprintf(&ToString[strlen(ToString)], "To: %s\r\n", Addr); *sockptr->RecpTo[i] = 0; // So we dont create individual one later continue; diff --git a/RigControl.c b/RigControl.c index 6bc414f..90349fe 100644 --- a/RigControl.c +++ b/RigControl.c @@ -5286,10 +5286,13 @@ BOOL DecodeModePtr(char * Param, double * Dwell, double * Freq, char * Mode, ptr = strtok_s(NULL, ",", &Context); - if (ptr == NULL || strlen(ptr) > 8) - return FALSE; + if (ptr == NULL) + if (*MemoryNumber) // If channel, dont need mode + return TRUE; + + if (ptr == NULL || strlen(ptr) > 8) + return FALSE; // Mode Missing - // If channel, dont need mode if (*MemoryNumber == 0) { @@ -7393,6 +7396,8 @@ VOID SetupScanInterLockGroups(struct RIGINFO *RIG) int Interlock = RIG->Interlock; char PortString[128] = ""; char TxPortString[128] = ""; + int n = 0; + int nn = 0; // Find TNC ports in this Rig's scan group @@ -7409,7 +7414,7 @@ VOID SetupScanInterLockGroups(struct RIGINFO *RIG) { int p = PortRecord->PORTNUMBER; RIG->BPQPort |= ((uint64_t)1 << p); - sprintf(PortString, "%s,%d", PortString, p); + n += sprintf(&PortString[n], ",%d", p); TNC->RIG = RIG; if (RIG->PTTMode == 0 && TNC->PTTMode) @@ -7419,7 +7424,7 @@ VOID SetupScanInterLockGroups(struct RIGINFO *RIG) { int p = PortRecord->PORTNUMBER; RIG->BPQPort |= ((uint64_t)1 << p); - sprintf(TxPortString, "%s,%d", TxPortString, p); + nn += sprintf(&TxPortString[nn], ",%d", p); TNC->TXRIG = RIG; if (RIG->PTTMode == 0 && TNC->PTTMode) diff --git a/SCSTrackeMulti64.c b/SCSTrackeMulti64.c deleted file mode 100644 index a7dc3bf..0000000 --- a/SCSTrackeMulti64.c +++ /dev/null @@ -1,1714 +0,0 @@ -/* -Copyright 2001-2018 John Wiseman G8BPQ - -This file is part of LinBPQ/BPQ32. - -LinBPQ/BPQ32 is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -LinBPQ/BPQ32 is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses -*/ - -// -// DLL to inteface DED Host Mode TNCs to BPQ32 switch -// -// Uses BPQ EXTERNAL interface - -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_DEPRECATE - -#include -#include -#include "time.h" - -#define MaxStreams 10 - -#include "CHeaders.h" -#include "tncinfo.h" - -#include "bpq32.h" - -static char ClassName[]="TRACKERSTATUS"; -static char WindowTitle[] = "SCS Tracker"; -static int RigControlRow = 140; - -#define NARROWMODE 30 -#define WIDEMODE 30 // PIII only - -extern UCHAR BPQDirectory[]; - -extern char * PortConfig[33]; - -static RECT Rect; - -struct TNCINFO * TNCInfo[34]; // Records are Malloc'd - -VOID __cdecl Debugprintf(const char * format, ...); -char * strlop(char * buf, char delim); -BOOL KAMStartPort(struct PORTCONTROL * PORT); -BOOL KAMStopPort(struct PORTCONTROL * PORT); - -char NodeCall[11]; // Nodecall, Null Terminated -void WriteDebugLogLine(int Port, char Dirn, char * Msg, int MsgLen); - -static int ProcessLine(char * buf, int Port) -{ - UCHAR * ptr; - char * p_port = 0; - int BPQport; - int len=510; - struct TNCINFO * TNC; - char errbuf[256]; - - strcpy(errbuf, buf); - - BPQport = Port; - - TNC = TNCInfo[BPQport] = malloc(sizeof(struct TNCINFO)); - memset(TNC, 0, sizeof(struct TNCINFO)); - - TNC->InitScript = malloc(1000); - TNC->InitScript[0] = 0; - - TNC->PacketChannels = 10; // Default - - goto ConfigLine; - - while(TRUE) - { - if (GetLine(buf) == 0) - return TRUE; -ConfigLine: - strcpy(errbuf, buf); - - if (memcmp(buf, "****", 4) == 0) - return TRUE; - - ptr = strchr(buf, ';'); - - if (ptr) - { - *ptr++ = 13; - *ptr = 0; - } - - if (_memicmp(buf, "APPL", 4) == 0) - { - } - else - if (_memicmp(buf, "RIGCONTROL", 10) == 0) - { - } - else - - if (_memicmp(buf, "SWITCHMODES", 11) == 0) - { - } - else - if (_memicmp(buf, "USEAPPLCALLS", 12) == 0) - { -// TNC->UseAPPLCalls = TRUE; - } - else if (_memicmp(buf, "DEBUGLOG", 8) == 0) // Write Debug Log - TNC->WRITELOG = atoi(&buf[8]); - else - if (_memicmp(buf, "DEFAULT ROBUST", 14) == 0) - { - } - else - - if (_memicmp(buf, "WL2KREPORT", 10) == 0) - { - } - else - if (_memicmp(buf, "UPDATEMAP", 9) == 0) - TNC->PktUpdateMap = TRUE; - else - if (_memicmp(buf, "PACKETCHANNELS", 14) == 0) - - // Packet Channels - - TNC->PacketChannels = atoi(&buf[14]); - else - strcat (TNC->InitScript, buf); - } - return (TRUE); - -} - -struct TNCINFO * CreateTTYInfo(int port, int speed); -BOOL OpenConnection(int); -BOOL SetupConnection(int); -BOOL CloseConnection(struct TNCINFO * conn); -static BOOL WriteCommBlock(struct TNCINFO * TNC); -BOOL DestroyTTYInfo(int port); -static void DEDCheckRX(struct TNCINFO * TNC); -static VOID DEDPoll(int Port); -VOID StuffAndSend(struct TNCINFO * TNC, UCHAR * Msg, int Len); -unsigned short int compute_crc(unsigned char *buf,int len); -int Unstuff(UCHAR * MsgIn, UCHAR * MsgOut, int len); -static VOID ProcessDEDFrame(struct TNCINFO * TNC); -static VOID ProcessTermModeResponse(struct TNCINFO * TNC); -static VOID ExitHost(struct TNCINFO * TNC); -static VOID DoTNCReinit(struct TNCINFO * TNC); -static VOID DoTermModeTimeout(struct TNCINFO * TNC); -VOID DoMonitorHddr(struct TNCINFO * TNC, UCHAR * Msg, int Len, int Type); -VOID DoMonitorData(struct TNCINFO * TNC, UCHAR * Msg, int Len); -int Switchmode(struct TNCINFO * TNC, int Mode); -VOID SwitchToRPacket(struct TNCINFO * TNC); -VOID SwitchToNormPacket(struct TNCINFO * TNC); - - -static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) -{ - PMSGWITHLEN buffptr; - unsigned int txlen = 0; - - struct TNCINFO * TNC = TNCInfo[port]; - int Stream = 0; - struct STREAMINFO * STREAM; - int TNCOK; - - if (TNC == NULL) - return 0; - - if (TNC->hDevice == 0) - { - // Clear anything from UI_Q - - while (TNC->PortRecord->UI_Q) - { - buffptr = Q_REM(&TNC->PortRecord->UI_Q); - ReleaseBuffer(buffptr); - } - - if (fn > 3 && fn < 6) - goto ok; - - // Try to reopen every 30 secs - - TNC->ReopenTimer++; - - if (TNC->ReopenTimer < 300) - return 0; - - TNC->ReopenTimer = 0; - - if (TNC->PortRecord->PORTCONTROL.PortStopped == 0) - OpenCOMMPort(TNC, TNC->PortRecord->PORTCONTROL.SerialPortName, TNC->PortRecord->PORTCONTROL.BAUDRATE, TRUE); - - if (TNC->hDevice == 0) - return 0; - } -ok: - switch (fn) - { - case 1: // poll - - for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (TNC->Streams[Stream].ReportDISC) - { - TNC->Streams[Stream].ReportDISC = FALSE; - buff->PORT = Stream; - - return -1; - } - } - - DEDCheckRX(TNC); - DEDPoll(port); - DEDCheckRX(TNC); - - for (Stream = 0; Stream <= MaxStreams; Stream++) - { - STREAM = &TNC->Streams[Stream]; - - if (STREAM->PACTORtoBPQ_Q == 0) - { - if (STREAM->DiscWhenAllSent) - { - STREAM->DiscWhenAllSent--; - if (STREAM->DiscWhenAllSent == 0) - STREAM->ReportDISC = TRUE; // Dont want to leave session attached. Causes too much confusion - } - } - else - { - int datalen; - - buffptr=Q_REM(&STREAM->PACTORtoBPQ_Q); - - datalen = (int)buffptr->Len; - - buff->PORT = Stream; // Compatibility with Kam Driver - buff->PID = 0xf0; - memcpy(&buff->L2DATA, &buffptr->Data[0], datalen); // Data goes to + 7, but we have an extra byte - datalen += sizeof(void *) + 4; - - PutLengthinBuffer((PDATAMESSAGE)buff, datalen); // Neded for arm5 portability - - // buff[5]=(datalen & 0xff); - // buff[6]=(datalen >> 8); - - ReleaseBuffer(buffptr); - - return (1); - } - } - - - return 0; - - case 2: // send - - buffptr = GetBuff(); - - if (buffptr == 0) return (0); // No buffers, so ignore - - Stream = buff->PORT; - - if (!TNC->TNCOK) - { - // Send Error Response - - buffptr->Len = 21; - memcpy(&buffptr->Data[0], "No Connection to TNC\r", 21); - - C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); - - return 0; - } - - txlen = GetLengthfromBuffer(buff) - (sizeof(void *) + 4); - - buffptr->Len = txlen; - memcpy(&buffptr->Data[0], &buff->L2DATA[0], txlen); - - C_Q_ADD(&TNC->Streams[Stream].BPQtoPACTOR_Q, buffptr); - - TNC->Streams[Stream].FramesOutstanding++; - - return (0); - - - case 3: // CHECK IF OK TO SEND. Also used to check if TNC is responding - - Stream = (int)(size_t)buff; - - TNCOK = (TNC->HostMode == 1 && TNC->ReinitState != 10); - - STREAM = &TNC->Streams[Stream]; - - if (Stream == 0) - { - if (STREAM->FramesOutstanding > 4) - return (1 | TNCOK << 8 | STREAM->Disconnecting << 15); - } - else - { - if (STREAM->FramesOutstanding > 3 || TNC->Buffers < 200) - return (1 | TNCOK << 8 | STREAM->Disconnecting << 15); } - - return TNCOK << 8 | STREAM->Disconnecting << 15; // OK, but lock attach if disconnecting - - - case 4: // reinit - - ExitHost(TNC); - Sleep(50); - CloseCOMPort(TNC->hDevice); - TNC->hDevice =(HANDLE) 0; - TNC->ReopenTimer = 250; - TNC->HostMode = FALSE; - - return (0); - - case 5: // Close - - // Ensure in Pactor - - ExitHost(TNC); - - Sleep(25); - - CloseCOMPort(TNCInfo[port]->hDevice); - return (0); - - case 6: - - return 0; // No scan interface -} - return 0; -} - -void * TrackerMExtInit(EXTPORTDATA * PortEntry) -{ - char msg[500]; - struct TNCINFO * TNC; - int port; - char * ptr; - int Stream = 0; - char * TempScript; - char YCmd[10]; - - // - // Will be called once for each DED Host TNC Port - // The COM port number is in IOBASE - // - - sprintf(msg,"SCSTRK M %s", PortEntry->PORTCONTROL.SerialPortName); - - WritetoConsole(msg); - - port=PortEntry->PORTCONTROL.PORTNUMBER; - - ReadConfigFile(port, ProcessLine); - - TNC = TNCInfo[port]; - - if (TNC == NULL) - { - // Not defined in Config file - - sprintf(msg," ** Error - no info in BPQ32.cfg for this port\n"); - WritetoConsole(msg); - - return ExtProc; - } - - TNC->Port = port; - TNC->Hardware = H_TRKM; - - // Set up DED addresses for streams - - for (Stream = 0; Stream <= MaxStreams; Stream++) - { - TNC->Streams[Stream].DEDStream = Stream; // DED Stream = BPQ Stream (We don't use Stream 0) - } - - if (TNC->PacketChannels > MaxStreams) - TNC->PacketChannels = MaxStreams; - - PortEntry->MAXHOSTMODESESSIONS = TNC->PacketChannels + 1; //TNC->PacketChannels + 1; - PortEntry->PERMITGATEWAY = TRUE; // Can change ax.25 call on each stream - PortEntry->SCANCAPABILITIES = NONE; // Scan Control 3 stage/conlock - - TNC->PortRecord = PortEntry; - - if (PortEntry->PORTCONTROL.PORTCALL[0] == 0) - memcpy(TNC->NodeCall, MYNODECALL, 10); - else - ConvFromAX25(&PortEntry->PORTCONTROL.PORTCALL[0], TNC->NodeCall); - - PortEntry->PORTCONTROL.PROTOCOL = 10; - PortEntry->PORTCONTROL.PORTQUALITY = 0; - PortEntry->PORTCONTROL.UICAPABLE = 1; - - if (PortEntry->PORTCONTROL.PORTPACLEN == 0) - PortEntry->PORTCONTROL.PORTPACLEN = 100; - - PortEntry->PORTCONTROL.PORTSTARTCODE = KAMStartPort; - PortEntry->PORTCONTROL.PORTSTOPCODE = KAMStopPort; - - ptr=strchr(TNC->NodeCall, ' '); - if (ptr) *(ptr) = 0; // Null Terminate - - // get NODECALL for RP tests - - memcpy(NodeCall, MYNODECALL, 10); - - ptr=strchr(NodeCall, ' '); - if (ptr) *(ptr) = 0; // Null Terminate - - TempScript = malloc(1000); - - strcpy(TempScript, "M UISC\r"); - strcat(TempScript, "F 200\r"); // Sets SABM retry time to about 5 secs - strcat(TempScript, "%F 1500\r"); // Tones may be changed but I want this as standard - - strcat(TempScript, TNC->InitScript); - - free(TNC->InitScript); - TNC->InitScript = TempScript; - - // Others go on end so they can't be overriden - - strcat(TNC->InitScript, "Z 0\r"); // No Flow Control - sprintf(YCmd, "Y %d\r", TNC->PacketChannels); - strcat(TNC->InitScript, YCmd); - strcat(TNC->InitScript, "E 1\r"); // Echo - Restart process needs echo - - sprintf(msg, "I %s\r", TNC->NodeCall); - strcat(TNC->InitScript, msg); - - OpenCOMMPort(TNC,PortEntry->PORTCONTROL.SerialPortName, PortEntry->PORTCONTROL.BAUDRATE, FALSE); - - TNC->InitPtr = TNC->InitScript; - - WritetoConsole("\n"); - - return ExtProc; -} - -static void DEDCheckRX(struct TNCINFO * TNC) -{ - int Length, Len; - UCHAR * ptr; - UCHAR character; - UCHAR * CURSOR; - - Len = ReadCOMBlock(TNC->hDevice, &TNC->RXBuffer[TNC->RXLen], 500 - TNC->RXLen); - - if (Len == 0) - return; // Nothing doing - - TNC->RXLen += Len; - - Length = TNC->RXLen; - - ptr = TNC->RXBuffer; - - CURSOR = &TNC->DEDBuffer[TNC->InputLen]; - - if ((TNC->HostMode == 0 || TNC->ReinitState == 10) && Length > 80) - { - // Probably Signon Message - - if (TNC->WRITELOG) - WriteDebugLogLine(TNC->Port, 'R', ptr, Length); - - ptr[Length] = 0; - Debugprintf("TRK %s", ptr); - TNC->RXLen = 0; - return; - } - - if (TNC->HostMode == 0) - { - // If we are just restarting, and TNC is in host mode, we may get "Invalid Channel" Back - - if (memcmp(ptr, "\x18\x02INVALID", 9) == 0) - { - if (TNC->WRITELOG) - WriteDebugLogLine(TNC->Port, 'R', ptr, Length); - - TNC->HostMode = TRUE; - TNC->HOSTSTATE = 0; - TNC->Timeout = 0; - TNC->RXLen = 0; - return; - } - - // Command is echoed as * command * - - if (strstr(ptr, "*") || TNC->ReinitState == 5) // 5 is waiting for reponse to JHOST1 - { - ProcessTermModeResponse(TNC); - TNC->RXLen = 0; - TNC->HOSTSTATE = 0; - - return; - } - } - - if (TNC->ReinitState == 10) - { - if (Length == 1 && *(ptr) == '.') // 01 echoed as . - { - // TNC is in Term Mode - - if (TNC->WRITELOG) - WriteDebugLogLine(TNC->Port, 'R', ptr, Length); - TNC->ReinitState = 0; - TNC->HostMode = 0; - - return; - } - } - - while (Length--) - { - character = *(ptr++); - - if (TNC->HostMode) - { - // n 0 Success (nothing follows) - // n 1 Success (message follows, null terminated) - // n 2 Failure (message follows, null terminated) - // n 3 Link Status (null terminated) - // n 4 Monitor Header (null terminated) - // n 5 Monitor Header (null terminated) - // n 6 Monitor Information (preceeded by length-1) - // n 7 Connect Information (preceeded by length-1) - - - switch(TNC->HOSTSTATE) - { - case 0: // SETCHANNEL - - TNC->MSGCHANNEL = character; - TNC->HOSTSTATE++; - break; - - case 1: // SETMSGTYPE - - TNC->MSGTYPE = character; - - if (character == 0) - { - // Success, no more info - - ProcessDEDFrame(TNC); - - TNC->HOSTSTATE = 0; - break; - } - - if (character > 0 && character < 6) - { - // Null Terminated Response) - - TNC->HOSTSTATE = 5; - CURSOR = &TNC->DEDBuffer[0]; - break; - } - - if (character > 5 && character < 8) - { - TNC->HOSTSTATE = 2; // Get Length - break; - } - - // Invalid - - Debugprintf("TRK - Invalid MsgType %d %x %x %x", character, *(ptr), *(ptr+1), *(ptr+2)); - break; - - case 2: // Get Length - - TNC->MSGCOUNT = character; - TNC->MSGCOUNT++; // Param is len - 1 - TNC->MSGLENGTH = TNC->MSGCOUNT; - CURSOR = &TNC->DEDBuffer[0]; - TNC->HOSTSTATE = 3; // Get Data - - break; - - case 5: // Collecting Null Terminated Response - - *(CURSOR++) = character; - - if (character) - continue; // MORE TO COME - - ProcessDEDFrame(TNC); - - TNC->HOSTSTATE = 0; - TNC->InputLen = 0; - - break; - - default: - - // RECEIVING Counted Response - - *(CURSOR++) = character; - TNC->MSGCOUNT--; - - if (TNC->MSGCOUNT) - continue; // MORE TO COME - - TNC->InputLen = (int)(CURSOR - TNC->DEDBuffer); - ProcessDEDFrame(TNC); - - TNC->HOSTSTATE = 0; - TNC->InputLen = 0; - } - } - } - - // End of Input - Save buffer position - - TNC->InputLen = (int)(CURSOR - TNC->DEDBuffer); - TNC->RXLen = 0; -} - -static BOOL WriteCommBlock(struct TNCINFO * TNC) -{ - WriteCOMBlock(TNC->hDevice, TNC->TXBuffer, TNC->TXLen); - - if (TNC->WRITELOG) - WriteDebugLogLine(TNC->Port, 'T', TNC->TXBuffer, TNC->TXLen); - - TNC->Timeout = 20; // 2 secs - return TRUE; -} - -static VOID DEDPoll(int Port) -{ - struct TNCINFO * TNC = TNCInfo[Port]; - UCHAR * Poll = TNC->TXBuffer; - int Stream = 0; - int nn; - struct STREAMINFO * STREAM; - - for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (TNC->PortRecord->ATTACHEDSESSIONS[Stream] && TNC->Streams[Stream].Attached == 0) - { - // New Attach. Set call my session callsign - - int calllen=0; - - TNC->Streams[Stream].Attached = TRUE; - - TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4USER[6] |= 0x60; // Ensure P or T aren't used on ax.25 - calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[Stream]->L4USER, TNC->Streams[Stream].MyCall); - TNC->Streams[Stream].MyCall[calllen] = 0; - - if (Stream) //Leave Stream 0 call alone - { - TNC->Streams[Stream].CmdSet = TNC->Streams[Stream].CmdSave = zalloc(100); - sprintf(TNC->Streams[Stream].CmdSet, "%c%c%cI%s", Stream, 1, 1, TNC->Streams[Stream].MyCall); - } - } - } - - if (TNC->Timeout) - { - TNC->Timeout--; - - if (TNC->Timeout) // Still waiting - return; - - // Can't use retries, as we have no way of detecting lost chars. Have to re-init on timeout - - if (TNC->HostMode == 0 || TNC->ReinitState == 10) // 10 is Recovery Mode - { - DoTermModeTimeout(TNC); - return; - } - - // Timed out in host mode - Clear any connection and reinit the TNC - - Debugprintf("DEDHOST - Link to TNC Lost Port %d", TNC->Port); - TNC->TNCOK = FALSE; - - TNC->HostMode = 0; - TNC->ReinitState = 0; - - CloseCOMPort(TNC->hDevice); - OpenCOMMPort(TNC, TNC->PortRecord->PORTCONTROL.SerialPortName, TNC->PortRecord->PORTCONTROL.BAUDRATE, TRUE); - - TNC->InitPtr = TNC->InitScript; - TNC->HOSTSTATE = 0; - - for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (TNC->PortRecord->ATTACHEDSESSIONS[Stream]) // Connected - { - TNC->Streams[Stream].Connected = FALSE; // Back to Command Mode - TNC->Streams[Stream].ReportDISC = TRUE; // Tell Node - } - } - } - - for (Stream = 0; Stream <= MaxStreams; Stream++) - { - STREAM = &TNC->Streams[Stream]; - - if (STREAM->Attached) - CheckForDetach(TNC, Stream, STREAM, TidyClose, ForcedClose, CloseComplete); - - if (TNC->Timeout) - return; // We've sent something - } - - // if we have just restarted or TNC appears to be in terminal mode, run Initialisation Sequence - - if (!TNC->HostMode) - { - DoTNCReinit(TNC); - return; - } - - if (TNC->InitPtr) - { - char * start, * end; - int len; - - start = TNC->InitPtr; - - if (*(start) == 0) // End of Script - { - TNC->InitPtr = NULL; - Debugprintf("TRK - Init Complete Port %d", TNC->Port); - } - else - { - end = strchr(start, 13); - len = (int)(++end - start - 1); // exclude cr - - TNC->InitPtr = end; - - Poll[0] = 0; // Channel - Poll[1] = 1; // Command - Poll[2] = len - 1; - memcpy(&Poll[3], start, len); - - StuffAndSend(TNC, Poll, len + 3); - - return; - - } - } - - for (Stream = 0; Stream <= MaxStreams; Stream++) - { - if (TNC->Streams[Stream].CmdSet) - { - char * start, * end; - int len; - - start = TNC->Streams[Stream].CmdSet; - - if (*(start + 2) == 0) // End of Script - { - free(TNC->Streams[Stream].CmdSave); - TNC->Streams[Stream].CmdSet = NULL; - } - else - { - end = strchr(start + 3, 0); - len = (int)(++end - start - 1); // exclude cr - TNC->Streams[Stream].CmdSet = end; - - memcpy(&Poll[0], start, len); - Poll[2] = len - 4; - - StuffAndSend(TNC, Poll, len); - - return; - } - } - } - - for (nn = 0; nn <= MaxStreams; nn++) - { - Stream = TNC->LastStream++; - - if (TNC->LastStream > MaxStreams) TNC->LastStream = 0; - - if (TNC->TNCOK && TNC->Streams[Stream].BPQtoPACTOR_Q) - { - int datalen; - UINT * buffptr; - char * Buffer; - - buffptr=Q_REM(&TNC->Streams[Stream].BPQtoPACTOR_Q); - - datalen=buffptr[1]; - Buffer = (char *)&buffptr[2]; // Data portion of frame - - Poll[0] = TNC->Streams[Stream].DEDStream; // Channel - - if (TNC->Streams[Stream].Connected) - { - if (TNC->SwallowSignon && Stream == 0) - { - TNC->SwallowSignon = FALSE; - if (strstr(Buffer, "Connected")) // Discard *** connected - { - ReleaseBuffer(buffptr); - return; - } - } - - Poll[1] = 0; // Data - TNC->Streams[Stream].BytesTXed += datalen; - - Poll[2] = datalen - 1; - memcpy(&Poll[3], buffptr+2, datalen); - - ReleaseBuffer(buffptr); - - StuffAndSend(TNC, Poll, datalen + 3); - - TNC->Streams[Stream].InternalCmd = TNC->Streams[Stream].Connected; - - if (STREAM->Disconnecting && TNC->Streams[Stream].BPQtoPACTOR_Q == 0) - TidyClose(TNC, 0); - - return; - } - - // Command. Do some sanity checking and look for things to process locally - - Poll[1] = 1; // Command - datalen--; // Exclude CR - - if (datalen == 0) // Null Command - { - ReleaseBuffer(buffptr); - return; - } - - Buffer[datalen] = 0; // Null Terminate - _strupr(Buffer); - - if (_memicmp(Buffer, "D", 1) == 0) - { - TNC->Streams[Stream].ReportDISC = TRUE; // Tell Node - ReleaseBuffer(buffptr); - return; - } - - if (Buffer[0] == 'C' && datalen > 2) // Connect - { - if (Stream == 0) - { - // No connects on Stream zero - for mgmt only - - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "TRK} Can't Connect after ATTACH\r"); - C_Q_ADD(&TNC->Streams[0].PACTORtoBPQ_Q, buffptr); - - return; - - } - - if (*(++Buffer) == ' ') Buffer++; // Space isn't needed - - memcpy(TNC->Streams[Stream].RemoteCall, Buffer, 9); - - TNC->Streams[Stream].Connecting = TRUE; - - TNC->Streams[Stream].CmdSet = TNC->Streams[Stream].CmdSave = zalloc(100); - - sprintf(TNC->Streams[Stream].CmdSet, "%c%c%cI%s%c%c%c%c%s", Stream, 1, 1, - TNC->Streams[Stream].MyCall, 0, Stream, 1, 1, (char *)buffptr+8); - - ReleaseBuffer(buffptr); - - TNC->Streams[Stream].InternalCmd = FALSE; - return; - } - - Poll[2] = datalen - 1; - memcpy(&Poll[3], buffptr+2, datalen); - - ReleaseBuffer(buffptr); - - StuffAndSend(TNC, Poll, datalen + 3); - - TNC->Streams[Stream].InternalCmd = TNC->Streams[Stream].Connected; - - return; - } - } - - if (TNC->TNCOK && TNC->PortRecord->UI_Q) - { - int datalen; - char * Buffer; - char CCMD[80] = "C"; - char Call[12] = " "; - struct _MESSAGE * buffptr; - - buffptr = Q_REM(&TNC->PortRecord->UI_Q); - - datalen = buffptr->LENGTH - 7; - Buffer = &buffptr->DEST[0]; // Raw Frame - Buffer[datalen] = 0; - - TNC->Streams[0].CmdSet = TNC->Streams[0].CmdSave = zalloc(500); - -// sprintf(TNC->Streams[Stream].CmdSet, "I%s\r%s\r", TNC->Streams[Stream].MyCall, buffptr+2); - - // Buffer has an ax.25 header, which we need to pick out and set as channel 0 Connect address - // before sending the beacon - - ConvFromAX25(Buffer, &Call[1]); // Dest - strlop(&Call[1], ' '); - strcat(CCMD, Call); - Buffer += 14; // Skip Origin - datalen -= 7; - - while ((Buffer[-1] & 1) == 0) - { - ConvFromAX25(Buffer, &Call[1]); - strlop(&Call[1], ' '); - strcat(CCMD, Call); - Buffer += 7; // End of addr - datalen -= 7; - } - - if (Buffer[0] == 3) // UI - { - Buffer += 2; - datalen -= 2; - - Poll[0] = 0; // UI Channel - Poll[1] = 1; // Data - Poll[2] = (int)strlen(CCMD) - 1; - strcpy(&Poll[3], CCMD); - StuffAndSend(TNC, Poll, Poll[2] + 4); - - sprintf(TNC->Streams[0].CmdSet, "%c%c%c%s", 0, 0, 1, Buffer); - } - - ReleaseBuffer((UINT *)buffptr); - return; - } - - // if frames outstanding, issue a poll (but not too often) - - TNC->IntCmdDelay++; - - if (TNC->IntCmdDelay > 10) - { - TNC->IntCmdDelay = 0; - - Poll[0] = TNC->Streams[0].DEDStream; - Poll[1] = 0x1; // Command - TNC->Streams[0].InternalCmd = TRUE; - - Poll[2] = 1; // Len-1 - Poll[3] = '@'; - Poll[4] = 'B'; // Buffers - StuffAndSend(TNC, Poll, 5); - return; - } - - // Need to poll all channels . Just Poll zero here, the ProcessMessage will poll next - - Poll[0] = 0; // Channel - Poll[1] = 0x1; // Command - Poll[2] = 0; // Len-1 - Poll[3] = 'G'; // Poll - - StuffAndSend(TNC, Poll, 4); - - return; - - - Stream = TNC->StreamtoPoll; - - STREAM = &TNC->Streams[Stream]; - - STREAM->IntCmdDelay++; - - if (STREAM->IntCmdDelay > 10) - { - STREAM->IntCmdDelay = 0; - - if (STREAM->FramesOutstanding) - { - Poll[0] = STREAM->DEDStream; - Poll[1] = 0x1; // Command - STREAM->InternalCmd = TRUE; - - Poll[2] = 0; // Len-1 - Poll[3] = 'L'; // Status - StuffAndSend(TNC, Poll, 4); - - return; - } - } - - - Poll[0] = Stream; // Channel - Poll[1] = 0x1; // Command - Poll[2] = 0; // Len-1 - Poll[3] = 'G'; // Poll - - StuffAndSend(TNC, Poll, 4); - STREAM->InternalCmd = FALSE; - - return; - -} - -static VOID DoTNCReinit(struct TNCINFO * TNC) -{ - UCHAR * Poll = TNC->TXBuffer; - - if (TNC->ReinitState == 0) - { - // Just Starting - Send a TNC Mode Command to see if in Terminal or Host Mode - - TNC->TNCOK = FALSE; - - memcpy(&TNC->TXBuffer[0], "\x18\x1b\r", 2); - TNC->TXLen = 2; - - if (WriteCommBlock(TNC) == FALSE) - { - CloseCOMPort(TNC->hDevice); - OpenCOMMPort(TNC, TNC->PortRecord->PORTCONTROL.SerialPortName, TNC->PortRecord->PORTCONTROL.BAUDRATE, TRUE); - } - - return; - } - - if (TNC->ReinitState == 1) // Forcing back to Term - TNC->ReinitState = 0; - - if (TNC->ReinitState == 2) // In Term State, Sending Initialisation Commands - { - // Put into Host Mode - - memcpy(Poll, "\x18\x1bJHOST1\r", 9); - - TNC->TXLen = 9; - WriteCommBlock(TNC); - - TNC->ReinitState = 5; - return; - } - - if (TNC->ReinitState == 5) - TNC->ReinitState = 0; - -} - -static VOID DoTermModeTimeout(struct TNCINFO * TNC) -{ - UCHAR * Poll = TNC->TXBuffer; - - if (TNC->ReinitState == 0) - { - //Checking if in Terminal Mode - Try to set back to Term Mode - - TNC->ReinitState = 1; - ExitHost(TNC); - - return; - } - - if (TNC->ReinitState == 1) - { - // No Response to trying to enter term mode - do error recovery - - Debugprintf("TRK - Starting Resync Port %d", TNC->Port); - - TNC->ReinitState = 10; - TNC->ReinitCount = 256; - TNC->HostMode = TRUE; // Must be in Host Mode if we need recovery - - Poll[0] = 1; - TNC->TXLen = 1; - WriteCommBlock(TNC); - TNC->Timeout = 10; // 2 secs - - return; - } - - if (TNC->ReinitState == 10) - { - // Continue error recovery - - TNC->ReinitCount--; - - if (TNC->ReinitCount) - { - Poll[0] = 1; - TNC->TXLen = 1; - WriteCommBlock(TNC); - TNC->Timeout = 3; // 0.3 secs - - return; - } - - // Try Again - - Debugprintf("TRK Continuing recovery Port %d", TNC->Port); - - TNC->ReinitState = 0; - - // Close and re-open TNC - - ExitHost(TNC); - Sleep(50); - CloseCOMPort(TNC->hDevice); - TNC->hDevice =(HANDLE) 0; - TNC->ReopenTimer = 290; - TNC->HostMode = FALSE; - - return; - } - if (TNC->ReinitState == 3) - { - // Entering Host Mode - - // Assume ok - - TNC->HostMode = TRUE; - TNC->IntCmdDelay = 10; - - return; - } -} - - -static VOID ExitHost(struct TNCINFO * TNC) -{ - UCHAR * Poll = TNC->TXBuffer; - - // Try to exit Host Mode - - TNC->TXBuffer[0] = 1; - TNC->TXBuffer[1] = 1; - TNC->TXBuffer[2] = 1; - memcpy(&TNC->TXBuffer[3], "%R", 2); - - StuffAndSend(TNC, Poll, 5); - - return; -} - -static VOID ProcessTermModeResponse(struct TNCINFO * TNC) -{ - UCHAR * Poll = TNC->TXBuffer; - - if (TNC->WRITELOG) - WriteDebugLogLine(TNC->Port, 'R', TNC->RXBuffer, TNC->RXLen); - - if (TNC->ReinitState == 0) - { - // Testing if in Term Mode. It is, so can now send Init Commands - - TNC->InitPtr = TNC->InitScript; - TNC->ReinitState = 2; - } - - if (TNC->ReinitState == 1) - { - // trying to set term mode - - // If already in Term Mode, TNC echos command, with control chars replaced with '.' - - if (memcmp(TNC->RXBuffer, "....%R", 6) == 0) - { - // In term mode, Need to put into Host Mode - - TNC->ReinitState = 2; - DoTNCReinit(TNC); - return; - } - } - - if (TNC->ReinitState == 2) - { - // Sending Init Commands - - DoTNCReinit(TNC); // Send Next Command - return; - } - - if (TNC->ReinitState == 5) // Waiting for response to JHOST1 - { - if (TNC->RXBuffer[TNC->RXLen-1] == 10 || TNC->RXBuffer[TNC->RXLen-1] == 13) // NewLine - { - TNC->HostMode = TRUE; - TNC->Timeout = 0; - } - return; - } -} - -static VOID ProcessDEDFrame(struct TNCINFO * TNC) -{ - UINT * buffptr; - char * Buffer; // Data portion of frame - UINT Stream = 0; - UCHAR * Msg = TNC->DEDBuffer; - int framelen = TNC->InputLen; - struct STREAMINFO * STREAM; - - if (TNC->WRITELOG) - WriteDebugLogLine(TNC->Port, 'R', Msg, framelen); - - if (TNC->ReinitState == 10) - { - // Recovering from Sync Failure - - // Any Response indicates we are in host mode, and back in sync - - TNC->HostMode = TRUE; - TNC->Timeout = 0; - TNC->ReinitState = 0; - TNC->RXLen = 0; - TNC->HOSTSTATE = 0; - return; - } - - // Any valid frame is an ACK - - TNC->Timeout = 0; - TNC->TNCOK = TRUE; - - if (TNC->InitPtr) // Response to Init Script - return; - - if (TNC->MSGCHANNEL > 26) - return; - - Stream = TNC->MSGCHANNEL; - - // See if Poll Reply or Data - - if (TNC->MSGTYPE == 0) - { - // Success - Nothing Follows - - if (TNC->Streams[Stream].CmdSet) - return; // Response to Command Set or Init Script - - if ((TNC->TXBuffer[1] & 1) == 0) // Data - return; - - // If the response to a Command, then we should convert to a text "Ok" for forward scripts, etc - - if (TNC->TXBuffer[3] == 'G') // Poll - { - UCHAR * Poll = TNC->TXBuffer; - - // Poll Next Channel (we need to scan all channels every DEDPOLL cycle - - Stream++; - - if (Stream > MaxStreams) - return; - - STREAM = &TNC->Streams[Stream]; - - STREAM->IntCmdDelay++; - - if (STREAM->IntCmdDelay > 10) - { - STREAM->IntCmdDelay = 0; - - if (STREAM->FramesOutstanding) - { - Poll[0] = STREAM->DEDStream; - Poll[1] = 0x1; // Command - STREAM->InternalCmd = TRUE; - - Poll[2] = 0; // Len-1 - Poll[3] = 'L'; // Status - StuffAndSend(TNC, Poll, 4); - return; - } - } - - Poll[0] = Stream; // Channel - Poll[1] = 0x1; // Command - Poll[2] = 0; // Len-1 - Poll[3] = 'G'; // Poll - - StuffAndSend(TNC, Poll, 4); - STREAM->InternalCmd = FALSE; - - return; - } - - if (TNC->TXBuffer[3] == 'C') // Connect - reply we need is async - return; - - if (TNC->TXBuffer[3] == 'L') // Shouldnt happen! - return; - - - if (TNC->TXBuffer[3] == 'J') // JHOST - { - if (TNC->TXBuffer[8] == '0') // JHOST0 - { - TNC->Timeout = 1; // - return; - } - } - - if (TNC->MSGCHANNEL == 0) // Unproto Channel - return; - - buffptr = GetBuff(); - - if (buffptr == NULL) return; // No buffers, so ignore - - buffptr[1] = sprintf((UCHAR *)&buffptr[2],"TRK} Ok\r"); - - C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); - - return; - } - - if (TNC->MSGTYPE > 0 &&TNC->MSGTYPE < 6) - { - // Success with message - null terminated - - char * ptr; - int len; - - Buffer = Msg; - - ptr = strchr(Buffer, 0); - - if (ptr == 0) - return; - - *(ptr++) = 13; - *(ptr) = 0; - - len = (int)(ptr - Buffer); - - if (len > 256) - return; - - // See if we need to process locally (Response to our command, Incoming Call, Disconencted, etc - - if (TNC->MSGTYPE < 3) // 1 or 2 - Success or Fail - { - // See if a response to internal command - - if (TNC->Streams[Stream].InternalCmd) - { - // Process it - - char LastCmd = TNC->TXBuffer[3]; - - if (LastCmd == 'L') // Status - { - int s1, s2, s3, s4, s5, s6, num; - - num = sscanf(Buffer, "%d %d %d %d %d %d", &s1, &s2, &s3, &s4, &s5, &s6); - - TNC->Streams[Stream].FramesOutstanding = s3; - return; - } - - if (LastCmd == '@') // @ Commands - { - if (TNC->TXBuffer[4]== 'B') // Buffer Status - { - TNC->Buffers = atoi(Buffer); -// SetDlgItemText(TNC->hDlg, IDC_BUFFERS, Buffer); - return; - } - } - - return; - } - - // Not Internal Command, so send to user - - if (TNC->Streams[Stream].CmdSet) - return; // Response to Command Set - - if ((TNC->TXBuffer[1] & 1) == 0) // Data - return; - - // If the response to a Command, then we should convert to a text "Ok" for forward scripts, etc - - if (TNC->TXBuffer[3] == 'G') // Poll - return; - - if (TNC->TXBuffer[3] == 'C') // Connect - reply we need is async - return; - - if (TNC->TXBuffer[3] == 'L') // Shouldnt happen! - return; - - if (TNC->TXBuffer[3] == 'J') // JHOST - { - if (TNC->TXBuffer[8] == '0') // JHOST0 - { - TNC->Timeout = 1; // - return; - } - } - - if (TNC->MSGCHANNEL == 0) // Unproto Channel - return; - - buffptr = GetBuff(); - - if (buffptr == NULL) return; // No buffers, so ignore - - buffptr[1] = sprintf((UCHAR *)&buffptr[2],"TRK} %s", Buffer); - - C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); - - return; - } - - if (TNC->MSGTYPE == 3) // Status - { - struct STREAMINFO * STREAM = &TNC->Streams[Stream]; - - if (strstr(Buffer, "DISCONNECTED") || strstr(Buffer, "LINK FAILURE") || strstr(Buffer, "BUSY")) - { - if ((STREAM->Connecting | STREAM->Connected) == 0) - return; - - if (STREAM->Connecting && STREAM->Disconnecting == FALSE) - { - // Connect Failed - - buffptr = GetBuff(); - if (buffptr == 0) return; // No buffers, so ignore - - if (strstr(Buffer, "BUSY")) - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "*** Busy from %s\r", TNC->Streams[Stream].RemoteCall); - else - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "*** Failure with %s\r", TNC->Streams[Stream].RemoteCall); - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - STREAM->Connecting = FALSE; - STREAM->Connected = FALSE; // In case! - STREAM->FramesOutstanding = 0; - - STREAM->DiscWhenAllSent = 15; // Dont want to leave session attached. Causes too much confusion - - return; - } - - // Must Have been connected or disconnecting - Release Session - - STREAM->Connecting = FALSE; - STREAM->Connected = FALSE; // Back to Command Mode - STREAM->FramesOutstanding = 0; - - if (STREAM->Disconnecting == FALSE) - STREAM->ReportDISC = TRUE; // Tell Node - - STREAM->Disconnecting = FALSE; - return; - } - - if (strstr(Buffer, "CONNECTED")) - { - char * Call = strstr(Buffer, " to "); - char * ptr; - char MHCall[30]; - - Call += 4; - - if (Call[1] == ':') - Call +=2; - - ptr = strchr(Call, ' '); - if (ptr) *ptr = 0; - - ptr = strchr(Call, 13); - if (ptr) *ptr = 0; - - STREAM->Connected = TRUE; // Subsequent data to data channel - STREAM->Connecting = FALSE; - - STREAM->BytesRXed = STREAM->BytesTXed = 0; - - memcpy(MHCall, Call, 9); - MHCall[9] = 0; - - if (TNC->PortRecord->ATTACHEDSESSIONS[Stream] == 0) - { - // Incoming Connect - -// APPLCALLS * APPL; -// char * ApplPtr = &APPLS; -// int App; -// char Appl[10]; -// char DestCall[10]; - - UpdateMH(TNC, MHCall, '+', 'I'); - - ProcessIncommingConnect(TNC, Call, Stream, TRUE); - - if (FULL_CTEXT && HFCTEXTLEN == 0) - { - int Len = CTEXTLEN, CTPaclen = 100; - int Next = 0; - - while (Len > CTPaclen) // CTEXT Paclen - { - buffptr = GetBuff(); - if (buffptr == 0) return; // No buffers, so ignore - - buffptr[1] = CTPaclen; - memcpy(&buffptr[2], &CTEXTMSG[Next], CTPaclen); - C_Q_ADD(&STREAM->BPQtoPACTOR_Q, buffptr); - - Next += CTPaclen; - Len -= CTPaclen; - } - - buffptr = GetBuff(); - if (buffptr == 0) return; // No buffers, so ignore - - buffptr[1] = Len; - memcpy(&buffptr[2], &CTEXTMSG[Next], Len); - C_Q_ADD(&STREAM->BPQtoPACTOR_Q, buffptr); - } - - return; - } - else - { - // Connect Complete - - buffptr = GetBuff(); - if (buffptr == 0) return; // No buffers, so ignore - - buffptr[1] = sprintf((UCHAR *)&buffptr[2], "*** Connected to %s\r", Call);; - - C_Q_ADD(&STREAM->PACTORtoBPQ_Q, buffptr); - - } - } - return; - } - - if (TNC->MSGTYPE == 4 || TNC->MSGTYPE == 5) - { - struct STREAMINFO * STREAM = &TNC->Streams[0]; // RP Stream - - // Monitor - -/* - if (TNC->UseAPPLCalls && strstr(&Msg[4], "SABM") && STREAM->Attached == FALSE) - { - // See if a call to Nodecall or one of our APPLCALLS - if so, stop scan and switch MYCALL - - char DestCall[10] = "NOCALL "; - char * ptr1 = strstr(&Msg[7], "to "); - int i; - APPLCALLS * APPL; - char Appl[11]; - char Status[80]; - - if (ptr1) memcpy(DestCall, &ptr1[3], 10); - - ptr1 = strchr(DestCall, ' '); - if (ptr1) *(ptr1) = 0; // Null Terminate - - Debugprintf("RP SABM Received for %s" , DestCall); - - if (strcmp(TNC->NodeCall, DestCall) != 0) - { - // Not Calling NodeCall/Portcall - - if (strcmp(NodeCall, DestCall) == 0) - goto SetThisCall; - - // See if to one of our ApplCalls - - for (i = 0; i < 32; i++) - { - APPL=&APPLCALLTABLE[i]; - - if (APPL->APPLCALL_TEXT[0] > ' ') - { - char * ptr; - memcpy(Appl, APPL->APPLCALL_TEXT, 10); - ptr=strchr(Appl, ' '); - - if (ptr) *ptr = 0; - - if (strcmp(Appl, DestCall) == 0) - { - SetThisCall: - Debugprintf("RP SABM is for NODECALL or one of our APPLCalls - setting MYCALL to %s and pausing scan", DestCall); - - sprintf(Status, "%d SCANSTART 60", TNC->Port); // Pause scan for 60 secs - Rig_Command(-1, Status); - TNC->SwitchToPactor = 600; // Don't change modes for 60 secs - - strcpy(STREAM->MyCall, DestCall); - STREAM->CmdSet = STREAM->CmdSave = zalloc(100); - sprintf(STREAM->CmdSet, "I%s\r", DestCall); - break; - } - } - } - } - } -*/ - DoMonitorHddr(TNC, Msg, framelen, TNC->MSGTYPE); - return; - - } - - // 1, 2, 4, 5 - pass to Appl - - if (TNC->MSGCHANNEL == 0) // Unproto Channel - return; - - buffptr = GetBuff(); - - if (buffptr == NULL) return; // No buffers, so ignore - - buffptr[1] = sprintf((UCHAR *)&buffptr[2],"Trk} %s", &Msg[4]); - - C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); - - return; - } - - if (TNC->MSGTYPE == 6) - { - // Monitor Data With length) - - DoMonitorData(TNC, Msg, framelen); - return; - } - - if (TNC->MSGTYPE == 7) - { - //char StatusMsg[60]; - //int Status, ISS, Offset; - - // Connected Data - - buffptr = GetBuff(); - - if (buffptr == NULL) return; // No buffers, so ignore - - buffptr[1] = framelen; // Length - TNC->Streams[Stream].BytesRXed += buffptr[1]; - memcpy(&buffptr[2], Msg, buffptr[1]); - - C_Q_ADD(&TNC->Streams[Stream].PACTORtoBPQ_Q, buffptr); - - return; - } -} - -VOID TidyClose(struct TNCINFO * TNC, int Stream) -{ - // Queue it as we may have just sent data - - TNC->Streams[Stream].CmdSet = TNC->Streams[Stream].CmdSave = zalloc(100); - sprintf(TNC->Streams[Stream].CmdSet, "%c%c%cD", Stream, 1, 1); -} - - -VOID ForcedClose(struct TNCINFO * TNC, int Stream) -{ - TidyClose(TNC, Stream); // I don't think Hostmode has a DD -} - -VOID CloseComplete(struct TNCINFO * TNC, int Stream) -{ -} - - diff --git a/SerialPort.c b/SerialPort.c index 2df4ed6..d3b045b 100644 --- a/SerialPort.c +++ b/SerialPort.c @@ -508,9 +508,12 @@ ok: if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; - if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, cnd); + + if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { } else diff --git a/TelnetV6.c b/TelnetV6.c index 287118b..62b0885 100644 --- a/TelnetV6.c +++ b/TelnetV6.c @@ -4501,7 +4501,7 @@ MsgLoop: WritetoTrace(Stream, MsgPtr, InputLen, sockptr->ADIF, 'R'); } - if (InputLen == 8 && memcmp(MsgPtr, ";;;\r\n", 8) == 0) + if (InputLen == 8 && memcmp(MsgPtr, ";;;;;;\r\n", 8) == 0) { // CMS Keepalive @@ -5146,7 +5146,13 @@ int DataSocket_ReadHTTP(struct TNCINFO * TNC, struct ConnectionInfo * sockptr, S } } else + { Debugprintf("WebSock Opcode %d Msg %s", Opcode, &MsgPtr[6]); + closesocket(sockptr->socket); + sockptr->SocketActive = FALSE; + ShowConnections(TNC); + } + sockptr->InputLen = 0; return 0; @@ -5467,8 +5473,7 @@ int WriteLog(char * msg) strcat(Value, "logs/Telnet_"); } - sprintf(Value, "%s%02d%02d%02d.log", Value, - tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); + sprintf(&Value[strlen(Value)], "%02d%02d%02d.log", tm->tm_year - 100, tm->tm_mon+1, tm->tm_mday); if ((file = fopen(Value, "a")) == NULL) return FALSE; @@ -5523,8 +5528,7 @@ VOID WriteCMSLog(char * msg) strcat(Value, "logs/CMSAccess"); } - sprintf(Value, "%s_%04d%02d%02d.log", Value, - tm->tm_year +1900, tm->tm_mon+1, tm->tm_mday); + sprintf(&Value[strlen(Value)], "_%04d%02d%02d.log", tm->tm_year +1900, tm->tm_mon+1, tm->tm_mday); Handle = fopen(Value, "ab"); diff --git a/UZ7HODrv.c b/UZ7HODrv.c index 3288510..8c36e2b 100644 --- a/UZ7HODrv.c +++ b/UZ7HODrv.c @@ -1023,8 +1023,12 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, cmd); + + if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { } diff --git a/V4.c b/V4.c index 54d5e5d..d9815af 100644 --- a/V4.c +++ b/V4.c @@ -622,7 +622,10 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) if (_memicmp(buff->L2DATA, "RADIO ", 6) == 0) { - sprintf(buff->L2DATA, "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + + strcpy(cmd, &buff->L2DATA[6]); + sprintf(buff->L2DATA, "%d %s", TNC->Port, cmd); if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, buff->L2DATA)) { diff --git a/Versions.h b/Versions.h index 6098cd4..bf6fb8a 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,24,65 -#define KVerstring "6.0.24.65\0" +#define KVers 6,0,24,66 +#define KVerstring "6.0.24.66\0" #ifdef CKernel diff --git a/WINMOR.c b/WINMOR.c index 5faf722..f0f9d98 100644 --- a/WINMOR.c +++ b/WINMOR.c @@ -984,8 +984,12 @@ static size_t ExtProc(int fn, int port, PDATAMESSAGE buff) if (_memicmp(&buff->L2DATA[0], "RADIO ", 6) == 0) { - sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &buff->L2DATA[6]); + char cmd[56]; + strcpy(cmd, &buff->L2DATA[6]); + sprintf(&buff->L2DATA[0], "%d %s", TNC->Port, &cmd); + + if (Rig_Command(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4CROSSLINK, &buff->L2DATA[0])) { } diff --git a/WebMail.c b/WebMail.c index a21bf7f..a3ff5b1 100644 --- a/WebMail.c +++ b/WebMail.c @@ -2293,6 +2293,7 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL struct HtmlFormDir * Dir; int i; + int len; SubDir = strlop(&NodeURL[17], ':'); DirNo = atoi(&NodeURL[17]); @@ -2313,9 +2314,9 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL Dir = HtmlFormDirs[DirNo]; if (SubDir) - sprintf(popup, popuphddr, Key, Dir->Dirs[SubDirNo]->DirName); + len = sprintf(popup, popuphddr, Key, Dir->Dirs[SubDirNo]->DirName); else - sprintf(popup, popuphddr, Key, Dir->DirName); + len = sprintf(popup, popuphddr, Key, Dir->DirName); if (SubDir) { @@ -2326,7 +2327,7 @@ void ProcessWebMailMessage(struct HTTPConnectionInfo * Session, char * Key, BOOL // We only send if there is a .txt file if (_stricmp(&Name[strlen(Name) - 4], ".txt") == 0) - sprintf(popup, "%s