diff --git a/APRSStdPages.c b/APRSStdPages.c index 7cb38e1..112e8be 100644 --- a/APRSStdPages.c +++ b/APRSStdPages.c @@ -3226,335 +3226,328 @@ char * get_plane(int * Len) } - - char * get_aprs() { char Msg[] = - -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"G8BPQ APRS Display\n" -"\n" - -"\n" -"\n" - - -//"\n" -//"\n" -"\n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -"\n" -"\n" -"\n" -"
\n" -"\n" -""; - + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "G8BPQ APRS Display\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + " \n" + "\n" + "\n" + "\n" + "\n" + "\n" + "
\n" + "\n" + ""; return _strdup(Msg);; } diff --git a/BPQMail.c b/BPQMail.c index 344dc5f..f5319f9 100644 --- a/BPQMail.c +++ b/BPQMail.c @@ -1104,10 +1104,11 @@ // Add auto-refresh option to Webmail index page (25) // Fix displaying help and info files with crlf line endings on Linux (28) // Improve validation of extended FC message (32) -// Improve WP check for SYSTEM as a callsihn (33) +// Improve WP check for SYSTEM as a callsign (33) // Improvements to RMS Relay SYNC mode (47) // Fix BID Hold and Reject filters - +// Fix Webmail auto-refresh when page exceeds 64K bytes (54) +// Fix Webmail send when using both headers/footers and attachmonts (55) #include "bpqmail.h" diff --git a/Bpq32.c b/Bpq32.c index 0308f62..2fdcdd1 100644 --- a/Bpq32.c +++ b/Bpq32.c @@ -1147,7 +1147,10 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses // Check L4 connects against EXCLUDE list (47) // Add vaidation of LOC in WL2K Session Reports (49) // Change gpsd support for compatibility with Share Gps (50) - +// Switch APRS Map to my Tiles (52) +// Fix using ; in UNPROTO Mode messages (52) +// Use sha1 code from https://www.packetizer.com/security/sha1/ instead of openssl (53) +// Fix TNC Emulator Monitoring (53) #define CKernel @@ -1162,7 +1165,6 @@ along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses #include #include "compatbits.h" - #include "AsmStrucs.h" #include "SHELLAPI.H" diff --git a/Cmd.c b/Cmd.c index f6c3fc1..2157939 100644 --- a/Cmd.c +++ b/Cmd.c @@ -4064,6 +4064,24 @@ noFlip1: checkattachandcall: + // If set freq on attach is defined, do it + + if (TNC && TNC->ActiveRXFreq && TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->ActiveRXFreq); + Rig_Command(-1, Msg); + } + + if (TNC && TNC->ActiveTXFreq && TNC->TXRadio && TNC->TXRadio != TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->ActiveTXFreq); + Rig_Command(-1, Msg); + } + if (ptr) { // we have a call to connect to @@ -4528,7 +4546,15 @@ VOID InnerCommandHandler(TRANSPORTENTRY * Session, struct DATAMESSAGE * Buffer) // SendUIModeFrame(Session, (PMESSAGE)Buffer, Session->UNPROTO); ReleaseBuffer((UINT *)Buffer); // Not using buffer for reply - + + // Assume we don't allow multiple lines in buffer with UI + + if (Session->PARTCMDBUFFER) + { + Buffer = Session->PARTCMDBUFFER; + ReleaseBuffer((UINT *)Buffer); // Not using buffer for reply + Session->PARTCMDBUFFER = NULL; + } return; } diff --git a/CommonCode.c b/CommonCode.c index 2abf722..f7e1685 100644 --- a/CommonCode.c +++ b/CommonCode.c @@ -772,6 +772,22 @@ NotConnected: CloseComplete(TNC, Stream); + if (TNC->DefaultRXFreq && TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->DefaultRXFreq); + Rig_Command(-1, Msg); + } + + if (TNC->DefaultTXFreq && TNC->TXRadio && TNC->TXRadio != TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->DefaultTXFreq); + Rig_Command(-1, Msg); + } + while(STREAM->BPQtoPACTOR_Q) { buffptr=Q_REM(&STREAM->BPQtoPACTOR_Q); diff --git a/HFCommon.c b/HFCommon.c index 21b7376..0ef6145 100644 --- a/HFCommon.c +++ b/HFCommon.c @@ -1870,8 +1870,14 @@ int standardParams(struct TNCINFO * TNC, char * buf) TNC->RXRadio = atoi(&buf[8]); else if (_memicmp(buf, "TXFreq", 6) == 0) // For PTT Sets Freq mode TNC->TXFreq = strtoll(&buf[7], NULL, 10); - else if (_memicmp(buf, "DefaultFreq", 11) == 0) // For PTT Sets Freq mode - TNC->DefaultFreq = strtoll(&buf[12], NULL, 10); + else if (_memicmp(buf, "DefaultTXFreq", 13) == 0) // Set at end of session + TNC->DefaultTXFreq = atof(&buf[14]); + else if (_memicmp(buf, "DefaultRXFreq", 13) == 0) // Set at end of session + TNC->DefaultRXFreq = atof(&buf[14]); + else if (_memicmp(buf, "ActiveTXFreq", 12) == 0) // Set at start of session + TNC->ActiveTXFreq = atof(&buf[13]); + else if (_memicmp(buf, "ActiveRXFreq", 12) == 0) // Set at start of session + TNC->ActiveRXFreq = atof(&buf[13]); else if (_memicmp(buf, "PTTONHEX", 8) == 0) { // Hex String to use for PTT on for this port diff --git a/HTTPcode.c b/HTTPcode.c index eaf894b..783e55a 100644 --- a/HTTPcode.c +++ b/HTTPcode.c @@ -2035,6 +2035,11 @@ Returnit: return 0; } + // Add tail + + strcpy(&Reply[ReplyLen], Tail); + ReplyLen += strlen(Tail); + // compress if allowed if (allowDeflate) @@ -2096,7 +2101,29 @@ doHeader: return 0; } - HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); + // Add tail + + strcpy(&_REPLYBUFFER[ReplyLen], Tail); + ReplyLen += strlen(Tail); + + // compress if allowed + + if (allowDeflate) + Compressed = Compressit(_REPLYBUFFER, ReplyLen, &ReplyLen); + else + Compressed = Reply; + + HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n%s\r\n", ReplyLen, Encoding); + sendandcheck(sock, Header, HeaderLen); + sendandcheck(sock, Compressed, ReplyLen); + + if (allowDeflate) + free (Compressed); + + return 0; + + +/* HeaderLen = sprintf(Header, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n", ReplyLen + (int)strlen(Tail)); send(sock, Header, HeaderLen, 0); @@ -2124,7 +2151,7 @@ doHeader: send(sock, Tail, (int)strlen(Tail), 0); return 0; - +*/ } if (_memicmp(Context, "/CHAT/", 6) == 0) @@ -4176,53 +4203,96 @@ int ProcessChatSignon(struct TCPINFO * TCP, char * MsgPtr, char * Appl, char * R } -#ifdef WIN32 - -#include -#include - #define SHA1_HASH_LEN 20 + +/* + +Copyright (C) 1998, 2009 +Paul E. Jones + +Freeware Public License (FPL) + +This software is licensed as "freeware." Permission to distribute +this software in source and binary forms, including incorporation +into other products, is hereby granted without a fee. THIS SOFTWARE +IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR SHALL NOT BE HELD +LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER +DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA +OR DATA BEING RENDERED INACCURATE. +*/ + +/* sha1.h + * + * Copyright (C) 1998, 2009 + * Paul E. Jones + * All Rights Reserved + * + ***************************************************************************** + * $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $ + ***************************************************************************** + * + * Description: + * This class implements the Secure Hashing Standard as defined + * in FIPS PUB 180-1 published April 17, 1995. + * + * Many of the variable names in the SHA1Context, especially the + * single character names, were used because those were the names + * used in the publication. + * + * Please read the file sha1.c for more information. + * + */ + +#ifndef _SHA1_H_ +#define _SHA1_H_ + +/* + * This structure will hold context information for the hashing + * operation + */ +typedef struct SHA1Context +{ + unsigned Message_Digest[5]; /* Message Digest (output) */ + + unsigned Length_Low; /* Message length in bits */ + unsigned Length_High; /* Message length in bits */ + + unsigned char Message_Block[64]; /* 512-bit message blocks */ + int Message_Block_Index; /* Index into message block array */ + + int Computed; /* Is the digest computed? */ + int Corrupted; /* Is the message digest corruped? */ +} SHA1Context; + +/* + * Function Prototypes + */ +void SHA1Reset(SHA1Context *); +int SHA1Result(SHA1Context *); +void SHA1Input( SHA1Context *, const unsigned char *, unsigned); + +#endif BOOL SHA1PasswordHash(char * lpszPassword, char * Hash) { - HCRYPTPROV hCryptProv; // Handle to our context - HCRYPTHASH hCryptHash; // Handle to our hash - BYTE bHashValue[SHA1_HASH_LEN]; // This will hold our SHA-1 hash - DWORD dwSize = SHA1_HASH_LEN; // Size of output - BOOL bSuccess = FALSE; // We change this to TRUE if we complete the operations - // Declare all the variables at the start of our code for C89 compatability - - if(CryptAcquireContext(&hCryptProv, NULL, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - { // Initiate usage of the functions - if(CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hCryptHash)) - { // Create a SHA1 hash - if(CryptHashData(hCryptHash, (PBYTE)lpszPassword, lstrlen(lpszPassword) * sizeof(TCHAR), 0)) - { // Update the hash, (process our password) - if(CryptGetHashParam(hCryptHash, HP_HASHVAL, bHashValue, &dwSize, 0)) - { // Extract the hash - - memcpy(Hash, bHashValue, 20); - bSuccess = TRUE; - } - } - CryptDestroyHash(hCryptHash); - } - CryptReleaseContext(hCryptProv, 0); - } - - return bSuccess; -} + SHA1Context sha; + int i; -#else + SHA1Reset(&sha); + SHA1Input(&sha, lpszPassword, strlen(lpszPassword)); + SHA1Result(&sha); -#include + // swap byte order if little endian + + for (i = 0; i < 5; i++) + sha.Message_Digest[i] = htonl(sha.Message_Digest[i]); -BOOL SHA1PasswordHash(char * data, char * Hash) -{ - SHA1(data, strlen(data), Hash); - return 1; + memcpy(Hash, &sha.Message_Digest[0], 20); + + return TRUE; } -#endif int BuildRigCtlPage(char * _REPLYBUFFER) { @@ -4341,9 +4411,9 @@ void ProcessWebmailWebSockThread(void * conn) char * URL = sockptr->WebURL; int Loops = 0; int Sent; - int InputLen; struct HTTPConnectionInfo Dummy = {0}; int ReplyLen = 0; + int InputLen = 0; #ifdef LINBPQ @@ -4423,6 +4493,377 @@ void ProcessWebmailWebSockThread(void * conn) return; } +/* + * sha1.c + * + * Copyright (C) 1998, 2009 + * Paul E. Jones + * All Rights Reserved + * + ***************************************************************************** + * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $ + ***************************************************************************** + * + * Description: + * This file implements the Secure Hashing Standard as defined + * in FIPS PUB 180-1 published April 17, 1995. + * + * The Secure Hashing Standard, which uses the Secure Hashing + * Algorithm (SHA), produces a 160-bit message digest for a + * given data stream. In theory, it is highly improbable that + * two messages will produce the same message digest. Therefore, + * this algorithm can serve as a means of providing a "fingerprint" + * for a message. + * + * Portability Issues: + * SHA-1 is defined in terms of 32-bit "words". This code was + * written with the expectation that the processor has at least + * a 32-bit machine word size. If the machine word size is larger, + * the code should still function properly. One caveat to that + * is that the input functions taking characters and character + * arrays assume that only 8 bits of information are stored in each + * character. + * + * Caveats: + * SHA-1 is designed to work with messages less than 2^64 bits + * long. Although SHA-1 allows a message digest to be generated for + * messages of any number of bits less than 2^64, this + * implementation only works with messages with a length that is a + * multiple of the size of an 8-bit character. + * + */ + +/* + * Define the circular shift macro + */ +#define SHA1CircularShift(bits,word) \ + ((((word) << (bits)) & 0xFFFFFFFF) | \ + ((word) >> (32-(bits)))) + +/* Function prototypes */ +void SHA1ProcessMessageBlock(SHA1Context *); +void SHA1PadMessage(SHA1Context *); + +/* + * SHA1Reset + * + * Description: + * This function will initialize the SHA1Context in preparation + * for computing a new message digest. + * + * Parameters: + * context: [in/out] + * The context to reset. + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1Reset(SHA1Context *context) +{ + context->Length_Low = 0; + context->Length_High = 0; + context->Message_Block_Index = 0; + + context->Message_Digest[0] = 0x67452301; + context->Message_Digest[1] = 0xEFCDAB89; + context->Message_Digest[2] = 0x98BADCFE; + context->Message_Digest[3] = 0x10325476; + context->Message_Digest[4] = 0xC3D2E1F0; + + context->Computed = 0; + context->Corrupted = 0; +} + +/* + * SHA1Result + * + * Description: + * This function will return the 160-bit message digest into the + * Message_Digest array within the SHA1Context provided + * + * Parameters: + * context: [in/out] + * The context to use to calculate the SHA-1 hash. + * + * Returns: + * 1 if successful, 0 if it failed. + * + * Comments: + * + */ +int SHA1Result(SHA1Context *context) +{ + + if (context->Corrupted) + { + return 0; + } + + if (!context->Computed) + { + SHA1PadMessage(context); + context->Computed = 1; + } + + return 1; +} + +/* + * SHA1Input + * + * Description: + * This function accepts an array of octets as the next portion of + * the message. + * + * Parameters: + * context: [in/out] + * The SHA-1 context to update + * message_array: [in] + * An array of characters representing the next portion of the + * message. + * length: [in] + * The length of the message in message_array + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1Input( SHA1Context *context, + const unsigned char *message_array, + unsigned length) +{ + if (!length) + { + return; + } + + if (context->Computed || context->Corrupted) + { + context->Corrupted = 1; + return; + } + + while(length-- && !context->Corrupted) + { + context->Message_Block[context->Message_Block_Index++] = + (*message_array & 0xFF); + + context->Length_Low += 8; + /* Force it to 32 bits */ + context->Length_Low &= 0xFFFFFFFF; + if (context->Length_Low == 0) + { + context->Length_High++; + /* Force it to 32 bits */ + context->Length_High &= 0xFFFFFFFF; + if (context->Length_High == 0) + { + /* Message is too long */ + context->Corrupted = 1; + } + } + + if (context->Message_Block_Index == 64) + { + SHA1ProcessMessageBlock(context); + } + + message_array++; + } +} + +/* + * SHA1ProcessMessageBlock + * + * Description: + * This function will process the next 512 bits of the message + * stored in the Message_Block array. + * + * Parameters: + * None. + * + * Returns: + * Nothing. + * + * Comments: + * Many of the variable names in the SHAContext, especially the + * single character names, were used because those were the names + * used in the publication. + * + * + */ +void SHA1ProcessMessageBlock(SHA1Context *context) +{ + const unsigned K[] = /* Constants defined in SHA-1 */ + { + 0x5A827999, + 0x6ED9EBA1, + 0x8F1BBCDC, + 0xCA62C1D6 + }; + int t; /* Loop counter */ + unsigned temp; /* Temporary word value */ + unsigned W[80]; /* Word sequence */ + unsigned A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + for(t = 0; t < 16; t++) + { + W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); + } + + for(t = 16; t < 80; t++) + { + W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = context->Message_Digest[0]; + B = context->Message_Digest[1]; + C = context->Message_Digest[2]; + D = context->Message_Digest[3]; + E = context->Message_Digest[4]; + + for(t = 0; t < 20; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 20; t < 40; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 40; t < 60; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 60; t < 80; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + context->Message_Digest[0] = + (context->Message_Digest[0] + A) & 0xFFFFFFFF; + context->Message_Digest[1] = + (context->Message_Digest[1] + B) & 0xFFFFFFFF; + context->Message_Digest[2] = + (context->Message_Digest[2] + C) & 0xFFFFFFFF; + context->Message_Digest[3] = + (context->Message_Digest[3] + D) & 0xFFFFFFFF; + context->Message_Digest[4] = + (context->Message_Digest[4] + E) & 0xFFFFFFFF; + + context->Message_Block_Index = 0; +} + +/* + * SHA1PadMessage + * + * Description: + * According to the standard, the message must be padded to an even + * 512 bits. The first padding bit must be a '1'. The last 64 + * bits represent the length of the original message. All bits in + * between should be 0. This function will pad the message + * according to those rules by filling the Message_Block array + * accordingly. It will also call SHA1ProcessMessageBlock() + * appropriately. When it returns, it can be assumed that the + * message digest has been computed. + * + * Parameters: + * context: [in/out] + * The context to pad + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1PadMessage(SHA1Context *context) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (context->Message_Block_Index > 55) + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 64) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + + SHA1ProcessMessageBlock(context); + + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + else + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + + /* + * Store the message length as the last 8 octets + */ + context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; + context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; + context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; + context->Message_Block[59] = (context->Length_High) & 0xFF; + context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; + context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; + context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; + context->Message_Block[63] = (context->Length_Low) & 0xFF; + + SHA1ProcessMessageBlock(context); +} + + diff --git a/RigControl.c b/RigControl.c index e0d38be..a864c1e 100644 --- a/RigControl.c +++ b/RigControl.c @@ -303,6 +303,8 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) { char FreqString[80]; char * CmdPtr = onString; + UCHAR * Poll = PORT->TXBuffer; + RIG->lastSetFreq = txfreq; @@ -330,6 +332,7 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) *(CmdPtr++) = (FreqString[9] - 48) | ((FreqString[8] - 48) << 4); *(CmdPtr++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4); *(CmdPtr++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4); + if (RIG->IC735) { *(CmdPtr++) = 0xFD; @@ -349,6 +352,40 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) break; + case YAESU: + + *(Poll++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4); + *(Poll++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4); + *(Poll++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4); + *(Poll++) = (FreqString[10] - 48) | ((FreqString[9] - 48) << 4); + *(Poll++) = 1; // Set Freq + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + + + if (RIG->PTTMode & PTTCI_V) + { + Sleep(150); + Poll = PORT->TXBuffer; + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = 0; + + *(Poll++) = 0; + *(Poll++) = PTTState ? 0x08 : 0x88; // CMD = 08 : PTT ON CMD = 88 : PTT OFF + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + } + + PORT->Retries = 1; + PORT->Timeout = 0; + + return; + + + case HAMLIB: // Dont need to save, as we can send strings separately @@ -356,6 +393,9 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) Len = sprintf(cmd, "F %lld\n", txfreq); i = send(PORT->remoteSock, cmd, Len, 0); RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF + + break; + } } } @@ -395,7 +435,8 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) { char FreqString[80]; char * CmdPtr = offString; - + UCHAR * Poll = PORT->TXBuffer; + RIG->lastSetFreq = txfreq; // Convert to CAT string @@ -443,7 +484,41 @@ VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC) sprintf(cmd, "%lld", txfreq); FLRIGSendCommand(PORT, "rig.set_vfo", cmd); RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF - + + case YAESU: + + // Easier to add PTT string, send and return; + + Len = 0; + + if (RIG->PTTMode & PTTCI_V) + { + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = 0; + *(Poll++) = PTTState ? 0x08 : 0x88; // CMD = 08 : PTT ON CMD = 88 : PTT OFF + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + Poll = PORT->TXBuffer; + Sleep(100); + } + + *(Poll++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4); + *(Poll++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4); + *(Poll++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4); + *(Poll++) = (FreqString[10] - 48) | ((FreqString[9] - 48) << 4); + *(Poll++) = 1; // Set Freq + + PORT->TXLen = 5; + RigWriteCommBlock(PORT); + + PORT->Retries = 1; + PORT->Timeout = 0; + + return; + case HAMLIB: // Dont need to save, as we can send strings separately @@ -1633,6 +1708,8 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, int Session, C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr); + saveNewFreq(RIG, Freq, Mode); + return TRUE; diff --git a/TNCEmulators.c b/TNCEmulators.c index 7497419..a4b85c1 100644 --- a/TNCEmulators.c +++ b/TNCEmulators.c @@ -2224,16 +2224,27 @@ VOID DOMONITORING(int NeedTrace) BOOL SaveMTX = MTX; BOOL SaveMCOM = MCOM; BOOL SaveMUI = MUIONLY; + int BPQStream = 0; if (NeedTrace) Tracebit = 0x80; - if (TNC->CONOK) - SetAppl(TNC->BPQPort, TNC->APPLFLAGS | Tracebit, TNC->APPLICATION); - else - SetAppl(TNC->BPQPort, TNC->APPLFLAGS | Tracebit, 0); + if (TNC->Channels[0]) + BPQStream = TNC->Channels[0]->BPQStream; + else if (TNC->TNC2Stream[0]) + BPQStream = TNC->TNC2Stream[0]->BPQPort; + else if (TNC->BPQPort) + BPQStream = TNC->BPQPort; + + if (BPQStream) + { + if (TNC->CONOK) + SetAppl(BPQStream, TNC->APPLFLAGS | Tracebit, TNC->APPLICATION); + else + SetAppl(BPQStream, TNC->APPLFLAGS | Tracebit, 0); + } - Stamp = GetRaw(TNC->BPQPort, (char *)&MONITORDATA, &len, &count); + Stamp = GetRaw(BPQStream, (char *)&MONITORDATA, &len, &count); if (len == 0) return; diff --git a/VARA.c b/VARA.c index 40a02c2..73b4b11 100644 --- a/VARA.c +++ b/VARA.c @@ -2433,6 +2433,24 @@ static VOID CloseComplete(struct TNCINFO * TNC, int Stream) VARASendCommand(TNC, "BW500\r", TRUE); else if (TNC->DefaultMode == 54) VARASendCommand(TNC, "BW2750\r", TRUE); + + // If a default frequency is specified, set it + + if (TNC->DefaultTXFreq && TNC->TXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->TXRadio, TNC->DefaultTXFreq); + Rig_Command(-1, Msg); + } + + if (TNC->DefaultRXFreq && TNC->RXRadio && TNC->TXRadio != TNC->RXRadio) + { + char Msg[128]; + + sprintf(Msg, "R%d %f", TNC->RXRadio, TNC->DefaultRXFreq); + Rig_Command(-1, Msg); + } } diff --git a/Versions.h b/Versions.h index 42c9d9f..0d1f361 100644 --- a/Versions.h +++ b/Versions.h @@ -10,8 +10,8 @@ #endif -#define KVers 6,0,23,51 -#define KVerstring "6.0.23.51\0" +#define KVers 6,0,23,55 +#define KVerstring "6.0.23.55\0" #ifdef CKernel diff --git a/WebMail.c b/WebMail.c index f76584b..b5d0e6b 100644 --- a/WebMail.c +++ b/WebMail.c @@ -3589,7 +3589,7 @@ char * BuildB2Header(WebMailInfo * WebMail, struct MsgInfo * Msg, char ** ToCall "Mbo: %s\r\n", Msg->title, BBSName); - NewMsg += sprintf(NewMsg, "Body: %d\r\n", (int)strlen(WebMail->Body)); + NewMsg += sprintf(NewMsg, "Body: %d\r\n", (int)strlen(WebMail->Body) + WebMail->HeaderLen + WebMail->FooterLen); Msg->B2Flags = B2Msg; @@ -6063,7 +6063,7 @@ int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer) struct UserInfo * User; int m; struct MsgInfo * Msg; - char * ptr = &OutBuffer[4]; + char * ptr = &OutBuffer[10]; // allow room for full payload length (64 bit) int n = NumberofMessages; char Via[64]; @@ -6145,25 +6145,39 @@ int ProcessWebmailWebSock(char * MsgPtr, char * OutBuffer) ptr += sprintf(ptr, "%s \r\n", ptr); - Len = ptr - &OutBuffer[4]; + Len = ptr - &OutBuffer[10]; OutBuffer[0] = 0x81; // Fin, Data if (Len < 126) { OutBuffer[1] = Len; - memmove(&OutBuffer[2], &OutBuffer[4], Len); + memmove(&OutBuffer[2], &OutBuffer[10], Len); return Len + 2; } - else + else if (Len < 65536) { - OutBuffer[1] = 126; // Unmasked, Extended Len + OutBuffer[1] = 126; // Unmasked, Extended Len 16 OutBuffer[2] = Len >> 8; OutBuffer[3] = Len & 0xff; - + memmove(&OutBuffer[4], &OutBuffer[10], Len); return Len + 4; } + else + { + OutBuffer[1] = 127; // Unmasked, Extended Len 64 bits + // Len is 32 bits, so pad with zeros + OutBuffer[2] = 0; + OutBuffer[3] = 0; + OutBuffer[4] = 0; + OutBuffer[5] = 0; + OutBuffer[6] = (Len >> 24) & 0xff; + OutBuffer[7] = (Len >> 16) & 0xff; + OutBuffer[8] = (Len >> 8) & 0xff; + OutBuffer[9] = Len & 0xff; + return Len + 10; + } } diff --git a/tncinfo.h b/tncinfo.h index f795d94..d29886f 100644 --- a/tncinfo.h +++ b/tncinfo.h @@ -538,7 +538,13 @@ typedef struct TNCINFO int RXRadio; // Rigcontrol Radio Number for RX long long int TXFreq; // Freq to set on tx before ptt - long long int DefaultFreq; // Freq to set on tx after ptt + double ActiveTXFreq; // Freq to set on tx after attach + double ActiveRXFreq; // Freq to set on rx after attach + + double DefaultTXFreq; // Freq to set on tx after close + double DefaultRXFreq; // Freq to set on rx after close + + int TXOffset; // Correction to TXFreq int PID; // Process ID for Software TNC