From b2315840b26a7ae5c38b0f9ed25e597f320c545e Mon Sep 17 00:00:00 2001 From: Dave Hibberd Date: Mon, 14 Jul 2025 23:14:11 +0100 Subject: [PATCH] New upstream version 6.0.24.75+repack --- AGWAPI.c | 60 +++++++++++++++------- AGWMoncode.c | 92 ++++++++++++++++++++++++++++++++- ARDOP.c | 35 ++++++++----- BBSUtilities.c | 58 +++++++++++++++++++-- BPQINP3.c | 3 ++ BPQMail.c | 4 ++ Bpq32.c | 9 ++++ ChatHTMLConfig.c | 4 +- CommonCode.c | 11 +++- KAMPactor.c | 123 +++++++++++++++++++++++++++++++++++++++----- L2Code.c | 6 ++- L3Code.c | 29 +---------- MHSave.txt | 0 TelnetV6.c | 129 ++++++++++++++++++++++++++++------------------- Versions.h | 6 +-- WebMail.c | 36 +++++++++++++ asmstrucs.h | 4 ++ bpq32.h | 2 + bpqaxip.c | 48 ++++++++++++------ cMain.c | 3 ++ cheaders.h | 7 +-- config.c | 9 ++-- configstructs.h | 1 + 23 files changed, 522 insertions(+), 157 deletions(-) delete mode 100644 MHSave.txt diff --git a/AGWAPI.c b/AGWAPI.c index dcf3494..126a72a 100644 --- a/AGWAPI.c +++ b/AGWAPI.c @@ -36,7 +36,8 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses struct AGWHeader { - unsigned int Port; + uint8_t Port; + uint8_t filler1[3]; unsigned char DataKind; unsigned char filler2; unsigned char PID; @@ -128,7 +129,7 @@ int DataSocket_Write(struct AGWSocketConnectionInfo * sockptr, SOCKET sock); int AGWGetSessionKey(char * key, struct AGWSocketConnectionInfo * sockptr); int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr); int SendDataToAppl(int Stream, byte * Buffer, int Length); -int InternalAGWDecodeFrame(char * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int doNodes); +int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * FrameType, int useLocalTime, int doNodes); int AGWDataSocket_Disconnect( struct AGWSocketConnectionInfo * sockptr); int SendRawPacket(struct AGWSocketConnectionInfo * sockptr, char *txmsg, int Length); int ShowApps(); @@ -720,7 +721,7 @@ int AGWDoMonitorData() RawLen = monbuff->LENGTH; - if (RawLen < 7 || RawLen > 350) + if (RawLen < MSGHDDRLEN || RawLen > 350) { ReleaseBuffer(monbuff); FreeSemaphore(&Semaphore); @@ -734,12 +735,16 @@ int AGWDoMonitorData() ReleaseBuffer(monbuff); FreeSemaphore(&Semaphore); + + // Set monbuff to point to the copy + + monbuff = (MESSAGE *)Buffer; //' 4 byte chain //' 1 byte port - top bit = transmit //' 2 byte length (LO-HI) - Port = Buffer[4]; + Port = monbuff->PORT; if (Port > 127) { @@ -751,6 +756,12 @@ int AGWDoMonitorData() RXFlag = TRUE; } + if (Port == 0) + { + Debugprintf("AGWMON Port number is zero"); + return 0; + } + // Can now have different mon flags per connection, so need to run decode for each socket for (n = 1; n<= CurrentSockets; n++) @@ -759,7 +770,7 @@ int AGWDoMonitorData() if (sockptr->SocketActive && sockptr->MonFlag && (RXFlag || LoopMonFlag)) { - Length = InternalAGWDecodeFrame(Buffer, AGWBuffer, Stamp, &Frametype, sockptr->useLocalTime, sockptr->doNodes); + Length = InternalAGWDecodeFrame(monbuff, AGWBuffer, Stamp, &Frametype, sockptr->useLocalTime, sockptr->doNodes); if (Length > 0) { @@ -803,7 +814,7 @@ int AGWDoMonitorData() } } - RawLen = RawLen - 6; + RawLen = RawLen - (MSGHDDRLEN - 1); // One more for KISS control if (RXFlag || Loopflag) // Send transmitted frames if requested { @@ -811,8 +822,12 @@ int AGWDoMonitorData() // // Send raw data to any sockets that have requested Raw frames // - - Buffer[6]=0; + + // Format is ax.25 packet prceeded by a KISS command byte 00 for channel 1 0x10 for channel 2 etc + // As this is an application API I think all should go as Port 1 + + + Buffer[MSGHDDRLEN - 1] = 0; // Just in case big-endian AGWTXHeader.Port = Port - 1; // AGW Ports start from 0 AGWTXHeader.DataKind = 'K'; @@ -824,14 +839,12 @@ int AGWDoMonitorData() sockptr=&Sockets[n]; if (sockptr->SocketActive && sockptr->RawFlag) - SendRawPacket(sockptr, &Buffer[6], RawLen); + SendRawPacket(sockptr, &Buffer[MSGHDDRLEN - 1], RawLen); } } } - - return 0; - + return 0; } int DeleteConnection(struct BPQConnectionInfo * Con) @@ -1128,6 +1141,7 @@ int AGWDataSocket_Read(struct AGWSocketConnectionInfo * sockptr, SOCKET sock) int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) { int AGWVersion[2]={2003,999}; + byte AGWPortCaps[12] = { 0, 255, 30, 10, 63, 10, 4, 0, 1, 0, 0, 0 }; char AGWRegReply[1]; struct BPQConnectionInfo * Connection; int Stream; @@ -1195,7 +1209,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) // Need to convert port index (used by AGW) to port number - conport=GetPortNumber(VisiblePortToRealPort[key[0]-48]); + conport=GetPortNumber(VisiblePortToRealPort[key[0]-49] + 1); n = sprintf(ConnectMsg,"C %d %s",conport,ToCall); @@ -1293,9 +1307,7 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) // Version memset(&AGWTXHeader,0,36); - AGWTXHeader.DataKind = 'R'; - AGWTXHeader.DataLength = 8; // Length SendtoSocket(sockptr->socket, (char *)&AGWVersion[0]); @@ -1309,15 +1321,27 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) memset(&AGWTXHeader,0,36); - AGWTXHeader.DataKind = 'G'; - AGWTXHeader.DataLength =(int)strlen(AGWPorts)+1; // Length SendtoSocket(sockptr->socket, AGWPorts); return 0; + + case 'g': + + // Port capabilities. Currently hard-coded. + + AGWTXHeader.Port = sockptr->AGWRXHeader.Port; + AGWTXHeader.DataKind = 'g'; + AGWTXHeader.DataLength = 12; + + SendtoSocket(sockptr->socket, (char *)&AGWPortCaps[0]); + + return 0; + + case 'k': @@ -1416,6 +1440,8 @@ int ProcessAGWCommand(struct AGWSocketConnectionInfo * sockptr) AGWTXHeader.DataKind = 'X'; + memcpy(&AGWTXHeader.callfrom, RegCall, 10); + AGWTXHeader.DataLength = 1; // Length AGWRegReply[0] = 1; diff --git a/AGWMoncode.c b/AGWMoncode.c index 7427804..2c26191 100644 --- a/AGWMoncode.c +++ b/AGWMoncode.c @@ -49,9 +49,14 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #define DM 0x0F #define UA 0x63 #define FRMR 0x87 +#define XID 0xAF +#define TEST 0xE3 #define RR 1 #define RNR 5 #define REJ 9 +#define SREJ 0x0D +#define SABME 0x6F + #define PFBIT 0x10 // POLL/FINAL BIT IN CONTROL BYTE @@ -261,6 +266,18 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra strcpy(SUP, "FRMR"); FRMRFLAG = 1; break; + + case XID: + + strcpy(SUP, "XID"); + XIDFLAG = 1; + break; + + case TEST: + + strcpy(SUP, "TEST"); + TESTFLAG = 1; + break; } Output += sprintf((char *)Output, "<%s%s%s>", SUP, CRCHAR, PFCHAR); @@ -270,7 +287,7 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra // Super int NR = (CTL >> 5) & 7; - char SUP[4] = "??"; + char SUP[5] = "??"; switch (CTL & 0x0F) { @@ -288,6 +305,13 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra strcpy(SUP, "REJ"); break; + + + case SREJ: + + strcpy(SUP, "SREJ"); + break; + } Output += sprintf((char *)Output, "<%s%s%s R%d>", SUP, CRCHAR, PFCHAR, NR); @@ -300,6 +324,72 @@ int InternalAGWDecodeFrame(MESSAGE * msg, char * buffer, time_t Stamp, int * Fra if (FRMRFLAG) Output += sprintf((char *)Output, "%02X %02X %02X", ADJBUFFER->PID, ADJBUFFER->L2DATA[0], ADJBUFFER->L2DATA[1]); + if (XIDFLAG) + { + // Decode and display XID + + UCHAR * ptr = &ADJBUFFER->PID; + + if (*ptr++ == 0x82 && *ptr++ == 0x80) + { + int Type; + int Len; + unsigned int value; + int xidlen = *(ptr++) << 8; + xidlen += *ptr++; + + // XID is set of Type, Len, Value n-tuples + +// G8BPQ-2>G8BPQ:(XID cmd, p=1) Half-Duplex SREJ modulo-128 I-Field-Length-Rx=256 Window-Size-Rx=32 Ack-Timer=3000 Retries=10 + + + while (xidlen > 0) + { + Type = *ptr++; + Len = *ptr++; + + value = 0; + xidlen -= (Len + 2); + + while (Len--) + { + value <<=8; + value += *ptr++; + } + switch(Type) + { + case 2: //Bin fields + case 3: + + Output += sprintf((char *)Output, " %d=%x", Type, value); + break; + + case 6: //RX Size + + Output += sprintf((char *)Output, " RX Paclen=%d", value / 8); + break; + + case 8: //RX Window + + Output += sprintf((char *)Output, " RX Window=%d", value); + break; + + case 16: + + Output += sprintf((char *)Output, " Can Compress"); + break; + + case 17: + + Output += sprintf((char *)Output, " Compress ok"); + break; + } + } + } + } + + + if (Info) { // We have an info frame diff --git a/ARDOP.c b/ARDOP.c index 8230039..ade0ecf 100644 --- a/ARDOP.c +++ b/ARDOP.c @@ -2061,21 +2061,12 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry) strcat(TempScript, "ARQTIMEOUT 90\r"); // strcat(TempScript, "ROBUST False\r"); - strcat(TempScript, TNC->InitScript); - - free(TNC->InitScript); - TNC->InitScript = TempScript; - - // Set MYCALL - -// strcat(TNC->InitScript,"FECRCV True\r"); -// strcat(TNC->InitScript,"AUTOBREAK True\r"); + // Make MYAUX and MYCALL overridable + sprintf(Msg, "MYCALL %s\r", TNC->NodeCall); - strcat(TNC->InitScript, Msg); -// strcat(TNC->InitScript,"PROCESSID\r"); -// strcat(TNC->InitScript,"CODEC TRUE\r"); -// strcat(TNC->InitScript,"LISTEN TRUE\r"); + strcat(TempScript, Msg); + for (i = 0; i < 32; i++) { @@ -2099,9 +2090,25 @@ VOID * ARDOPExtInit(EXTPORTDATA * PortEntry) if (strlen(Aux) > 8) { Aux[strlen(Aux) - 1] = '\r'; - strcat(TNC->InitScript, Aux); + strcat(TempScript, Aux); } + + strcat(TempScript, TNC->InitScript); + + free(TNC->InitScript); + TNC->InitScript = TempScript; + + + +// strcat(TNC->InitScript,"FECRCV True\r"); +// strcat(TNC->InitScript,"AUTOBREAK True\r"); +// strcat(TNC->InitScript,"PROCESSID\r"); +// strcat(TNC->InitScript,"CODEC TRUE\r"); +// strcat(TNC->InitScript,"LISTEN TRUE\r"); + + + strcpy(TNC->CurrentMYC, TNC->NodeCall); if (TNC->WL2K == NULL) diff --git a/BBSUtilities.c b/BBSUtilities.c index d7291d0..90b4c7b 100644 --- a/BBSUtilities.c +++ b/BBSUtilities.c @@ -69,6 +69,10 @@ extern BPQVECSTRUC ** BPQHOSTVECPTR; UCHAR * GetLogDirectory(); DllExport int APIENTRY SessionStateNoAck(int stream, int * state); int RefreshWebMailIndex(); +struct PORTCONTROL * GetPortTableEntryFromSlot(int portslot); +int GetPortHardwareType(struct PORTCONTROL *PORT); +int GetNumberofPorts(); + #else __declspec(dllimport) BPQVECSTRUC ** BPQHOSTVECPTR; typedef char * (WINAPI FAR *FARPROCZ)(); @@ -5252,7 +5256,6 @@ char * CheckToAddress(CIRCUIT * conn, char * Addr) return NewAddr; } } - else { WPRecP WP = LookupWP(Addr); @@ -5473,7 +5476,18 @@ BOOL DecodeSendParams(CIRCUIT * conn, char * Context, char ** From, char *To, ch } else { - conn->LocalMsg = TRUE; + // See if a WP entry + + WP = LookupWP(To); + + if (WP) + { + *ATBBS = WP->first_homebbs; + nodeprintf(conn, "Address @%s added from WP\r", *ATBBS); + conn->LocalMsg = FALSE; + } + else + conn->LocalMsg = TRUE; } } else @@ -9052,6 +9066,10 @@ CheckForSID: return TRUE; } +#ifndef LINBPQ +extern FARPROCX pGetPortHardwareType; +#endif + VOID Parse_SID(CIRCUIT * conn, char * SID, int len) { ChangeSessionIdletime(conn->BPQStream, BBSIDLETIME); // Default Idletime for BBS Sessions @@ -9108,10 +9126,44 @@ VOID Parse_SID(CIRCUIT * conn, char * SID, int len) { // We should really only do this on Telnet Connections, as OpenBCM flag is used to remove relnet transparency + // See if Telnet + + struct PORTCONTROL * PORT; + char Call[11] = ""; + int port, dummy; + + GetConnectionInfo(conn->BPQStream, Call, &port, &dummy, &dummy, &dummy, &dummy); + + PORT = GetPortTableEntryFromSlot(0); // Get first entry + + do + { + if (PORT->PORTNUMBER == port) + break; + + PORT=PORT->PORTPOINTER; + + } while (PORT); + +#define H_TELNET 6 + +#ifndef LINBPQ + + if (pGetPortHardwareType) + { + if (PORT && GetPortHardwareType(PORT) == H_TELNET) + conn->OpenBCM = TRUE; + } + else + conn->OpenBCM = TRUE; // Old Node version so follow old behavoiur and treat all as telnet +#else + if (PORT && GetPortHardwareType(PORT) == H_TELNET) + conn->OpenBCM = TRUE; +#endif - conn->OpenBCM = TRUE; } + if (_memicmp(SID, "PMS-3.2", 7) == 0) { // Paccom TNC that doesn't send newline prompt ater receiving subject diff --git a/BPQINP3.c b/BPQINP3.c index 2b1e3ae..aa4929c 100644 --- a/BPQINP3.c +++ b/BPQINP3.c @@ -1341,6 +1341,9 @@ VOID SendRIPToNeighbour(struct ROUTE * Route) if (Msg == NULL) Msg = Route->Msg = CreateRIFHeader(Route); + if (Msg == NULL) + return; + Msg->LENGTH += BuildRIF(&Msg->L3SRCE[Msg->LENGTH], Dest->DEST_CALL, Dest->DEST_ALIAS, Entry->Hops + 1, Entry->SRTT + Entry->ROUT_NEIGHBOUR->SRTT/10); diff --git a/BPQMail.c b/BPQMail.c index 0ac9f1c..2aab885 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -1153,6 +1153,7 @@ // Save FBB transfer restart data over program restarts (69) // Add Send and Receive byte counts to status displays (69) // Validate Mode and Frequency and fix formatting in Connected Message (71) +// Fix using OpenBCM on other than Telnet connections (75) #include "bpqmail.h" #include "winstdint.h" @@ -1173,6 +1174,7 @@ FARPROCX pRunEventProgram; FARPROCX pGetPortFrequency; FARPROCX pSendWebRequest; FARPROCX pGetLatLon; +FARPROCX pGetPortHardwareType; BOOL WINE = FALSE; @@ -1956,6 +1958,8 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) pGetPortFrequency = GetProcAddress(ExtDriver,"_GetPortFrequency@8"); pSendWebRequest = GetProcAddress(ExtDriver,"_SendWebRequest@16"); pGetLatLon = GetProcAddress(ExtDriver,"_GetLatLon@8"); + pGetPortHardwareType = GetProcAddress(ExtDriver,"_GetPortHardwareType@4"); + if (pGetLOC) diff --git a/Bpq32.c b/Bpq32.c index fc36356..b282d88 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1267,6 +1267,15 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Add MHUV and MHLV commands (Verbose listing with timestamps in clock time) (70) // Improvements to INP3 (71) // Improvements to KAM driver including support for GTOR connects (71) +// Support IPv6 for Telnet outward connects (72) +// Fix decaying NETROM routes (72) +// Add OnlyVer2point0 config command (72) +// Add option to allow AX/UDP on a network using NAT (72) +// Include AGWAPI fixes from Martin KD6YAM to enable use with Paracon terminal (72) +// Fix 64 bit compatiblility issues with AGWAPI (73) +// Fix KAM Pactor Interlock (73) +// Fix Node map reporting, broken in .73 (74) + #define CKernel diff --git a/ChatHTMLConfig.c b/ChatHTMLConfig.c index c4071cf..604db8f 100644 --- a/ChatHTMLConfig.c +++ b/ChatHTMLConfig.c @@ -590,7 +590,7 @@ VOID SendChatStatusPage(char * Reply, int * ReplyLen, char * Key) { if (conn->Flags & CHATLINK) { - if (conn->BPQStream > 64 || conn->u.link == 0) + if (conn->BPQStream > 64 || conn->u.link == 0 || conn->u.link->alias == 0) Len += sprintf(&Streams[Len], "** Corrupt ChatLink **" "        ", i, i); else @@ -600,7 +600,7 @@ VOID SendChatStatusPage(char * Reply, int * ReplyLen, char * Key) "", conn->OutputQueueLength - conn->OutputGetPointer); } else - if ((conn->Flags & CHATMODE) && conn->topic) + if ((conn->Flags & CHATMODE) && conn->topic && conn->u.user && conn->u.user->call) { Len += sprintf(&Streams[Len], "%s%s%d%s%d", i, i, conn->u.user->name, conn->u.user->call, conn->BPQStream, diff --git a/CommonCode.c b/CommonCode.c index ecac115..9c0032d 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -2142,7 +2142,16 @@ int CanPortDigi(int Port) return TRUE; } -struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum) +DllExport int APIENTRY GetPortHardwareType(struct PORTCONTROL *PORT) +{ + if (PORT) + return PORT->Hardware; + + return 0; +} + + +DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum) { struct PORTCONTROL * PORTVEC = PORTTABLE; diff --git a/KAMPactor.c b/KAMPactor.c index ec461d3..239b183 100644 --- a/KAMPactor.c +++ b/KAMPactor.c @@ -915,24 +915,39 @@ VOID KAMPoll(int Port) calllen = ConvFromAX25(TNC->PortRecord->ATTACHEDSESSIONS[0]->L4USER, TNC->Streams[0].MyCall); TNC->Streams[0].MyCall[calllen] = 0; - EncodeAndSend(TNC, "X", 1); // ??Return to packet mode?? - if (TNC->VeryOldMode) - datalen = sprintf(TXMsg, "C20MYCALL %s", TNC->Streams[0].MyCall); - else - datalen = sprintf(TXMsg, "C20MYPTCALL %s", TNC->Streams[0].MyCall); + EncodeAndSend(TNC, "X", 1); // ??Return to packet mode?? + + if (TNC->VeryOldMode) + { + datalen = sprintf(TXMsg, "C20MYCALL %s", TNC->Streams[0].MyCall); EncodeAndSend(TNC, TXMsg, datalen); - TNC->InternalCmd = 'M'; + } + else + { + datalen = sprintf(TXMsg, "C20MYPTCALL %s", TNC->Streams[0].MyCall); + EncodeAndSend(TNC, TXMsg, datalen); + + if (TNC->OldMode == 0) + { + EncodeAndSend(TNC, TXMsg, datalen); + datalen = sprintf(TXMsg, "C20MYGTCALL %s", TNC->Streams[0].MyCall); + } + } + + TNC->InternalCmd = 'M'; - TNC->NeedPACTOR = 0; // Cancel enter Pactor + TNC->NeedPACTOR = 0; // Cancel enter Pactor - sprintf(TNC->WEB_TNCSTATE, "In Use by %s", TNC->Streams[0].MyCall); - SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); + SuspendOtherPorts(TNC); - // Stop Scanning + sprintf(TNC->WEB_TNCSTATE, "In Use by %s", TNC->Streams[0].MyCall); + SetWindowText(TNC->xIDC_TNCSTATE, TNC->WEB_TNCSTATE); - sprintf(Msg, "%d SCANSTOP", TNC->Port); + // Stop Scanning + + sprintf(Msg, "%d SCANSTOP", TNC->Port); - Rig_Command( (TRANSPORTENTRY *) -1, Msg); + Rig_Command( (TRANSPORTENTRY *) -1, Msg); } } @@ -1065,9 +1080,22 @@ VOID KAMPoll(int Port) UCHAR TXMsg[80] = "D20"; if (TNC->VeryOldMode) + { datalen = sprintf(TXMsg, "C20MYCALL %s", TNC->NodeCall); + EncodeAndSend(TNC, TXMsg, datalen); + } else + { datalen = sprintf(TXMsg, "C20MYPTCALL %s", TNC->NodeCall); + EncodeAndSend(TNC, TXMsg, datalen); + + if (TNC->OldMode == 0) + { + datalen = sprintf(TXMsg, "C20MYGTCALL %s", TNC->NodeCall); + EncodeAndSend(TNC, TXMsg, datalen); + } + } + EncodeAndSend(TNC, TXMsg, datalen); if (TNC->OldMode) @@ -1075,6 +1103,7 @@ VOID KAMPoll(int Port) else EncodeAndSend(TNC, "C20TOR", 6); // Back to Listen + TNC->InternalCmd = 'T'; TNC->Timeout = 50; TNC->IntCmdDelay--; @@ -1758,6 +1787,76 @@ VOID ProcessKHOSTPacket(struct TNCINFO * TNC, UCHAR * Msg, int Len) if (Msg[0] == '?') // Status { TNC->Timeout = 0; + +/* + The response frame from the TNC will be: + ?0MSXY - where MSXY are coded as follows: + M One byte indicating the current mode of operation. + A=Packet + B=RTTY + C=ASCII + D=AMTOR + E=FEC + F=SELFEC + G=LAMTOR + H=PACTOR + I=PTLISTEN + J=GTOR + K=NAVTEX + L=CW + M=TOR Standby + N=GMON + O=PSK31 + S One byte indicating a sub-mode of operation. The byte + contains an ASCII character as follows: + 0=Standby + 1=Phasing + 2=Connected + 3=Disconnecting + 4=FEC + 5=SELFEC + 6=PTFEC + X One byte (called status byte X). This byte is bit- + encoded to indicate specific conditions as follows: + Bit 0 = (IDLE) set to 1 when receiving IDLE + characters in a frame. + Bit 1 = (ERR) set to 1 to indicate the received frame + failed CRC check, or was not a valid CS + response frame. + Bit 2 = (Combined receive) set to 1 to indicate that + the data was constructed through the use of + error correction (i.e. Golay error correction + for G-TOR or Memory ARQ for Pactor). + Bit 3 = (RQ) set to 1 to indicate an RQ frame. If you + are the ISS, it indicates that the receiving + station has asked for a repeat of the last + data due to received errors. When you are the + IRS, it indicates that the transmitting + station has sent the same data that you have + already received. This means that the sending + station did not properly copy your + acknowledgement (CS code). + Bit 4 = (Huffman) set to 1 to indicate that this + frame contains data which uses Huffman + compression. + Bit 5 = (ISS) set to 1 to indicate that your station + is currently the ISS. + Bit 6&7 = (Speed) these two bits indicate the current + speed of an ARQ link or the PSK31 mode. The + coding of the bits is: + 00 = 100 baud or BPSK31 + 01 = 200 baud or QPSK31 + 10 = 300 baud + Y One byte (called status byte Y). This byte is bit- + encoded to indicate specific conditions as follows: + Bit 0 = reserved (set to 0). + Bit 1 = (PTT) PTT is active. + Bit 2 = (Changeover) changeover in progress + Bits 3-7 = reserved (set to 0). +*/ + + + return; } diff --git a/L2Code.c b/L2Code.c index 5b13919..76924bf 100644 --- a/L2Code.c +++ b/L2Code.c @@ -154,6 +154,8 @@ extern BOOL LogAllConnects; APPLCALLS * APPL; +int SUPPORT2point2 = 1; + void SendL2ToMonMap(struct PORTCONTROL * PORT, char * ReportCall, char Mode, char Direction) { @@ -3242,7 +3244,7 @@ VOID L2TimerProc() if (PORT == NULL) { LINK++; - continue; // just ion case!! + continue; // just in case!! } if (LINK->L2TIMER) @@ -4003,7 +4005,7 @@ VOID CONNECTREFUSED(struct _LINKTABLE * LINK) ConnectFailedOrRefused(LINK, "Busy from"); } -VOID L3CONNECTFAILED(struct _LINKTABLE * LINK); + VOID L3LINKSETUPFAILED(struct _LINKTABLE * LINK); diff --git a/L3Code.c b/L3Code.c index b516634..48f71bc 100644 --- a/L3Code.c +++ b/L3Code.c @@ -1332,34 +1332,6 @@ VOID L3LINKSETUPFAILED(struct _LINKTABLE * LINK) Debugprintf("INP3 Route to %s connect failed", Normcall); } - - ROUTE->NEIGHBOUR_LINK = 0; // CLEAR IT - - L3TRYNEXTDEST(ROUTE); // RESET ASSOCIATED DEST ENTRIES -} - - -VOID L3CONNECTFAILED(struct _LINKTABLE * LINK) -{ - // L2 LINK SETUP HAS FAILED - SEE IF ANOTHER NEIGHBOUR CAN BE USED - - struct PORTCONTROL * PORT = PORTTABLE; - struct ROUTE * ROUTE; - - - ROUTE = LINK->NEIGHBOUR; // TO NEIGHBOUR - - if (ROUTE == NULL) - return; // NOTHING ??? - - if (ROUTE->INP3Node) - { - char Normcall[10]; - Normcall[ConvFromAX25(ROUTE->NEIGHBOUR_CALL, Normcall)] = 0; - Debugprintf("INP3 Route to %s connect failed or refused", Normcall); - } - - TellINP3LinkSetupFailed(ROUTE); ROUTE->NEIGHBOUR_LINK = 0; // CLEAR IT @@ -1368,6 +1340,7 @@ VOID L3CONNECTFAILED(struct _LINKTABLE * LINK) } + VOID L3TRYNEXTDEST(struct ROUTE * ROUTE) { // FIND ANY DESINATIONS WITH ROUTE AS ACTIVE NEIGHBOUR, AND diff --git a/MHSave.txt b/MHSave.txt deleted file mode 100644 index e69de29..0000000 diff --git a/TelnetV6.c b/TelnetV6.c index 62b0885..a0a0272 100644 --- a/TelnetV6.c +++ b/TelnetV6.c @@ -1498,6 +1498,8 @@ void * TelnetExtInit(EXTPORTDATA * PortEntry) PortEntry->PORTCONTROL.TNC = TNC; + PortEntry->PORTCONTROL.Hardware = TNC->Hardware; + TNC->WebWindowProc = WebProc; TNC->WebWinX = 260; TNC->WebWinY = 325; @@ -6342,26 +6344,80 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S struct ConnectionInfo * sockptr; SOCKET sock; struct sockaddr_in sinx; - struct sockaddr_in destaddr; int addrlen=sizeof(sinx); - int i; + char PortString[20]; + struct addrinfo hints, *res = 0, *saveres; + + + sprintf(PortString, "%d", Port); + + // get host info, make socket, and connect it + + memset(&hints, 0, sizeof hints); + + if (TCP->IPV6 == 0 && TCP->IPV4) + hints.ai_family = AF_INET; + else if (TCP->IPV4 == 0 && TCP->IPV6) + hints.ai_family = AF_INET6; + else if (TCP->IPV4 && TCP->IPV6) + hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever + + else + { + ReportError(STREAM, "Neither IPv4 nor IPv5 are enabled"); + return FALSE; // Resolve failed + } + + + hints.ai_socktype = SOCK_STREAM; + getaddrinfo(Host, PortString, &hints, &res); + + if (!res) + { + char Msg[256]; + err = WSAGetLastError(); + sprintf(Msg, "Resolve HostName Failed - Error %d", err); + ReportError(STREAM, Msg); + return FALSE; // Resolve failed + } + + // Step thorough the list of hosts + + saveres = res; // Save for free + +/* if (res->ai_next) // More than one + { + int n = ISHostIndex; + + while (n && res->ai_next) + { + res = res->ai_next; + n--; + } + + if (n) + { + // We have run off the end of the list + + ISHostIndex = 0; // Back to start + res = saveres; + } + else + ISHostIndex++; + + } +*/ +// getnameinfo(res->ai_addr, (int)res->ai_addrlen, RealISHost, 256, serv, 256, 0); sockptr = STREAM->ConnectionInfo; - sock = sockptr->socket = socket(AF_INET, SOCK_STREAM, 0); + sock = sockptr->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (sock == INVALID_SOCKET) - { - ReportError(STREAM, "Create Socket Failed"); - return FALSE; - } - sockptr->SocketActive = TRUE; sockptr->InputLen = 0; sockptr->LoginState = 2; sockptr->UserPointer = 0; sockptr->DoEcho = FALSE; - sockptr->FBBMode = FBB; // Raw Data if (sockptr->ADIF == NULL) @@ -6370,49 +6426,19 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S memset(sockptr->ADIF, 0, sizeof(struct ADIF)); - // Resolve Name if needed - - sockptr->sin.sin_family = AF_INET; - sockptr->sin.sin_port = htons(Port); - - sockptr->sin.sin_addr.s_addr = inet_addr(Host); - - if (sockptr->sin.sin_addr.s_addr == INADDR_NONE) + if (sock == INVALID_SOCKET) { - struct hostent * HostEnt; - - // Resolve name to address - - HostEnt = gethostbyname(Host); - - if (!HostEnt) - { - ReportError(STREAM, "Resolve HostName Failed"); - return FALSE; // Resolve failed - } - i = 0; - while (HostEnt->h_addr_list[i] != 0) - { - struct in_addr addr; - addr.s_addr = *(u_long *) HostEnt->h_addr_list[i++]; - } - memcpy(&sockptr->sin.sin_addr.s_addr, HostEnt->h_addr, 4); + ReportError(STREAM, "Create Socket Failed"); + return FALSE; } - ioctl (sockptr->socket, FIONBIO, ¶m); - - setsockopt (sockptr->socket, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4); + ioctl (sock, FIONBIO, ¶m); - sinx.sin_family = AF_INET; - sinx.sin_addr.s_addr = INADDR_ANY; - sinx.sin_port = 0; + setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt,4); - if (bind(sockptr->socket, (struct sockaddr *) &sinx, addrlen) != 0 ) - { - ReportError(STREAM, "Bind Failed"); - return FALSE; - } +// memcpy(work, res->ai_addr->sa_data, 4); + if (LogEnabled) { char logmsg[512]; @@ -6421,21 +6447,21 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S WriteLog (logmsg); } - - if (connect(sockptr->socket,(struct sockaddr *) &sockptr->sin, sizeof(destaddr)) == 0) + if (connect(sock, res->ai_addr, (int)res->ai_addrlen) == 0) { // // Connected successful // ReportError(STREAM, "*** Connected"); - - // Get Send Buffer Size + freeaddrinfo(saveres); return TRUE; } else { + freeaddrinfo(saveres); + err=WSAGetLastError(); if (err == 10035 || err == 115 || err == 36) //EWOULDBLOCK @@ -6461,7 +6487,6 @@ int TCPConnect(struct TNCINFO * TNC, struct TCPINFO * TCP, struct STREAMINFO * S } return FALSE; - } diff --git a/Versions.h b/Versions.h index a8b7c24..181a6ab 100644 --- a/Versions.h +++ b/Versions.h @@ -10,15 +10,15 @@ #endif -#define KVers 6,0,24,71 -#define KVerstring "6.0.24.71\0" +#define KVers 6,0,24,75 +#define KVerstring "6.0.24.75\0" #ifdef CKernel #define Vers KVers #define Verstring KVerstring -#define Datestring "April 2025" +#define Datestring "June 2025" #define VerComments "G8BPQ Packet Switch (C Version)" KVerstring #define VerCopyright "Copyright © 2001-2025 John Wiseman G8BPQ\0" #define VerDesc "BPQ32 Switch\0" diff --git a/WebMail.c b/WebMail.c index 6510618..2c97f84 100644 --- a/WebMail.c +++ b/WebMail.c @@ -2822,6 +2822,18 @@ VOID SaveNewMessage(struct HTTPConnectionInfo * Session, char * MsgPtr, char * R strcpy(Msg->via, ToUser->HomeBBS); sprintf(Prompt, "%s added from HomeBBS. Message Saved", Msg->via); } + else + { + // No HomeBBS - check WP + + WPRecP WP = LookupWP(Msg->to); + + if (WP) + { + strcpy(Msg->via, WP->first_homebbs); + sprintf(Prompt, "%s added from WP", Msg->via); + } + } } else { @@ -4239,6 +4251,18 @@ VOID SaveTemplateMessage(struct HTTPConnectionInfo * Session, char * MsgPtr, cha strcpy(Msg->via, ToUser->HomeBBS); sprintf(Prompt, "%s added from HomeBBS. Message Saved", Msg->via); } + else + { + // No HomeBBS - Check WP + + WPRecP WP = LookupWP(Msg->to); + + if (WP) + { + strcpy(Msg->via, WP->first_homebbs); + sprintf(Prompt, "%s added from WP", Msg->via); + } + } } else { @@ -4459,6 +4483,18 @@ VOID BuildMessageFromHTMLInput(struct HTTPConnectionInfo * Session, char * Reply strcpy(Msg->via, ToUser->HomeBBS); sprintf(Prompt, "%s added from HomeBBS", Msg->via); } + else + { + // No HomeBBS - Check WP + + WPRecP WP = LookupWP(Msg->to); + + if (WP) + { + strcpy(Msg->via, WP->first_homebbs); + sprintf(Prompt, "%s added from WP", Msg->via); + } + } } else { diff --git a/asmstrucs.h b/asmstrucs.h index 34b8ce5..aa73b93 100644 --- a/asmstrucs.h +++ b/asmstrucs.h @@ -727,6 +727,9 @@ typedef struct PORTCONTROL UCHAR * TX; // % Sending UCHAR * BUSY; // % Active (Normally DCD active or TX) + int Hardware; // TNC H_TYPE. Copied here for access from application context + + } PORTCONTROLX, *PPORTCONTROL; typedef struct FULLPORTDATA @@ -1371,6 +1374,7 @@ struct arp_table_entry // SOCKET SourceSocket; struct AXIPPORTINFO * PORT; BOOL noUpdate; // Don't update dest address from incoming packet + BOOL replytoSourcePort; // Update map entry dest port from source port of each packet. time_t LastHeard; // Last Packet received from this ststiom }; diff --git a/bpq32.h b/bpq32.h index bdc5a20..2bab90a 100644 --- a/bpq32.h +++ b/bpq32.h @@ -22,6 +22,8 @@ count on BPQ32.dll gets messed up, and the code will not unload cleanly. struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portslot); struct PORTCONTROL * APIENTRY GetPortTableEntryFromSlot(int portslot); +int APIENTRY GetPortHardwareType(struct PORTCONTROL *PORT); + // Returns number of free buffers // (BPQHOST function 7 (part)). diff --git a/bpqaxip.c b/bpqaxip.c index 92cc9ab..d5afb62 100644 --- a/bpqaxip.c +++ b/bpqaxip.c @@ -204,7 +204,7 @@ int Update_MH_KeepAlive(struct AXIPPORTINFO * PORT, struct in_addr ipad, char pr unsigned short int compute_crc(unsigned char *buf,int l); unsigned int find_arp(unsigned char * call); BOOL add_arp_entry(struct AXIPPORTINFO * PORT, unsigned char * call, UCHAR * ip, int len, int port,unsigned char * name, -int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPMode, int SourcePort, BOOL IPv6, int noUpdate); + int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPMode, int SourcePort, BOOL IPv6, int noUpdate, int useSourcePort); BOOL add_bc_entry(struct AXIPPORTINFO * PORT, unsigned char * call, int len); BOOL convtoax25(unsigned char * callsign, unsigned char * ax25call, int * calllen); static BOOL ReadConfigFile(int Port); @@ -213,7 +213,7 @@ int CheckKeepalives(struct AXIPPORTINFO * PORT); BOOL CopyScreentoBuffer(char * buff, struct AXIPPORTINFO * PORT); int DumpFrameInHex(unsigned char * msg, int len); VOID SendFrame(struct AXIPPORTINFO * PORT, struct arp_table_entry * arp_table, UCHAR * buff, int txlen); -BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int Port, VOID * rxaddr); +BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int FromPort, VOID * rxaddr, int ToPort); int DataSocket_Read(struct arp_table_entry * sockptr, SOCKET sock); int GetMessageFromBuffer(struct AXIPPORTINFO * PORT, char * Buffer); int KissEncode(UCHAR * inbuff, UCHAR * outbuff, int len); @@ -429,7 +429,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff) if (PORT->Checkifcanreply) { - if (CheckSourceisResolvable(PORT, call, 0, &RXaddr)) + if (CheckSourceisResolvable(PORT, call, 0, &RXaddr, 0)) return 1; @@ -437,7 +437,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff) // Can't reply. If AutoConfig is set, add to table and accept, else reject if (PORT->AutoAddARP) - return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, 0, inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, 0, FALSE, 0); + return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, 0, inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, 0, FALSE, 0, 0); else { char From[11] = "|"; @@ -536,7 +536,7 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff) if (PORT->Checkifcanreply) { - if (CheckSourceisResolvable(PORT, call, htons(RXaddr.rxaddr.sin_port), &RXaddr)) + if (CheckSourceisResolvable(PORT, call, htons(RXaddr.rxaddr.sin_port), &RXaddr, PORT->udpport[i])) return 1; else { @@ -547,10 +547,10 @@ static size_t ExtProc(int fn, int port, PMESSAGE buff) { char Addr[80]; Format_Addr((UCHAR *)&RXaddr.rxaddr6.sin6_addr, Addr, TRUE); - return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr6.sin6_addr, 7, htons(RXaddr.rxaddr6.sin6_port), Addr, 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], TRUE, 0); + return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr6.sin6_addr, 7, htons(RXaddr.rxaddr6.sin6_port), Addr, 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], TRUE, 0, 0); } else - return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, htons(RXaddr.rxaddr.sin_port), inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], FALSE, 0); + return add_arp_entry(PORT, call, (UCHAR *)&RXaddr.rxaddr.sin_addr.s_addr, 7, htons(RXaddr.rxaddr.sin_port), inet_ntoa(RXaddr.rxaddr.sin_addr), 0, PORT->AutoAddBC, TRUE, 0, PORT->udpport[i], FALSE, 0, 0); else { char From[11] = "|"; @@ -1343,6 +1343,7 @@ LRESULT FAR PASCAL ConfigWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lPa char axcall[7]; BOOL UDPFlag, BCFlag; struct AXIPPORTINFO * PORT; + int useSourcePort = 0; for (i=1; i <= MAXBPQPORTS; i++) { @@ -1391,7 +1392,7 @@ LRESULT FAR PASCAL ConfigWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lPa { if (convtoax25(call,axcall,&calllen)) { - add_arp_entry(PORT, axcall,0,calllen,port,host,Interval, BCFlag, FALSE, 0, port, FALSE, 0); + add_arp_entry(PORT, axcall,0,calllen,port,host,Interval, BCFlag, FALSE, 0, port, FALSE, 0, useSourcePort); ResolveDelay = 2; return(DestroyWindow(hWnd)); } @@ -2147,6 +2148,7 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT) int Interval; int noUpdate=FALSE; int TCPMode; + int useSourcePort = 0; ptr = strtok(buf, " \t\n\r"); @@ -2234,6 +2236,7 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT) bcflag=0; TCPMode=0; SourcePort = 0; + useSourcePort = 0; // // Look for (optional) KEEPALIVE, DYNAMIC, UDP or BROADCAST params @@ -2264,7 +2267,14 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT) if (p_udpport == NULL) return (FALSE); - port = atoi(p_udpport); + if (_stricmp(p_udpport,"FROMPORT") == 0) + { + useSourcePort = TRUE; + port = 0; + } + else + port = atoi(p_udpport); + p_UDP = strtok(NULL, " \t\n\r"); continue; } @@ -2327,7 +2337,7 @@ static int ProcessLine(char * buf, struct AXIPPORTINFO * PORT) if (SourcePort == 0) SourcePort = port; - add_arp_entry(PORT, axcall, 0, calllen, port, p_ipad, Interval, bcflag, FALSE, TCPMode, SourcePort, FALSE, noUpdate); + add_arp_entry(PORT, axcall, 0, calllen, port, p_ipad, Interval, bcflag, FALSE, TCPMode, SourcePort, FALSE, noUpdate, useSourcePort); return (TRUE); } } // End of Process MAP @@ -2438,7 +2448,7 @@ BOOL convtoax25(unsigned char * callsign, unsigned char * ax25call,int * calllen } BOOL add_arp_entry(struct AXIPPORTINFO * PORT, UCHAR * call, UCHAR * ip, int len, int port, - UCHAR * name, int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPFlag, int SourcePort, BOOL IPv6, int noUpdate) + UCHAR * name, int keepalive, BOOL BCFlag, BOOL AutoAdded, int TCPFlag, int SourcePort, BOOL IPv6, int noUpdate, int useSourcePort) { struct arp_table_entry * arp; @@ -2457,7 +2467,8 @@ BOOL add_arp_entry(struct AXIPPORTINFO * PORT, UCHAR * call, UCHAR * ip, int len arp->PORT = PORT; - if (port == 0) PORT->needip = 1; // Enable Raw IP Mode + if (port == 0 && arp->replytoSourcePort == 0) + PORT->needip = 1; // Enable Raw IP Mode arp->ResolveFlag=TRUE; PORT->NeedResolver=TRUE; @@ -2476,6 +2487,7 @@ BOOL add_arp_entry(struct AXIPPORTINFO * PORT, UCHAR * call, UCHAR * ip, int len arp->TCPMode = TCPFlag; arp->noUpdate = noUpdate; PORT->arp_table_len++; + arp->replytoSourcePort = useSourcePort; if (PORT->MaxResWindowlength < (PORT->arp_table_len * 14) + 70) PORT->MaxResWindowlength = (PORT->arp_table_len * 14) + 70; @@ -2576,7 +2588,7 @@ int CheckKeepalives(struct AXIPPORTINFO * PORT) return (0); } -BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int Port, VOID * rxaddr) +BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int FromPort, VOID * rxaddr, int ToPort) { // Makes sure we can reply to call before accepting message @@ -2606,9 +2618,15 @@ BOOL CheckSourceisResolvable(struct AXIPPORTINFO * PORT, char * call, int Port, struct sockaddr_in * SA = rxaddr; memcpy(&arp->destaddr.sin_addr.s_addr, &SA->sin_addr, 4); } - // Dont think I should update port + // Dont think I should update port unless using source port for dest - //arp->port = Port; + if (arp->replytoSourcePort) + { + arp->port = FromPort; + arp->destaddr.sin_port = htons(arp->port); + if (arp->SourcePort == 0) + arp->SourcePort = ToPort; + } } arp->LastHeard = time(NULL); return 1; // Ok to process diff --git a/cMain.c b/cMain.c index 1815950..c87fac2 100644 --- a/cMain.c +++ b/cMain.c @@ -858,6 +858,9 @@ BOOL Start() PREFERINP3ROUTES = cfg->C_PREFERINP3ROUTES; + if (cfg->C_OnlyVer2point0) + SUPPORT2point2 = 0; + // Get pointers to PASSWORD and APPL1 commands diff --git a/cheaders.h b/cheaders.h index 4b765a2..4951cac 100644 --- a/cheaders.h +++ b/cheaders.h @@ -105,7 +105,7 @@ VOID CLOSECURRENTSESSION(TRANSPORTENTRY * Session); VOID SendCommandReply(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer, int Len); -struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum); +DllExport struct PORTCONTROL * APIENTRY GetPortTableEntryFromPortNum(int portnum); int cCOUNT_AT_L2(struct _LINKTABLE * LINK); VOID SENDL4CONNECT(TRANSPORTENTRY * Session); @@ -202,8 +202,6 @@ int TrytoGuessCode(unsigned char * Char, int Len); #define XID 0xAF #define TEST 0xE3 -#define SUPPORT2point2 1 - // XID Optional Functions #define OPMustHave 0x02A080 // Sync TEST 16 bit FCS Extended Address @@ -438,6 +436,9 @@ extern int MQTT_PORT; extern char MQTT_USER[80]; extern char MQTT_PASS[80]; +extern int SUPPORT2point2; + + DllExport uint64_t APIENTRY GetPortFrequency(int PortNo, char * FreqStringMhz); diff --git a/config.c b/config.c index 2ca25d3..a1b39a2 100644 --- a/config.c +++ b/config.c @@ -308,7 +308,8 @@ static char *keywords[] = "BTEXT:", "NETROMCALL", "C_IS_CHAT", "MAXRTT", "MAXHOPS", // IPGATEWAY= no longer allowed "LogL4Connects", "LogAllConnects", "SAVEMH", "ENABLEADIFLOG", "ENABLEEVENTS", "SAVEAPRSMSGS", "EnableM0LTEMap", "MQTT", "MQTT_HOST", "MQTT_PORT", "MQTT_USER", "MQTT_PASS", -"L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe", "L2CompPaclen", "PREFERINP3ROUTES" +"L4Compress", "L4CompMaxframe", "L4CompPaclen", "L2Compress", "L2CompMaxframe", +"L2CompPaclen", "PREFERINP3ROUTES", "OnlyVer2point0" }; /* parameter keywords */ static void * offset[] = @@ -331,7 +332,7 @@ static void * offset[] = &xxcfg.C_LogL4Connects, &xxcfg.C_LogAllConnects, &xxcfg.C_SaveMH, &xxcfg.C_ADIF, &xxcfg.C_EVENTS, &xxcfg.C_SaveAPRSMsgs, &xxcfg.C_M0LTEMap, &xxcfg.C_MQTT, &xxcfg.C_MQTT_HOST, &xxcfg.C_MQTT_PORT, &xxcfg.C_MQTT_USER, &xxcfg.C_MQTT_PASS, &xxcfg.C_L4Compress, &xxcfg.C_L4CompMaxframe, &xxcfg.C_L4CompPaclen, &xxcfg.C_L2Compress, &xxcfg.C_L2CompMaxframe, -&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES}; /* offset for corresponding data in config file */ +&xxcfg.C_L2CompPaclen, &xxcfg.C_PREFERINP3ROUTES, &xxcfg.C_OnlyVer2point0}; /* offset for corresponding data in config file */ static int routine[] = { @@ -353,7 +354,7 @@ static int routine[] = 2, 2, 1, 2, 2, 2, 2, 2, 0, 1, 20, 20, 1, 1, 1, 1, 1, -1, 1} ; // Routine to process param +1, 1, 1} ; // Routine to process param int PARAMLIM = sizeof(routine)/sizeof(int); //int NUMBEROFKEYWORDS = sizeof(routine)/sizeof(int); @@ -629,7 +630,7 @@ BOOL ProcessConfig() paramok[90]=1; // L2Compress Maxframe paramok[91]=1; // L2Compress Paclen paramok[92]=1; // PREFERINP3ROUTES - + paramok[93]=1; // C_ONLYVer2point0 for (i=0; i < PARAMLIM; i++) { diff --git a/configstructs.h b/configstructs.h index f2efec3..9fb75cf 100644 --- a/configstructs.h +++ b/configstructs.h @@ -178,6 +178,7 @@ struct CONFIGTABLE int C_L2CompMaxframe; int C_L2CompPaclen; int C_PREFERINP3ROUTES; + int C_OnlyVer2point0; //#define ApplOffset 80000 // Applications offset in config buffer