10506 lines
228 KiB
C
10506 lines
228 KiB
C
/*
|
|
Copyright 2001-2022 John Wiseman G8BPQ
|
|
|
|
This file is part of LinBPQ/BPQ32.
|
|
|
|
LinBPQ/BPQ32 is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
LinBPQ/BPQ32 is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
|
|
*/
|
|
|
|
//
|
|
// Rig Control Module
|
|
//
|
|
|
|
// Dec 29 2009
|
|
|
|
// Add Scan Control for SCS
|
|
|
|
// August 2010
|
|
|
|
// Fix logic error in Port Initialisation (wasn't always raising RTS and DTR
|
|
// Clear RTS and DTR on close
|
|
|
|
// Fix Kenwood processing of multiple messages in one packet.
|
|
|
|
// Fix reporting of set errors in scan to the wrong session
|
|
|
|
|
|
// Yaesu List
|
|
|
|
// FT990 define as FT100
|
|
|
|
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
#define _CRT_SECURE_NO_DEPRECATE
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "time.h"
|
|
|
|
#include "CHeaders.h"
|
|
#include "tncinfo.h"
|
|
#ifdef WIN32
|
|
#include <commctrl.h>
|
|
#else
|
|
char *fcvt(double number, int ndigits, int *decpt, int *sign);
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <netinet/tcp.h>
|
|
#endif
|
|
#include "bpq32.h"
|
|
|
|
#include "hidapi.h"
|
|
|
|
int Row = -20;
|
|
|
|
extern struct PORTCONTROL * PORTTABLE;
|
|
|
|
VOID __cdecl Debugprintf(const char * format, ...);
|
|
|
|
struct RIGINFO * RigConfig(struct TNCINFO * TNC, char * buf, int Port);
|
|
struct RIGPORTINFO * CreateTTYInfo(int port, int speed);
|
|
BOOL RigCloseConnection(struct RIGPORTINFO * PORT);
|
|
BOOL RigWriteCommBlock(struct RIGPORTINFO * PORT);
|
|
BOOL DestroyTTYInfo(int port);
|
|
void CheckRX(struct RIGPORTINFO * PORT);
|
|
static int OpenRigCOMMPort(struct RIGPORTINFO * PORT, VOID * Port, int Speed);
|
|
VOID ICOMPoll(struct RIGPORTINFO * PORT);
|
|
VOID ProcessFrame(struct RIGPORTINFO * PORT, UCHAR * rxbuff, int len);
|
|
VOID ProcessICOMFrame(struct RIGPORTINFO * PORT, UCHAR * rxbuffer, int Len);
|
|
int SendResponse(int Stream, char * Msg);
|
|
VOID ProcessYaesuFrame(struct RIGPORTINFO * PORT);
|
|
VOID YaesuPoll(struct RIGPORTINFO * PORT);
|
|
VOID ProcessYaesuCmdAck(struct RIGPORTINFO * PORT);
|
|
VOID ProcessKenwoodFrame(struct RIGPORTINFO * PORT, int Length);
|
|
VOID KenwoodPoll(struct RIGPORTINFO * PORT);
|
|
VOID DummyPoll(struct RIGPORTINFO * PORT);
|
|
VOID SwitchAntenna(struct RIGINFO * RIG, char Antenna);
|
|
VOID DoBandwidthandAntenna(struct RIGINFO *RIG, struct ScanEntry * ptr);
|
|
VOID SetupScanInterLockGroups(struct RIGINFO *RIG);
|
|
VOID ProcessFT100Frame(struct RIGPORTINFO * PORT);
|
|
VOID ProcessFT990Frame(struct RIGPORTINFO * PORT);
|
|
VOID ProcessFT1000Frame(struct RIGPORTINFO * PORT);
|
|
VOID AddNMEAChecksum(char * msg);
|
|
VOID ProcessNMEA(struct RIGPORTINFO * PORT, char * NMEAMsg, int len);
|
|
VOID COMSetDTR(HANDLE fd);
|
|
VOID COMClearDTR(HANDLE fd);
|
|
VOID COMSetRTS(HANDLE fd);
|
|
VOID COMClearRTS(HANDLE fd);
|
|
void CM108_set_ptt(struct RIGINFO *RIG, int PTTState);
|
|
BOOL OpenHIDPort(struct RIGPORTINFO * PORT, VOID * Port, int Speed);
|
|
int HID_Read_Block(struct RIGPORTINFO * PORT);
|
|
int HID_Write_Block(struct RIGPORTINFO * PORT);
|
|
HANDLE rawhid_open(char * Device);
|
|
int rawhid_recv(int num, void *buf, int len, int timeout);
|
|
int rawhid_send(int num, void *buf, int len, int timeout);
|
|
void rawhid_close(int num);
|
|
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT);
|
|
VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT);
|
|
int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr);
|
|
void ProcessHAMLIBFrame(struct RIGPORTINFO * PORT, int Length);
|
|
VOID HAMLIBPoll(struct RIGPORTINFO * PORT);
|
|
void HAMLIBSlaveThread(struct RIGINFO * RIG);
|
|
void CheckAndProcessRTLUDP(struct RIGPORTINFO * PORT);
|
|
VOID RTLUDPPoll(struct RIGPORTINFO * PORT);
|
|
VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT);
|
|
VOID FLRIGPoll(struct RIGPORTINFO * PORT);
|
|
void ProcessFLRIGFrame(struct RIGPORTINFO * PORT);
|
|
VOID FLRIGSendCommand(struct RIGPORTINFO * PORT, char * Command, char * Value);
|
|
|
|
VOID ProcessSDRRadioFrame(struct RIGPORTINFO * PORT, int Length);
|
|
VOID SDRRadioPoll(struct RIGPORTINFO * PORT);
|
|
|
|
VOID SetupPortRIGPointers();
|
|
VOID PTTCATThread(struct RIGINFO *RIG);
|
|
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT);
|
|
|
|
// ----- G7TAJ ----
|
|
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT);
|
|
VOID SDRANGELPoll(struct RIGPORTINFO * PORT);
|
|
void ProcessSDRANGELFrame(struct RIGPORTINFO * PORT);
|
|
VOID SDRANGELSendCommand(struct RIGPORTINFO * PORT, char * Command, char * Value);
|
|
void SDRANGELProcessMessage(struct RIGPORTINFO * PORT);
|
|
|
|
// ----- G7TAJ ----
|
|
|
|
|
|
int SendPTCRadioCommand(struct TNCINFO * TNC, char * Block, int Length);
|
|
int GetPTCRadioCommand(struct TNCINFO * TNC, char * Block);
|
|
int BuildRigCtlPage(char * _REPLYBUFFER);
|
|
void SendRigWebPage();
|
|
|
|
extern TRANSPORTENTRY * L4TABLE;
|
|
HANDLE hInstance;
|
|
|
|
VOID APIENTRY CreateOneTimePassword(char * Password, char * KeyPhrase, int TimeOffset);
|
|
BOOL APIENTRY CheckOneTimePassword(char * Password, char * KeyPhrase);
|
|
|
|
char * GetApplCallFromName(char * App);
|
|
|
|
char Modes[25][6] = {"LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", "CW-R", "RTTY-R",
|
|
"????","????","????","????","????","????","????","????","DV", "LSBD1",
|
|
"USBD1", "LSBD2","USBD2", "LSBD3","USBD3", "????"};
|
|
|
|
/*
|
|
DV = 17
|
|
F8101
|
|
(0000=LSB, 0001=USB, 0002=AM,
|
|
0003=CW, 0004=RTTY,
|
|
0018=LSB D1, 0019=USB D1,
|
|
0020=LSB D2, 0021=USB D2,
|
|
0022=LSB D3, 0023=USB D3
|
|
*/
|
|
// 0 1 2 3 4 5 6 7 8 9 0A 0B 0C 88
|
|
|
|
char YaesuModes[16][6] = {"LSB", "USB", "CW", "CWR", "AM", "", "", "", "FM", "", "DIG", "", "PKT", "FMN", "????"};
|
|
|
|
char FT100Modes[9][6] = {"LSB", "USB", "CW", "CWR", "AM", "DIG", "FM", "WFM", "????"};
|
|
|
|
char FT990Modes[13][6] = {"LSB", "USB", "CW2k4", "CW500", "AM6k", "AM2k4", "FM", "FM", "RTTYL", "RTTYU", "PKTL", "PKTFM", "????"};
|
|
|
|
char FT1000Modes[13][6] = {"LSB", "USB", "CW", "CWR", "AM", "AMS", "FM", "WFM", "RTTYL", "RTTYU", "PKTL", "PKTF", "????"};
|
|
|
|
char FTRXModes[8][6] = {"LSB", "USB", "CW", "AM", "FM", "RTTY", "PKT", ""};
|
|
|
|
char KenwoodModes[16][6] = {"????", "LSB", "USB", "CW", "FM", "AM", "FSK", "????"};
|
|
|
|
char FT2000Modes[16][6] = {"????", "LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "PKT-L", "FSK-R", "PKT-FM", "FM-N", "PKT-U", "????"};
|
|
|
|
char FTDX10Modes[16][9] = {"????", "LSB", "USB", "CW-U", "FM", "AM", "RTTY-L", "CW-L", "DATA-L", "RTTY-U", "DATA-FM", "FM-N", "DATA-U", "AM-N", "PSK", "DATA-FM-N"};
|
|
|
|
char FT991AModes[16][9] = {"????", "LSB", "USB", "CW-U", "FM", "AM", "RTTY-LSB", "CW-L", "DATA-LSB", "RTTY-USB", "DATA-FM", "FM-N", "DATA-USB", "AM-N", "C4FM", "????"};
|
|
|
|
char FLEXModes[16][6] = {"LSB", "USB", "DSB", "CWL", "CWU", "FM", "AM", "DIGU", "SPEC", "DIGL", "SAM", "DRM"};
|
|
|
|
char AuthPassword[100] = "";
|
|
|
|
char LastPassword[17];
|
|
|
|
int NumberofPorts = 0;
|
|
|
|
BOOL EndPTTCATThread = FALSE;
|
|
|
|
int HAMLIBMasterRunning = 0;
|
|
int HAMLIBSlaveRunning = 0;
|
|
int FLRIGRunning = 0;
|
|
|
|
// ---- G7TAJ ----
|
|
int SDRANGELRunning = 0;
|
|
// ---- G7TAJ ----
|
|
|
|
char * RigWebPage = 0;
|
|
int RigWebPageLen = 0;
|
|
|
|
|
|
struct RIGPORTINFO * PORTInfo[MAXBPQPORTS + 2] = {NULL}; // Records are Malloc'd
|
|
|
|
struct RIGINFO * DLLRIG = NULL; // Rig record for dll PTT interface (currently only for UZ7HO);
|
|
|
|
|
|
struct TimeScan * AllocateTimeRec(struct RIGINFO * RIG)
|
|
{
|
|
struct TimeScan * Band = zalloc(sizeof (struct TimeScan));
|
|
|
|
RIG->TimeBands = realloc(RIG->TimeBands, (++RIG->NumberofBands+2) * sizeof(void *));
|
|
RIG->TimeBands[RIG->NumberofBands] = Band;
|
|
RIG->TimeBands[RIG->NumberofBands+1] = NULL;
|
|
|
|
return Band;
|
|
}
|
|
|
|
struct ScanEntry ** CheckTimeBands(struct RIGINFO * RIG)
|
|
{
|
|
int i = 0;
|
|
time_t NOW = time(NULL) % 86400;
|
|
|
|
// Find TimeBand
|
|
|
|
while (i < RIG->NumberofBands)
|
|
{
|
|
if (RIG->TimeBands[i + 1]->Start > NOW)
|
|
{
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
RIG->FreqPtr = RIG->TimeBands[i]->Scanlist;
|
|
|
|
return RIG->FreqPtr;
|
|
}
|
|
|
|
VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC);
|
|
|
|
VOID Rig_PTT(struct TNCINFO * TNC, BOOL PTTState)
|
|
{
|
|
if (TNC == NULL) return;
|
|
|
|
if (TNC->TXRIG)
|
|
Rig_PTTEx(TNC->TXRIG, PTTState, TNC);
|
|
else
|
|
Rig_PTTEx(TNC->RIG, PTTState, TNC);
|
|
}
|
|
|
|
VOID Rig_PTTEx(struct RIGINFO * RIG, BOOL PTTState, struct TNCINFO * TNC)
|
|
{
|
|
struct RIGPORTINFO * PORT;
|
|
int i, Len;
|
|
char cmd[32];
|
|
char onString[128]; // Actual CAT strings to send. May be modified for QSY on PTT
|
|
char offString[128];
|
|
int onLen = 0, offLen = 0;
|
|
|
|
if (RIG == NULL) return;
|
|
|
|
PORT = RIG->PORT;
|
|
|
|
if (PORT == NULL)
|
|
return;
|
|
|
|
// CAT string defaults to that set up by RIGConfig in RIG->PTTOn and RIG->PTTOff,
|
|
// but can be overidden by Port specify strings from TNC->PTTOn and TNC->PTTOff.
|
|
// If PTTSetsFreq is set on a Rig, that overrides the RIG->PTTOn but not TNC->PTTOn
|
|
|
|
|
|
if (PTTState)
|
|
{
|
|
MySetWindowText(RIG->hPTT, "T");
|
|
RIG->WEB_PTT = 'T';
|
|
RIG->PTTTimer = PTTLimit;
|
|
RIG->repeatPTTOFFTimer = 0; // Cancel repeated off command
|
|
|
|
if (TNC && TNC->PTTOn[0])
|
|
{
|
|
memcpy(onString, TNC->PTTOn, TNC->PTTOnLen);
|
|
onLen = TNC->PTTOnLen;
|
|
}
|
|
else
|
|
{
|
|
memcpy(onString, RIG->PTTOn, RIG->PTTOnLen);
|
|
onLen = RIG->PTTOnLen;
|
|
|
|
// If PTT_SETS_FREQ set calculate TX Freq and see if changed
|
|
|
|
// Freq can be set on the TNC, the RIG, or calculated from current rx freq + pttOffset
|
|
|
|
if (TNC && RIG->PTTSetsFreq)
|
|
{
|
|
long long txfreq = 0;
|
|
|
|
if (TNC->TXFreq)
|
|
txfreq = TNC->TXFreq + TNC->TXOffset + RIG->txError;
|
|
else if (TNC->RIG && TNC->RIG->txFreq)
|
|
txfreq = RIG->txFreq; // Used if not associated with a TNC port - eg HAMLIB + WSJT
|
|
else if (TNC->RIG && TNC->RIG->RigFreq != 0.0)
|
|
{
|
|
// Use RigFreq + pttOffset, so TX Tracks RX
|
|
|
|
long long rxfreq = (long long)(TNC->RIG->RigFreq * 1000000.0) - TNC->RIG->rxOffset;
|
|
txfreq = rxfreq + RIG->pttOffset + RIG->txError;
|
|
txfreq += RIG->rxError;
|
|
}
|
|
|
|
if (txfreq)
|
|
{
|
|
if (RIG->lastSetFreq != txfreq)
|
|
{
|
|
char FreqString[80];
|
|
char * CmdPtr = onString;
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
|
|
|
|
RIG->lastSetFreq = txfreq;
|
|
|
|
// Convert to CAT string
|
|
|
|
sprintf(FreqString, "%012d", txfreq);
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
// CI-V must send all commands as one string, or Radio will start to ack them and
|
|
// collide with rest of command
|
|
|
|
// Set Freq is sent before set PTT, so set up QSY string then copy PTT string to buffer
|
|
// Need to convert two chars to bcd digit
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x5; // Set frequency command
|
|
|
|
*(CmdPtr++) = (FreqString[11] - 48) | ((FreqString[10] - 48) << 4);
|
|
*(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;
|
|
onLen = 10;
|
|
}
|
|
else
|
|
{
|
|
*(CmdPtr++) = (FreqString[3] - 48);
|
|
*(CmdPtr++) = 0xFD;
|
|
onLen = 11;
|
|
}
|
|
|
|
// Now add PTT String
|
|
|
|
memcpy(&onString[onLen], RIG->PTTOn, RIG->PTTOnLen);
|
|
onLen += RIG->PTTOnLen;
|
|
|
|
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
|
|
|
|
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;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Drop PTT
|
|
|
|
MySetWindowText(RIG->hPTT, " ");
|
|
RIG->WEB_PTT = ' ';
|
|
RIG->PTTTimer = 0;
|
|
if (PORT->PortType == ICOM)
|
|
RIG->repeatPTTOFFTimer = 300; // set 30 second repeated off command
|
|
|
|
if (TNC && TNC->PTTOff[0])
|
|
{
|
|
memcpy(offString, TNC->PTTOff, TNC->PTTOffLen);
|
|
offLen = TNC->PTTOffLen;
|
|
RIG->lastSetFreq = 0;
|
|
}
|
|
else
|
|
{
|
|
memcpy(offString, RIG->PTTOff, RIG->PTTOffLen);
|
|
offLen = RIG->PTTOffLen;
|
|
|
|
// If PTT_SETS_FREQ set calculate TX Freq and see if changed
|
|
|
|
if (PTTState == 0 && RIG->PTTSetsFreq && RIG->defaultFreq)
|
|
{
|
|
// Dropped PTT. See if need to set freq back to default
|
|
|
|
long long txfreq = RIG->defaultFreq + RIG->txError;
|
|
|
|
if (RIG->lastSetFreq != txfreq)
|
|
{
|
|
char FreqString[80];
|
|
char * CmdPtr = offString;
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
|
|
RIG->lastSetFreq = txfreq;
|
|
|
|
// Convert to CAT string
|
|
|
|
sprintf(FreqString, "%012d", txfreq);
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
// CI-V must send all commands as one string, or Radio will start to ack them and
|
|
// collide with rest of command
|
|
|
|
// Set Freq is sent after drop PTT, so copy PTT string to buffer then set up QSY string
|
|
// Need to convert two chars to bcd digit
|
|
|
|
// We copied off string earlier, so just append QSY string
|
|
|
|
CmdPtr += offLen;
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x5; // Set frequency command
|
|
|
|
*(CmdPtr++) = (FreqString[11] - 48) | ((FreqString[10] - 48) << 4);
|
|
*(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;
|
|
offLen += 10;
|
|
}
|
|
else
|
|
{
|
|
*(CmdPtr++) = (FreqString[3] - 48);
|
|
*(CmdPtr++) = 0xFD;
|
|
offLen += 11;
|
|
}
|
|
|
|
case FLRIG:
|
|
|
|
sprintf(cmd, "<double>%lld</double>", 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
|
|
|
|
Len = sprintf(cmd, "F %lld\n", txfreq);
|
|
send(PORT->remoteSock, cmd, Len, 0);
|
|
RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Now send the command
|
|
|
|
if (RIG->PTTMode & PTTCI_V)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
|
|
// Don't read for 10 secs to avoid clash with PTT OFF
|
|
// Should do this for all rigs on port
|
|
|
|
for (i = 0; i< PORT->ConfiguredRigs; i++)
|
|
PORT->Rigs[i].PollCounter = 100;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
case KENWOOD:
|
|
case FT2000:
|
|
case FTDX10:
|
|
case FT991A:
|
|
case FLEX:
|
|
case NMEA:
|
|
|
|
if (PTTState)
|
|
{
|
|
memcpy(Poll, onString, onLen);
|
|
PORT->TXLen = onLen;
|
|
}
|
|
else
|
|
{
|
|
memcpy(Poll, offString, offLen);
|
|
PORT->TXLen = offLen;
|
|
}
|
|
|
|
RigWriteCommBlock(PORT);
|
|
|
|
if (PORT->PortType == ICOM && !PTTState)
|
|
RigWriteCommBlock(PORT); // Send ICOM PTT OFF Twice
|
|
|
|
PORT->Retries = 1;
|
|
|
|
if (PORT->PortType != ICOM)
|
|
PORT->Timeout = 0;
|
|
|
|
return;
|
|
|
|
case FT100:
|
|
case FT990:
|
|
case FT1000:
|
|
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = PTTState; // OFF/ON
|
|
*(Poll++) = 15;
|
|
|
|
PORT->TXLen = 5;
|
|
RigWriteCommBlock(PORT);
|
|
|
|
PORT->Retries = 1;
|
|
PORT->Timeout = 0;
|
|
|
|
return;
|
|
|
|
case YAESU: // 897 - maybe others
|
|
|
|
*(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 FLRIG:
|
|
|
|
sprintf(cmd, "<i4>%d</i4>", PTTState);
|
|
FLRIGSendCommand(PORT, "rig.set_ptt", cmd);
|
|
RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF
|
|
|
|
return;
|
|
|
|
case HAMLIB:
|
|
|
|
Len = sprintf(cmd, "T %d\n", PTTState);
|
|
send(PORT->remoteSock, cmd, Len, 0);
|
|
RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (RIG->PTTMode & PTTRTS)
|
|
if (PTTState)
|
|
COMSetRTS(PORT->hPTTDevice);
|
|
else
|
|
COMClearRTS(PORT->hPTTDevice);
|
|
|
|
if (RIG->PTTMode & PTTDTR)
|
|
if (PTTState)
|
|
COMSetDTR(PORT->hPTTDevice);
|
|
else
|
|
COMClearDTR(PORT->hPTTDevice);
|
|
|
|
if (RIG->PTTMode & PTTCM108)
|
|
CM108_set_ptt(RIG, PTTState);
|
|
|
|
if (RIG->PTTMode & PTTHAMLIB)
|
|
{
|
|
char Msg[16];
|
|
int Len = sprintf(Msg, "T %d\n", PTTState);
|
|
|
|
Len = send(PORT->remoteSock, Msg, Len, 0);
|
|
RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF
|
|
}
|
|
if (RIG->PTTMode & PTTFLRIG)
|
|
{
|
|
char cmd[32];
|
|
|
|
sprintf(cmd, "<i4>%d</i4>", PTTState);
|
|
FLRIGSendCommand(PORT, "rig.set_ptt", cmd);
|
|
RIG->PollCounter = 100; // Don't read for 10 secs to avoid clash with PTT OFF
|
|
}
|
|
}
|
|
|
|
void saveNewFreq(struct RIGINFO * RIG, double Freq, char * Mode)
|
|
{
|
|
if (Freq > 0.0)
|
|
{
|
|
_gcvt((Freq + RIG->rxOffset) / 1000000.0, 9, RIG->Valchar);
|
|
strcpy(RIG->WEB_FREQ, RIG->Valchar);
|
|
MySetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
}
|
|
|
|
if (Mode[0])
|
|
{
|
|
strcpy(RIG->ModeString, Mode);
|
|
MySetWindowText(RIG->hMODE, Mode);
|
|
}
|
|
|
|
}
|
|
|
|
// Need version that doesn't need Port Number
|
|
|
|
int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTRY * Session, char * Command);
|
|
|
|
int Rig_Command(TRANSPORTENTRY * Session, char * Command)
|
|
{
|
|
char * ptr;
|
|
int i, n, p, Port;
|
|
TRANSPORTENTRY * L4 = L4TABLE;
|
|
struct RIGPORTINFO * PORT;
|
|
struct RIGINFO * RIG;
|
|
|
|
// Only Allow RADIO from Secure Applications
|
|
|
|
_strupr(Command);
|
|
|
|
ptr = strchr(Command, 13);
|
|
if (ptr) *(ptr) = 0; // Null Terminate
|
|
|
|
if (memcmp(Command, "AUTH ", 5) == 0)
|
|
{
|
|
if (AuthPassword[0] && (memcmp(LastPassword, &Command[5], 16) != 0))
|
|
{
|
|
if (CheckOneTimePassword(&Command[5], AuthPassword))
|
|
{
|
|
Session->Secure_Session = 1;
|
|
|
|
sprintf(Command, "Ok\r");
|
|
|
|
memcpy(LastPassword, &Command[5], 16); // Save
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
sprintf(Command, "Sorry AUTH failed\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (Session != (TRANSPORTENTRY *) -1) // Used for internal Stop/Start
|
|
{
|
|
if (Session->Secure_Session == 0)
|
|
{
|
|
sprintf(Command, "Sorry - you are not allowed to use this command\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
if (NumberofPorts == 0)
|
|
{
|
|
sprintf(Command, "Sorry - Rig Control not configured\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// if Port starts with 'R' then select Radio (was Interlock) number, not BPQ Port
|
|
|
|
if (Command[0] == 'R')
|
|
{
|
|
n = sscanf(&Command[1],"%d ", &Port);
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
{
|
|
PORT = PORTInfo[p];
|
|
|
|
for (i=0; i< PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
if (RIG->Interlock == Port)
|
|
goto portok;
|
|
}
|
|
}
|
|
|
|
sprintf(Command, "Sorry - Port not found\r");
|
|
return FALSE;
|
|
}
|
|
|
|
n = sscanf(Command,"%d ", &Port);
|
|
|
|
// Look for the port
|
|
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
{
|
|
PORT = PORTInfo[p];
|
|
|
|
for (i=0; i< PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
if (RIG->BPQPort & ((uint64_t)1 << Port))
|
|
goto portok;
|
|
}
|
|
}
|
|
|
|
sprintf(Command, "Sorry - Port not found\r");
|
|
return FALSE;
|
|
|
|
portok:
|
|
|
|
return Rig_CommandEx(PORT, RIG, Session, Command);
|
|
}
|
|
|
|
|
|
|
|
static 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";
|
|
|
|
static char Req[] = "<?xml version=\"1.0\"?>\r\n"
|
|
"<methodCall><methodName>%s</methodName>\r\n"
|
|
"%s"
|
|
"</methodCall>\r\n";
|
|
|
|
|
|
// ---- G7TAJ ----
|
|
static char SDRANGEL_MsgHddr[] = "PATCH HTTP/1.1\r\n"
|
|
"User-Agent: BPQ32\r\n"
|
|
"Host: %s\r\n"
|
|
"accept: application/json"
|
|
"Content-Type: application/json"
|
|
"Content-length: %d\r\n"
|
|
"\r\n%s";
|
|
|
|
static char SDRANGEL_FREQ_DATA[] = "{"
|
|
"\"deviceHwType\": \"%s\", "
|
|
"\"direction\": 0,"
|
|
"\"rtlSdrSettings\": {"
|
|
" \"centerFrequency\": \"%s\""
|
|
"}}";
|
|
|
|
//freq = 10489630000
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
|
|
|
|
int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTRY * Session, char * Command)
|
|
{
|
|
int n, ModeNo, Filter, Port = 0;
|
|
double Freq = 0.0;
|
|
char FreqString[80]="", FilterString[80]="", Mode[80]="", Data[80] = "", Dummy[80] = "";
|
|
struct MSGWITHOUTLEN * buffptr;
|
|
UCHAR * Poll;
|
|
|
|
int i;
|
|
TRANSPORTENTRY * L4 = L4TABLE;
|
|
char * ptr;
|
|
int Split, DataFlag, Bandwidth, Antenna;
|
|
struct ScanEntry * FreqPtr;
|
|
char * CmdPtr;
|
|
int Len;
|
|
char MemoryBank = 0; // For Memory Scanning
|
|
int MemoryNumber = 0;
|
|
|
|
// Only Allow RADIO from Secure Applications
|
|
|
|
_strupr(Command);
|
|
|
|
ptr = strchr(Command, 13);
|
|
if (ptr) *(ptr) = 0; // Null Terminate
|
|
|
|
if (memcmp(Command, "AUTH ", 5) == 0)
|
|
{
|
|
if (AuthPassword[0] && (memcmp(LastPassword, &Command[5], 16) != 0))
|
|
{
|
|
if (CheckOneTimePassword(&Command[5], AuthPassword))
|
|
{
|
|
Session->Secure_Session = 1;
|
|
|
|
sprintf(Command, "Ok\r");
|
|
|
|
memcpy(LastPassword, &Command[5], 16); // Save
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
sprintf(Command, "Sorry AUTH failed\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (Session != (TRANSPORTENTRY *) -1) // Used for internal Stop/Start
|
|
{
|
|
if (Session->Secure_Session == 0)
|
|
{
|
|
sprintf(Command, "Sorry - you are not allowed to use this command\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
if (NumberofPorts == 0)
|
|
{
|
|
sprintf(Command, "Sorry - Rig Control not configured\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// if Port starts with 'R' then select Radio (was Interlock) number, not BPQ Port
|
|
|
|
if (Command[0] == 'R')
|
|
n = sscanf(Command,"%s %s %s %s %s", &Dummy, &FreqString[0], &Mode[0], &FilterString[0], &Data[0]);
|
|
else
|
|
n = sscanf(Command,"%d %s %s %s %s", &Port, &FreqString[0], &Mode[0], &FilterString[0], &Data[0]);
|
|
|
|
if (_stricmp(FreqString, "CLOSE") == 0)
|
|
{
|
|
PORT->Closed = 1;
|
|
RigCloseConnection(PORT);
|
|
|
|
MySetWindowText(RIG->hSCAN, "C");
|
|
RIG->WEB_SCAN = 'C';
|
|
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (_stricmp(FreqString, "OPEN") == 0)
|
|
{
|
|
PORT->ReopenDelay = 300;
|
|
PORT->Closed = 0;
|
|
|
|
MySetWindowText(RIG->hSCAN, "");
|
|
RIG->WEB_SCAN = ' ';
|
|
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (n > 1)
|
|
{
|
|
if (_stricmp(FreqString, "SCANSTART") == 0)
|
|
{
|
|
if (RIG->NumberofBands)
|
|
{
|
|
RIG->ScanStopped &= (0xffffffffffffffff ^ ((uint64_t)1 << Port));
|
|
|
|
if (Session != (TRANSPORTENTRY *) -1) // Used for internal Stop/Start
|
|
RIG->ScanStopped &= 0xfffffffffffffffe; // Clear Manual Stopped Bit
|
|
|
|
if (n > 2)
|
|
RIG->ScanCounter = atoi(Mode) * 10; //Start Delay
|
|
else
|
|
RIG->ScanCounter = 10;
|
|
|
|
RIG->WaitingForPermission = FALSE; // In case stuck
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
{
|
|
SetWindowText(RIG->hSCAN, "S");
|
|
RIG->WEB_SCAN = 'S';
|
|
}
|
|
sprintf(Command, "Ok\r");
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 SCANSTART Port %d", Port);
|
|
}
|
|
else
|
|
sprintf(Command, "Sorry no Scan List defined for this port\r");
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (_stricmp(FreqString, "SCANSTOP") == 0)
|
|
{
|
|
RIG->ScanStopped |= ((uint64_t)1 << Port);
|
|
|
|
if (Session != (TRANSPORTENTRY *) -1) // Used for internal Stop/Start
|
|
RIG->ScanStopped |= 1; // Set Manual Stopped Bit
|
|
|
|
MySetWindowText(RIG->hSCAN, "");
|
|
RIG->WEB_SCAN = ' ';
|
|
|
|
sprintf(Command, "Ok\r");
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 SCANSTOP Port %d", Port);
|
|
|
|
RIG->PollCounter = 50 / RIG->PORT->ConfiguredRigs; // Dont read freq for 5 secs
|
|
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (RIG->RIGOK == 0)
|
|
{
|
|
if (Session != (TRANSPORTENTRY *) -1)
|
|
{
|
|
if (PORT->Closed)
|
|
sprintf(Command, "Sorry - Radio port closed\r");
|
|
else
|
|
sprintf(Command, "Sorry - Radio not responding\r");
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
if (n == 2 && _stricmp(FreqString, "FREQ") == 0)
|
|
{
|
|
if (RIG->Valchar[0])
|
|
sprintf(Command, "Frequency is %s MHz\r", RIG->Valchar);
|
|
else
|
|
sprintf(Command, "Frequency not known\r");
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (n == 2 && _stricmp(FreqString, "PTT") == 0)
|
|
{
|
|
Rig_PTTEx(RIG, TRUE, NULL);
|
|
RIG->PTTTimer = 10; // 1 sec
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (Session != (void *)-1)
|
|
{
|
|
if (Session->CIRCUITINDEX == 255)
|
|
RIG->Session = -1;
|
|
else
|
|
RIG->Session = Session->CIRCUITINDEX; // BPQ Stream
|
|
|
|
RIG->PollCounter = 50; // Dont read freq for 5 secs in case clash with Poll
|
|
}
|
|
|
|
if (_stricmp(FreqString, "TUNE") == 0)
|
|
{
|
|
char ReqBuf[256];
|
|
char SendBuff[256];
|
|
char FLPoll[80];
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
CmdPtr = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
FreqPtr->Cmd2 = NULL;
|
|
FreqPtr->Cmd3 = NULL;
|
|
|
|
// IC7100 Tune Fe fe 88 e0 1c 01 02 fd
|
|
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x1C;
|
|
*(CmdPtr++) = 0x01;
|
|
*(CmdPtr++) = 0x02;
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0].Cmd1Len = 8;
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
return TRUE;
|
|
|
|
case KENWOOD:
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
Poll = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "AC111;AC;");
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
return TRUE;
|
|
|
|
case FLRIG:
|
|
|
|
strcpy(FLPoll, "rig.tune");
|
|
|
|
Len = sprintf(ReqBuf, Req, FLPoll, "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
|
|
if (PORT->CONNECTED)
|
|
{
|
|
if (send(PORT->remoteSock, SendBuff, Len, 0) != Len)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
}
|
|
}
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
|
|
sprintf(Command, "Sorry - TUNE not supported on your radio\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (_stricmp(FreqString, "POWER") == 0)
|
|
{
|
|
char PowerString[8] = "";
|
|
int Power = atoi(Mode);
|
|
int len;
|
|
char cmd[80];
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
if (n != 3 || Power > 255)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be POWER Level (0 - 255)\r");
|
|
return FALSE;
|
|
}
|
|
|
|
sprintf(PowerString, "%04d", Power);
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
CmdPtr = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
FreqPtr->Cmd2 = NULL;
|
|
FreqPtr->Cmd3 = NULL;
|
|
|
|
// IC7100 Set Power Fe fe 88 e0 14 0a xx xx fd
|
|
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x14;
|
|
*(CmdPtr++) = 0x0A;
|
|
|
|
// Need to convert param to decimal digits
|
|
|
|
*(CmdPtr++) = (PowerString[1] - 48) | ((PowerString[0] - 48) << 4);
|
|
*(CmdPtr++) = (PowerString[3] - 48) | ((PowerString[2] - 48) << 4);
|
|
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0].Cmd1Len = 9;
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
return TRUE;
|
|
|
|
case KENWOOD:
|
|
|
|
if (n != 3 || Power > 200 || Power < 5)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be POWER Level (5 - 200)\r");
|
|
return FALSE;
|
|
}
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
Poll = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "PC%03d;PC;", Power);
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
return TRUE;
|
|
|
|
case FLRIG:
|
|
|
|
len = sprintf(cmd, "<i4>%d</i4>", Power);
|
|
|
|
FLRIGSendCommand(PORT, "rig.set_power", cmd);
|
|
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
|
|
sprintf(Command, "Sorry - POWER not supported on your Radio\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (_stricmp(FreqString, "CMD") == 0)
|
|
{
|
|
// Send arbitrary command to radio
|
|
|
|
char c;
|
|
int val;
|
|
char * ptr1;
|
|
char * ptr2;
|
|
int Len;
|
|
|
|
if (n < 3)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be CMD Params\r");
|
|
return FALSE;
|
|
}
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == NULL)
|
|
return FALSE;
|
|
|
|
ptr1 = strstr(Command, "CMD");
|
|
|
|
if (ptr1 == NULL)
|
|
return FALSE;
|
|
|
|
ptr1 += 4;
|
|
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
CmdPtr = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
FreqPtr->Cmd2 = NULL;
|
|
FreqPtr->Cmd3 = NULL;
|
|
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
// String is in Hex
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
|
|
while (c = *(ptr1++))
|
|
{
|
|
if (c == ' ') continue; // Allow space between pairs
|
|
|
|
val = c - 0x30;
|
|
if (val > 15) val -= 7;
|
|
val <<= 4;
|
|
c = *(ptr1++) - 0x30;
|
|
if (c > 15) c -= 7;
|
|
val |= c;
|
|
*(CmdPtr++) = val;
|
|
}
|
|
|
|
*(CmdPtr++) = 0xFD;
|
|
*(CmdPtr) = 0;
|
|
|
|
Len = (int)(CmdPtr - (char *)&buffptr[30]);
|
|
break;
|
|
|
|
case KENWOOD:
|
|
case FT991A:
|
|
case FT2000:
|
|
case FTDX10:
|
|
case FLEX:
|
|
case NMEA:
|
|
|
|
// use text command
|
|
|
|
Len = sprintf(CmdPtr, "%S", ptr1);
|
|
break;
|
|
|
|
case YAESU:
|
|
|
|
// String is in Hex (5 values)
|
|
|
|
while (c = *(ptr1++))
|
|
{
|
|
if (c == ' ') continue; // Allow space between pairs
|
|
|
|
val = c - 0x30;
|
|
if (val > 15) val -= 7;
|
|
val <<= 4;
|
|
c = *(ptr1++) - 0x30;
|
|
if (c > 15) c -= 7;
|
|
val |= c;
|
|
*(CmdPtr++) = val;
|
|
}
|
|
|
|
*(CmdPtr) = 0;
|
|
|
|
Len = 5;
|
|
break;
|
|
|
|
case FLRIG:
|
|
|
|
// Two string params - command and params eg rig.set_ptt <i4>1</i4>"
|
|
// or maybe param could be format data - eg i 1
|
|
|
|
_strlwr(ptr1);
|
|
|
|
ptr2 = strlop(ptr1, ' ');
|
|
|
|
if (ptr2 == 0)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be CMD cmd params\r");
|
|
return FALSE;
|
|
}
|
|
|
|
strlop(ptr2, ' ');
|
|
|
|
FLRIGSendCommand(PORT, ptr1, ptr2);
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
sprintf(Command, "Sorry - CMD not supported on your Radio\r");
|
|
return FALSE;
|
|
}
|
|
|
|
FreqPtr[0].Cmd1Len = Len; // for ICOM
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (_memicmp(FreqString, "Chan", 4) == 0)
|
|
{
|
|
if (strchr(FreqString, '/') ) // Bank/Chan
|
|
{
|
|
MemoryBank = FreqString[4];
|
|
MemoryNumber = atoi(&FreqString[6]);
|
|
}
|
|
else
|
|
MemoryNumber = atoi(&FreqString[4]); // Just Chan
|
|
|
|
Freq = 0.0;
|
|
}
|
|
else
|
|
{
|
|
Freq = atof(FreqString);
|
|
|
|
if (Freq < 0.1 && PORT->PortType != FLRIG)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Frequency\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
Freq = Freq * 1000000.0;
|
|
|
|
sprintf(FreqString, "%09.0f", Freq);
|
|
|
|
if (PORT->PortType != ICOM)
|
|
strcpy(Data, FilterString); // Others don't have a filter.
|
|
|
|
Split = DataFlag = Bandwidth = Antenna = 0;
|
|
|
|
_strupr(Data);
|
|
|
|
if (strchr(Data, '+'))
|
|
Split = '+';
|
|
else if (strchr(Data, '-'))
|
|
Split = '-';
|
|
else if (strchr(Data, 'S'))
|
|
Split = 'S';
|
|
else if (strchr(Data, 'D'))
|
|
DataFlag = 1;
|
|
|
|
if (strchr(Data, 'W'))
|
|
Bandwidth = 'W';
|
|
else if (strchr(Data, 'N'))
|
|
Bandwidth = 'N';
|
|
|
|
if (strstr(Data, "A1"))
|
|
Antenna = '1';
|
|
else if (strstr(Data, "A2"))
|
|
Antenna = '2';
|
|
else if (strstr(Data, "A3"))
|
|
Antenna = '3';
|
|
else if (strstr(Data, "A4"))
|
|
Antenna = '4';
|
|
else if (strstr(Data, "A5"))
|
|
Antenna = '5';
|
|
else if (strstr(Data, "A6"))
|
|
Antenna = '6';
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
if (n == 2)
|
|
// Set Freq Only
|
|
|
|
ModeNo = -1;
|
|
else
|
|
{
|
|
if (n < 4 && RIG->ICF8101 == 0)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be Port Freq Mode Filter Width\r");
|
|
return FALSE;
|
|
}
|
|
|
|
Filter = atoi(FilterString);
|
|
|
|
for (ModeNo = 0; ModeNo < 24; ModeNo++)
|
|
{
|
|
if (_stricmp(Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
|
|
if (ModeNo == 24)
|
|
{
|
|
sprintf(Command, "Sorry - Invalid Mode\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
FreqPtr->Freq = Freq;
|
|
FreqPtr->Bandwidth = Bandwidth;
|
|
FreqPtr->Antenna = Antenna;
|
|
FreqPtr->Dwell = 51;
|
|
|
|
CmdPtr = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
FreqPtr->Cmd2 = NULL;
|
|
FreqPtr->Cmd3 = NULL;
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
|
|
|
|
if (MemoryNumber)
|
|
{
|
|
// Set Memory Channel instead of Freq, Mode, etc
|
|
|
|
char ChanString[5];
|
|
|
|
// Send Set Memory, then Channel
|
|
|
|
*(CmdPtr++) = 0x08;
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
|
|
sprintf(ChanString, "%04d", MemoryNumber);
|
|
|
|
*(CmdPtr++) = 0x08;
|
|
*(CmdPtr++) = (ChanString[1] - 48) | ((ChanString[0] - 48) << 4);
|
|
*(CmdPtr++) = (ChanString[3] - 48) | ((ChanString[2] - 48) << 4);
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
FreqPtr[0].Cmd1Len = 14;
|
|
|
|
if (MemoryBank)
|
|
{
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x08;
|
|
*(CmdPtr++) = 0xA0;
|
|
*(CmdPtr++) = MemoryBank - 0x40;
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
FreqPtr[0].Cmd1Len += 8;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (RIG->ICF8101)
|
|
{
|
|
// Set Freq is 1A 35 and set Mode 1A 36
|
|
|
|
*(CmdPtr++) = 0x1A;
|
|
*(CmdPtr++) = 0x35; // Set frequency command
|
|
|
|
// Need to convert two chars to bcd digit
|
|
|
|
*(CmdPtr++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[2] - 48) | ((FreqString[1] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[0] - 48);
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0].Cmd1Len = 12;
|
|
|
|
if (ModeNo != -1) // Dont Set
|
|
{
|
|
CmdPtr = FreqPtr->Cmd2 = FreqPtr->Cmd2Msg;
|
|
FreqPtr[0].Cmd2Len = 9;
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x1A;
|
|
*(CmdPtr++) = 0x36; // Set mode command
|
|
*(CmdPtr++) = 0;
|
|
if (ModeNo > 19)
|
|
*(CmdPtr++) = ModeNo + 12;
|
|
else if (ModeNo > 9)
|
|
*(CmdPtr++) = ModeNo + 6;
|
|
else
|
|
*(CmdPtr++) = ModeNo;
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
// Mode = (Msg[7] >> 4);
|
|
// Mode *= 10;
|
|
// Mode += Msg[7] & 0xf;
|
|
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
*(CmdPtr++) = 0x5; // Set frequency command
|
|
|
|
// Need to convert two chars to bcd digit
|
|
|
|
*(CmdPtr++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[2] - 48) | ((FreqString[1] - 48) << 4);
|
|
if (RIG->IC735)
|
|
{
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0].Cmd1Len = 10;
|
|
}
|
|
else
|
|
{
|
|
*(CmdPtr++) = (FreqString[0] - 48);
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0].Cmd1Len = 11;
|
|
}
|
|
|
|
// Send Set VFO in case last chan was memory
|
|
|
|
// *(CmdPtr++) = 0xFE;
|
|
// *(CmdPtr++) = 0xFE;
|
|
// *(CmdPtr++) = RIG->RigAddr;
|
|
// *(CmdPtr++) = 0xE0;
|
|
|
|
// *(CmdPtr++) = 0x07;
|
|
// *(CmdPtr++) = 0xFD;
|
|
|
|
// FreqPtr[0].Cmd1Len = 17;
|
|
|
|
if (ModeNo != -1) // Dont Set
|
|
{
|
|
CmdPtr = FreqPtr->Cmd2 = FreqPtr->Cmd2Msg;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x6; // Set Mode
|
|
*(CmdPtr++) = ModeNo;
|
|
*(CmdPtr++) = Filter;
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
FreqPtr->Cmd2Len = 8;
|
|
|
|
if (Split)
|
|
{
|
|
CmdPtr = FreqPtr->Cmd3 = FreqPtr->Cmd3Msg;
|
|
FreqPtr->Cmd3Len = 7;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0xF; // Set Mode
|
|
if (Split == 'S')
|
|
*(CmdPtr++) = 0x10;
|
|
else
|
|
if (Split == '+')
|
|
*(CmdPtr++) = 0x12;
|
|
else
|
|
if (Split == '-')
|
|
*(CmdPtr++) = 0x11;
|
|
|
|
*(CmdPtr++) = 0xFD;
|
|
}
|
|
else if (DataFlag)
|
|
{
|
|
CmdPtr = FreqPtr->Cmd3 = FreqPtr->Cmd3Msg;
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x1a;
|
|
|
|
if ((strcmp(RIG->RigName, "IC7100") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7410") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7600") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7610") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7300") == 0))
|
|
{
|
|
FreqPtr[0].Cmd3Len = 9;
|
|
*(CmdPtr++) = 0x6; // Send/read DATA mode with filter set
|
|
*(CmdPtr++) = 0x1; // Data On
|
|
*(CmdPtr++) = Filter; //Filter
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7200") == 0)
|
|
{
|
|
FreqPtr[0].Cmd3Len = 9;
|
|
*(CmdPtr++) = 0x4; // Send/read DATA mode with filter set
|
|
*(CmdPtr++) = 0x1; // Data On
|
|
*(CmdPtr++) = Filter; // Filter
|
|
}
|
|
else
|
|
{
|
|
FreqPtr[0].Cmd3Len = 8;
|
|
*(CmdPtr++) = 0x6; // Set Data
|
|
*(CmdPtr++) = 0x1; //On
|
|
}
|
|
|
|
*(CmdPtr++) = 0xFD;
|
|
}
|
|
}
|
|
|
|
if (Antenna == '5' || Antenna == '6')
|
|
{
|
|
// Antenna select for 746 and maybe others
|
|
|
|
// Could be going in cmd2 3 or 4
|
|
|
|
if (FreqPtr[0].Cmd2 == NULL)
|
|
{
|
|
CmdPtr = FreqPtr->Cmd2 = FreqPtr->Cmd2Msg;
|
|
FreqPtr[0].Cmd2Len = 7;
|
|
}
|
|
else if (FreqPtr[0].Cmd3 == NULL)
|
|
{
|
|
CmdPtr = FreqPtr->Cmd3 = FreqPtr->Cmd3Msg;
|
|
FreqPtr[0].Cmd3Len = 7;
|
|
}
|
|
else
|
|
{
|
|
CmdPtr = FreqPtr->Cmd4 = FreqPtr->Cmd4Msg;
|
|
FreqPtr[0].Cmd4Len = 7;
|
|
}
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x12; // Set Antenna
|
|
*(CmdPtr++) = Antenna - '5'; // 0 for A5 1 for A6
|
|
*(CmdPtr++) = 0xFD;
|
|
}
|
|
}
|
|
}
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
return TRUE;
|
|
|
|
case YAESU:
|
|
|
|
if (n == 2) // Just set freq
|
|
{
|
|
ModeNo = -1;
|
|
}
|
|
else
|
|
{
|
|
for (ModeNo = 0; ModeNo < 15; ModeNo++)
|
|
{
|
|
if (_stricmp(YaesuModes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
|
|
if (ModeNo == 15)
|
|
{
|
|
sprintf(Command, "Sorry -Invalid Mode\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
FreqPtr->Freq = Freq;
|
|
FreqPtr->Bandwidth = Bandwidth;
|
|
FreqPtr->Antenna = Antenna;
|
|
|
|
Poll = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
|
|
// Send Mode then Freq - setting Mode seems to change frequency
|
|
|
|
FreqPtr->Cmd1Len = 0;
|
|
|
|
if (ModeNo != -1) // Set freq only
|
|
{
|
|
*(Poll++) = ModeNo;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 7; // Set Mode
|
|
FreqPtr->Cmd1Len = 5;
|
|
}
|
|
|
|
*(Poll++) = (FreqString[1] - 48) | ((FreqString[0] - 48) << 4);
|
|
*(Poll++) = (FreqString[3] - 48) | ((FreqString[2] - 48) << 4);
|
|
*(Poll++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4);
|
|
*(Poll++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4);
|
|
*(Poll++) = 1; // Set Freq
|
|
|
|
FreqPtr->Cmd1Len += 5;
|
|
|
|
if (strcmp(PORT->Rigs[0].RigName, "FT847") == 0)
|
|
{
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 3; // Status Poll
|
|
|
|
FreqPtr->Cmd1Len = 15;
|
|
}
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
saveNewFreq(RIG, Freq, Mode);
|
|
|
|
return TRUE;
|
|
|
|
|
|
case FT100:
|
|
case FT990:
|
|
case FT1000:
|
|
|
|
if (n == 2) // Set Freq Only
|
|
ModeNo = -1;
|
|
else
|
|
{
|
|
if (n < 3)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be Port Freq Mode\r");
|
|
return FALSE;
|
|
}
|
|
|
|
if (PORT->PortType == FT100)
|
|
{
|
|
for (ModeNo = 0; ModeNo < 8; ModeNo++)
|
|
{
|
|
if (_stricmp(FT100Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
|
|
if (ModeNo == 8)
|
|
{
|
|
sprintf(Command, "Sorry -Invalid Mode\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
else if (PORT->PortType == FT990)
|
|
{
|
|
for (ModeNo = 0; ModeNo < 12; ModeNo++)
|
|
{
|
|
if (_stricmp(FT990Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
|
|
if (ModeNo == 12)
|
|
{
|
|
sprintf(Command, "Sorry -Invalid Mode\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (ModeNo = 0; ModeNo < 12; ModeNo++)
|
|
{
|
|
if (_stricmp(FT1000Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
|
|
if (ModeNo == 12)
|
|
{
|
|
sprintf(Command, "Sorry -Invalid Mode\r");
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
FreqPtr->Freq = Freq;
|
|
FreqPtr->Bandwidth = Bandwidth;
|
|
FreqPtr->Antenna = Antenna;
|
|
|
|
Poll = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
|
|
// Send Mode then Freq - setting Mode seems to change frequency
|
|
|
|
if (ModeNo == -1) // Don't set Mode
|
|
{
|
|
// Changing the length messes up a lot of code,
|
|
// so set freq twice instead of omitting entry
|
|
|
|
*(Poll++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4);
|
|
*(Poll++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4);
|
|
*(Poll++) = (FreqString[3] - 48) | ((FreqString[2] - 48) << 4);
|
|
*(Poll++) = (FreqString[1] - 48) | ((FreqString[0] - 48) << 4);
|
|
*(Poll++) = 10; // Set Freq
|
|
}
|
|
else
|
|
{
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = ModeNo;
|
|
*(Poll++) = 12; // Set Mode
|
|
}
|
|
|
|
*(Poll++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4);
|
|
*(Poll++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4);
|
|
*(Poll++) = (FreqString[3] - 48) | ((FreqString[2] - 48) << 4);
|
|
*(Poll++) = (FreqString[1] - 48) | ((FreqString[0] - 48) << 4);
|
|
*(Poll++) = 10; // Set Freq
|
|
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
*(Poll++) = 0;
|
|
if (PORT->PortType == FT990 || PORT->YaesuVariant == FT1000D)
|
|
*(Poll++) = 3;
|
|
else
|
|
*(Poll++) = 2; // 100 or 1000MP
|
|
|
|
*(Poll++) = 16; // Status Poll
|
|
|
|
FreqPtr->Cmd1Len = 15;
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
return TRUE;
|
|
|
|
case KENWOOD:
|
|
case FT2000:
|
|
case FTDX10:
|
|
case FT991A:
|
|
case FLEX:
|
|
|
|
if (n < 3)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be Port Freq Mode\r");
|
|
return FALSE;
|
|
}
|
|
|
|
for (ModeNo = 0; ModeNo < 16; ModeNo++)
|
|
{
|
|
if (PORT->PortType == FT2000)
|
|
if (_stricmp(FT2000Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
|
|
if (PORT->PortType == FTDX10)
|
|
if (_stricmp(FTDX10Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
|
|
if (PORT->PortType == FT991A)
|
|
if (_stricmp(FT991AModes[ModeNo], Mode) == 0)
|
|
break;
|
|
|
|
if (PORT->PortType == KENWOOD)
|
|
if (_stricmp(KenwoodModes[ModeNo], Mode) == 0)
|
|
break;
|
|
if (PORT->PortType == FLEX)
|
|
if (_stricmp(FLEXModes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
|
|
if (ModeNo > 15)
|
|
{
|
|
sprintf(Command, "Sorry -Invalid Mode\r");
|
|
return FALSE;
|
|
}
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
FreqPtr->Freq = Freq;
|
|
FreqPtr->Bandwidth = Bandwidth;
|
|
FreqPtr->Antenna = Antenna;
|
|
|
|
Poll = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
|
|
if (PORT->PortType == FT2000)
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "FA%s;MD0%X;FA;MD;", &FreqString[1], ModeNo);
|
|
else
|
|
if (PORT->PortType == FT991A || PORT->PortType == FTDX10)
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "FA%s;MD0%X;FA;MD;", FreqString, ModeNo);
|
|
else
|
|
if (PORT->PortType == FLEX)
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "ZZFA00%s;ZZMD%02d;ZZFA;ZZMD;", &FreqString[1], ModeNo);
|
|
else
|
|
{
|
|
if (Antenna == '5' || Antenna == '6')
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "FA00%s;MD%d;AN%c;FA;MD;", FreqString, ModeNo, Antenna - 4);
|
|
else
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "FA00%s;MD%d;FA;MD;", FreqString, ModeNo);
|
|
}
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
return TRUE;
|
|
|
|
|
|
case SDRRADIO:
|
|
|
|
if (n < 3)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be Port Freq Mode\r");
|
|
return FALSE;
|
|
}
|
|
|
|
for (ModeNo = 0; ModeNo < 16; ModeNo++)
|
|
{
|
|
if (_stricmp(KenwoodModes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
|
|
if (ModeNo > 15)
|
|
{
|
|
sprintf(Command, "Sorry -Invalid Mode\r");
|
|
return FALSE;
|
|
}
|
|
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
FreqPtr->Freq = Freq;
|
|
FreqPtr->Bandwidth = Bandwidth;
|
|
FreqPtr->Antenna = Antenna;
|
|
|
|
Poll = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
|
|
FreqPtr->Cmd1Len = sprintf(Poll, "F%c00%s;MD%d;F%c;MD;", RIG->RigAddr, FreqString, ModeNo, RIG->RigAddr);
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
return TRUE;
|
|
|
|
|
|
case NMEA:
|
|
|
|
if (n < 3)
|
|
{
|
|
strcpy(Command, "Sorry - Invalid Format - should be Port Freq Mode\r");
|
|
return FALSE;
|
|
}
|
|
buffptr = GetBuff();
|
|
|
|
if (buffptr == 0)
|
|
{
|
|
sprintf(Command, "Sorry - No Buffers available\r");
|
|
return FALSE;
|
|
}
|
|
|
|
// Build a ScanEntry in the buffer
|
|
|
|
FreqPtr = (struct ScanEntry *)buffptr->Data;
|
|
memset(FreqPtr, 0, sizeof(struct ScanEntry));
|
|
|
|
FreqPtr->Freq = Freq;
|
|
FreqPtr->Bandwidth = Bandwidth;
|
|
FreqPtr->Antenna = Antenna;
|
|
|
|
Poll = FreqPtr->Cmd1 = FreqPtr->Cmd1Msg;
|
|
|
|
i = sprintf(Poll, "$PICOA,90,%02x,RXF,%.6f*xx\r\n", RIG->RigAddr, Freq/1000000.);
|
|
AddNMEAChecksum(Poll);
|
|
Len = i;
|
|
i = sprintf(Poll + Len, "$PICOA,90,%02x,TXF,%.6f*xx\r\n", RIG->RigAddr, Freq/1000000.);
|
|
AddNMEAChecksum(Poll + Len);
|
|
Len += i;
|
|
i = sprintf(Poll + Len, "$PICOA,90,%02x,MODE,%s*xx\r\n", RIG->RigAddr, Mode);
|
|
AddNMEAChecksum(Poll + Len);
|
|
|
|
FreqPtr->Cmd1Len = i + Len;
|
|
|
|
C_Q_ADD(&RIG->BPQtoRADIO_Q, buffptr);
|
|
|
|
return TRUE;
|
|
|
|
case HAMLIB:
|
|
{
|
|
char cmd[80];
|
|
|
|
int len = sprintf(cmd, "F %s\n+f\nM %s %d\n+m\n",
|
|
FreqString, Mode, atoi(Data));
|
|
|
|
send(PORT->remoteSock, cmd, len, 0);
|
|
sprintf(Command, "Ok\r");
|
|
|
|
saveNewFreq(RIG, Freq, Mode);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
case FLRIG:
|
|
{
|
|
char cmd[80];
|
|
|
|
int len = sprintf(cmd, "<double>%.0f</double>", Freq);
|
|
|
|
strcpy(PORT->ScanEntry.Cmd2Msg, Mode);
|
|
strcpy(PORT->ScanEntry.Cmd3Msg, FilterString);
|
|
|
|
if (Freq > 0.0)
|
|
FLRIGSendCommand(PORT, "rig.set_vfo", cmd);
|
|
|
|
else if (PORT->ScanEntry.Cmd2Msg[0] && Mode[0] != '*')
|
|
{
|
|
sprintf(cmd, "<i4>%s</i4>", PORT->ScanEntry.Cmd2Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_mode", cmd);
|
|
}
|
|
|
|
else if (PORT->ScanEntry.Cmd3Msg[0] && strcmp(PORT->ScanEntry.Cmd3Msg, "0") != 0)
|
|
{
|
|
sprintf(cmd, "<i4>%s</i4>", PORT->ScanEntry.Cmd3Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_bandwidth", cmd);
|
|
}
|
|
else
|
|
{
|
|
sprintf(Command, "Sorry - Nothing to do\r");
|
|
return FALSE;
|
|
}
|
|
|
|
PORT->AutoPoll = 0;
|
|
|
|
saveNewFreq(RIG, Freq, Mode);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
case RTLUDP:
|
|
{
|
|
char cmd[80];
|
|
int len = 5;
|
|
int FreqInt = (int)Freq;
|
|
int FM = 0;
|
|
int AM = 1;
|
|
int USB = 2;
|
|
int LSB = 3;
|
|
|
|
cmd[0] = 0;
|
|
cmd[1] = FreqInt & 0xff;
|
|
cmd[2] = (FreqInt >> 8) & 0xff;
|
|
cmd[3] = (FreqInt >> 16) & 0xff;
|
|
cmd[4] = (FreqInt >> 24) & 0xff;
|
|
|
|
len = sendto(PORT->remoteSock, cmd, 5, 0, &PORT->remoteDest, sizeof(struct sockaddr));
|
|
|
|
if (Mode[0])
|
|
{
|
|
if (strcmp(Mode, "FM") == 0)
|
|
memcpy(&cmd[1], &FM, 4);
|
|
else if (strcmp(Mode, "AM") == 0)
|
|
memcpy(&cmd[1], &AM, 4);
|
|
else if (strcmp(Mode, "USB") == 0)
|
|
memcpy(&cmd[1], &USB, 4);
|
|
else if (strcmp(Mode, "LSB") == 0)
|
|
memcpy(&cmd[1], &LSB, 4);
|
|
|
|
cmd[0] = 1;
|
|
len = sendto(PORT->remoteSock, cmd, 5, 0, &PORT->remoteDest, sizeof(struct sockaddr));
|
|
}
|
|
|
|
saveNewFreq(RIG, Freq, Mode);
|
|
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
// --- G7TAJ ----
|
|
case SDRANGEL:
|
|
{
|
|
char cmd[80];
|
|
int len = sprintf(cmd, "%.0f", Freq);
|
|
|
|
strcpy(PORT->ScanEntry.Cmd2Msg, Mode);
|
|
strcpy(PORT->ScanEntry.Cmd3Msg, FilterString);
|
|
|
|
if (Freq > 0.0)
|
|
{
|
|
SDRANGELSendCommand(PORT, "FREQSET", cmd);
|
|
sprintf(Command, "Ok\r");
|
|
return FALSE;
|
|
}
|
|
//TODO
|
|
/* else if (PORT->ScanEntry.Cmd2Msg[0] && Mode[0] != '*')
|
|
{
|
|
sprintf(cmd, "<i4>%s</i4>", PORT->ScanEntry.Cmd2Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_mode", cmd);
|
|
}
|
|
|
|
else if (PORT->ScanEntry.Cmd3Msg[0] && strcmp(PORT->ScanEntry.Cmd3Msg, "0") != 0)
|
|
{
|
|
sprintf(cmd, "<i4>%s</i4>", PORT->ScanEntry.Cmd3Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_bandwidth", cmd);
|
|
}
|
|
*/
|
|
else
|
|
{
|
|
sprintf(Command, "Sorry - Nothing to do\r");
|
|
return FALSE;
|
|
}
|
|
|
|
PORT->AutoPoll = 0;
|
|
}
|
|
// --- G7TAJ ----
|
|
|
|
|
|
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int BittoInt(UINT BitMask)
|
|
{
|
|
// Returns bit position of first 1 bit in BitMask
|
|
|
|
int i = 0;
|
|
while ((BitMask & 1) == 0)
|
|
{
|
|
BitMask >>= 1;
|
|
i ++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
extern char * RadioConfigMsg[36];
|
|
|
|
struct TNCINFO RIGTNC; // Dummy TNC Record for Rigcontrol without a corresponding TNC
|
|
|
|
DllExport BOOL APIENTRY Rig_Init()
|
|
{
|
|
struct RIGPORTINFO * PORT;
|
|
int i, p, port;
|
|
struct RIGINFO * RIG;
|
|
struct TNCINFO * TNC = &RIGTNC;
|
|
HWND hDlg;
|
|
#ifndef LINBPQ
|
|
int RigRow = 0;
|
|
#endif
|
|
int NeedRig = 0;
|
|
int Interlock = 0;
|
|
|
|
memset(&RIGTNC, 0, sizeof(struct TNCINFO));
|
|
|
|
TNCInfo[70] = TNC;
|
|
|
|
// Get config info
|
|
|
|
NumberofPorts = 0;
|
|
|
|
for (port = 0; port < MAXBPQPORTS; port++)
|
|
PORTInfo[port] = NULL;
|
|
|
|
// See if any rigcontrol defined (either RADIO or RIGCONTROL lines)
|
|
|
|
for (port = 0; port < MAXBPQPORTS; port++)
|
|
{
|
|
if (RadioConfigMsg[port])
|
|
NeedRig++;
|
|
}
|
|
|
|
if (NeedRig == 0)
|
|
{
|
|
SetupPortRIGPointers(); // Sets up Dummy Rig Pointer
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#ifndef LINBPQ
|
|
|
|
TNC->Port = 70;
|
|
CreatePactorWindow(TNC, "RIGCONTROL", "RigControl", 10, PacWndProc, 550, NeedRig * 20 + 60, NULL);
|
|
hDlg = TNC->hDlg;
|
|
|
|
#endif
|
|
|
|
TNC->ClientHeight = NeedRig * 20 + 60;
|
|
TNC->ClientWidth = 550;
|
|
|
|
for (port = 0; port < MAXBPQPORTS; port++)
|
|
{
|
|
if (RadioConfigMsg[port])
|
|
{
|
|
char msg[1000];
|
|
|
|
char * SaveRigConfig = _strdup(RadioConfigMsg[port]);
|
|
char * RigConfigMsg1 = _strdup(RadioConfigMsg[port]);
|
|
|
|
Interlock = atoi(&RigConfigMsg1[5]);
|
|
|
|
RIG = RigConfig(TNC, RigConfigMsg1, port);
|
|
|
|
if (RIG == NULL)
|
|
{
|
|
// Report Error
|
|
|
|
sprintf(msg,"Port %d Invalid Rig Config %s", port, SaveRigConfig);
|
|
WritetoConsole(msg);
|
|
free(SaveRigConfig);
|
|
free(RigConfigMsg1);
|
|
continue;
|
|
}
|
|
|
|
RIG->Interlock = Interlock;
|
|
|
|
if (RIG->PORT->IOBASE[0] == 0)
|
|
{
|
|
// We have to find the SCS TNC in this scan group as TNC is now a dummy
|
|
|
|
struct TNCINFO * PTCTNC;
|
|
int n;
|
|
|
|
for (n = 1; n < MAXBPQPORTS; n++)
|
|
{
|
|
PTCTNC = TNCInfo[n];
|
|
|
|
if (PTCTNC == NULL || (PTCTNC->Hardware != H_SCS && PTCTNC->Hardware != H_ARDOP))
|
|
continue;
|
|
|
|
if (PTCTNC->RXRadio != Interlock)
|
|
continue;
|
|
|
|
RIG->PORT->PTC = PTCTNC;
|
|
}
|
|
}
|
|
|
|
#ifndef LINBPQ
|
|
|
|
// Create line for this rig
|
|
|
|
RIG->hLabel = CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
10, RigRow, 80,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
// RIG->hCAT = CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
// 90, RigRow, 40,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
RIG->hFREQ = CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
95, RigRow, 100,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
RIG->hMODE = CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
200, RigRow, 100,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
RIG->hSCAN = CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
300, RigRow, 20,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
RIG->hPTT = CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
320, RigRow, 20,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
RIG->hPORTS = CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
340, RigRow, 210, 20, hDlg, NULL, hInstance, NULL);
|
|
|
|
RigRow += 20;
|
|
|
|
//if (PORT->PortType == ICOM)
|
|
//{
|
|
// sprintf(msg,"%02X", PORT->Rigs[i].RigAddr);
|
|
// SetWindowText(RIG->hCAT, msg);
|
|
//}
|
|
SetWindowText(RIG->hLabel, RIG->RigName);
|
|
#endif
|
|
|
|
RIG->WEB_Label = _strdup(RIG->RigName);
|
|
// RIG->WEB_CAT;
|
|
RIG->WEB_FREQ = zalloc(80);
|
|
RIG->WEB_MODE = zalloc(80);
|
|
RIG->WEB_PORTS = zalloc(80);
|
|
strcpy(RIG->WEB_FREQ, "-----------");
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
RIG->WEB_PTT = ' ';
|
|
RIG->WEB_SCAN = ' ';
|
|
}
|
|
}
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
{
|
|
PORT = PORTInfo[p];
|
|
|
|
if (PORT->PortType == HAMLIB)
|
|
{
|
|
HAMLIBMasterRunning = 1;
|
|
ConnecttoHAMLIB(PORT);
|
|
}
|
|
else if (PORT->PortType == FLRIG)
|
|
{
|
|
FLRIGRunning = 1;
|
|
ConnecttoFLRIG(PORT);
|
|
}
|
|
else if (PORT->PortType == RTLUDP)
|
|
ConnecttoRTLUDP(PORT);
|
|
//---- G7TAJ ----
|
|
else if (PORT->PortType == SDRANGEL)
|
|
{
|
|
SDRANGELRunning = 1;
|
|
ConnecttoSDRANGEL(PORT);
|
|
}
|
|
//---- G7TAJ ----
|
|
else if (PORT->HIDDevice) // This is RAWHID, Not CM108
|
|
OpenHIDPort(PORT, PORT->IOBASE, PORT->SPEED);
|
|
else if (PORT->PTC == 0 && _stricmp(PORT->IOBASE, "CM108") != 0)
|
|
OpenRigCOMMPort(PORT, PORT->IOBASE, PORT->SPEED);
|
|
|
|
if (PORT->PTTIOBASE[0]) // Using separate port for PTT?
|
|
{
|
|
if (PORT->PTTIOBASE[3] == '=')
|
|
PORT->hPTTDevice = OpenCOMPort(&PORT->PTTIOBASE[4], PORT->SPEED, FALSE, FALSE, FALSE, 0);
|
|
else
|
|
PORT->hPTTDevice = OpenCOMPort(&PORT->PTTIOBASE[3], PORT->SPEED, FALSE, FALSE, FALSE, 0);
|
|
}
|
|
else
|
|
PORT->hPTTDevice = PORT->hDevice; // Use same port for PTT
|
|
}
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
{
|
|
PORT = PORTInfo[p];
|
|
|
|
for (i=0; i < PORT->ConfiguredRigs; i++)
|
|
{
|
|
int j;
|
|
int k = 0;
|
|
uint64_t BitMask;
|
|
struct _EXTPORTDATA * PortEntry;
|
|
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
SetupScanInterLockGroups(RIG);
|
|
|
|
// Get record for each port in Port Bitmap
|
|
|
|
// The Scan "Request Permission to Change" code needs the Port Records in order -
|
|
// Those with active connect lock (eg SCS) first, then those with just a connect pending lock (eg WINMOR)
|
|
// then those with neither
|
|
|
|
BitMask = RIG->BPQPort;
|
|
for (j = 0; j < MAXBPQPORTS; j++)
|
|
{
|
|
if (BitMask & 1)
|
|
{
|
|
PortEntry = (struct _EXTPORTDATA *)GetPortTableEntryFromPortNum(j); // BPQ32 port record for this port
|
|
if (PortEntry)
|
|
if (PortEntry->SCANCAPABILITIES == CONLOCK)
|
|
RIG->PortRecord[k++] = PortEntry;
|
|
}
|
|
BitMask >>= 1;
|
|
}
|
|
|
|
BitMask = RIG->BPQPort;
|
|
for (j = 0; j < MAXBPQPORTS; j++)
|
|
{
|
|
if (BitMask & 1)
|
|
{
|
|
PortEntry = (struct _EXTPORTDATA *)GetPortTableEntryFromPortNum(j); // BPQ32 port record for this port
|
|
if (PortEntry)
|
|
if (PortEntry->SCANCAPABILITIES == SIMPLE)
|
|
RIG->PortRecord[k++] = PortEntry;
|
|
}
|
|
BitMask >>= 1;
|
|
}
|
|
|
|
BitMask = RIG->BPQPort;
|
|
for (j = 0; j < MAXBPQPORTS; j++)
|
|
{
|
|
if (BitMask & 1)
|
|
{
|
|
PortEntry = (struct _EXTPORTDATA *)GetPortTableEntryFromPortNum(j); // BPQ32 port record for this port
|
|
if (PortEntry)
|
|
if (PortEntry->SCANCAPABILITIES == NONE)
|
|
RIG->PortRecord[k++] = PortEntry;
|
|
}
|
|
BitMask >>= 1;
|
|
}
|
|
|
|
RIG->PORT = PORT; // For PTT
|
|
|
|
if (RIG->NumberofBands)
|
|
CheckTimeBands(RIG); // Set initial timeband
|
|
|
|
#ifdef WIN32
|
|
if (RIG->PTTCATPort[0]) // Serial port RTS to CAT
|
|
_beginthread(PTTCATThread,0,RIG);
|
|
#endif
|
|
if (RIG->HAMLIBPORT)
|
|
{
|
|
// Open listening socket
|
|
|
|
struct sockaddr_in local_sin; /* Local socket - internet style */
|
|
struct sockaddr_in * psin;
|
|
SOCKET sock = 0;
|
|
u_long param=1;
|
|
|
|
char szBuff[80];
|
|
|
|
psin=&local_sin;
|
|
psin->sin_family = AF_INET;
|
|
psin->sin_addr.s_addr = INADDR_ANY;
|
|
|
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *)¶m,4);
|
|
|
|
psin->sin_port = htons(RIG->HAMLIBPORT); // Convert to network ordering
|
|
|
|
if (bind( sock, (struct sockaddr FAR *) &local_sin, sizeof(local_sin)) == SOCKET_ERROR)
|
|
{
|
|
sprintf(szBuff, "bind(sock) failed port %d Error %d\n", port, WSAGetLastError());
|
|
WritetoConsoleLocal(szBuff);
|
|
closesocket(sock);
|
|
}
|
|
else
|
|
{
|
|
if (listen(sock, 5) < 0)
|
|
{
|
|
sprintf(szBuff, "listen(sock) failed port %d Error %d\n", port, WSAGetLastError());
|
|
WritetoConsoleLocal(szBuff);
|
|
}
|
|
else
|
|
{
|
|
ioctl(sock, FIONBIO, ¶m);
|
|
RIG->ListenSocket = sock;
|
|
_beginthread(HAMLIBSlaveThread, 0, RIG);
|
|
}
|
|
}
|
|
}
|
|
Rig_PTTEx(RIG, 0, NULL); // Send initial PTT Off (Mainly to set input mux on soundcard rigs)
|
|
}
|
|
}
|
|
|
|
// MoveWindow(hDlg, Rect.left, Rect.top, Rect.right - Rect.left, Row + 100, TRUE);
|
|
|
|
SetupPortRIGPointers();
|
|
|
|
RigWebPage = zalloc(10);
|
|
|
|
WritetoConsole("\nRig Control Enabled\n");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DllExport BOOL APIENTRY Rig_Close()
|
|
{
|
|
struct RIGPORTINFO * PORT;
|
|
struct TNCINFO * TNC;
|
|
int n, p;
|
|
|
|
HAMLIBMasterRunning = 0; // Close HAMLIB thread(s)
|
|
HAMLIBSlaveRunning = 0; // Close HAMLIB thread(s)
|
|
FLRIGRunning = 0; // Close FLRIG thread(s)
|
|
// ---- G7TAJ ----
|
|
SDRANGELRunning = 0; // Close SDRANGEL thread(s)
|
|
// ---- G7TAJ ----
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
{
|
|
PORT = PORTInfo[p];
|
|
|
|
if (PORT->PortType == NMEA)
|
|
{
|
|
// Send Remote OFF
|
|
|
|
int i;
|
|
char REMOFF[80];
|
|
|
|
i = sprintf(REMOFF, "$PICOA,90,%02x,REMOTE,OFF*xx\r\n", PORT->Rigs[0].RigAddr);
|
|
AddNMEAChecksum(REMOFF);
|
|
|
|
WriteCOMBlock(PORT->hDevice, REMOFF, i);
|
|
Sleep(200);
|
|
}
|
|
|
|
if (PORT->PortType != HAMLIB && PORT->PortType != RTLUDP && PORT->PortType != FLRIG && strcmp(PORT->IOBASE, "RAWHID") != 0)
|
|
{
|
|
if (PORT->hPTTDevice != PORT->hDevice)
|
|
CloseCOMPort(PORT->hPTTDevice);
|
|
|
|
CloseCOMPort(PORT->hDevice);
|
|
}
|
|
|
|
PORT->hDevice = 0;
|
|
PORT->hPTTDevice = 0;
|
|
|
|
// Free the RIG and Port Records
|
|
|
|
for (n = 0; n < PORT->ConfiguredRigs; n++)
|
|
{
|
|
struct RIGINFO * RIG = &PORT->Rigs[n];
|
|
struct HAMLIBSOCK * Entry = RIG->Sockets;
|
|
struct HAMLIBSOCK * Save;
|
|
|
|
// if RIG has any HAMLIB slave connections, close them
|
|
|
|
Entry = RIG->Sockets;
|
|
|
|
while (Entry)
|
|
{
|
|
closesocket(Entry->Sock);
|
|
Save = Entry;
|
|
Entry = Entry->Next;
|
|
free(Save);
|
|
}
|
|
|
|
RIG->Sockets = 0;
|
|
|
|
if (RIG->TimeBands)
|
|
free (RIG->TimeBands[1]->Scanlist);
|
|
|
|
if (RIG->PTTCATPort[0])
|
|
{
|
|
Rig_PTTEx(RIG, FALSE, NULL); // Make sure PTT is down
|
|
EndPTTCATThread = TRUE;
|
|
}
|
|
}
|
|
|
|
free (PORT);
|
|
PORTInfo[p] = NULL;
|
|
}
|
|
|
|
NumberofPorts = 0; // For possible restart
|
|
|
|
// And free the TNC config info
|
|
|
|
for (p = 1; p < MAXBPQPORTS; p++)
|
|
{
|
|
TNC = TNCInfo[p];
|
|
|
|
if (TNC == NULL)
|
|
continue;
|
|
|
|
TNC->RIG = NULL;
|
|
|
|
// memset(TNC->WL2KInfoList, 0, sizeof(TNC->WL2KInfoList));
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL Rig_Poll()
|
|
{
|
|
int p, i, Len;
|
|
char RigWeb[16384];
|
|
|
|
struct RIGPORTINFO * PORT;
|
|
struct RIGINFO * RIG;
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
{
|
|
PORT = PORTInfo[p];
|
|
|
|
if (PORT->PortType == DUMMY)
|
|
{
|
|
DummyPoll(PORT);
|
|
return TRUE;
|
|
}
|
|
|
|
if (PORT->hDevice == 0)
|
|
{
|
|
// Try to reopen every 15 secs
|
|
|
|
PORT->ReopenDelay++;
|
|
|
|
if (PORT->ReopenDelay > 150)
|
|
{
|
|
PORT->ReopenDelay = 0;
|
|
|
|
if (PORT->PortType == HAMLIB)
|
|
ConnecttoHAMLIB(PORT);
|
|
else if (PORT->PortType == FLRIG)
|
|
ConnecttoFLRIG(PORT);
|
|
else if (PORT->PortType == RTLUDP)
|
|
ConnecttoRTLUDP(PORT);
|
|
// ---- G7TAJ ----
|
|
else if (PORT->PortType == SDRANGEL)
|
|
ConnecttoSDRANGEL(PORT);
|
|
// ---- G7TAJ ----
|
|
else if (PORT->HIDDevice)
|
|
OpenHIDPort(PORT, PORT->IOBASE, PORT->SPEED);
|
|
else if (PORT->PTC == 0
|
|
&& _stricmp(PORT->IOBASE, "REMOTE") != 0
|
|
&& _stricmp(PORT->IOBASE, "CM108") != 0)
|
|
{
|
|
if (PORT->Closed == 0)
|
|
{
|
|
OpenRigCOMMPort(PORT, PORT->IOBASE, PORT->SPEED);
|
|
if (PORT->IOBASE && PORT->PTTIOBASE[0] == 0) // Using separate port for PTT?
|
|
PORT->hPTTDevice = PORT->hDevice;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (PORT == NULL || (PORT->hDevice == 0 && PORT->PTC == 0 && PORT->remoteSock == 0))
|
|
continue;
|
|
|
|
// Check PTT Timers
|
|
|
|
for (i=0; i< PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
// Active PTT command
|
|
|
|
if (RIG->PTTTimer)
|
|
{
|
|
RIG->PTTTimer--;
|
|
if (RIG->PTTTimer == 0)
|
|
Rig_PTTEx(RIG, FALSE, NULL);
|
|
}
|
|
|
|
// repeated off timer
|
|
|
|
if (RIG->repeatPTTOFFTimer)
|
|
{
|
|
RIG->repeatPTTOFFTimer--;
|
|
if (RIG->repeatPTTOFFTimer == 0)
|
|
{
|
|
Rig_PTTEx(RIG, FALSE, NULL);
|
|
RIG->repeatPTTOFFTimer = 0; // Don't repeat repeat!
|
|
}
|
|
}
|
|
}
|
|
|
|
CheckRX(PORT);
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
ICOMPoll(PORT);
|
|
break;
|
|
|
|
case YAESU:
|
|
case FT100:
|
|
case FT990:
|
|
case FT1000:
|
|
|
|
YaesuPoll(PORT);
|
|
break;
|
|
|
|
case KENWOOD:
|
|
case FT2000:
|
|
case FTDX10:
|
|
case FT991A:
|
|
case FLEX:
|
|
case NMEA:
|
|
|
|
KenwoodPoll(PORT);
|
|
break;
|
|
|
|
|
|
case SDRRADIO:
|
|
SDRRadioPoll(PORT);
|
|
break;
|
|
|
|
case HAMLIB:
|
|
HAMLIBPoll(PORT);
|
|
break;
|
|
|
|
case RTLUDP:
|
|
RTLUDPPoll(PORT);
|
|
break;
|
|
|
|
case FLRIG:
|
|
FLRIGPoll(PORT);
|
|
break;
|
|
// ---- G7TAJ ----
|
|
case SDRANGEL:
|
|
SDRANGELPoll(PORT);
|
|
break; }
|
|
// ---- G7TAJ ----
|
|
}
|
|
|
|
// Build page for Web Display
|
|
|
|
Len = BuildRigCtlPage(RigWeb);
|
|
|
|
if (strcmp(RigWebPage, RigWeb) == 0)
|
|
return TRUE; // No change
|
|
|
|
free(RigWebPage);
|
|
|
|
RigWebPage = _strdup(RigWeb);
|
|
|
|
SendRigWebPage();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL RigCloseConnection(struct RIGPORTINFO * PORT)
|
|
{
|
|
// disable event notification and wait for thread
|
|
// to halt
|
|
|
|
CloseCOMPort(PORT->hDevice);
|
|
PORT->hDevice = 0;
|
|
return TRUE;
|
|
|
|
} // end of CloseConnection()
|
|
|
|
#ifndef WIN32
|
|
#define ONESTOPBIT 0
|
|
#define ONE5STOPBITS 1
|
|
#define TWOSTOPBITS 2
|
|
#endif
|
|
|
|
int OpenRigCOMMPort(struct RIGPORTINFO * PORT, VOID * Port, int Speed)
|
|
{
|
|
if (PORT->remoteSock) // Using WINMORCONTROL
|
|
return TRUE;
|
|
|
|
if (PORT->PortType == FT2000 || PORT->PortType == FT991A || PORT->PortType == FTDX10 || strcmp(PORT->Rigs[0].RigName, "FT847") == 0) // FT2000 and similar seem to need two stop bits
|
|
PORT->hDevice = OpenCOMPort((VOID *)Port, Speed, FALSE, FALSE, PORT->Alerted, TWOSTOPBITS);
|
|
else if (PORT->PortType == NMEA)
|
|
PORT->hDevice = OpenCOMPort((VOID *)Port, Speed, FALSE, FALSE, PORT->Alerted, ONESTOPBIT);
|
|
else
|
|
PORT->hDevice = OpenCOMPort((VOID *)Port, Speed, FALSE, FALSE, PORT->Alerted, TWOSTOPBITS);
|
|
|
|
if (PORT->hDevice == 0)
|
|
{
|
|
PORT->Alerted = TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
PORT->Alerted = FALSE;
|
|
|
|
if (PORT->PortType == PTT || (PORT->Rigs[0].PTTMode & PTTRTS))
|
|
COMClearRTS(PORT->hDevice);
|
|
else
|
|
COMSetRTS(PORT->hDevice);
|
|
|
|
if (PORT->PortType == PTT || (PORT->Rigs[0].PTTMode & PTTDTR))
|
|
COMClearDTR(PORT->hDevice);
|
|
else
|
|
COMSetDTR(PORT->hDevice);
|
|
if (strcmp(PORT->Rigs[0].RigName, "FT847") == 0)
|
|
{
|
|
// Looks like FT847 Needa a "Cat On" Command
|
|
|
|
UCHAR CATON[6] = {0,0,0,0,0};
|
|
|
|
WriteCOMBlock(PORT->hDevice, CATON, 5);
|
|
}
|
|
|
|
|
|
if (PORT->PortType == NMEA)
|
|
{
|
|
// Looks like NMEA Needs Remote ON
|
|
|
|
int i;
|
|
char REMON[80];
|
|
|
|
i = sprintf(REMON, "$PICOA,90,%02x,REMOTE,ON*xx\r\n", PORT->Rigs[0].RigAddr);
|
|
AddNMEAChecksum(REMON);
|
|
|
|
WriteCOMBlock(PORT->hDevice, REMON, i);
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CheckRX(struct RIGPORTINFO * PORT)
|
|
{
|
|
int Length;
|
|
char NMEAMsg[100];
|
|
unsigned char * ptr;
|
|
int len;
|
|
|
|
if (PORT->PortType == FLRIG)
|
|
{
|
|
// Data received in thread
|
|
|
|
return;
|
|
}
|
|
|
|
if (PORT->PortType == HAMLIB)
|
|
{
|
|
// Data received in thread (do we need thread??
|
|
|
|
Length = PORT->RXLen;
|
|
PORT->RXLen = 0;
|
|
}
|
|
|
|
else if (PORT->PortType == RTLUDP)
|
|
{
|
|
CheckAndProcessRTLUDP(PORT);
|
|
Length = 0;
|
|
PORT->RXLen = 0;
|
|
return;
|
|
}
|
|
|
|
else if (PORT->HIDDevice)
|
|
Length = HID_Read_Block(PORT);
|
|
else if (PORT->PTC)
|
|
Length = GetPTCRadioCommand(PORT->PTC, &PORT->RXBuffer[PORT->RXLen]);
|
|
else if (PORT->remoteSock)
|
|
{
|
|
struct sockaddr_in rxaddr;
|
|
int addrlen = sizeof(struct sockaddr_in);
|
|
|
|
Length = recvfrom(PORT->remoteSock, PORT->RXBuffer, 500, 0, (struct sockaddr *)&rxaddr, &addrlen);
|
|
if (Length == -1)
|
|
Length = 0;
|
|
}
|
|
else
|
|
{
|
|
if (PORT->hDevice == 0)
|
|
return;
|
|
|
|
// only try to read number of bytes in queue
|
|
|
|
if (PORT->RXLen == 500)
|
|
PORT->RXLen = 0;
|
|
|
|
Length = 500 - (DWORD)PORT->RXLen;
|
|
|
|
Length = ReadCOMBlock(PORT->hDevice, &PORT->RXBuffer[PORT->RXLen], Length);
|
|
}
|
|
|
|
if (Length == 0)
|
|
return; // Nothing doing
|
|
|
|
PORT->RXLen += Length;
|
|
|
|
Length = PORT->RXLen;
|
|
|
|
switch (PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
if (Length < 6) // Minimum Frame Sise
|
|
return;
|
|
|
|
if (PORT->RXBuffer[Length-1] != 0xfd)
|
|
return; // Echo
|
|
|
|
ProcessICOMFrame(PORT, PORT->RXBuffer, Length); // Could have multiple packets in buffer
|
|
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
|
|
case YAESU:
|
|
|
|
// Possible responses are a single byte ACK/NAK or a 5 byte info frame
|
|
|
|
if (Length == 1 && PORT->CmdSent > 0)
|
|
{
|
|
ProcessYaesuCmdAck(PORT);
|
|
return;
|
|
}
|
|
|
|
if (Length < 5) // Frame Sise
|
|
return;
|
|
|
|
if (Length > 5) // Frame Sise
|
|
{
|
|
PORT->RXLen = 0; // Corruption - reset and wait for retry
|
|
return;
|
|
}
|
|
|
|
ProcessYaesuFrame(PORT);
|
|
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
|
|
case FT100:
|
|
|
|
// Only response should be a 16 byte info frame
|
|
|
|
if (Length < 32) // Frame Sise why???????
|
|
return;
|
|
|
|
if (Length > 32) // Frame Sise
|
|
{
|
|
PORT->RXLen = 0; // Corruption - reset and wait for retry
|
|
return;
|
|
}
|
|
|
|
ProcessFT100Frame(PORT);
|
|
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
|
|
case FT990:
|
|
|
|
// Only response should be a 32 byte info frame
|
|
|
|
if (Length < 32) // Frame Sise
|
|
return;
|
|
|
|
if (Length > 32) // Frame Sise
|
|
{
|
|
PORT->RXLen = 0; // Corruption - reset and wait for retry
|
|
return;
|
|
}
|
|
|
|
ProcessFT990Frame(PORT);
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
|
|
|
|
case FT1000:
|
|
|
|
// Only response should be a 16 byte info frame
|
|
|
|
ptr = PORT->RXBuffer;
|
|
|
|
if (Length < 16) // Frame Sise
|
|
return;
|
|
|
|
if (Length > 16) // Frame Sise
|
|
{
|
|
PORT->RXLen = 0; // Corruption - reset and wait for retry
|
|
return;
|
|
}
|
|
|
|
ProcessFT1000Frame(PORT);
|
|
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
|
|
case KENWOOD:
|
|
case FT2000:
|
|
case FTDX10:
|
|
case FT991A:
|
|
case FLEX:
|
|
|
|
if (Length < 2) // Minimum Frame Sise
|
|
return;
|
|
|
|
if (Length > 50) // Garbage
|
|
{
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
}
|
|
|
|
if (PORT->RXBuffer[Length-1] != ';')
|
|
return;
|
|
|
|
ProcessKenwoodFrame(PORT, Length);
|
|
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
|
|
case SDRRADIO:
|
|
|
|
if (Length < 2) // Minimum Frame Sise
|
|
return;
|
|
|
|
if (Length > 50) // Garbage
|
|
{
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
}
|
|
|
|
if (PORT->RXBuffer[Length-1] != ';')
|
|
return;
|
|
|
|
ProcessSDRRadioFrame(PORT, Length);
|
|
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
return;
|
|
|
|
case NMEA:
|
|
|
|
ptr = memchr(PORT->RXBuffer, 0x0a, Length);
|
|
|
|
while (ptr != NULL)
|
|
{
|
|
ptr++; // include lf
|
|
len = (int)(ptr - &PORT->RXBuffer[0]);
|
|
|
|
memcpy(NMEAMsg, PORT->RXBuffer, len);
|
|
|
|
NMEAMsg[len] = 0;
|
|
|
|
// if (Check0183CheckSum(NMEAMsg, len))
|
|
ProcessNMEA(PORT, NMEAMsg, len);
|
|
|
|
Length -= len; // bytes left
|
|
|
|
if (Length > 0)
|
|
{
|
|
memmove(PORT->RXBuffer, ptr, Length);
|
|
ptr = memchr(PORT->RXBuffer, 0x0a, Length);
|
|
}
|
|
else
|
|
ptr=0;
|
|
}
|
|
|
|
PORT->RXLen = Length;
|
|
return;
|
|
|
|
case HAMLIB:
|
|
|
|
ProcessHAMLIBFrame(PORT, Length);
|
|
PORT->RXLen = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
VOID ProcessICOMFrame(struct RIGPORTINFO * PORT, UCHAR * rxbuffer, int Len)
|
|
{
|
|
UCHAR * FendPtr;
|
|
int NewLen;
|
|
|
|
// Split into Packets. By far the most likely is a single frame
|
|
// so treat as special case
|
|
|
|
FendPtr = memchr(rxbuffer, 0xfd, Len);
|
|
|
|
if (FendPtr == &rxbuffer[Len-1])
|
|
{
|
|
ProcessFrame(PORT, rxbuffer, Len);
|
|
return;
|
|
}
|
|
|
|
// Process the first Packet in the buffer
|
|
|
|
NewLen = (int)(FendPtr - rxbuffer + 1);
|
|
|
|
ProcessFrame(PORT, rxbuffer, NewLen);
|
|
|
|
// Loop Back
|
|
|
|
ProcessICOMFrame(PORT, FendPtr+1, Len - NewLen);
|
|
return;
|
|
}
|
|
|
|
|
|
BOOL RigWriteCommBlock(struct RIGPORTINFO * PORT)
|
|
{
|
|
// if using a PTC radio interface send to the SCSPactor Driver, else send to COM port
|
|
|
|
int ret;
|
|
|
|
if (PORT->HIDDevice)
|
|
HID_Write_Block(PORT);
|
|
else
|
|
if (PORT->PTC)
|
|
SendPTCRadioCommand(PORT->PTC, PORT->TXBuffer, PORT->TXLen);
|
|
else if (PORT->remoteSock)
|
|
ret = sendto(PORT->remoteSock, PORT->TXBuffer, PORT->TXLen, 0, &PORT->remoteDest, sizeof(struct sockaddr));
|
|
else
|
|
{
|
|
BOOL fWriteStat;
|
|
DWORD BytesWritten;
|
|
|
|
#ifndef WIN32
|
|
BytesWritten = write(PORT->hDevice, PORT->TXBuffer, PORT->TXLen);
|
|
#else
|
|
DWORD Mask = 0;
|
|
int Err;
|
|
|
|
Err = GetCommModemStatus(PORT->hDevice, &Mask);
|
|
|
|
if (Mask == 0) // trap com0com other end not open
|
|
return TRUE;
|
|
|
|
fWriteStat = WriteFile(PORT->hDevice, PORT->TXBuffer, PORT->TXLen, &BytesWritten, NULL );
|
|
#endif
|
|
if (PORT->TXLen != BytesWritten)
|
|
{
|
|
struct RIGINFO * RIG = &PORT->Rigs[PORT->CurrentRig]; // Only one on Yaseu
|
|
|
|
if (RIG->RIGOK)
|
|
{
|
|
SetWindowText(RIG->hFREQ, "Port Closed");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
}
|
|
|
|
RIG->RIGOK = FALSE;
|
|
|
|
if (PORT->hDevice)
|
|
CloseCOMPort(PORT->hDevice);
|
|
|
|
OpenRigCOMMPort(PORT, PORT->IOBASE, PORT->SPEED);
|
|
|
|
if (PORT->IOBASE && PORT->PTTIOBASE[0] == 0) // Using separate port for PTT?
|
|
PORT->hPTTDevice = PORT->hDevice;
|
|
|
|
if (PORT->hDevice)
|
|
{
|
|
// Try Again
|
|
|
|
#ifndef WIN32
|
|
BytesWritten = write(PORT->hDevice, PORT->TXBuffer, PORT->TXLen);
|
|
#else
|
|
fWriteStat = WriteFile(PORT->hDevice, PORT->TXBuffer, PORT->TXLen, &BytesWritten, NULL );
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = GetLastError();
|
|
|
|
PORT->Timeout = 100; // 2 secs
|
|
return TRUE;
|
|
}
|
|
|
|
VOID ReleasePermission(struct RIGINFO *RIG)
|
|
{
|
|
int i = 0;
|
|
struct _EXTPORTDATA * PortRecord;
|
|
|
|
while (RIG->PortRecord[i])
|
|
{
|
|
PortRecord = RIG->PortRecord[i];
|
|
PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, (PDATAMESSAGE)3); // Release Perrmission
|
|
i++;
|
|
}
|
|
}
|
|
|
|
int GetPermissionToChange(struct RIGPORTINFO * PORT, struct RIGINFO *RIG)
|
|
{
|
|
struct ScanEntry ** ptr;
|
|
struct _EXTPORTDATA * PortRecord;
|
|
int i = 0;
|
|
|
|
// Get Permission to change
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("GetPermissionToChange - WaitingForPermission = %d", RIG->WaitingForPermission);
|
|
|
|
// See if any two stage (CONLOCK) ports
|
|
|
|
if (RIG->PortRecord[0] && RIG->PortRecord[0]->SCANCAPABILITIES != CONLOCK)
|
|
goto CheckOtherPorts;
|
|
|
|
|
|
if (RIG->WaitingForPermission)
|
|
{
|
|
// This code should only be called if port needs two stage
|
|
// eg Request then confirm. only SCS Pactor at the moment.
|
|
|
|
// TNC has been asked for permission, and we are waiting respoonse
|
|
// Only SCS pactor returns WaitingForPrmission, so check shouldn't be called on others
|
|
|
|
RIG->OKtoChange = (int)(intptr_t)RIG->PortRecord[0]->PORT_EXT_ADDR(6, RIG->PortRecord[0]->PORTCONTROL.PORTNUMBER, (PDATAMESSAGE)2); // Get Ok Flag
|
|
|
|
if (RIG->OKtoChange == 1)
|
|
{
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("Check Permission returned OK to change");
|
|
|
|
i = 1;
|
|
goto CheckOtherPorts;
|
|
}
|
|
|
|
if (RIG->OKtoChange == -1)
|
|
{
|
|
// Permission Refused. Wait Scan Interval and try again
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("Scan Debug %s Refused permission - waiting ScanInterval %d",
|
|
RIG->PortRecord[0]->PORT_DLL_NAME, PORT->FreqPtr->Dwell );
|
|
|
|
RIG->WaitingForPermission = FALSE;
|
|
SetWindowText(RIG->hSCAN, "-");
|
|
RIG->WEB_SCAN = '=';
|
|
|
|
RIG->ScanCounter = PORT->FreqPtr->Dwell;
|
|
|
|
if (RIG->ScanCounter == 0) // ? After manual change
|
|
RIG->ScanCounter = 50;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("Scan Debug %s Still Waiting", RIG->PortRecord[0]->PORT_DLL_NAME);
|
|
|
|
|
|
return FALSE; // Haven't got reply yet. Will re-enter next tick
|
|
}
|
|
else
|
|
{
|
|
// not waiting for permission, so must be first call of a cycle
|
|
|
|
if (RIG->PortRecord[0] && RIG->PortRecord[0]->PORT_EXT_ADDR)
|
|
RIG->WaitingForPermission = (int)(intptr_t)RIG->PortRecord[0]->PORT_EXT_ADDR(6, RIG->PortRecord[0]->PORTCONTROL.PORTNUMBER, (PDATAMESSAGE)1); // Request Perrmission
|
|
|
|
// If it returns zero there is no need to wait.
|
|
// Normally SCS Returns True for first call, but returns 0 if Link not running
|
|
|
|
if (RIG->WaitingForPermission)
|
|
return FALSE; // Wait till driver has status
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("First call to %s returned OK to change", RIG->PortRecord[0]->PORT_DLL_NAME);
|
|
|
|
i = 1;
|
|
}
|
|
|
|
CheckOtherPorts:
|
|
|
|
// Either first TNC gave permission or there are no SCS like ports.
|
|
// Ask any others (these are assumed to give immediate yes/no
|
|
|
|
while (RIG->PortRecord[i])
|
|
{
|
|
PortRecord = RIG->PortRecord[i];
|
|
|
|
if (PortRecord->PORT_EXT_ADDR && PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, (PDATAMESSAGE)1))
|
|
{
|
|
// 1 means can't change - release all
|
|
|
|
if (RIG->RIG_DEBUG && PORT->FreqPtr)
|
|
Debugprintf("Scan Debug %s Refused permission - waiting ScanInterval %d",
|
|
PortRecord->PORT_DLL_NAME, PORT->FreqPtr->Dwell);
|
|
|
|
RIG->WaitingForPermission = FALSE;
|
|
MySetWindowText(RIG->hSCAN, "-");
|
|
RIG->WEB_SCAN = '-';
|
|
|
|
if (PORT->FreqPtr)
|
|
RIG->ScanCounter = PORT->FreqPtr->Dwell;
|
|
|
|
if (RIG->ScanCounter == 0) // ? After manual change
|
|
RIG->ScanCounter = 50;
|
|
|
|
ReleasePermission(RIG);
|
|
return FALSE;
|
|
}
|
|
else
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("Scan Debug %s gave permission", PortRecord->PORT_DLL_NAME);
|
|
|
|
i++;
|
|
}
|
|
|
|
|
|
RIG->WaitingForPermission = FALSE;
|
|
|
|
// Update pointer to next frequency
|
|
|
|
RIG->FreqPtr++;
|
|
|
|
ptr = RIG->FreqPtr;
|
|
|
|
if (ptr == NULL)
|
|
{
|
|
Debugprintf("Scan Debug - No freqs - quitting");
|
|
return FALSE; // No Freqs
|
|
}
|
|
|
|
if (ptr[0] == (struct ScanEntry *)0) // End of list - reset to start
|
|
{
|
|
ptr = CheckTimeBands(RIG);
|
|
|
|
if (ptr[0] == (struct ScanEntry *)0)
|
|
{
|
|
// Empty Timeband - delay 60 secs (we need to check for timeband change sometimes)
|
|
|
|
RIG->ScanCounter = 600;
|
|
ReleasePermission(RIG);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
PORT->FreqPtr = ptr[0]; // Save Scan Command Block
|
|
|
|
RIG->ScanCounter = PORT->FreqPtr->Dwell;
|
|
|
|
if (RIG->ScanCounter == 0) // ? After manual change
|
|
RIG->ScanCounter = 150;
|
|
|
|
MySetWindowText(RIG->hSCAN, "S");
|
|
RIG->WEB_SCAN = 'S';
|
|
|
|
// Do Bandwidth and antenna switches (if needed)
|
|
|
|
DoBandwidthandAntenna(RIG, ptr[0]);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
VOID DoBandwidthandAntenna(struct RIGINFO *RIG, struct ScanEntry * ptr)
|
|
{
|
|
// If Bandwidth Change needed, do it
|
|
|
|
int i;
|
|
struct _EXTPORTDATA * PortRecord;
|
|
|
|
if (ptr->Bandwidth || ptr->RPacketMode || ptr->HFPacketMode
|
|
|| ptr->PMaxLevel || ptr->ARDOPMode[0] || ptr->VARAMode)
|
|
{
|
|
i = 0;
|
|
|
|
while (RIG->PortRecord[i])
|
|
{
|
|
PortRecord = RIG->PortRecord[i];
|
|
|
|
RIG->CurrentBandWidth = ptr->Bandwidth;
|
|
|
|
PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, (PDATAMESSAGE)ptr);
|
|
|
|
/* if (ptr->Bandwidth == 'R') // Robust Packet
|
|
PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, 6); // Set Robust Packet
|
|
else
|
|
|
|
if (ptr->Bandwidth == 'W')
|
|
PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, 4); // Set Wide Mode
|
|
else
|
|
PortRecord->PORT_EXT_ADDR(6, PortRecord->PORTCONTROL.PORTNUMBER, 5); // Set Narrow Mode
|
|
*/
|
|
i++;
|
|
}
|
|
}
|
|
|
|
// If Antenna Change needed, do it
|
|
|
|
// 5 and 6 are used for CI-V switching so ignore here
|
|
|
|
if (ptr->Antenna && ptr->Antenna < '5')
|
|
{
|
|
SwitchAntenna(RIG, ptr->Antenna);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID ICOMPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
int i;
|
|
|
|
struct RIGINFO * RIG;
|
|
|
|
for (i=0; i< PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
}
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
PORT->Retries--;
|
|
|
|
if(PORT->Retries)
|
|
{
|
|
RigWriteCommBlock(PORT); // Retransmit Block
|
|
return;
|
|
}
|
|
|
|
RIG = &PORT->Rigs[PORT->CurrentRig];
|
|
|
|
|
|
SetWindowText(RIG->hFREQ, "-----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");
|
|
SetWindowText(RIG->hMODE, "------");
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
// SetWindowText(RIG->hFREQ, "145.810000");
|
|
// SetWindowText(RIG->hMODE, "RTTY/1");
|
|
|
|
PORT->Rigs[PORT->CurrentRig].RIGOK = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
PORT->CurrentRig++;
|
|
|
|
if (PORT->CurrentRig >= PORT->ConfiguredRigs)
|
|
PORT->CurrentRig = 0;
|
|
|
|
RIG = &PORT->Rigs[PORT->CurrentRig];
|
|
|
|
/*
|
|
RIG->DebugDelay ++;
|
|
|
|
if (RIG->DebugDelay > 600)
|
|
{
|
|
RIG->DebugDelay = 0;
|
|
Debugprintf("Scan Debug %d %d %d %d %d %d", PORT->CurrentRig,
|
|
RIG->NumberofBands, RIG->RIGOK, RIG->ScanStopped, RIG->ScanCounter,
|
|
RIG->WaitingForPermission);
|
|
}
|
|
*/
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq/1000000.0);
|
|
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
|
|
if (PORT->FreqPtr->Freq > 0.0)
|
|
{
|
|
_gcvt((PORT->FreqPtr->Freq + RIG->rxOffset) / 1000000.0, 9, RIG->Valchar); // For MH
|
|
strcpy(RIG->WEB_FREQ, RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
}
|
|
|
|
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->RIGOK && RIG->BPQtoRADIO_Q)
|
|
{
|
|
struct MSGWITHOUTLEN * buffptr;
|
|
|
|
buffptr = Q_REM(&RIG->BPQtoRADIO_Q);
|
|
|
|
// Copy the ScanEntry struct from the Buffer to the PORT Scanentry
|
|
|
|
memcpy(&PORT->ScanEntry, buffptr->Data, sizeof(struct ScanEntry));
|
|
|
|
PORT->FreqPtr = &PORT->ScanEntry; // Block we are currently sending.
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Manual Change Freq to %9.4f", PORT->FreqPtr->Freq/1000000.0);
|
|
|
|
|
|
memcpy(Poll, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
|
|
DoBandwidthandAntenna(RIG, &PORT->ScanEntry);
|
|
|
|
if (PORT->FreqPtr->Freq > 0.0)
|
|
{
|
|
_gcvt((PORT->FreqPtr->Freq + RIG->rxOffset) / 1000000.0, 9, RIG->Valchar); // For MH
|
|
strcpy(RIG->WEB_FREQ, RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
}
|
|
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len; // First send the set Freq
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
|
|
ReleaseBuffer(buffptr);
|
|
|
|
PORT->AutoPoll = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
if (RIG->RIGOK && RIG->ScanStopped == 0 && RIG->NumberofBands &&
|
|
RIG->ScanCounter && RIG->ScanCounter < 30) // no point in reading freq if we are about to change
|
|
return;
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter)
|
|
return;
|
|
}
|
|
|
|
// Need to make sure we don't poll multiple rigs on port at the same time
|
|
|
|
if (RIG->RIGOK)
|
|
{
|
|
PORT->Retries = 2;
|
|
RIG->PollCounter = 10 / PORT->ConfiguredRigs; // Once Per Sec
|
|
}
|
|
else
|
|
{
|
|
PORT->Retries = 1;
|
|
RIG->PollCounter = 100 / PORT->ConfiguredRigs; // Slow Poll if down
|
|
}
|
|
|
|
RIG->PollCounter += PORT->CurrentRig * 3;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
// Read Frequency
|
|
|
|
Poll[0] = 0xFE;
|
|
Poll[1] = 0xFE;
|
|
Poll[2] = RIG->RigAddr;
|
|
Poll[3] = 0xE0;
|
|
Poll[4] = 0x3; // Get frequency command
|
|
Poll[5] = 0xFD;
|
|
|
|
PORT->TXLen = 6;
|
|
|
|
RigWriteCommBlock(PORT);
|
|
|
|
PORT->Retries = 1;
|
|
PORT->Timeout = 10;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID ProcessFrame(struct RIGPORTINFO * PORT, UCHAR * Msg, int framelen)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG;
|
|
int i;
|
|
int cmdSent = PORT->TXBuffer[4];
|
|
|
|
if (Msg[0] != 0xfe || Msg[1] != 0xfe)
|
|
|
|
// Duff Packet - return
|
|
|
|
return;
|
|
|
|
if (Msg[2] != 0xe0 && Msg[2] != 0)
|
|
{
|
|
// Echo - Proves a CI-V interface is attached
|
|
|
|
if (PORT->PORTOK == FALSE)
|
|
{
|
|
// Just come up
|
|
PORT->PORTOK = TRUE;
|
|
Debugprintf("Cat Port OK");
|
|
}
|
|
return;
|
|
}
|
|
|
|
for (i=0; i< PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
if (Msg[3] == RIG->RigAddr)
|
|
goto ok;
|
|
}
|
|
|
|
return;
|
|
|
|
ok:
|
|
|
|
if (Msg[4] == 0xFB)
|
|
{
|
|
// Accept
|
|
|
|
if (cmdSent == 0x1C && PORT->TXBuffer[5] == 1) // Tune
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Tune OK");
|
|
|
|
PORT->Timeout = 0;
|
|
return;
|
|
}
|
|
|
|
if (cmdSent == 0x14 && PORT->TXBuffer[5] == 0x0A) // Power
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Set Power OK");
|
|
|
|
PORT->Timeout = 0;
|
|
return;
|
|
}
|
|
|
|
// if it was the set freq, send the set mode
|
|
|
|
if (RIG->ICF8101)
|
|
{
|
|
if (cmdSent == 0x1A && PORT->TXBuffer[5] == 0x35)
|
|
{
|
|
if (PORT->FreqPtr->Cmd2)
|
|
{
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd2, PORT->FreqPtr->Cmd2Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd2Len;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
}
|
|
else
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Frequency Set OK");
|
|
|
|
PORT->Timeout = 0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (cmdSent == 0x1a && PORT->TXBuffer[5] == 0x36)
|
|
{
|
|
// Set Mode Response - if scanning read freq, else return OK to user
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
{
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
|
|
Poll[0] = 0xFE;
|
|
Poll[1] = 0xFE;
|
|
Poll[2] = RIG->RigAddr;
|
|
Poll[3] = 0xE0;
|
|
Poll[4] = 0x3; // Get frequency command
|
|
Poll[5] = 0xFD;
|
|
|
|
PORT->TXLen = 6;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Frequency and Mode Set OK");
|
|
|
|
RIG->PollCounter = 30 / RIG->PORT->ConfiguredRigs; // Dont read freq for 3 secs
|
|
}
|
|
}
|
|
|
|
PORT->Timeout = 0;
|
|
return;
|
|
}
|
|
|
|
if (cmdSent == 5 || cmdSent == 7) // Freq or VFO
|
|
{
|
|
if (PORT->FreqPtr && PORT->FreqPtr->Cmd2)
|
|
{
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd2, PORT->FreqPtr->Cmd2Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd2Len;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
}
|
|
else
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Frequency Set OK");
|
|
|
|
PORT->Timeout = 0;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (cmdSent == 6) // Set Mode
|
|
{
|
|
if (PORT->FreqPtr && PORT->FreqPtr->Cmd3)
|
|
{
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd3, PORT->FreqPtr->Cmd3Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd3Len;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
return;
|
|
}
|
|
|
|
goto SetFinished;
|
|
}
|
|
|
|
if (cmdSent == 0x08)
|
|
{
|
|
// Memory Chan
|
|
|
|
cmdSent = 0; // So we only do it once
|
|
|
|
goto SetFinished;
|
|
}
|
|
|
|
if (cmdSent == 0x12)
|
|
goto SetFinished; // Antenna always sent last
|
|
|
|
|
|
if (cmdSent == 0x0f || cmdSent == 0x01a) // Set DUP or Data
|
|
{
|
|
// These are send from cmd3. There may be a cmd4
|
|
// for antenna switching
|
|
|
|
if (PORT->FreqPtr && PORT->FreqPtr->Cmd4)
|
|
{
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd4, PORT->FreqPtr->Cmd4Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd4Len;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
return;
|
|
}
|
|
|
|
SetFinished:
|
|
|
|
// Set Mode Response - if scanning read freq, else return OK to user
|
|
|
|
if (RIG->ScanStopped == 0 && PORT->AutoPoll)
|
|
{
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
|
|
Poll[0] = 0xFE;
|
|
Poll[1] = 0xFE;
|
|
Poll[2] = RIG->RigAddr;
|
|
Poll[3] = 0xE0;
|
|
Poll[4] = 0x3; // Get frequency command
|
|
Poll[5] = 0xFD;
|
|
|
|
PORT->TXLen = 6;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
return;
|
|
}
|
|
|
|
else
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Frequency and Mode Set OK");
|
|
|
|
RIG->PollCounter = 30 / RIG->PORT->ConfiguredRigs; // Dont read freq for 3 secs
|
|
}
|
|
}
|
|
|
|
PORT->Timeout = 0;
|
|
return;
|
|
}
|
|
|
|
if (Msg[4] == 0xFA)
|
|
{
|
|
// Reject
|
|
|
|
PORT->Timeout = 0;
|
|
|
|
if (!PORT->AutoPoll)
|
|
{
|
|
if (cmdSent == 5)
|
|
SendResponse(RIG->Session, "Sorry - Set Frequency Command Rejected");
|
|
else
|
|
if (cmdSent == 6)
|
|
SendResponse(RIG->Session, "Sorry - Set Mode Command Rejected");
|
|
else
|
|
if (cmdSent == 0x0f)
|
|
SendResponse(RIG->Session, "Sorry - Set Shift Command Rejected");
|
|
else
|
|
if (cmdSent == 0x12)
|
|
SendResponse(RIG->Session, "Sorry - Set Antenna Command Rejected");
|
|
else
|
|
if (cmdSent == 0x1C && PORT->TXBuffer[5] == 1) // Tune
|
|
SendResponse(RIG->Session, "Sorry - Tune Command Rejected");
|
|
else
|
|
if (cmdSent == 0x14 && PORT->TXBuffer[5] == 0x0a) // Power
|
|
SendResponse(RIG->Session, "Sorry - Power Command Rejected");
|
|
else
|
|
SendResponse(RIG->Session, "Sorry - Command Rejected");
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (Msg[4] == PORT->TXBuffer[4])
|
|
{
|
|
// Response to our command
|
|
|
|
// Any valid frame is an ACK
|
|
|
|
RIG->RIGOK = TRUE;
|
|
PORT->Timeout = 0;
|
|
|
|
if (!PORT->AutoPoll)
|
|
{
|
|
// Manual response probably to CMD Query. Return response
|
|
|
|
char reply[256] = "CMD Response ";
|
|
char * p1 = &reply[13];
|
|
UCHAR * p2 = &Msg[4];
|
|
int n = framelen - 4;
|
|
|
|
while (n > 0)
|
|
{
|
|
sprintf(p1, "%02X ", *(p2));
|
|
p1 += 3;
|
|
p2++;
|
|
n--;
|
|
}
|
|
|
|
SendResponse(RIG->Session, reply);
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
return; // What does this mean??
|
|
|
|
|
|
if (PORT->PORTOK == FALSE)
|
|
{
|
|
// Just come up
|
|
// char Status[80];
|
|
|
|
PORT->PORTOK = TRUE;
|
|
// sprintf(Status,"COM%d PORT link OK", PORT->IOBASE);
|
|
// SetWindowText(PORT->hStatus, Status);
|
|
}
|
|
|
|
if (Msg[4] == 3)
|
|
{
|
|
// Rig Frequency
|
|
int n, j, decdigit;
|
|
long long Freq = 0;
|
|
int start = 9;
|
|
long long MHz, Hz;
|
|
char CharMHz[16] = "";
|
|
char CharHz[16] = "";
|
|
|
|
int i;
|
|
|
|
|
|
if (RIG->IC735)
|
|
start = 8; // shorted msg
|
|
|
|
for (j = start; j > 4; j--)
|
|
{
|
|
n = Msg[j];
|
|
decdigit = (n >> 4);
|
|
decdigit *= 10;
|
|
decdigit += n & 0xf;
|
|
Freq = (Freq *100 ) + decdigit;
|
|
}
|
|
|
|
Freq += RIG->rxOffset;
|
|
|
|
RIG->RigFreq = Freq / 1000000.0;
|
|
|
|
// If we convert to float to display we get rounding errors, so convert to MHz and Hz to display
|
|
|
|
MHz = Freq / 1000000;
|
|
|
|
Hz = Freq - MHz * 1000000;
|
|
|
|
sprintf(CharMHz, "%lld", MHz);
|
|
sprintf(CharHz, "%06lld", Hz);
|
|
|
|
for (i = 5; i > 2; i--)
|
|
{
|
|
if (CharHz[i] == '0')
|
|
CharHz[i] = 0;
|
|
else
|
|
break;
|
|
}
|
|
|
|
sprintf(RIG->WEB_FREQ,"%lld.%s", MHz, CharHz);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
strcpy(RIG->Valchar, RIG->WEB_FREQ);
|
|
|
|
|
|
// Now get Mode
|
|
|
|
Poll[0] = 0xFE;
|
|
Poll[1] = 0xFE;
|
|
Poll[2] = RIG->RigAddr;
|
|
Poll[3] = 0xE0;
|
|
|
|
if (RIG->ICF8101)
|
|
{
|
|
Poll[4] = 0x1A; // Get Mode
|
|
Poll[5] = 0x34;
|
|
Poll[6] = 0xFD;
|
|
PORT->TXLen = 7;
|
|
}
|
|
else
|
|
{
|
|
Poll[4] = 0x4; // Get Mode
|
|
Poll[5] = 0xFD;
|
|
|
|
PORT->TXLen = 6;
|
|
}
|
|
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
return;
|
|
}
|
|
|
|
if (RIG->ICF8101)
|
|
{
|
|
if (cmdSent == 0x1A && PORT->TXBuffer[5] == 0x34)
|
|
{
|
|
// Get Mode
|
|
|
|
unsigned int Mode;
|
|
|
|
Mode = (Msg[7] >> 4);
|
|
Mode *= 10;
|
|
Mode += Msg[7] & 0xf;
|
|
|
|
if (Mode > 24) Mode = 24;
|
|
|
|
sprintf(RIG->WEB_MODE,"%s", Modes[Mode]);
|
|
|
|
strcpy(RIG->ModeString, Modes[Mode]);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if (Msg[4] == 4)
|
|
{
|
|
// Mode
|
|
|
|
unsigned int Mode;
|
|
|
|
Mode = (Msg[5] >> 4);
|
|
Mode *= 10;
|
|
Mode += Msg[5] & 0xf;
|
|
|
|
if (Mode > 24) Mode = 24;
|
|
|
|
if (RIG->IC735)
|
|
sprintf(RIG->WEB_MODE,"%s", Modes[Mode]);
|
|
else
|
|
sprintf(RIG->WEB_MODE,"%s/%d", Modes[Mode], Msg[6]);
|
|
|
|
strcpy(RIG->ModeString, Modes[Mode]);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
}
|
|
}
|
|
|
|
int SendResponse(int Session, char * Msg)
|
|
{
|
|
PDATAMESSAGE Buffer;
|
|
BPQVECSTRUC * VEC;
|
|
TRANSPORTENTRY * L4 = L4TABLE;
|
|
|
|
if (Session == -1)
|
|
return 0;
|
|
|
|
Buffer = GetBuff();
|
|
|
|
L4 += Session;
|
|
|
|
Buffer->PID = 0xf0;
|
|
Buffer->LENGTH = MSGHDDRLEN + 1; // Includes PID
|
|
Buffer->LENGTH += sprintf(Buffer->L2DATA, "%s\r", Msg);
|
|
|
|
VEC = L4->L4TARGET.HOST;
|
|
|
|
C_Q_ADD(&L4->L4TX_Q, (UINT *)Buffer);
|
|
|
|
#ifndef LINBPQ
|
|
|
|
if (VEC)
|
|
PostMessage(VEC->HOSTHANDLE, BPQMsg, VEC->HOSTSTREAM, 2);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
VOID ProcessFT100Frame(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Only one we should see is a Status Message
|
|
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
UCHAR * Msg = PORT->RXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
int Freq;
|
|
double FreqF;
|
|
unsigned int Mode;
|
|
|
|
RIG->RIGOK = TRUE;
|
|
PORT->Timeout = 0;
|
|
|
|
// Bytes 0 is Band
|
|
// 1 - 4 is Freq in binary in units of 1.25 HZ (!)
|
|
// Byte 5 is Mode
|
|
|
|
Freq = (Msg[1] << 24) + (Msg[2] << 16) + (Msg[3] << 8) + Msg[4];
|
|
|
|
FreqF = (Freq * 1.25) / 1000000;
|
|
|
|
if (PORT->YaesuVariant == FT1000MP)
|
|
FreqF = FreqF / 2; // No idea why!
|
|
|
|
RIG->RigFreq = FreqF;
|
|
|
|
_gcvt(FreqF, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
|
|
if (PORT->PortType == FT100)
|
|
{
|
|
Mode = Msg[5] & 15;
|
|
if (Mode > 8) Mode = 8;
|
|
sprintf(RIG->WEB_MODE,"%s", FT100Modes[Mode]);
|
|
}
|
|
else // FT1000
|
|
{
|
|
Mode = Msg[7] & 7;
|
|
sprintf(RIG->WEB_MODE,"%s", FTRXModes[Mode]);
|
|
}
|
|
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
else
|
|
if (PORT->TXLen > 5) // Poll is 5 Change is more
|
|
ReleasePermission(RIG); // Release Perrmission to change
|
|
}
|
|
|
|
|
|
|
|
VOID ProcessFT990Frame(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Only one we should see is a Status Message
|
|
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
UCHAR * Msg = PORT->RXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
int Freq;
|
|
double FreqF;
|
|
unsigned int Mode;
|
|
|
|
RIG->RIGOK = TRUE;
|
|
PORT->Timeout = 0;
|
|
|
|
// Bytes 0 is Band
|
|
// 1 - 4 is Freq in units of 10Hz (I think!)
|
|
// Byte 5 is Mode
|
|
|
|
Freq = (Msg[1] << 16) + (Msg[2] << 8) + Msg[3];
|
|
|
|
FreqF = (Freq * 10.0) / 1000000;
|
|
|
|
RIG->RigFreq = FreqF;
|
|
|
|
_gcvt(FreqF, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
|
|
Mode = Msg[7] & 7;
|
|
sprintf(RIG->WEB_MODE,"%s", FTRXModes[Mode]);
|
|
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
else
|
|
if (PORT->TXLen > 5) // Poll is 5 change is more
|
|
ReleasePermission(RIG); // Release Perrmission to change
|
|
}
|
|
|
|
VOID ProcessFT1000Frame(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Only one we should see is a Status Message
|
|
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
UCHAR * Msg = PORT->RXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
int Freq;
|
|
double FreqF;
|
|
unsigned int Mode;
|
|
|
|
RIG->RIGOK = TRUE;
|
|
PORT->Timeout = 0;
|
|
|
|
// I think the FT1000/1000D is same as 990
|
|
// FT1000MP is similar to FT100, but steps on .625 Hz (despite manual)
|
|
// Bytes 0 is Band
|
|
// 1 - 4 is Freq in binary in units of 1.25 HZ (!)
|
|
// Byte 5 is Mode
|
|
|
|
if (PORT->YaesuVariant == FT1000MP)
|
|
{
|
|
Freq = (Msg[1] << 24) + (Msg[2] << 16) + (Msg[3] << 8) + Msg[4];
|
|
FreqF = (Freq * 1.25) / 1000000;
|
|
FreqF = FreqF / 2; // No idea why!
|
|
}
|
|
else
|
|
{
|
|
Freq = (Msg[1] << 16) + (Msg[2] << 8) + Msg[3];
|
|
FreqF = (Freq * 10.0) / 1000000;
|
|
}
|
|
|
|
RIG->RigFreq = FreqF;
|
|
|
|
_gcvt(FreqF, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
|
|
if (PORT->PortType == FT100)
|
|
{
|
|
Mode = Msg[5] & 15;
|
|
if (Mode > 8) Mode = 8;
|
|
sprintf(RIG->WEB_MODE,"%s", FT100Modes[Mode]);
|
|
}
|
|
else // FT1000
|
|
{
|
|
Mode = Msg[7] & 7;
|
|
sprintf(RIG->WEB_MODE,"%s", FTRXModes[Mode]);
|
|
}
|
|
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
else
|
|
if (PORT->TXLen > 5) // Poll is 5 change is more
|
|
ReleasePermission(RIG); // Release Perrmission to change
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID ProcessYaesuCmdAck(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
UCHAR * Msg = PORT->RXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
|
|
PORT->Timeout = 0;
|
|
PORT->RXLen = 0; // Ready for next frame
|
|
|
|
if (PORT->CmdSent == 1) // Set Freq
|
|
{
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
|
|
if (Msg[0])
|
|
{
|
|
// I think nonzero is a Reject
|
|
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Sorry - Set Frequency Rejected");
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (RIG->ScanStopped == 0)
|
|
{
|
|
// Send a Get Freq - We Don't Poll when scanning
|
|
|
|
Poll[0] = Poll[1] = Poll[2] = Poll[3] = 0;
|
|
Poll[4] = 0x3; // Get frequency amd mode command
|
|
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
PORT->CmdSent = 0;
|
|
}
|
|
else
|
|
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (PORT->CmdSent == 7) // Set Mode
|
|
{
|
|
if (Msg[0])
|
|
{
|
|
// I think nonzero is a Reject
|
|
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Sorry - Set Mode Rejected");
|
|
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
// Send the Frequency
|
|
|
|
memcpy(Poll, &Poll[5], 5);
|
|
RigWriteCommBlock(PORT);
|
|
PORT->CmdSent = Poll[4];
|
|
PORT->Retries = 2;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
VOID ProcessYaesuFrame(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
UCHAR * Msg = PORT->RXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
int n, j, Freq = 0, decdigit;
|
|
double FreqF;
|
|
unsigned int Mode;
|
|
|
|
// I'm not sure we get anything but a Command Response,
|
|
// and the only command we send is Get Rig Frequency and Mode
|
|
|
|
|
|
RIG->RIGOK = TRUE;
|
|
PORT->Timeout = 0;
|
|
|
|
for (j = 0; j < 4; j++)
|
|
{
|
|
n = Msg[j];
|
|
decdigit = (n >> 4);
|
|
decdigit *= 10;
|
|
decdigit += n & 0xf;
|
|
Freq = (Freq *100 ) + decdigit;
|
|
}
|
|
|
|
FreqF = Freq / 100000.0;
|
|
|
|
RIG->RigFreq = FreqF;
|
|
|
|
// Valchar = _fcvt(FreqF, 6, &dec, &sign);
|
|
_gcvt(FreqF, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
|
|
Mode = Msg[4];
|
|
|
|
if (Mode > 15) Mode = 15;
|
|
|
|
sprintf(RIG->WEB_MODE,"%s", YaesuModes[Mode]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
// FT847 Manual Freq Change response ends up here
|
|
|
|
if (strcmp(RIG->RigName, "FT847") == 0)
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
|
|
if (PORT->CmdSent == -1)
|
|
ReleasePermission(RIG); // Release Perrmission to change
|
|
}
|
|
}
|
|
|
|
VOID YaesuPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
PORT->Retries--;
|
|
|
|
if(PORT->Retries)
|
|
{
|
|
RigWriteCommBlock(PORT); // Retransmit Block
|
|
return;
|
|
}
|
|
|
|
SetWindowText(RIG->hFREQ, "------------------");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
|
|
PORT->Rigs[PORT->CurrentRig].RIGOK = FALSE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
if (RIG->NumberofBands && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd1, 24);
|
|
|
|
if (PORT->PortType == YAESU)
|
|
{
|
|
if (strcmp(PORT->Rigs[0].RigName, "FT847") == 0)
|
|
{
|
|
PORT->TXLen = 15; // No Cmd ACK, so send Mode, Freq and Poll
|
|
PORT->CmdSent = -1;
|
|
}
|
|
else
|
|
{
|
|
PORT->TXLen = 5;
|
|
PORT->CmdSent = Poll[4];
|
|
}
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
PORT->AutoPoll = TRUE;
|
|
return;
|
|
}
|
|
|
|
// FT100
|
|
|
|
PORT->TXLen = 15; // Set Mode, Set Freq, Poll
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
PORT->AutoPoll = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->RIGOK && RIG->BPQtoRADIO_Q)
|
|
{
|
|
struct MSGWITHOUTLEN * buffptr;
|
|
|
|
buffptr = Q_REM(&RIG->BPQtoRADIO_Q);
|
|
|
|
// Copy the ScanEntry struct from the Buffer to the PORT Scanentry
|
|
|
|
memcpy(&PORT->ScanEntry, buffptr->Data, sizeof(struct ScanEntry));
|
|
|
|
PORT->FreqPtr = &PORT->ScanEntry; // Block we are currently sending.
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
DoBandwidthandAntenna(RIG, &PORT->ScanEntry);
|
|
|
|
memcpy(Poll, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
|
|
if (PORT->PortType == YAESU)
|
|
{
|
|
if (strcmp(PORT->Rigs[0].RigName, "FT847") == 0)
|
|
{
|
|
PORT->TXLen = 15; // Send all
|
|
PORT->CmdSent = -1;
|
|
}
|
|
else
|
|
{
|
|
PORT->TXLen = 5; // First send the set Freq
|
|
PORT->CmdSent = Poll[4];
|
|
}
|
|
}
|
|
else
|
|
PORT->TXLen = 15; // Send all
|
|
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
|
|
ReleaseBuffer(buffptr);
|
|
PORT->AutoPoll = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
if (RIG->RIGOK && RIG->ScanStopped == 0 && RIG->NumberofBands &&
|
|
RIG->ScanCounter && RIG->ScanCounter < 30) // no point in reading freq if we are about to change
|
|
return;
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter)
|
|
return;
|
|
}
|
|
|
|
RIG->PollCounter = 10; // Once Per Sec
|
|
|
|
// Read Frequency
|
|
|
|
Poll[0] = 0;
|
|
Poll[1] = 0;
|
|
Poll[2] = 0;
|
|
|
|
if (PORT->PortType == FT990 || PORT->PortType == YAESU || PORT->YaesuVariant == FT1000D)
|
|
Poll[3] = 3;
|
|
else
|
|
Poll[3] = 2;
|
|
|
|
if (PORT->PortType == YAESU)
|
|
Poll[4] = 0x3; // Get frequency amd mode command
|
|
else
|
|
Poll[4] = 16; // FT100/990/1000 Get frequency amd mode command
|
|
|
|
PORT->TXLen = 5;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 2;
|
|
PORT->CmdSent = 0;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
VOID ProcessNMEA(struct RIGPORTINFO * PORT, char * Msg, int Length)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
|
|
Msg[Length] = 0;
|
|
|
|
if (PORT->PORTOK == FALSE)
|
|
{
|
|
// Just come up
|
|
PORT->PORTOK = TRUE;
|
|
}
|
|
|
|
RIG->RIGOK = TRUE;
|
|
PORT->Timeout = 0;
|
|
|
|
if (!PORT->AutoPoll)
|
|
{
|
|
// Response to a RADIO Command
|
|
|
|
if (Msg[0] == '?')
|
|
SendResponse(RIG->Session, "Sorry - Command Rejected");
|
|
else
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
}
|
|
|
|
if (memcmp(&Msg[13], "RXF", 3) == 0)
|
|
{
|
|
if (Length < 24)
|
|
return;
|
|
|
|
RIG->RigFreq = atof(&Msg[17]);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%f", RIG->RigFreq);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
strcpy(RIG->Valchar, RIG->WEB_FREQ);
|
|
|
|
return;
|
|
}
|
|
|
|
if (memcmp(&Msg[13], "MODE", 3) == 0)
|
|
{
|
|
char * ptr;
|
|
|
|
if (Length < 24)
|
|
return;
|
|
|
|
ptr = strchr(&Msg[18], '*');
|
|
if (ptr) *(ptr) = 0;
|
|
|
|
SetWindowText(RIG->hMODE, &Msg[18]);
|
|
strcpy(RIG->WEB_MODE, &Msg[18]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
return;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//FA00014103000;MD2;
|
|
|
|
|
|
VOID ProcessSDRRadioFrame(struct RIGPORTINFO * PORT, int Length)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
UCHAR * Msg = PORT->RXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0];
|
|
UCHAR * ptr;
|
|
int CmdLen;
|
|
int i;
|
|
|
|
Msg[Length] = 0;
|
|
|
|
if (PORT->PORTOK == FALSE)
|
|
{
|
|
// Just come up
|
|
PORT->PORTOK = TRUE;
|
|
}
|
|
|
|
if (!PORT->AutoPoll)
|
|
{
|
|
// Response to a RADIO Command
|
|
|
|
if (Msg[0] == '?')
|
|
SendResponse(RIG->Session, "Sorry - Command Rejected");
|
|
else if (Msg[0] == 'A' && Msg[1] == 'C')
|
|
SendResponse(RIG->Session, "TUNE OK");
|
|
else if (Msg[0] == 'P' && Msg[1] == 'C')
|
|
SendResponse(RIG->Session, "Power Set OK");
|
|
else
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
return;
|
|
}
|
|
|
|
|
|
LoopR:
|
|
|
|
ptr = strchr(Msg, ';');
|
|
CmdLen = (int)(ptr - Msg + 1);
|
|
|
|
// Find Device. FA to FF for frequency
|
|
|
|
// Note. SDRConsole reports the same mode for all receivers, so don't rely on reported mode
|
|
|
|
if (Msg[0] == 'F')
|
|
{
|
|
for (i = 0; i < PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
if (Msg[1] == RIG->RigAddr)
|
|
goto ok;
|
|
}
|
|
return;
|
|
ok:
|
|
|
|
if (CmdLen > 9)
|
|
{
|
|
char CharMHz[16] = "";
|
|
char CharHz[16] = "";
|
|
|
|
int i;
|
|
long long Freq;
|
|
long long MHz, Hz;
|
|
|
|
RIG->RIGOK = TRUE;
|
|
|
|
Freq = strtoll(&Msg[2], NULL, 10) + RIG->rxOffset;
|
|
|
|
RIG->RigFreq = Freq / 1000000.0;
|
|
|
|
// If we convert to float to display we get rounding errors, so convert to MHz and Hz to display
|
|
|
|
MHz = Freq / 1000000;
|
|
|
|
Hz = Freq - MHz * 1000000;
|
|
|
|
sprintf(CharMHz, "%lld", MHz);
|
|
sprintf(CharHz, "%06lld", Hz);
|
|
|
|
for (i = 5; i > 2; i--)
|
|
{
|
|
if (CharHz[i] == '0')
|
|
CharHz[i] = 0;
|
|
else
|
|
break;
|
|
}
|
|
|
|
|
|
sprintf(RIG->WEB_FREQ,"%lld.%s", MHz, CharHz);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
strcpy(RIG->Valchar, RIG->WEB_FREQ);
|
|
|
|
PORT->Timeout = 0;
|
|
}
|
|
}
|
|
else if (Msg[0] == 'M' && Msg[1] == 'D')
|
|
{
|
|
int Mode;
|
|
|
|
Mode = Msg[2] - 48;
|
|
if (Mode > 7) Mode = 7;
|
|
SetWindowText(RIG->hMODE, KenwoodModes[Mode]);
|
|
strcpy(RIG->WEB_MODE, KenwoodModes[Mode]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
|
|
}
|
|
|
|
if (CmdLen < Length)
|
|
{
|
|
// Another Message in Buffer
|
|
|
|
ptr++;
|
|
Length -= (int)(ptr - Msg);
|
|
|
|
if (Length <= 0)
|
|
return;
|
|
|
|
memmove(Msg, ptr, Length +1);
|
|
|
|
goto LoopR;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID ProcessKenwoodFrame(struct RIGPORTINFO * PORT, int Length)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
UCHAR * Msg = PORT->RXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
UCHAR * ptr;
|
|
int CmdLen;
|
|
|
|
Msg[Length] = 0;
|
|
|
|
if (PORT->PORTOK == FALSE)
|
|
{
|
|
// Just come up
|
|
PORT->PORTOK = TRUE;
|
|
}
|
|
|
|
RIG->RIGOK = TRUE;
|
|
|
|
if (!PORT->AutoPoll)
|
|
{
|
|
// Response to a RADIO Command
|
|
|
|
if (Msg[0] == '?')
|
|
SendResponse(RIG->Session, "Sorry - Command Rejected");
|
|
else if (Msg[0] == 'A' && Msg[1] == 'C')
|
|
SendResponse(RIG->Session, "TUNE OK");
|
|
else if (Msg[0] == 'P' && Msg[1] == 'C')
|
|
SendResponse(RIG->Session, "Power Set OK");
|
|
else
|
|
SendResponse(RIG->Session, "Mode and Frequency Set OK");
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
return;
|
|
}
|
|
|
|
Loop:
|
|
|
|
if (PORT->PortType == FLEX)
|
|
{
|
|
Msg += 2; // Skip ZZ
|
|
Length -= 2;
|
|
}
|
|
|
|
ptr = strchr(Msg, ';');
|
|
CmdLen = (int)(ptr - Msg + 1);
|
|
|
|
if (Msg[0] == 'F' && Msg[1] == 'A' && CmdLen > 9)
|
|
{
|
|
char CharMHz[16] = "";
|
|
char CharHz[16] = "";
|
|
|
|
int i;
|
|
long long Freq;
|
|
long long MHz, Hz;
|
|
|
|
Freq = strtoll(&Msg[2], NULL, 10) + RIG->rxOffset;
|
|
|
|
RIG->RigFreq = Freq / 1000000.0;
|
|
|
|
// If we convert to float to display we get rounding errors, so convert to MHz and Hz to display
|
|
|
|
MHz = Freq / 1000000;
|
|
|
|
Hz = Freq - MHz * 1000000;
|
|
|
|
sprintf(CharMHz, "%lld", MHz);
|
|
sprintf(CharHz, "%06lld", Hz);
|
|
|
|
/*
|
|
if (PORT->PortType == FT2000)
|
|
{
|
|
memcpy(FreqDecimal,&Msg[4], 6);
|
|
Msg[4] = 0;
|
|
}
|
|
else if (PORT->PortType == FT991A)
|
|
{
|
|
memcpy(FreqDecimal,&Msg[5], 6);
|
|
Msg[5] = 0;
|
|
}
|
|
|
|
else
|
|
{
|
|
memcpy(FreqDecimal,&Msg[7], 6);
|
|
Msg[7] = 0;
|
|
}
|
|
FreqDecimal[6] = 0;
|
|
*/
|
|
|
|
for (i = 5; i > 2; i--)
|
|
{
|
|
if (CharHz[i] == '0')
|
|
CharHz[i] = 0;
|
|
else
|
|
break;
|
|
}
|
|
|
|
|
|
sprintf(RIG->WEB_FREQ,"%lld.%s", MHz, CharHz);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
strcpy(RIG->Valchar, RIG->WEB_FREQ);
|
|
|
|
PORT->Timeout = 0;
|
|
}
|
|
else if (Msg[0] == 'M' && Msg[1] == 'D')
|
|
{
|
|
int Mode;
|
|
|
|
if (PORT->PortType == FT2000)
|
|
{
|
|
Mode = Msg[3] - 48;
|
|
if (Mode > 13) Mode = 13;
|
|
SetWindowText(RIG->hMODE, FT2000Modes[Mode]);
|
|
strcpy(RIG->WEB_MODE, FT2000Modes[Mode]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
}
|
|
else if (PORT->PortType == FT991A)
|
|
{
|
|
Mode = Msg[3] - 48;
|
|
if (Mode > 16)
|
|
Mode -= 7;
|
|
|
|
if (Mode > 15) Mode = 13;
|
|
SetWindowText(RIG->hMODE, FT991AModes[Mode]);
|
|
strcpy(RIG->WEB_MODE, FT991AModes[Mode]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
}
|
|
else if (PORT->PortType == FTDX10)
|
|
{
|
|
Mode = Msg[3] - 48;
|
|
if (Mode > 16)
|
|
Mode -= 7;
|
|
|
|
if (Mode > 15) Mode = 15;
|
|
SetWindowText(RIG->hMODE, FTDX10Modes[Mode]);
|
|
strcpy(RIG->WEB_MODE, FTDX10Modes[Mode]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
}
|
|
else if (PORT->PortType == FLEX)
|
|
{
|
|
Mode = atoi(&Msg[3]);
|
|
if (Mode > 12) Mode = 12;
|
|
SetWindowText(RIG->hMODE, FLEXModes[Mode]);
|
|
strcpy(RIG->WEB_MODE, FLEXModes[Mode]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
}
|
|
else
|
|
{
|
|
Mode = Msg[2] - 48;
|
|
if (Mode > 7) Mode = 7;
|
|
SetWindowText(RIG->hMODE, KenwoodModes[Mode]);
|
|
strcpy(RIG->WEB_MODE, KenwoodModes[Mode]);
|
|
strcpy(RIG->ModeString, RIG->WEB_MODE);
|
|
}
|
|
}
|
|
|
|
if (CmdLen < Length)
|
|
{
|
|
// Another Message in Buffer
|
|
|
|
ptr++;
|
|
Length -= (int)(ptr - Msg);
|
|
|
|
if (Length <= 0)
|
|
return;
|
|
|
|
memmove(Msg, ptr, Length +1);
|
|
|
|
goto Loop;
|
|
}
|
|
}
|
|
|
|
|
|
VOID KenwoodPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Kenwood
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
PORT->Retries--;
|
|
|
|
if(PORT->Retries)
|
|
{
|
|
RigWriteCommBlock(PORT); // Retransmit Block
|
|
return;
|
|
}
|
|
|
|
SetWindowText(RIG->hFREQ, "------------------");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
RIG->RIGOK = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
RigWriteCommBlock(PORT);
|
|
PORT->CmdSent = 1;
|
|
PORT->Retries = 0;
|
|
PORT->Timeout = 0;
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
// There isn't a response to a set command, so clear Scan Lock here
|
|
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->RIGOK && RIG->BPQtoRADIO_Q)
|
|
{
|
|
struct MSGWITHOUTLEN * buffptr;
|
|
|
|
buffptr = Q_REM(&RIG->BPQtoRADIO_Q);
|
|
|
|
// Copy the ScanEntry struct from the Buffer to the PORT Scanentry
|
|
|
|
memcpy(&PORT->ScanEntry, buffptr->Data, sizeof(struct ScanEntry));
|
|
|
|
PORT->FreqPtr = &PORT->ScanEntry; // Block we are currently sending.
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
DoBandwidthandAntenna(RIG, &PORT->ScanEntry);
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
memcpy(Poll, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->CmdSent = Poll[4];
|
|
PORT->Timeout = 0;
|
|
RIG->PollCounter = 10;
|
|
|
|
ReleaseBuffer(buffptr);
|
|
PORT->AutoPoll = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter > 1)
|
|
return;
|
|
}
|
|
|
|
if (RIG->RIGOK && RIG->ScanStopped == 0 && RIG->NumberofBands &&
|
|
RIG->ScanCounter && RIG->ScanCounter < 30)
|
|
return; // no point in reading freq if we are about to change it
|
|
|
|
RIG->PollCounter = 10; // Once Per Sec
|
|
|
|
// Read Frequency
|
|
|
|
PORT->TXLen = RIG->PollLen;
|
|
strcpy(Poll, RIG->Poll);
|
|
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 1;
|
|
PORT->Timeout = 10;
|
|
PORT->CmdSent = 0;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
VOID SDRRadioPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG;
|
|
int i;
|
|
|
|
for (i=0; i< PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
}
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
PORT->Retries--;
|
|
|
|
if(PORT->Retries)
|
|
{
|
|
RigWriteCommBlock(PORT); // Retransmit Block
|
|
return;
|
|
}
|
|
|
|
SetWindowText(RIG->hFREQ, "------------------");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
RIG->RIGOK = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
|
|
PORT->CurrentRig++;
|
|
|
|
if (PORT->CurrentRig >= PORT->ConfiguredRigs)
|
|
PORT->CurrentRig = 0;
|
|
|
|
RIG = &PORT->Rigs[PORT->CurrentRig];
|
|
|
|
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
RigWriteCommBlock(PORT);
|
|
PORT->CmdSent = 1;
|
|
PORT->Retries = 0;
|
|
PORT->Timeout = 0;
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
// There isn't a response to a set command, so clear Scan Lock here
|
|
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->RIGOK && RIG->BPQtoRADIO_Q)
|
|
{
|
|
struct MSGWITHOUTLEN * buffptr;
|
|
|
|
buffptr = Q_REM(&RIG->BPQtoRADIO_Q);
|
|
|
|
// Copy the ScanEntry struct from the Buffer to the PORT Scanentry
|
|
|
|
memcpy(&PORT->ScanEntry, buffptr->Data, sizeof(struct ScanEntry));
|
|
|
|
PORT->FreqPtr = &PORT->ScanEntry; // Block we are currently sending.
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
DoBandwidthandAntenna(RIG, &PORT->ScanEntry);
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
memcpy(Poll, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
RigWriteCommBlock(PORT);
|
|
PORT->CmdSent = Poll[4];
|
|
PORT->Timeout = 0;
|
|
RIG->PollCounter = 10;
|
|
|
|
ReleaseBuffer(buffptr);
|
|
PORT->AutoPoll = FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter > 1)
|
|
return;
|
|
}
|
|
|
|
if (RIG->RIGOK && RIG->ScanStopped == 0 && RIG->NumberofBands &&
|
|
RIG->ScanCounter && RIG->ScanCounter < 30)
|
|
return; // no point in reading freq if we are about to change it
|
|
|
|
// Need to make sure we don't poll multiple rigs on port at the same time
|
|
|
|
if (RIG->RIGOK)
|
|
{
|
|
PORT->Retries = 2;
|
|
RIG->PollCounter = 10 / PORT->ConfiguredRigs; // Once Per Sec
|
|
}
|
|
else
|
|
{
|
|
PORT->Retries = 1;
|
|
RIG->PollCounter = 100 / PORT->ConfiguredRigs; // Slow Poll if down
|
|
}
|
|
|
|
RIG->PollCounter += PORT->CurrentRig * 3;
|
|
|
|
// Read Frequency
|
|
|
|
PORT->TXLen = RIG->PollLen;
|
|
strcpy(Poll, RIG->Poll);
|
|
|
|
RigWriteCommBlock(PORT);
|
|
PORT->Retries = 1;
|
|
PORT->Timeout = 10;
|
|
PORT->CmdSent = 0;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
VOID DummyPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0];
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
/*
|
|
RigWriteCommBlock(PORT);
|
|
PORT->CmdSent = 1;
|
|
PORT->Retries = 0;
|
|
PORT->Timeout = 0;
|
|
PORT->AutoPoll = TRUE;
|
|
*/
|
|
// There isn't a response to a set command, so clear Scan Lock here
|
|
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
VOID SwitchAntenna(struct RIGINFO * RIG, char Antenna)
|
|
{
|
|
struct RIGPORTINFO * PORT;
|
|
char Ant[3]=" ";
|
|
|
|
if (RIG == NULL) return;
|
|
|
|
PORT = RIG->PORT;
|
|
|
|
Ant[1] = Antenna;
|
|
|
|
SetWindowText(RIG->hPTT, Ant);
|
|
|
|
switch (Antenna)
|
|
{
|
|
case '1':
|
|
COMClearDTR(PORT->hDevice);
|
|
COMClearRTS(PORT->hDevice);
|
|
break;
|
|
case '2':
|
|
COMSetDTR(PORT->hDevice);
|
|
COMClearRTS(PORT->hDevice);
|
|
break;
|
|
case '3':
|
|
COMClearDTR(PORT->hDevice);
|
|
COMSetRTS(PORT->hDevice);
|
|
break;
|
|
case '4':
|
|
COMSetDTR(PORT->hDevice);
|
|
COMSetRTS(PORT->hDevice);
|
|
break;
|
|
}
|
|
}
|
|
|
|
BOOL DecodeModePtr(char * Param, double * Dwell, double * Freq, char * Mode,
|
|
char * PMinLevel, char * PMaxLevel, char * PacketMode,
|
|
char * RPacketMode, char * Split, char * Data, char * WinmorMode,
|
|
char * Antenna, BOOL * Supress, char * Filter, char * Appl,
|
|
char * MemoryBank, int * MemoryNumber, char * ARDOPMode, char * VARAMode, int * BandWidth, int * Power)
|
|
{
|
|
char * Context;
|
|
char * ptr;
|
|
|
|
*Filter = '1'; // Defaults
|
|
*PMinLevel = 1;
|
|
*MemoryBank = 0;
|
|
*MemoryNumber = 0;
|
|
*Mode = 0;
|
|
*ARDOPMode = 0;
|
|
*VARAMode = 0;
|
|
*Power = 0;
|
|
|
|
|
|
ptr = strtok_s(Param, ",", &Context);
|
|
|
|
if (ptr == NULL)
|
|
return FALSE;
|
|
|
|
// "New" format - Dwell, Freq, Params.
|
|
|
|
// Each param is a 2 char pair, separated by commas
|
|
|
|
// An - Antenna
|
|
// Pn - Pactor
|
|
// Wn - Winmor
|
|
// Pn - Packet
|
|
// Fn - Filter
|
|
// Sx - Split
|
|
|
|
// 7.0770/LSB,F1,A3,WN,P1,R1
|
|
|
|
*Dwell = atof(ptr);
|
|
|
|
ptr = strtok_s(NULL, ",", &Context);
|
|
|
|
if (ptr == NULL)
|
|
return FALSE;
|
|
|
|
|
|
// May be a frequency or a Memory Bank/Channel
|
|
|
|
if (_memicmp(ptr, "Chan", 4) == 0)
|
|
{
|
|
if (strchr(ptr, '/')) // Bank/Chan
|
|
{
|
|
memcpy(MemoryBank, &ptr[4], 1);
|
|
*MemoryNumber = atoi(&ptr[6]);
|
|
}
|
|
else
|
|
*MemoryNumber = atoi(&ptr[4]); // Just Chan
|
|
|
|
*Freq = 0.0;
|
|
}
|
|
else
|
|
*Freq = atof(ptr);
|
|
|
|
ptr = strtok_s(NULL, ",", &Context);
|
|
|
|
if (ptr == NULL || strlen(ptr) > 8)
|
|
return FALSE;
|
|
|
|
// If channel, dont need mode
|
|
|
|
if (*MemoryNumber == 0)
|
|
{
|
|
strcpy(Mode, ptr);
|
|
ptr = strtok_s(NULL, ",", &Context);
|
|
}
|
|
|
|
while (ptr)
|
|
{
|
|
if (isdigit(ptr[0]))
|
|
*BandWidth = atoi(ptr);
|
|
|
|
else if (memcmp(ptr, "APPL=", 5) == 0)
|
|
strcpy(Appl, ptr + 5);
|
|
|
|
else if (memcmp(ptr, "POWER=", 6) == 0)
|
|
*Power = atoi(ptr + 6);
|
|
|
|
else if (ptr[0] == 'A' && (ptr[1] == 'S' || ptr[1] == '0') && strlen(ptr) < 7)
|
|
strcpy(ARDOPMode, "S");
|
|
|
|
else if (ptr[0] == 'A' && strlen(ptr) > 2 && strlen(ptr) < 7)
|
|
strcpy(ARDOPMode, &ptr[1]);
|
|
|
|
else if (ptr[0] == 'A' && strlen(ptr) == 2)
|
|
*Antenna = ptr[1];
|
|
|
|
else if (ptr[0] == 'F')
|
|
*Filter = ptr[1];
|
|
|
|
else if (ptr[0] == 'R')
|
|
*RPacketMode = ptr[1];
|
|
|
|
else if (ptr[0] == 'H')
|
|
*PacketMode = ptr[1];
|
|
|
|
else if (ptr[0] == 'N')
|
|
*PacketMode = ptr[1];
|
|
|
|
else if (ptr[0] == 'P')
|
|
{
|
|
*PMinLevel = ptr[1];
|
|
*PMaxLevel = ptr[strlen(ptr) - 1];
|
|
}
|
|
else if (ptr[0] == 'W')
|
|
{
|
|
*WinmorMode = ptr[1];
|
|
if (*WinmorMode == '0')
|
|
*WinmorMode = 'X';
|
|
else if (*WinmorMode == '1')
|
|
*WinmorMode = 'N';
|
|
else if (*WinmorMode == '2')
|
|
*WinmorMode = 'W';
|
|
}
|
|
|
|
else if (ptr[0] == 'V')
|
|
{
|
|
*VARAMode = ptr[1];
|
|
// W N S T (skip) or 0 (also Skip)
|
|
if (ptr[1] == '0')
|
|
*VARAMode = 'S';
|
|
}
|
|
else if (ptr[0] == '+')
|
|
*Split = '+';
|
|
else if (ptr[0] == '-')
|
|
*Split = '-';
|
|
else if (ptr[0] == 'S')
|
|
*Split = 'S';
|
|
else if (ptr[0] == 'D')
|
|
*Data = 1;
|
|
else if (ptr[0] == 'X')
|
|
*Supress = TRUE;
|
|
|
|
ptr = strtok_s(NULL, ",", &Context);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID AddNMEAChecksum(char * msg)
|
|
{
|
|
UCHAR CRC = 0;
|
|
|
|
msg++; // Skip $
|
|
|
|
while (*(msg) != '*')
|
|
{
|
|
CRC ^= *(msg++);
|
|
}
|
|
|
|
sprintf(++msg, "%02X\r\n", CRC);
|
|
}
|
|
|
|
void DecodeRemote(struct RIGPORTINFO * PORT, char * ptr)
|
|
{
|
|
// Param is IPHOST:PORT for use with WINMORCONTROL
|
|
|
|
struct sockaddr_in * destaddr = (SOCKADDR_IN * )&PORT->remoteDest;
|
|
UCHAR param = 1;
|
|
u_long ioparam = 1;
|
|
|
|
char * port = strlop(ptr, ':');
|
|
|
|
PORT->remoteSock = socket(AF_INET,SOCK_DGRAM,0);
|
|
|
|
if (PORT->remoteSock == INVALID_SOCKET)
|
|
return;
|
|
|
|
setsockopt (PORT->remoteSock, SOL_SOCKET, SO_BROADCAST, ¶m, 1);
|
|
|
|
if (port == NULL)
|
|
return;
|
|
|
|
ioctl (PORT->remoteSock, FIONBIO, &ioparam);
|
|
|
|
destaddr->sin_family = AF_INET;
|
|
destaddr->sin_addr.s_addr = inet_addr(ptr);
|
|
destaddr->sin_port = htons(atoi(port));
|
|
|
|
if (destaddr->sin_addr.s_addr == INADDR_NONE)
|
|
{
|
|
// Resolve name to address
|
|
|
|
struct hostent * HostEnt = gethostbyname(ptr);
|
|
|
|
if (!HostEnt)
|
|
return; // Resolve failed
|
|
|
|
memcpy(&destaddr->sin_addr.s_addr,HostEnt->h_addr,4);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
char * CM108Device = NULL;
|
|
|
|
void DecodeCM108(int Port, char * ptr)
|
|
{
|
|
// Called if Device Name or PTT = Param is CM108
|
|
|
|
#ifdef WIN32
|
|
|
|
// Next Param is VID and PID - 0xd8c:0x8 or Full device name
|
|
// On Windows device name is very long and difficult to find, so
|
|
// easier to use VID/PID, but allow device in case more than one needed
|
|
|
|
char * next;
|
|
int32_t VID = 0, PID = 0;
|
|
char product[256];
|
|
char sernum[256] = "NULL";
|
|
|
|
struct hid_device_info *devs, *cur_dev;
|
|
const char *path_to_open = NULL;
|
|
hid_device *handle = NULL;
|
|
|
|
if (strlen(ptr) > 16)
|
|
CM108Device = _strdup(ptr);
|
|
else
|
|
{
|
|
VID = strtol(ptr, &next, 0);
|
|
if (next)
|
|
PID = strtol(++next, &next, 0);
|
|
|
|
// Look for Device
|
|
|
|
devs = hid_enumerate(0,0); // so we list devices(USHORT)VID, (USHORT)PID);
|
|
cur_dev = devs;
|
|
while (cur_dev)
|
|
{
|
|
wcstombs(product, cur_dev->product_string, 255);
|
|
if (cur_dev->serial_number)
|
|
wcstombs(sernum, cur_dev->serial_number, 255);
|
|
|
|
if (product)
|
|
Debugprintf("HID Device %s VID %X PID %X Ser %s %s", product, cur_dev->vendor_id, cur_dev->product_id, sernum, cur_dev->path);
|
|
else
|
|
Debugprintf("HID Device %s VID %X PID %X Ser %s %s", "Missing Product", cur_dev->vendor_id, cur_dev->product_id, sernum, cur_dev->path);
|
|
|
|
if (cur_dev->vendor_id == VID && cur_dev->product_id == PID)
|
|
path_to_open = cur_dev->path;
|
|
|
|
cur_dev = cur_dev->next;
|
|
}
|
|
|
|
if (path_to_open)
|
|
{
|
|
handle = hid_open_path(path_to_open);
|
|
|
|
if (handle)
|
|
{
|
|
hid_close(handle);
|
|
CM108Device = _strdup(path_to_open);
|
|
}
|
|
else
|
|
{
|
|
char msg[128];
|
|
sprintf(msg,"Port %d Unable to open CM108 device %x %x", Port, VID, PID);
|
|
WritetoConsole(msg);
|
|
}
|
|
}
|
|
hid_free_enumeration(devs);
|
|
}
|
|
#else
|
|
|
|
// Linux - Next Param HID Device, eg /dev/hidraw0
|
|
|
|
CM108Device = _strdup(ptr);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
// Called by Port Driver .dll to add/update rig info
|
|
|
|
// RIGCONTROL COM60 19200 ICOM IC706 5e 4 14.103/U1w 14.112/u1 18.1/U1n 10.12/l1
|
|
|
|
|
|
struct RIGINFO * RigConfig(struct TNCINFO * TNC, char * buf, int Port)
|
|
{
|
|
int i;
|
|
char * ptr;
|
|
char * COMPort = NULL;
|
|
char * RigName;
|
|
int RigAddr;
|
|
struct RIGPORTINFO * PORT;
|
|
struct RIGINFO * RIG;
|
|
struct ScanEntry ** FreqPtr;
|
|
char * CmdPtr;
|
|
char * Context;
|
|
struct TimeScan * SaveBand;
|
|
char PTTRigName[] = "PTT";
|
|
double ScanFreq;
|
|
double Dwell;
|
|
char MemoryBank; // For Memory Scanning
|
|
int MemoryNumber;
|
|
BOOL RIG_DEBUG = FALSE;
|
|
|
|
BOOL PTTControlsInputMUX = FALSE;
|
|
BOOL DataPTT = FALSE;
|
|
int DataPTTOffMode = 1; // ACC
|
|
int ICF8101Mode = 8; // USB (as in upper sideband)
|
|
|
|
char onString[256] = "";
|
|
char offString[256] = "";
|
|
int onLen = 0;
|
|
int offLen = 0;
|
|
|
|
CM108Device = NULL;
|
|
Debugprintf("Processing RIG line %s", buf);
|
|
|
|
// Starts RADIO Interlockgroup
|
|
|
|
ptr = strtok_s(&buf[5], " \t\n\r", &Context); // Skip Interlock
|
|
if (ptr == NULL) return FALSE;
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL) return FALSE;
|
|
|
|
if (_memicmp(ptr, "DEBUG", 5) == 0)
|
|
{
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
RIG_DEBUG = TRUE;
|
|
}
|
|
|
|
if (_memicmp(ptr, "AUTH", 4) == 0)
|
|
{
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
if (ptr == NULL) return FALSE;
|
|
if (strlen(ptr) > 100) return FALSE;
|
|
|
|
strcpy(AuthPassword, ptr);
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
}
|
|
|
|
if (ptr == NULL || ptr[0] == 0)
|
|
return FALSE;
|
|
|
|
if (_memicmp(ptr, "DUMMY", 5) == 0)
|
|
{
|
|
// Dummy to allow PTC application scanning
|
|
|
|
PORT = PORTInfo[NumberofPorts++] = zalloc(sizeof(struct RIGPORTINFO));
|
|
PORT->PortType = DUMMY;
|
|
PORT->ConfiguredRigs = 1;
|
|
RIG = &PORT->Rigs[0];
|
|
RIG->RIGOK = TRUE;
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
goto CheckScan;
|
|
}
|
|
|
|
if (_memicmp(ptr, "FLRIG", 5) == 0)
|
|
{
|
|
// Use FLRIG
|
|
|
|
// Need parameter - Host:Port
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL || strlen(ptr) > 79) return FALSE;
|
|
|
|
// Have a parameter to define port. Will decode it later
|
|
|
|
PORT = PORTInfo[NumberofPorts++] = zalloc(sizeof(struct RIGPORTINFO));
|
|
PORT->PortType = FLRIG;
|
|
PORT->ConfiguredRigs = 1;
|
|
RIG = &PORT->Rigs[0];
|
|
RIG->RIGOK = TRUE;
|
|
RIG->PORT = PORT;
|
|
|
|
strcpy(PORT->IOBASE, ptr);
|
|
strcpy(RIG->RigName, "FLRIG");
|
|
|
|
// Decode host
|
|
|
|
DecodeHAMLIBAddr(PORT, ptr);
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
// look for other config statementes and scan params
|
|
|
|
goto CheckOtherParams;
|
|
}
|
|
|
|
if (_memicmp(ptr, "HAMLIB", 5) == 0)
|
|
{
|
|
// Use rigctld
|
|
|
|
// Need parameter - Host:Port
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL || strlen(ptr) > 79) return FALSE;
|
|
|
|
// Have a parameter to define port. Will decode it later
|
|
|
|
PORT = PORTInfo[NumberofPorts++] = zalloc(sizeof(struct RIGPORTINFO));
|
|
PORT->PortType = HAMLIB;
|
|
PORT->ConfiguredRigs = 1;
|
|
RIG = &PORT->Rigs[0];
|
|
RIG->RIGOK = TRUE;
|
|
RIG->PORT = PORT;
|
|
|
|
strcpy(PORT->IOBASE, ptr);
|
|
strcpy(RIG->RigName, "HAMLIB");
|
|
|
|
// Decode host
|
|
|
|
DecodeHAMLIBAddr(PORT, ptr);
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
// look for scan params
|
|
|
|
goto CheckOtherParams;
|
|
}
|
|
|
|
if (_memicmp(ptr, "rtludp", 5) == 0)
|
|
{
|
|
// rtl_fm with udp freq control
|
|
|
|
// Need parameter - Host:Port
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL || strlen(ptr) > 79) return FALSE;
|
|
|
|
// Have a parameter to define port. Will decode it later
|
|
|
|
PORT = PORTInfo[NumberofPorts++] = zalloc(sizeof(struct RIGPORTINFO));
|
|
PORT->PortType = RTLUDP;
|
|
PORT->ConfiguredRigs = 1;
|
|
RIG = &PORT->Rigs[0];
|
|
RIG->RIGOK = TRUE;
|
|
RIG->PORT = PORT;
|
|
|
|
strcpy(PORT->IOBASE, ptr);
|
|
strcpy(RIG->RigName, "RTLUDP");
|
|
|
|
// Decode host
|
|
|
|
DecodeHAMLIBAddr(PORT, ptr);
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
// look for scan params
|
|
|
|
goto CheckOtherParams;
|
|
}
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
if (_memicmp(ptr, "sdrangel", 5) == 0)
|
|
{
|
|
// each instance (ip addr/port) of sdrangle can have one or more sampling devices (eg rltsdr) each with one ot
|
|
// more channels (eg ssb demod, ssb mod). each set of sampling device = channel(s) is a device set.
|
|
|
|
// We poll all devices/channels at once. we one PORT record plus a RIG record for each channel
|
|
|
|
// Need parameters - Host:Port device channel. Device and Channel will default to zero
|
|
|
|
int device = 0, channel = 0;
|
|
char * Name;
|
|
char * nptr1;
|
|
char * nptr2;
|
|
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL || strlen(ptr) > 79) return FALSE;
|
|
|
|
Name = strtok_s(NULL, " \t\n\r", &Context);
|
|
nptr1 = strtok_s(NULL, " \t\n\r", &Context);
|
|
nptr2 = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (nptr1 == 0 || nptr2 == 0 || Name == NULL || strlen(Name) > 9)
|
|
return FALSE;
|
|
|
|
device = atoi(nptr1);
|
|
channel = atoi(nptr2);
|
|
|
|
// Have a parameter to define port. Will decode it later
|
|
|
|
// See if already defined. PORT->IOBASE has Host:Port
|
|
|
|
for (i = 0; i < NumberofPorts; i++)
|
|
{
|
|
PORT = PORTInfo[i];
|
|
|
|
if (strcmp(PORT->IOBASE, ptr) == 0)
|
|
goto AngelRigFound;
|
|
}
|
|
|
|
// New Port
|
|
|
|
PORT = PORTInfo[NumberofPorts++] = zalloc(sizeof(struct RIGPORTINFO));
|
|
PORT->PortType = SDRANGEL;
|
|
PORT->ConfiguredRigs = 0;
|
|
strcpy(PORT->IOBASE, ptr);
|
|
|
|
// Decode host
|
|
|
|
DecodeHAMLIBAddr(PORT, ptr);
|
|
|
|
|
|
AngelRigFound:
|
|
|
|
RIG = &PORT->Rigs[PORT->ConfiguredRigs++];
|
|
RIG->RIGOK = TRUE;
|
|
RIG->PORT = PORT;
|
|
RIG->RigAddr = device;
|
|
RIG->Channel = channel;
|
|
|
|
strcpy(RIG->RigName, Name);
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
// look for scan params
|
|
|
|
goto CheckOtherParams;
|
|
}
|
|
// ---- G7TAJ ----
|
|
|
|
if ((_memicmp(ptr, "VCOM", 4) == 0) && TNC->Hardware == H_SCS) // Using Radio Port on PTC
|
|
COMPort = 0;
|
|
else if (_memicmp(ptr, "PTCPORT", 7) == 0)
|
|
COMPort = 0;
|
|
else
|
|
COMPort = ptr;
|
|
|
|
// See if port is already defined. We may be adding another radio (ICOM or SDRRADIO only) or updating an existing one
|
|
|
|
// Unless CM108 - they must be on separate Ports
|
|
|
|
if (COMPort && _stricmp("CM108", COMPort) != 0)
|
|
{
|
|
for (i = 0; i < NumberofPorts; i++)
|
|
{
|
|
PORT = PORTInfo[i];
|
|
|
|
if (COMPort)
|
|
if (strcmp(PORT->IOBASE, COMPort) == 0)
|
|
goto PortFound;
|
|
|
|
if (COMPort == 0)
|
|
if (PORT->IOBASE == COMPort)
|
|
goto PortFound;
|
|
}
|
|
}
|
|
|
|
// Allocate a new one
|
|
|
|
PORT = PORTInfo[NumberofPorts++] = zalloc(sizeof(struct RIGPORTINFO));
|
|
|
|
if (COMPort)
|
|
strcpy(PORT->IOBASE, COMPort);
|
|
|
|
PortFound:
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL) return (FALSE);
|
|
|
|
if (_stricmp(PORT->IOBASE, "RAWHID") == 0) // HID Addr instead of Speed
|
|
{
|
|
DecodeCM108(Port, ptr);
|
|
if (CM108Device)
|
|
PORT->HIDDevice = CM108Device;
|
|
else
|
|
PORT->HIDDevice = _strdup ("MissingHID");
|
|
|
|
CM108Device = 0;
|
|
}
|
|
|
|
if ( _stricmp(PORT->IOBASE, "CM108") == 0) // HID Addr instead of Speed
|
|
{
|
|
DecodeCM108(Port, ptr);
|
|
}
|
|
|
|
if (_stricmp(PORT->IOBASE, "REMOTE") == 0) // IP Addr/Port
|
|
DecodeRemote(PORT, ptr);
|
|
else
|
|
PORT->SPEED = atoi(ptr);
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL) return (FALSE);
|
|
|
|
if (_memicmp(ptr, "PTTCOM", 6) == 0 || _memicmp(ptr, "PTT=", 4) == 0)
|
|
{
|
|
if (_stricmp(ptr, "PTT=CM108") == 0)
|
|
{
|
|
// PTT on CM108 GPIO
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
if (ptr == NULL) return (FALSE);
|
|
|
|
DecodeCM108(Port, ptr);
|
|
}
|
|
else
|
|
{
|
|
strcpy(PORT->PTTIOBASE, ptr);
|
|
}
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
if (ptr == NULL) return (FALSE);
|
|
|
|
}
|
|
|
|
// if (strcmp(ptr, "ICOM") == 0 || strcmp(ptr, "YAESU") == 0
|
|
// || strcmp(ptr, "KENWOOD") == 0 || strcmp(ptr, "PTTONLY") == 0 || strcmp(ptr, "ANTENNA") == 0)
|
|
|
|
// RADIO IC706 4E 5 14.103/U1 14.112/u1 18.1/U1 10.12/l1
|
|
// Read RADIO Lines
|
|
|
|
_strupr(ptr);
|
|
|
|
|
|
if (strcmp(ptr, "ICOM") == 0)
|
|
PORT->PortType = ICOM;
|
|
else if (strcmp(ptr, "YAESU") == 0)
|
|
PORT->PortType = YAESU;
|
|
else if (strcmp(ptr, "KENWOOD") == 0)
|
|
PORT->PortType = KENWOOD;
|
|
else if (strcmp(ptr, "SDRRADIO") == 0)
|
|
PORT->PortType = SDRRADIO; // Varient of KENWOOD that supports multiple devices on one serial port
|
|
else if (strcmp(ptr, "FLEX") == 0)
|
|
PORT->PortType = FLEX;
|
|
else if (strcmp(ptr, "NMEA") == 0)
|
|
PORT->PortType = NMEA;
|
|
else if (strcmp(ptr, "PTTONLY") == 0)
|
|
PORT->PortType = PTT;
|
|
else if (strcmp(ptr, "ANTENNA") == 0)
|
|
PORT->PortType = ANT;
|
|
else
|
|
return FALSE;
|
|
|
|
Debugprintf("Port type = %d", PORT->PortType);
|
|
|
|
_strupr(Context);
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr && memcmp(ptr, "HAMLIB=", 7) == 0)
|
|
{
|
|
// HAMLIB Emulator - param is port to listen on
|
|
|
|
if (PORT->PortType == PTT)
|
|
{
|
|
RIG = &PORT->Rigs[PORT->ConfiguredRigs++];
|
|
strcpy(RIG->RigName, PTTRigName);
|
|
|
|
RIG->HAMLIBPORT = atoi(&ptr[7]);
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
}
|
|
}
|
|
|
|
if (ptr && strcmp(ptr, "PTTMUX") == 0)
|
|
{
|
|
if (PORT->PortType == PTT)
|
|
{
|
|
RIG = &PORT->Rigs[PORT->ConfiguredRigs++];
|
|
strcpy(RIG->RigName, PTTRigName);
|
|
goto domux; // PTTONLY with PTTMUX
|
|
}
|
|
}
|
|
|
|
|
|
if (ptr == NULL)
|
|
{
|
|
if (PORT->PortType == PTT)
|
|
ptr = PTTRigName;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
if (strlen(ptr) > 9) return FALSE;
|
|
|
|
RigName = ptr;
|
|
|
|
Debugprintf("Rigname = *%s*", RigName);
|
|
|
|
// FT100 seems to be different to most other YAESU types
|
|
|
|
if (strcmp(RigName, "FT100") == 0 && PORT->PortType == YAESU)
|
|
{
|
|
PORT->PortType = FT100;
|
|
}
|
|
|
|
// FT990 seems to be different to most other YAESU types
|
|
|
|
if (strcmp(RigName, "FT990") == 0 && PORT->PortType == YAESU)
|
|
{
|
|
PORT->PortType = FT990;
|
|
}
|
|
|
|
// FT1000 seems to be different to most other YAESU types
|
|
|
|
if (strstr(RigName, "FT1000") && PORT->PortType == YAESU)
|
|
{
|
|
PORT->PortType = FT1000;
|
|
|
|
// Subtypes need different code. D and no suffix are same
|
|
|
|
if (strstr(RigName, "FT1000MP"))
|
|
PORT->YaesuVariant = FT1000MP;
|
|
else
|
|
PORT->YaesuVariant = FT1000D;
|
|
}
|
|
|
|
// FT2000 seems to be different to most other YAESU types
|
|
|
|
if (strcmp(RigName, "FT2000") == 0 && PORT->PortType == YAESU)
|
|
{
|
|
PORT->PortType = FT2000;
|
|
}
|
|
|
|
// FTDX10 seems to be different to most other YAESU types
|
|
|
|
if (strcmp(RigName, "FTDX10") == 0 && PORT->PortType == YAESU)
|
|
{
|
|
PORT->PortType = FTDX10;
|
|
}
|
|
|
|
// FT991A seems to be different to most other YAESU types
|
|
|
|
if (strcmp(RigName, "FT991A") == 0 && PORT->PortType == YAESU)
|
|
{
|
|
PORT->PortType = FT991A;
|
|
}
|
|
|
|
|
|
// If ICOM or SDRRADIO, we may be adding a new Rig
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (PORT->PortType == ICOM || PORT->PortType == NMEA || PORT->PortType == SDRRADIO)
|
|
{
|
|
if (ptr == NULL) return (FALSE);
|
|
|
|
if (PORT->PortType == SDRRADIO)
|
|
RigAddr = ptr[0];
|
|
else
|
|
sscanf(ptr, "%x", &RigAddr);
|
|
|
|
// See if already defined
|
|
|
|
for (i = 0; i < PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
if (RIG->RigAddr == RigAddr)
|
|
goto RigFound;
|
|
}
|
|
|
|
// Allocate a new one
|
|
|
|
RIG = &PORT->Rigs[PORT->ConfiguredRigs++];
|
|
RIG->RigAddr = RigAddr;
|
|
|
|
RigFound:
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
// if (ptr == NULL) return (FALSE);
|
|
}
|
|
else
|
|
{
|
|
// Only allows one RIG
|
|
|
|
PORT->ConfiguredRigs = 1;
|
|
RIG = &PORT->Rigs[0];
|
|
}
|
|
|
|
RIG->RIG_DEBUG = RIG_DEBUG;
|
|
RIG->PORT = PORT;
|
|
|
|
strcpy(RIG->RigName, RigName);
|
|
|
|
RIG->TSMenu = 63; // Default to TS590S
|
|
|
|
// IC735 uses shorter freq message
|
|
|
|
if (strcmp(RigName, "IC735") == 0 && PORT->PortType == ICOM)
|
|
RIG->IC735 = TRUE;
|
|
|
|
// IC-F8101 uses a different set of commands
|
|
|
|
if (strstr(RigName, "F8101") && PORT->PortType == ICOM)
|
|
RIG->ICF8101 = TRUE;
|
|
|
|
if (PORT->PortType == KENWOOD)
|
|
{
|
|
RIG->TSMenu = 63; // Default to TS590S
|
|
|
|
if (strcmp(RigName, "TS590SG") == 0)
|
|
RIG->TSMenu = 69;
|
|
}
|
|
|
|
if (PORT->PortType == FT991A)
|
|
RIG->TSMenu = 72; //Menu for Data/USB siwtching
|
|
|
|
domux:
|
|
|
|
RIG->CM108Device = CM108Device;
|
|
|
|
CheckOtherParams:
|
|
|
|
while (ptr)
|
|
{
|
|
if (strcmp(ptr, "PTTMUX") == 0)
|
|
{
|
|
// Ports whose RTS/DTR will be converted to CAT commands (for IC7100/IC7200 etc)
|
|
|
|
int PIndex = 0;
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
while (memcmp(ptr, "COM", 3) == 0)
|
|
{
|
|
char * tncport = strlop(ptr, '/');
|
|
|
|
strcpy(RIG->PTTCATPort[PIndex], &ptr[3]);
|
|
|
|
if (tncport)
|
|
RIG->PTTCATTNC[PIndex] = TNCInfo[atoi(tncport)];
|
|
|
|
if (PIndex < 3)
|
|
PIndex++;
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL)
|
|
break;
|
|
}
|
|
if (ptr == NULL)
|
|
break;
|
|
else
|
|
continue;
|
|
}
|
|
else if (strcmp(ptr, "PTT_SETS_INPUT") == 0)
|
|
{
|
|
// Send Select Soundcard as mod source with PTT commands
|
|
|
|
PTTControlsInputMUX = TRUE;
|
|
|
|
// See if following param is an PTT Off Mode
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL)
|
|
break;
|
|
|
|
if (strcmp(ptr, "MIC") == 0)
|
|
DataPTTOffMode = 0;
|
|
else if (strcmp(ptr, "AUX") == 0)
|
|
DataPTTOffMode = 1;
|
|
else if (strcmp(ptr, "MICAUX") == 0)
|
|
DataPTTOffMode = 2;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "LSB") == 0)
|
|
ICF8101Mode = 0x7;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "USB") == 0)
|
|
ICF8101Mode = 0x8;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "LSBD1") == 0)
|
|
ICF8101Mode = 0x18;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "USBD1") == 0)
|
|
ICF8101Mode = 0x19;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "LSBD2") == 0)
|
|
ICF8101Mode = 0x20;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "USBD2") == 0)
|
|
ICF8101Mode = 0x21;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "LSBD3") == 0)
|
|
ICF8101Mode = 0x22;
|
|
else if (RIG->ICF8101 && strcmp(ptr, "USBD3") == 0)
|
|
ICF8101Mode = 0x23;
|
|
else
|
|
continue;
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
continue;
|
|
|
|
}
|
|
else if (strcmp(ptr, "PTT_SETS_FREQ") == 0)
|
|
{
|
|
// Send Select Soundcard as mod source with PTT commands
|
|
|
|
RIG->PTTSetsFreq = TRUE;
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (strcmp(ptr, "DATAPTT") == 0)
|
|
{
|
|
// Send Select Soundcard as mod source with PTT commands
|
|
|
|
DataPTT = TRUE;
|
|
}
|
|
|
|
else if (memcmp(ptr, "PTTONHEX=", 9) == 0)
|
|
{
|
|
// Hex String to use for PTT on
|
|
|
|
char * ptr1 = ptr;
|
|
char * ptr2 = onString ;
|
|
int i, j, len;
|
|
|
|
ptr1 += 9;
|
|
onLen = len = strlen(ptr1) / 2;
|
|
|
|
if (len < 240)
|
|
{
|
|
while ((len--) > 0)
|
|
{
|
|
i = *(ptr1++);
|
|
i -= '0';
|
|
if (i > 9)
|
|
i -= 7;
|
|
|
|
j = i << 4;
|
|
|
|
i = *(ptr1++);
|
|
i -= '0';
|
|
if (i > 9)
|
|
i -= 7;
|
|
|
|
*(ptr2++) = j | i;
|
|
}
|
|
}
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL)
|
|
break;
|
|
}
|
|
|
|
else if (memcmp(ptr, "PTTOFFHEX=", 10) == 0)
|
|
{
|
|
// Hex String to use for PTT off
|
|
|
|
char * ptr2 = offString ;
|
|
int i, j, len;
|
|
|
|
ptr += 10;
|
|
offLen = len = strlen(ptr) / 2;
|
|
|
|
if (len < 240)
|
|
{
|
|
while ((len--) > 0)
|
|
{
|
|
i = *(ptr++);
|
|
i -= '0';
|
|
if (i > 9)
|
|
i -= 7;
|
|
|
|
j = i << 4;
|
|
|
|
i = *(ptr++);
|
|
i -= '0';
|
|
if (i > 9)
|
|
i -= 7;
|
|
|
|
*(ptr2++) = j | i;
|
|
}
|
|
}
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
|
|
if (ptr == NULL)
|
|
break;
|
|
|
|
}
|
|
|
|
else if (memcmp(ptr, "HAMLIB=", 7) == 0)
|
|
{
|
|
// HAMLIB Emulator - param is port to listen on
|
|
|
|
RIG->HAMLIBPORT = atoi(&ptr[7]);
|
|
}
|
|
|
|
else if (memcmp(ptr, "TXOFFSET", 8) == 0)
|
|
{
|
|
RIG->txOffset = strtoll(&ptr[9], NULL, 10);
|
|
}
|
|
|
|
else if (memcmp(ptr, "RXOFFSET", 8) == 0)
|
|
{
|
|
RIG->rxOffset = strtoll(&ptr[9], NULL, 10);
|
|
}
|
|
|
|
else if (memcmp(ptr, "PTTOFFSET", 9) == 0)
|
|
{
|
|
RIG->pttOffset = strtoll(&ptr[10], NULL, 10);
|
|
}
|
|
|
|
else if (memcmp(ptr, "RXERROR", 7) == 0)
|
|
{
|
|
RIG->rxError = atoi(&ptr[8]);
|
|
}
|
|
|
|
else if (memcmp(ptr, "TXERROR", 7) == 0)
|
|
{
|
|
RIG->txError = atoi(&ptr[8]);
|
|
}
|
|
|
|
else if (memcmp(ptr, "REPORTFREQS", 11) == 0)
|
|
{
|
|
RIG->reportFreqs = _strdup(&ptr[12]);
|
|
}
|
|
|
|
else if (memcmp(ptr, "DEFAULTFREQ", 11) == 0)
|
|
{
|
|
RIG->defaultFreq = atoi(&ptr[12]);
|
|
}
|
|
|
|
else if (atoi(ptr) || ptr[2] == ':')
|
|
break; // Not scan freq oe timeband, so see if another param
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
}
|
|
|
|
if (PORT->PortType == PTT || PORT->PortType == ANT)
|
|
return RIG;
|
|
|
|
// Set up PTT and Poll Strings
|
|
|
|
if (PORT->PortType == ICOM)
|
|
{
|
|
char * Poll;
|
|
Poll = &RIG->PTTOn[0];
|
|
|
|
if (onLen && offLen)
|
|
{
|
|
memcpy(RIG->PTTOn, onString, onLen);
|
|
RIG->PTTOnLen = onLen;
|
|
memcpy(RIG->PTTOff, offString, offLen);
|
|
RIG->PTTOffLen = offLen;
|
|
}
|
|
|
|
else if (RIG->ICF8101)
|
|
{
|
|
// Need to send ACC PTT command (1A 37 0002), not normal ICOM IC 00
|
|
|
|
if (PTTControlsInputMUX)
|
|
{
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1a;
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = ICF8101Mode;
|
|
*(Poll++) = 0x03; // USB Data Mode Source
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x01; // Soundcard
|
|
*(Poll++) = 0xFD;
|
|
}
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1A;
|
|
*(Poll++) = 0x37; // Send/read the TX status
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x02; // ACC PTT
|
|
*(Poll++) = 0xFD;
|
|
|
|
RIG->PTTOnLen = (int)(Poll - &RIG->PTTOn[0]);
|
|
|
|
Poll = &RIG->PTTOff[0];
|
|
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1A;
|
|
*(Poll++) = 0x37; // Send/read the TX status
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x00; // RX
|
|
*(Poll++) = 0xFD;
|
|
|
|
if (PTTControlsInputMUX)
|
|
{
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1a;
|
|
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = ICF8101Mode;
|
|
*(Poll++) = 0x03; // USB Data Mode Source
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x02; // ACC
|
|
*(Poll++) = 0xFD;
|
|
}
|
|
RIG->PTTOffLen = (int)(Poll - &RIG->PTTOff[0]);
|
|
}
|
|
else
|
|
{
|
|
if (PTTControlsInputMUX)
|
|
{
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1a;
|
|
|
|
if (strcmp(RIG->RigName, "IC7100") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x91; // Data Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7200") == 0)
|
|
{
|
|
*(Poll++) = 0x03;
|
|
*(Poll++) = 0x24; // Data Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7300") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x67; // Data Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7600") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x31; // Data1 Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7610") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x92; // Data1 Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7410") == 0)
|
|
{
|
|
*(Poll++) = 0x03;
|
|
*(Poll++) = 0x39; // Data Mode Source
|
|
}
|
|
|
|
*(Poll++) = 0x03; // USB Soundcard
|
|
*(Poll++) = 0xFD;
|
|
}
|
|
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1C; // RIG STATE
|
|
*(Poll++) = 0x00; // PTT
|
|
*(Poll++) = 1; // ON
|
|
*(Poll++) = 0xFD;
|
|
|
|
RIG->PTTOnLen = (int)(Poll - &RIG->PTTOn[0]);
|
|
|
|
Poll = &RIG->PTTOff[0];
|
|
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1C; // RIG STATE
|
|
*(Poll++) = 0x00; // PTT
|
|
*(Poll++) = 0; // OFF
|
|
*(Poll++) = 0xFD;
|
|
|
|
if (PTTControlsInputMUX)
|
|
{
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = 0xFE;
|
|
*(Poll++) = RIG->RigAddr;
|
|
*(Poll++) = 0xE0;
|
|
*(Poll++) = 0x1a;
|
|
|
|
if (strcmp(RIG->RigName, "IC7100") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x91; // Data Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7200") == 0)
|
|
{
|
|
*(Poll++) = 0x03;
|
|
*(Poll++) = 0x24; // Data Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7300") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x67; // Data Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7410") == 0)
|
|
{
|
|
*(Poll++) = 0x03;
|
|
*(Poll++) = 0x39; // Data Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7600") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x31; // Data1 Mode Source
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7610") == 0)
|
|
{
|
|
*(Poll++) = 0x05;
|
|
*(Poll++) = 0x00;
|
|
*(Poll++) = 0x92; // Data1 Mode Source
|
|
}
|
|
|
|
*(Poll++) = DataPTTOffMode;
|
|
*(Poll++) = 0xFD;
|
|
}
|
|
RIG->PTTOffLen = (int)(Poll - &RIG->PTTOff[0]);
|
|
}
|
|
}
|
|
else if (PORT->PortType == KENWOOD)
|
|
{
|
|
RIG->PollLen = 6;
|
|
strcpy(RIG->Poll, "FA;MD;");
|
|
|
|
if (PTTControlsInputMUX)
|
|
{
|
|
sprintf(RIG->PTTOn, "EX%03d00001;TX1;", RIG->TSMenu); // Select USB before PTT
|
|
sprintf(RIG->PTTOff, "RX;EX%03d00000;", RIG->TSMenu); // Select ACC after dropping PTT
|
|
}
|
|
else
|
|
{
|
|
strcpy(RIG->PTTOff, "RX;");
|
|
|
|
if (DataPTT)
|
|
strcpy(RIG->PTTOn, "TX1;");
|
|
else
|
|
strcpy(RIG->PTTOn, "TX;");
|
|
}
|
|
|
|
RIG->PTTOnLen = (int)strlen(RIG->PTTOn);
|
|
RIG->PTTOffLen = (int)strlen(RIG->PTTOff);
|
|
|
|
}
|
|
else if (PORT->PortType == SDRRADIO)
|
|
{
|
|
RIG->PollLen = sprintf(RIG->Poll, "F%c;MD;", RIG->RigAddr);
|
|
|
|
/* if (PTTControlsInputMUX)
|
|
{
|
|
sprintf(RIG->PTTOn, "EX%03d00001;TX1;", RIG->TSMenu); // Select USB before PTT
|
|
sprintf(RIG->PTTOff, "RX;EX%03d00000;", RIG->TSMenu); // Select ACC after dropping PTT
|
|
}
|
|
else
|
|
{
|
|
strcpy(RIG->PTTOff, "RX;");
|
|
|
|
if (DataPTT)
|
|
strcpy(RIG->PTTOn, "TX1;");
|
|
else
|
|
strcpy(RIG->PTTOn, "TX;");
|
|
}
|
|
*/
|
|
RIG->PTTOnLen = (int)strlen(RIG->PTTOn);
|
|
RIG->PTTOffLen = (int)strlen(RIG->PTTOff);
|
|
|
|
} else if (PORT->PortType == FLEX)
|
|
{
|
|
RIG->PollLen = 10;
|
|
strcpy(RIG->Poll, "ZZFA;ZZMD;");
|
|
|
|
strcpy(RIG->PTTOn, "ZZTX1;");
|
|
RIG->PTTOnLen = 6;
|
|
strcpy(RIG->PTTOff, "ZZTX0;");
|
|
RIG->PTTOffLen = 6;
|
|
}
|
|
else if (PORT->PortType == FT2000)
|
|
{
|
|
RIG->PollLen = 6;
|
|
strcpy(RIG->Poll, "FA;MD;");
|
|
|
|
strcpy(RIG->PTTOn, "TX1;");
|
|
RIG->PTTOnLen = 4;
|
|
strcpy(RIG->PTTOff, "TX0;");
|
|
RIG->PTTOffLen = 4;
|
|
}
|
|
else if (PORT->PortType == FT991A || PORT->PortType == FTDX10)
|
|
{
|
|
RIG->PollLen = 7;
|
|
strcpy(RIG->Poll, "FA;MD0;");
|
|
|
|
if (PTTControlsInputMUX)
|
|
{
|
|
RIG->PTTOnLen = sprintf(RIG->PTTOn, "EX0721;TX1;"); // Select USB before PTT
|
|
RIG->PTTOffLen = sprintf(RIG->PTTOff, "TX0;EX0720;"); // Select DATA after dropping PTT
|
|
}
|
|
else
|
|
{
|
|
strcpy(RIG->PTTOn, "TX1;");
|
|
RIG->PTTOnLen = 4;
|
|
strcpy(RIG->PTTOff, "TX0;");
|
|
RIG->PTTOffLen = 4;
|
|
}
|
|
}
|
|
else if (PORT->PortType == NMEA)
|
|
{
|
|
int Len;
|
|
|
|
i = sprintf(RIG->Poll, "$PICOA,90,%02x,RXF*xx\r\n", RIG->RigAddr);
|
|
AddNMEAChecksum(RIG->Poll);
|
|
Len = i;
|
|
i = sprintf(RIG->Poll + Len, "$PICOA,90,%02x,MODE*xx\r\n", RIG->RigAddr);
|
|
AddNMEAChecksum(RIG->Poll + Len);
|
|
RIG->PollLen = Len + i;
|
|
|
|
i = sprintf(RIG->PTTOn, "$PICOA,90,%02x,TRX,TX*xx\r\n", RIG->RigAddr);
|
|
AddNMEAChecksum(RIG->PTTOn);
|
|
RIG->PTTOnLen = i;
|
|
|
|
i = sprintf(RIG->PTTOff, "$PICOA,90,%02x,TRX,RX*xx\r\n", RIG->RigAddr);
|
|
AddNMEAChecksum(RIG->PTTOff);
|
|
RIG->PTTOffLen = i;
|
|
}
|
|
|
|
if (ptr == NULL) return RIG; // No Scanning, just Interactive control
|
|
|
|
if (strchr(ptr, ',') == 0 && strchr(ptr, ':') == 0) // Old Format
|
|
{
|
|
ScanFreq = atof(ptr);
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4244)
|
|
|
|
RIG->ScanFreq = ScanFreq * 10;
|
|
|
|
#pragma warning(push)
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
}
|
|
|
|
// Frequency List
|
|
|
|
CheckScan:
|
|
|
|
if (ptr)
|
|
if (ptr[0] == ';' || ptr[0] == '#')
|
|
ptr = NULL;
|
|
|
|
if (ptr != NULL)
|
|
{
|
|
// Create Default Timeband
|
|
|
|
struct TimeScan * Band;
|
|
|
|
RIG->TimeBands = zalloc(sizeof(void *));
|
|
|
|
Band = AllocateTimeRec(RIG);
|
|
SaveBand = Band;
|
|
|
|
Band->Start = 0;
|
|
Band->End = 84540; //23:59
|
|
FreqPtr = Band->Scanlist = RIG->FreqPtr = malloc(1000);
|
|
memset(FreqPtr, 0, 1000);
|
|
}
|
|
|
|
while(ptr)
|
|
{
|
|
int ModeNo;
|
|
BOOL Supress;
|
|
double Freq = 0.0;
|
|
int FreqInt = 0;
|
|
char FreqString[80]="";
|
|
char * Modeptr = NULL;
|
|
char Split, Data, PacketMode, RPacketMode, PMinLevel, PMaxLevel, Filter;
|
|
char Mode[10] = "";
|
|
char WinmorMode, Antenna;
|
|
char ARDOPMode[6] = "";
|
|
char VARAMode[6] = "";
|
|
char Appl[13];
|
|
char * ApplCall;
|
|
int BandWidth;
|
|
int Power;
|
|
|
|
if (ptr[0] == ';' || ptr[0] == '#')
|
|
break;
|
|
|
|
Filter = PMinLevel = PMaxLevel = PacketMode = RPacketMode = Split =
|
|
Data = WinmorMode = Antenna = ModeNo = Supress =
|
|
MemoryBank = MemoryNumber = BandWidth = 0;
|
|
|
|
Appl[0] = 0;
|
|
ARDOPMode[0] = 0;
|
|
VARAMode[0] = 0;
|
|
Dwell = 0.0;
|
|
|
|
while (ptr && strchr(ptr, ':'))
|
|
{
|
|
// New TimeBand
|
|
|
|
struct TimeScan * Band;
|
|
|
|
Band = AllocateTimeRec(RIG);
|
|
|
|
*FreqPtr = (struct ScanEntry *)0; // Terminate Last Band
|
|
|
|
Band->Start = (atoi(ptr) * 3600) + (atoi(&ptr[3]) * 60);
|
|
Band->End = 84540; //23:59
|
|
SaveBand->End = Band->Start - 60;
|
|
|
|
SaveBand = Band;
|
|
|
|
FreqPtr = Band->Scanlist = RIG->FreqPtr = malloc(1000);
|
|
memset(FreqPtr, 0, 1000);
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context);
|
|
}
|
|
|
|
if (ptr == 0)
|
|
break;
|
|
|
|
if (strchr(ptr, ',')) // New Format
|
|
{
|
|
DecodeModePtr(ptr, &Dwell, &Freq, Mode, &PMinLevel, &PMaxLevel, &PacketMode,
|
|
&RPacketMode, &Split, &Data, &WinmorMode, &Antenna, &Supress, &Filter, &Appl[0],
|
|
&MemoryBank, &MemoryNumber, ARDOPMode, VARAMode, &BandWidth, &Power);
|
|
}
|
|
else
|
|
{
|
|
Modeptr = strchr(ptr, '/');
|
|
|
|
if (Modeptr)
|
|
*Modeptr++ = 0;
|
|
|
|
Freq = atof(ptr);
|
|
|
|
if (Modeptr)
|
|
{
|
|
// Mode can include 1/2/3 for Icom Filers. W/N for Winmor/Pactor Bandwidth, and +/-/S for Repeater Shift (S = Simplex)
|
|
// First is always Mode
|
|
// First char is Mode (USB, LSB etc)
|
|
|
|
Mode[0] = Modeptr[0];
|
|
Filter = Modeptr[1];
|
|
|
|
if (strchr(&Modeptr[1], '+'))
|
|
Split = '+';
|
|
else if (strchr(&Modeptr[1], '-'))
|
|
Split = '-';
|
|
else if (strchr(&Modeptr[1], 'S'))
|
|
Split = 'S';
|
|
else if (strchr(&Modeptr[1], 'D'))
|
|
Data = 1;
|
|
|
|
if (strchr(&Modeptr[1], 'W'))
|
|
{
|
|
WinmorMode = 'W';
|
|
PMaxLevel = '3';
|
|
PMinLevel = '1';
|
|
}
|
|
else if (strchr(&Modeptr[1], 'N'))
|
|
{
|
|
WinmorMode = 'N';
|
|
PMaxLevel = '2';
|
|
PMinLevel = '1';
|
|
}
|
|
|
|
if (strchr(&Modeptr[1], 'R')) // Robust Packet
|
|
RPacketMode = '2'; // R600
|
|
else if (strchr(&Modeptr[1], 'H')) // HF Packet on Tracker
|
|
PacketMode = '1'; // 300
|
|
|
|
if (strchr(&Modeptr[1], 'X')) // Dont Report to WL2K
|
|
Supress = 1;
|
|
|
|
if (strstr(&Modeptr[1], "A1"))
|
|
Antenna = '1';
|
|
else if (strstr(&Modeptr[1], "A2"))
|
|
Antenna = '2';
|
|
else if (strstr(&Modeptr[1], "A3"))
|
|
Antenna = '3';
|
|
else if (strstr(&Modeptr[1], "A4"))
|
|
Antenna = '4';
|
|
else if (strstr(&Modeptr[1], "A5"))
|
|
Antenna = '5';
|
|
else if (strstr(&Modeptr[1], "A6"))
|
|
Antenna = '6';
|
|
}
|
|
}
|
|
|
|
switch(PORT->PortType)
|
|
{
|
|
case ICOM:
|
|
|
|
for (ModeNo = 0; ModeNo < 24; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (Modes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case YAESU:
|
|
|
|
for (ModeNo = 0; ModeNo < 16; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (YaesuModes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(YaesuModes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case KENWOOD:
|
|
|
|
for (ModeNo = 0; ModeNo < 8; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (KenwoodModes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(KenwoodModes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FLEX:
|
|
|
|
for (ModeNo = 0; ModeNo < 12; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (FLEXModes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(FLEXModes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FT2000:
|
|
|
|
if (Modeptr)
|
|
{
|
|
if (strstr(Modeptr, "PL"))
|
|
{
|
|
ModeNo = 8;
|
|
break;
|
|
}
|
|
if (strstr(Modeptr, "PU"))
|
|
{
|
|
ModeNo = 12;
|
|
break;
|
|
}
|
|
}
|
|
for (ModeNo = 0; ModeNo < 14; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (FT2000Modes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(FT2000Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FT991A:
|
|
|
|
/* if (Modeptr)
|
|
{
|
|
if (strstr(Modeptr, "PL"))
|
|
{
|
|
ModeNo = 8;
|
|
break;
|
|
}
|
|
if (strstr(Modeptr, "PU"))
|
|
{
|
|
ModeNo = 12;
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
for (ModeNo = 0; ModeNo < 15; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (FT991AModes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(FT991AModes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FTDX10:
|
|
|
|
for (ModeNo = 0; ModeNo < 16; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (FTDX10Modes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(FTDX10Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
case FT100:
|
|
|
|
for (ModeNo = 0; ModeNo < 8; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (FT100Modes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(FT100Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FT990:
|
|
|
|
for (ModeNo = 0; ModeNo < 12; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (FT990Modes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(FT990Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FT1000:
|
|
|
|
for (ModeNo = 0; ModeNo < 12; ModeNo++)
|
|
{
|
|
if (strlen(Mode) == 1)
|
|
{
|
|
if (FT1000Modes[ModeNo][0] == Mode[0])
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (_stricmp(FT1000Modes[ModeNo], Mode) == 0)
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
Freq = Freq * 1000000.0;
|
|
|
|
sprintf(FreqString, "%09.0f", Freq);
|
|
|
|
FreqInt = Freq;
|
|
|
|
FreqPtr[0] = malloc(sizeof(struct ScanEntry));
|
|
memset(FreqPtr[0], 0, sizeof(struct ScanEntry));
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4244)
|
|
|
|
if (Dwell == 0.0)
|
|
FreqPtr[0]->Dwell = ScanFreq * 10;
|
|
else
|
|
FreqPtr[0]->Dwell = Dwell * 10;
|
|
|
|
#pragma warning(pop)
|
|
|
|
FreqPtr[0]->Freq = Freq;
|
|
FreqPtr[0]->Bandwidth = WinmorMode;
|
|
FreqPtr[0]->RPacketMode = RPacketMode;
|
|
FreqPtr[0]->HFPacketMode = PacketMode;
|
|
FreqPtr[0]->PMaxLevel = PMaxLevel;
|
|
FreqPtr[0]->PMinLevel = PMinLevel;
|
|
FreqPtr[0]->Antenna = Antenna;
|
|
strcpy(FreqPtr[0]->ARDOPMode, ARDOPMode);
|
|
FreqPtr[0]->VARAMode = VARAMode[0];
|
|
|
|
strcpy(FreqPtr[0]->APPL, Appl);
|
|
|
|
ApplCall = GetApplCallFromName(Appl);
|
|
|
|
if (strcmp(Appl, "NODE") == 0)
|
|
{
|
|
memcpy(FreqPtr[0]->APPLCALL, TNC->NodeCall, 9);
|
|
strlop(FreqPtr[0]->APPLCALL, ' ');
|
|
}
|
|
else
|
|
{
|
|
if (ApplCall && ApplCall[0] > 32)
|
|
{
|
|
memcpy(FreqPtr[0]->APPLCALL, ApplCall, 9);
|
|
strlop(FreqPtr[0]->APPLCALL, ' ');
|
|
}
|
|
}
|
|
|
|
CmdPtr = FreqPtr[0]->Cmd1 = malloc(100);
|
|
|
|
if (PORT->PortType == ICOM)
|
|
{
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
|
|
if (RIG->ICF8101)
|
|
{
|
|
// Set Freq is 1A 35 and set Mode 1A 36
|
|
|
|
|
|
*(CmdPtr++) = 0x1A;
|
|
*(CmdPtr++) = 0x35; // Set frequency command
|
|
|
|
// Need to convert two chars to bcd digit
|
|
|
|
*(CmdPtr++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[2] - 48) | ((FreqString[1] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[0] - 48);
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0]->Cmd1Len = 12;
|
|
|
|
CmdPtr = FreqPtr[0]->Cmd2 = malloc(10);
|
|
FreqPtr[0]->Cmd2Len = 9;
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x1A;
|
|
*(CmdPtr++) = 0x36; // Set mode command
|
|
*(CmdPtr++) = 0;
|
|
|
|
if (ModeNo > 19)
|
|
*(CmdPtr++) = ModeNo + 12;
|
|
else if (ModeNo > 9)
|
|
*(CmdPtr++) = ModeNo + 6;
|
|
else
|
|
*(CmdPtr++) = ModeNo;
|
|
|
|
*(CmdPtr++) = 0xFD;
|
|
}
|
|
else
|
|
{
|
|
if (MemoryNumber)
|
|
{
|
|
// Set Memory Channel instead of Freq, Mode, etc
|
|
|
|
char ChanString[5];
|
|
|
|
// Send Set Memory, then Channel
|
|
|
|
*(CmdPtr++) = 0x08;
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
|
|
sprintf(ChanString, "%04d", MemoryNumber);
|
|
|
|
*(CmdPtr++) = 0x08;
|
|
*(CmdPtr++) = (ChanString[1] - 48) | ((ChanString[0] - 48) << 4);
|
|
*(CmdPtr++) = (ChanString[3] - 48) | ((ChanString[2] - 48) << 4);
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
FreqPtr[0]->Cmd1Len = 14;
|
|
|
|
if (MemoryBank)
|
|
{
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x08;
|
|
*(CmdPtr++) = 0xA0;
|
|
*(CmdPtr++) = MemoryBank - 0x40;
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
FreqPtr[0]->Cmd1Len += 8;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*(CmdPtr++) = 0x5; // Set frequency command
|
|
|
|
// Need to convert two chars to bcd digit
|
|
|
|
*(CmdPtr++) = (FreqString[8] - 48) | ((FreqString[7] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[6] - 48) | ((FreqString[5] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[4] - 48) | ((FreqString[3] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[2] - 48) | ((FreqString[1] - 48) << 4);
|
|
if (RIG->IC735)
|
|
{
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0]->Cmd1Len = 10;
|
|
}
|
|
else
|
|
{
|
|
*(CmdPtr++) = (FreqString[0] - 48);
|
|
*(CmdPtr++) = 0xFD;
|
|
FreqPtr[0]->Cmd1Len = 11;
|
|
}
|
|
|
|
// Send Set VFO in case last chan was memory
|
|
|
|
// *(CmdPtr++) = 0xFE;
|
|
// *(CmdPtr++) = 0xFE;
|
|
// *(CmdPtr++) = RIG->RigAddr;
|
|
// *(CmdPtr++) = 0xE0;
|
|
|
|
// *(CmdPtr++) = 0x07;
|
|
// *(CmdPtr++) = 0xFD;
|
|
|
|
// FreqPtr[0]->Cmd1Len = 17;
|
|
|
|
if (Filter)
|
|
{
|
|
CmdPtr = FreqPtr[0]->Cmd2 = malloc(10);
|
|
FreqPtr[0]->Cmd2Len = 8;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x6; // Set Mode
|
|
*(CmdPtr++) = ModeNo;
|
|
*(CmdPtr++) = Filter - '0'; //Filter
|
|
*(CmdPtr++) = 0xFD;
|
|
|
|
if (Split)
|
|
{
|
|
CmdPtr = FreqPtr[0]->Cmd3 = malloc(10);
|
|
FreqPtr[0]->Cmd3Len = 7;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0xF; // Set Mode
|
|
if (Split == 'S')
|
|
*(CmdPtr++) = 0x10;
|
|
else
|
|
if (Split == '+')
|
|
*(CmdPtr++) = 0x12;
|
|
else
|
|
if (Split == '-')
|
|
*(CmdPtr++) = 0x11;
|
|
|
|
*(CmdPtr++) = 0xFD;
|
|
}
|
|
else
|
|
{
|
|
if (Data)
|
|
{
|
|
CmdPtr = FreqPtr[0]->Cmd3 = malloc(10);
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x1a;
|
|
|
|
|
|
if ((strcmp(RIG->RigName, "IC7100") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7410") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7600") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7610") == 0) ||
|
|
(strcmp(RIG->RigName, "IC7300") == 0))
|
|
{
|
|
FreqPtr[0]->Cmd3Len = 9;
|
|
*(CmdPtr++) = 0x6; // Send/read DATA mode with filter set
|
|
*(CmdPtr++) = 0x1; // Data On
|
|
*(CmdPtr++) = Filter - '0'; //Filter
|
|
}
|
|
else if (strcmp(RIG->RigName, "IC7200") == 0)
|
|
{
|
|
FreqPtr[0]->Cmd3Len = 9;
|
|
*(CmdPtr++) = 0x4; // Send/read DATA mode with filter set
|
|
*(CmdPtr++) = 0x1; // Data On
|
|
*(CmdPtr++) = Filter - '0'; //Filter
|
|
}
|
|
else
|
|
{
|
|
FreqPtr[0]->Cmd3Len = 8;
|
|
*(CmdPtr++) = 0x6; // Set Data
|
|
*(CmdPtr++) = 0x1; //On
|
|
}
|
|
|
|
*(CmdPtr++) = 0xFD;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Antenna == '5' || Antenna == '6')
|
|
{
|
|
// Antenna select for 746 and maybe others
|
|
|
|
// Could be going in cmd2 3 or 4
|
|
|
|
if (FreqPtr[0]->Cmd2 == NULL)
|
|
{
|
|
CmdPtr = FreqPtr[0]->Cmd2 = malloc(10);
|
|
FreqPtr[0]->Cmd2Len = 7;
|
|
}
|
|
else if (FreqPtr[0]->Cmd3 == NULL)
|
|
{
|
|
CmdPtr = FreqPtr[0]->Cmd3 = malloc(10);
|
|
FreqPtr[0]->Cmd3Len = 7;
|
|
}
|
|
else
|
|
{
|
|
CmdPtr = FreqPtr[0]->Cmd4 = malloc(10);
|
|
FreqPtr[0]->Cmd4Len = 7;
|
|
}
|
|
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = 0xFE;
|
|
*(CmdPtr++) = RIG->RigAddr;
|
|
*(CmdPtr++) = 0xE0;
|
|
*(CmdPtr++) = 0x12; // Set Antenna
|
|
*(CmdPtr++) = Antenna - '5'; // 0 for A5 1 for A6
|
|
*(CmdPtr++) = 0xFD;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (PORT->PortType == YAESU)
|
|
{
|
|
//Send Mode first - changing mode can change freq
|
|
|
|
*(CmdPtr++) = ModeNo;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 7;
|
|
|
|
*(CmdPtr++) = (FreqString[1] - 48) | ((FreqString[0] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[3] - 48) | ((FreqString[2] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4);
|
|
*(CmdPtr++) = 1;
|
|
|
|
// FT847 Needs a Poll Here. Set up anyway, but only send if 847
|
|
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 3;
|
|
|
|
|
|
}
|
|
else if (PORT->PortType == KENWOOD)
|
|
{
|
|
if (Power == 0)
|
|
{
|
|
if (Antenna == '5' || Antenna == '6')
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "FA00%s;MD%d;AN%c;FA;MD;", FreqString, ModeNo, Antenna - 4);
|
|
else
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "FA00%s;MD%d;FA;MD;", FreqString, ModeNo);
|
|
}
|
|
else
|
|
{
|
|
if (Antenna == '5' || Antenna == '6')
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "FA00%s;MD%d;AN%c;PC%03d;FA;MD;PC;", FreqString, ModeNo, Antenna - 4, Power);
|
|
else
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "FA00%s;MD%d;PC%03d;FA;MD;PC;", FreqString, ModeNo, Power);
|
|
}
|
|
}
|
|
else if (PORT->PortType == FLEX)
|
|
{
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "ZZFA00%s;ZZMD%02d;ZZFA;ZZMD;", FreqString, ModeNo);
|
|
}
|
|
else if (PORT->PortType == FT2000)
|
|
{
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "FA%s;MD0%X;FA;MD;", &FreqString[1], ModeNo);
|
|
}
|
|
else if (PORT->PortType == FT991A || PORT->PortType == FTDX10)
|
|
{
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "FA%s;MD0%X;FA;MD0;", &FreqString, ModeNo);
|
|
}
|
|
else if (PORT->PortType == FT100 || PORT->PortType == FT990
|
|
|| PORT->PortType == FT1000)
|
|
{
|
|
// Allow Mode = "LEAVE" to suppress mode change
|
|
|
|
//Send Mode first - changing mode can change freq
|
|
|
|
if (strcmp(Mode, "LEAVE") == 0)
|
|
{
|
|
// we can't easily change the string length,
|
|
// so just set freq twice
|
|
|
|
*(CmdPtr++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[3] - 48) | ((FreqString[2] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[1] - 48) | ((FreqString[0] - 48) << 4);
|
|
*(CmdPtr++) = 10;
|
|
}
|
|
else
|
|
{
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = ModeNo;
|
|
*(CmdPtr++) = 12;
|
|
}
|
|
|
|
*(CmdPtr++) = (FreqString[7] - 48) | ((FreqString[6] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[5] - 48) | ((FreqString[4] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[3] - 48) | ((FreqString[2] - 48) << 4);
|
|
*(CmdPtr++) = (FreqString[1] - 48) | ((FreqString[0] - 48) << 4);
|
|
*(CmdPtr++) = 10;
|
|
|
|
// Send Get Status, as these types doesn't ack commands
|
|
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
*(CmdPtr++) = 0;
|
|
|
|
if (PORT->PortType == FT990 || PORT->YaesuVariant == FT1000D)
|
|
*(CmdPtr++) = 3;
|
|
else
|
|
*(CmdPtr++) = 2; // F100 or FT1000MP
|
|
|
|
*(CmdPtr++) = 16; // Get Status
|
|
}
|
|
else if (PORT->PortType == NMEA)
|
|
{
|
|
int Len;
|
|
|
|
i = sprintf(CmdPtr, "$PICOA,90,%02x,RXF,%.6f*xx\r\n", RIG->RigAddr, Freq/1000000.);
|
|
AddNMEAChecksum(CmdPtr);
|
|
Len = i;
|
|
i = sprintf(CmdPtr + Len, "$PICOA,90,%02x,TXF,%.6f*xx\r\n", RIG->RigAddr, Freq/1000000.);
|
|
AddNMEAChecksum(CmdPtr + Len);
|
|
Len += i;
|
|
i = sprintf(CmdPtr + Len, "$PICOA,90,%02x,MODE,%s*xx\r\n", RIG->RigAddr, Mode);
|
|
AddNMEAChecksum(CmdPtr + Len);
|
|
FreqPtr[0]->Cmd1Len = Len + i;
|
|
|
|
i = sprintf(RIG->Poll, "$PICOA,90,%02x,RXF*xx\r\n", RIG->RigAddr);
|
|
AddNMEAChecksum(RIG->Poll);
|
|
Len = i;
|
|
i = sprintf(RIG->Poll + Len, "$PICOA,90,%02x,MODE*xx\r\n", RIG->RigAddr);
|
|
AddNMEAChecksum(RIG->Poll + Len);
|
|
RIG->PollLen = Len + i;
|
|
}
|
|
else if (PORT->PortType == HAMLIB)
|
|
{
|
|
FreqPtr[0]->Cmd1Len = sprintf(CmdPtr, "F %s\n+f\nM %s %d\n+m\n", FreqString, Mode, BandWidth);
|
|
}
|
|
|
|
else if (PORT->PortType == FLRIG)
|
|
{
|
|
sprintf(FreqPtr[0]->Cmd1Msg, "%.0f", Freq);
|
|
sprintf(FreqPtr[0]->Cmd2Msg, "%s", Mode);
|
|
sprintf(FreqPtr[0]->Cmd3Msg, "%d", BandWidth);
|
|
}
|
|
|
|
else if (PORT->PortType == RTLUDP)
|
|
{
|
|
int FM = 0;
|
|
int AM = 1;
|
|
int USB = 2;
|
|
int LSB = 3;
|
|
|
|
CmdPtr[0] = 0;
|
|
memcpy(&CmdPtr[1], &FreqInt, 4);
|
|
|
|
CmdPtr[1] = FreqInt & 0xff;
|
|
CmdPtr[2] = (FreqInt >> 8) & 0xff;
|
|
CmdPtr[3] = (FreqInt >> 16) & 0xff;
|
|
CmdPtr[4] = (FreqInt >> 24) & 0xff;
|
|
|
|
FreqPtr[0]->Cmd1Len = 5;
|
|
|
|
if (Mode[0])
|
|
{
|
|
CmdPtr[5] = 1;
|
|
FreqPtr[0]->Cmd1Len = 10;
|
|
|
|
if (strcmp(Mode, "FM") == 0)
|
|
memcpy(&CmdPtr[6], &FM, 4);
|
|
else if (strcmp(Mode, "AM") == 0)
|
|
memcpy(&CmdPtr[6], &AM, 4);
|
|
else if (strcmp(Mode, "USB") == 0)
|
|
memcpy(&CmdPtr[6], &USB, 4);
|
|
else if (strcmp(Mode, "LSB") == 0)
|
|
memcpy(&CmdPtr[6], &LSB, 4);
|
|
}
|
|
|
|
}
|
|
|
|
FreqPtr++;
|
|
|
|
RIG->ScanCounter = 20;
|
|
|
|
ptr = strtok_s(NULL, " \t\n\r", &Context); // Next Freq
|
|
}
|
|
|
|
|
|
|
|
if (RIG->NumberofBands)
|
|
{
|
|
CheckTimeBands(RIG); // Set initial FreqPtr;
|
|
PORT->FreqPtr = RIG->FreqPtr[0];
|
|
}
|
|
|
|
return RIG;
|
|
}
|
|
|
|
VOID SetupScanInterLockGroups(struct RIGINFO *RIG)
|
|
{
|
|
struct PORTCONTROL * PortRecord;
|
|
struct TNCINFO * TNC;
|
|
int port;
|
|
int Interlock = RIG->Interlock;
|
|
char PortString[128] = "";
|
|
char TxPortString[128] = "";
|
|
|
|
// Find TNC ports in this Rig's scan group
|
|
|
|
for (port = 1; port < MAXBPQPORTS; port++)
|
|
{
|
|
TNC = TNCInfo[port];
|
|
|
|
if (TNC == NULL)
|
|
continue;
|
|
|
|
PortRecord = &TNC->PortRecord->PORTCONTROL;
|
|
|
|
if (TNC->RXRadio == Interlock)
|
|
{
|
|
int p = PortRecord->PORTNUMBER;
|
|
RIG->BPQPort |= ((uint64_t)1 << p);
|
|
sprintf(PortString, "%s,%d", PortString, p);
|
|
TNC->RIG = RIG;
|
|
|
|
if (RIG->PTTMode == 0 && TNC->PTTMode)
|
|
RIG->PTTMode = TNC->PTTMode;
|
|
}
|
|
if (TNC->TXRadio == Interlock && TNC->TXRadio != TNC->RXRadio)
|
|
{
|
|
int p = PortRecord->PORTNUMBER;
|
|
RIG->BPQPort |= ((uint64_t)1 << p);
|
|
sprintf(TxPortString, "%s,%d", TxPortString, p);
|
|
TNC->TXRIG = RIG;
|
|
|
|
if (RIG->PTTMode == 0 && TNC->PTTMode)
|
|
RIG->PTTMode = TNC->PTTMode;
|
|
}
|
|
}
|
|
|
|
if (RIG->PTTMode == 0 && (RIG->PTTCATPort[0] || RIG->HAMLIBPORT)) // PTT Mux Implies CAT
|
|
RIG->PTTMode = PTTCI_V;
|
|
|
|
if (PortString[0] && TxPortString[0]) // Have both
|
|
sprintf(RIG->WEB_PORTS, "Rx: %s Tx: %s", &PortString[1], &TxPortString[1]);
|
|
else if (PortString[0])
|
|
strcpy(RIG->WEB_PORTS, &PortString[1]);
|
|
else if (TxPortString[0])
|
|
sprintf(RIG->WEB_PORTS, "Tx: %s", &TxPortString[1]);
|
|
|
|
SetWindowText(RIG->hPORTS, RIG->WEB_PORTS);
|
|
}
|
|
|
|
VOID SetupPortRIGPointers()
|
|
{
|
|
struct TNCINFO * TNC;
|
|
int port;
|
|
|
|
for (port = 1; port < MAXBPQPORTS; port++)
|
|
{
|
|
TNC = TNCInfo[port];
|
|
|
|
if (TNC == NULL)
|
|
continue;
|
|
|
|
if (TNC->RIG == NULL)
|
|
TNC->RIG = &TNC->DummyRig; // Not using Rig control, so use Dummy
|
|
}
|
|
}
|
|
|
|
#ifdef WIN32
|
|
|
|
VOID PTTCATThread(struct RIGINFO *RIG)
|
|
{
|
|
DWORD dwLength = 0;
|
|
int Length, ret, i;
|
|
UCHAR * ptr1;
|
|
UCHAR * ptr2;
|
|
UCHAR c;
|
|
UCHAR Block[4][80];
|
|
UCHAR CurrentState[4] = {0};
|
|
#define RTS 2
|
|
#define DTR 4
|
|
HANDLE Event;
|
|
HANDLE Handle[4];
|
|
DWORD EvtMask[4];
|
|
OVERLAPPED Overlapped[4];
|
|
char Port[32];
|
|
int PIndex = 0;
|
|
int HIndex = 0;
|
|
int rc;
|
|
|
|
EndPTTCATThread = FALSE;
|
|
|
|
while (PIndex < 4 && RIG->PTTCATPort[PIndex][0])
|
|
{
|
|
RIG->RealMux[HIndex] = 0;
|
|
|
|
sprintf(Port, "\\\\.\\pipe\\BPQCOM%s", RIG->PTTCATPort[PIndex]);
|
|
|
|
Handle[HIndex] = CreateFile(Port, GENERIC_READ | GENERIC_WRITE,
|
|
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
if (Handle[HIndex] == (HANDLE) -1)
|
|
{
|
|
int Err = GetLastError();
|
|
char errmsg[256] = "";
|
|
|
|
// Only report if both BPQCOM and Real COM fail
|
|
|
|
sprintf(errmsg, "PTTMUX port BPQCOM%s Open failed code %d - trying real com port", RIG->PTTCATPort[PIndex], Err);
|
|
|
|
// See if real com port
|
|
|
|
sprintf(Port, "\\\\.\\\\COM%s", RIG->PTTCATPort[PIndex]);
|
|
|
|
Handle[HIndex] = CreateFile(Port, GENERIC_READ | GENERIC_WRITE,
|
|
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
RIG->RealMux[HIndex] = 1;
|
|
|
|
if (Handle[HIndex] == (HANDLE) -1)
|
|
{
|
|
int Err = GetLastError();
|
|
if (errmsg[0])
|
|
{
|
|
Consoleprintf("%s", errmsg);
|
|
Consoleprintf("PTTMUX port COM%s Open failed code %d", RIG->PTTCATPort[PIndex], Err);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = SetCommMask(Handle[HIndex], EV_CTS | EV_DSR); // Request notifications
|
|
HIndex++;
|
|
}
|
|
}
|
|
else
|
|
HIndex++;
|
|
|
|
PIndex++;
|
|
|
|
}
|
|
|
|
if (PIndex == 0)
|
|
return; // No ports
|
|
|
|
Event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
for (i = 0; i < HIndex; i ++)
|
|
{
|
|
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
|
|
Overlapped[i].hEvent = Event;
|
|
|
|
if (RIG->RealMux[i])
|
|
{
|
|
// Request Interface change notifications
|
|
|
|
rc = WaitCommEvent(Handle[i], &EvtMask[i], &Overlapped[i]);
|
|
rc = GetLastError();
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
// Prime a read on each handle
|
|
|
|
ReadFile(Handle[i], Block[i], 80, &Length, &Overlapped[i]);
|
|
}
|
|
}
|
|
|
|
while (EndPTTCATThread == FALSE)
|
|
{
|
|
|
|
WaitAgain:
|
|
|
|
ret = WaitForSingleObject(Event, 1000);
|
|
|
|
if (ret == WAIT_TIMEOUT)
|
|
{
|
|
if (EndPTTCATThread)
|
|
{
|
|
for (i = 0; i < HIndex; i ++)
|
|
{
|
|
CancelIo(Handle[i]);
|
|
CloseHandle(Handle[i]);
|
|
Handle[i] = INVALID_HANDLE_VALUE;
|
|
}
|
|
CloseHandle(Event);
|
|
return;
|
|
}
|
|
goto WaitAgain;
|
|
}
|
|
|
|
ResetEvent(Event);
|
|
|
|
// See which request(s) have completed
|
|
|
|
for (i = 0; i < HIndex; i ++)
|
|
{
|
|
ret = GetOverlappedResult(Handle[i], &Overlapped[i], &Length, FALSE);
|
|
|
|
if (ret)
|
|
{
|
|
if (RIG->RealMux[i])
|
|
{
|
|
// Request Interface change notifications
|
|
|
|
DWORD Mask;
|
|
|
|
GetCommModemStatus(Handle[i], &Mask);
|
|
|
|
if (Mask & MS_CTS_ON)
|
|
Rig_PTTEx(RIG, TRUE, RIG->PTTCATTNC[i]);
|
|
else
|
|
Rig_PTTEx(RIG, FALSE, RIG->PTTCATTNC[i]);
|
|
|
|
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
|
|
Overlapped[i].hEvent = Event;
|
|
WaitCommEvent(Handle[i], &EvtMask[i], &Overlapped[i]);
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
ptr1 = Block[i];
|
|
ptr2 = Block[i];
|
|
|
|
while (Length > 0)
|
|
{
|
|
c = *(ptr1++);
|
|
|
|
Length--;
|
|
|
|
if (c == 0xff)
|
|
{
|
|
c = *(ptr1++);
|
|
Length--;
|
|
|
|
if (c == 0xff) // ff ff means ff
|
|
{
|
|
Length--;
|
|
}
|
|
else
|
|
{
|
|
// This is connection / RTS/DTR statua from other end
|
|
// Convert to CAT Command
|
|
|
|
if (c == CurrentState[i])
|
|
continue;
|
|
|
|
if (c & RTS)
|
|
Rig_PTTEx(RIG, TRUE, RIG->PTTCATTNC[i]);
|
|
else
|
|
Rig_PTTEx(RIG, FALSE, RIG->PTTCATTNC[i]);
|
|
|
|
CurrentState[i] = c;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
memset(&Overlapped[i], 0, sizeof(OVERLAPPED));
|
|
Overlapped[i].hEvent = Event;
|
|
|
|
ReadFile(Handle[i], Block[i], 80, &Length, &Overlapped[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
EndPTTCATThread = FALSE;
|
|
}
|
|
|
|
/*
|
|
memset(&Overlapped, 0, sizeof(Overlapped));
|
|
Overlapped.hEvent = Event;
|
|
ResetEvent(Event);
|
|
|
|
ret = ReadFile(Handle, Block, 80, &Length, &Overlapped);
|
|
|
|
if (ret == 0)
|
|
{
|
|
ret = GetLastError();
|
|
|
|
if (ret != ERROR_IO_PENDING)
|
|
{
|
|
if (ret == ERROR_BROKEN_PIPE || ret == ERROR_INVALID_HANDLE)
|
|
{
|
|
CloseHandle(Handle);
|
|
RIG->PTTCATHandles[0] = INVALID_HANDLE_VALUE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
#endif
|
|
|
|
// HAMLIB Support Code
|
|
|
|
VOID HAMLIBPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on HAMLIB
|
|
char cmd[80];
|
|
int len;
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
SetWindowText(RIG->hFREQ, "------------------");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
RIG->RIGOK = FALSE;
|
|
return;
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
send(PORT->remoteSock, PORT->TXBuffer, PORT->TXLen, 0);
|
|
PORT->CmdSent = 1;
|
|
PORT->Retries = 0;
|
|
PORT->Timeout = 0;
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
// There isn't a response to a set command, so clear Scan Lock here
|
|
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter > 1)
|
|
return;
|
|
}
|
|
|
|
if (RIG->RIGOK && (RIG->ScanStopped == 0) && RIG->NumberofBands)
|
|
return; // no point in reading freq if we are about to change it
|
|
|
|
RIG->PollCounter = 10; // Once Per Sec
|
|
|
|
// Read Frequency
|
|
|
|
len = sprintf(cmd, "+f\n+m\n");
|
|
|
|
send(PORT->remoteSock, cmd, len, 0);
|
|
|
|
PORT->Timeout = 10;
|
|
PORT->CmdSent = 0;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void HAMLIBProcessMessage(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Called from Background thread
|
|
|
|
int InputLen = recv(PORT->remoteSock, &PORT->RXBuffer[PORT->RXLen], 500 - PORT->RXLen, 0);
|
|
|
|
if (InputLen == 0 || InputLen == SOCKET_ERROR)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
return;
|
|
}
|
|
|
|
PORT->RXLen += InputLen;
|
|
}
|
|
|
|
void FLRIGProcessMessage(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Called from Background thread
|
|
|
|
int InputLen = recv(PORT->remoteSock, &PORT->RXBuffer[PORT->RXLen], 500 - PORT->RXLen, 0);
|
|
|
|
if (InputLen == 0 || InputLen == SOCKET_ERROR)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
return;
|
|
}
|
|
|
|
PORT->RXLen += InputLen;
|
|
ProcessFLRIGFrame(PORT);
|
|
}
|
|
|
|
void ProcessHAMLIBFrame(struct RIGPORTINFO * PORT, int Length)
|
|
{
|
|
char * msg = PORT->RXBuffer;
|
|
char * rest;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on Yaseu
|
|
msg[Length] = 0;
|
|
|
|
PORT->Timeout = 0;
|
|
RIG->RIGOK = 1;
|
|
|
|
// extract lines from input
|
|
|
|
while (msg && msg[0])
|
|
{
|
|
rest = strlop(msg, 10);
|
|
|
|
if (memcmp(msg, "Frequency:", 10) == 0)
|
|
{
|
|
RIG->RigFreq = atof(&msg[11]) / 1000000.0;
|
|
|
|
_gcvt(RIG->RigFreq, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
}
|
|
|
|
else if (memcmp(msg, "Mode:", 5) == 0)
|
|
{
|
|
if (strlen(&msg[6]) < 15)
|
|
strcpy(RIG->ModeString, &msg[6]);
|
|
}
|
|
|
|
else if (memcmp(msg, "Passband:", 9) == 0)
|
|
{
|
|
RIG->Passband = atoi(&msg[10]);
|
|
sprintf(RIG->WEB_MODE, "%s/%d", RIG->ModeString, RIG->Passband);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
}
|
|
|
|
msg = rest;
|
|
}
|
|
}
|
|
|
|
|
|
void ProcessFLRIGFrame(struct RIGPORTINFO * PORT)
|
|
{
|
|
char * msg;
|
|
int Length;
|
|
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one
|
|
char * ptr1, * ptr2, * val;
|
|
int Len, TotalLen;
|
|
char cmd[80];
|
|
char ReqBuf[256];
|
|
char SendBuff[256];
|
|
|
|
while (PORT->RXLen > 0)
|
|
{
|
|
int b1 = 0, b2 = 0;
|
|
|
|
msg = PORT->RXBuffer;
|
|
Length = PORT->RXLen;
|
|
|
|
msg[Length] = 0;
|
|
|
|
ptr1 = strstr(msg, "Content-length:");
|
|
|
|
if (ptr1 == NULL)
|
|
return;
|
|
|
|
ptr2 = strstr(ptr1, "\r\n\r\n");
|
|
|
|
if (ptr2 == NULL)
|
|
return;
|
|
|
|
Len = atoi(&ptr1[15]);
|
|
|
|
TotalLen = ptr2 + 4 + Len - msg;
|
|
|
|
if (TotalLen > Length) // Don't have it all
|
|
return;
|
|
|
|
val = strstr(ptr2, "<value>");
|
|
|
|
if (val)
|
|
{
|
|
val += 7;
|
|
|
|
RIG->RIGOK = 1;
|
|
PORT->RXLen -= TotalLen;
|
|
|
|
// It is quite difficult to corrolate responses with commands, but we only poll for freq, mode and bandwidth
|
|
// and the responses can be easily identified
|
|
|
|
if (strstr(val, "<i4>") || memcmp(val, "</value>", 8) == 0)
|
|
{
|
|
// Reply to set command - may need to send next in set or use to send OK if interactive
|
|
|
|
if (PORT->ScanEntry.Cmd2Msg[0])
|
|
{
|
|
sprintf(cmd, "<string>%s</string>", PORT->ScanEntry.Cmd2Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_mode", cmd);
|
|
PORT->ScanEntry.Cmd2Msg[0] = 0;
|
|
}
|
|
|
|
else if (PORT->ScanEntry.Cmd3Msg[0] && strcmp(PORT->ScanEntry.Cmd3Msg, "0") != 0)
|
|
{
|
|
sprintf(cmd, "<i4>%s</i4>", PORT->ScanEntry.Cmd3Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_bandwidth", cmd);
|
|
PORT->ScanEntry.Cmd3Msg[0] = 0;
|
|
}
|
|
|
|
else if (!PORT->AutoPoll)
|
|
{
|
|
GetSemaphore(&Semaphore, 61);
|
|
SendResponse(RIG->Session, "Set OK");
|
|
FreeSemaphore(&Semaphore);
|
|
PORT->AutoPoll = 1; // So we dond send another
|
|
}
|
|
}
|
|
else if(strstr(val, "<array>"))
|
|
{
|
|
// Reply to get BW
|
|
|
|
char * p1, * p2;
|
|
|
|
p1 = strstr(val, "<value>");
|
|
|
|
if (p1)
|
|
{
|
|
p1 += 7;
|
|
b1 = atoi(p1);
|
|
|
|
p2 = strstr(p1, "<value>");
|
|
|
|
if (p2)
|
|
{
|
|
p2 +=7;
|
|
b2 = atoi(p2);
|
|
}
|
|
}
|
|
|
|
if (b1)
|
|
{
|
|
if (b2)
|
|
sprintf(RIG->WEB_MODE, "%s/%d:%d", RIG->ModeString, b1, b2);
|
|
else
|
|
sprintf(RIG->WEB_MODE, "%s/%d", RIG->ModeString, b1);
|
|
|
|
MySetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Either freq or mode. See if numeric
|
|
|
|
double freq;
|
|
|
|
strlop(val, '<');
|
|
|
|
freq = atof(val) / 1000000.0;
|
|
|
|
if (freq > 0.0)
|
|
{
|
|
RIG->RigFreq = freq;
|
|
_gcvt(RIG->RigFreq, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
MySetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
|
|
// Read Mode
|
|
|
|
Len = sprintf(ReqBuf, Req, "rig.get_mode", "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
send(PORT->remoteSock, SendBuff, Len, 0);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (strlen(val)> 1)
|
|
{
|
|
strcpy(RIG->ModeString, val);
|
|
|
|
if (b1)
|
|
{
|
|
if (b2)
|
|
sprintf(RIG->WEB_MODE, "%s/%d:%d", RIG->ModeString, b1, b2);
|
|
else
|
|
sprintf(RIG->WEB_MODE, "%s/%d", RIG->ModeString, b1);
|
|
}
|
|
else
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
MySetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
Len = sprintf(ReqBuf, Req, "rig.get_bw", "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
|
|
send(PORT->remoteSock, SendBuff, Len, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// We now send all setting commands at once
|
|
|
|
/*
|
|
|
|
|
|
if (memcmp(PORT->TXBuffer, "rig.set_vfo", 11) == 0)
|
|
{
|
|
// Set Freq - Send Set Mode if needed
|
|
|
|
if (PORT->ScanEntry.Cmd2Msg[0])
|
|
{
|
|
sprintf(cmd, "<string>%s</string>", PORT->ScanEntry.Cmd2Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_mode", cmd);
|
|
if (strcmp(PORT->ScanEntry.Cmd3Msg, "0") != 0)
|
|
{
|
|
sprintf(cmd, "<i4>%s</i4>", PORT->ScanEntry.Cmd3Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_bandwidth", cmd);
|
|
}
|
|
strcpy(RIG->ModeString, PORT->ScanEntry.Cmd2Msg);
|
|
}
|
|
else
|
|
{
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Set Freq OK");
|
|
|
|
strcpy(PORT->TXBuffer, "rig.get_vfo");
|
|
Len = sprintf(ReqBuf, Req, "rig.get_vfo", "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
strcpy(PORT->TXBuffer, "rig.get_bw");
|
|
Len = sprintf(ReqBuf, Req, "rig.get_bw", "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
|
|
send(PORT->remoteSock, SendBuff, Len, 0);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (memcmp(PORT->TXBuffer, "rig.set_mode", 11) == 0)
|
|
{
|
|
strcpy(PORT->TXBuffer, "rig.get_vfo");
|
|
Len = sprintf(ReqBuf, Req, "rig.get_vfo", "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
|
|
send(PORT->remoteSock, SendBuff, Len, 0);
|
|
|
|
if (!PORT->AutoPoll)
|
|
SendResponse(RIG->Session, "Set Freq and Mode OK");
|
|
|
|
continue;
|
|
}
|
|
|
|
if (memcmp(PORT->TXBuffer, "rig.get_vfo", 11) == 0)
|
|
{
|
|
RIG->RigFreq = atof(val) / 1000000.0;
|
|
|
|
_gcvt(RIG->RigFreq, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
MySetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
|
|
strcpy(PORT->TXBuffer, "rig.get_mode");
|
|
Len = sprintf(ReqBuf, Req, "rig.get_mode", "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
send(PORT->remoteSock, SendBuff, Len, 0);
|
|
|
|
Len = sprintf(ReqBuf, Req, "rig.get_bw", "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
send(PORT->remoteSock, SendBuff, Len, 0);
|
|
continue;
|
|
}
|
|
|
|
if (memcmp(PORT->TXBuffer, "rig.get_mode", 11) == 0)
|
|
{
|
|
strlop(val, '<');
|
|
sprintf(RIG->WEB_MODE, "%s", val);
|
|
MySetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
}
|
|
}
|
|
|
|
*/
|
|
}
|
|
|
|
if (PORT->RXLen > 0)
|
|
memmove(PORT->RXBuffer, &PORT->RXBuffer[TotalLen], PORT->RXLen);
|
|
else
|
|
PORT->RXLen = 0;
|
|
|
|
PORT->Timeout = 0;
|
|
}
|
|
|
|
/*
|
|
POST /RPC2 HTTP/1.1
|
|
User-Agent: XMLRPC++ 0.8
|
|
Host: 127.0.0.1:12345
|
|
Content-type: text/xml
|
|
Content-length: 89
|
|
|
|
<?xml version="1.0"?>
|
|
<methodCall><methodName>rig.get_vfoA</methodName>
|
|
</methodCall>
|
|
HTTP/1.1 200 OK
|
|
Server: XMLRPC++ 0.8
|
|
Content-Type: text/xml
|
|
Content-length: 118
|
|
|
|
<?xml version="1.0"?>
|
|
<methodResponse><params><param>
|
|
<value>14070000</value>
|
|
</param></params></methodResponse>
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void HLSetMode(SOCKET Sock, struct RIGINFO * RIG, unsigned char * Msg, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
char mode[80] = "";
|
|
int filter = 0;
|
|
int n = sscanf(&Msg[1], "%s %d", mode, &filter);
|
|
|
|
// Send to RIGCommand. Can't set Mode without Freq so need to use current
|
|
|
|
// ?? Should be try to convert bandwidth to filter ??
|
|
|
|
RIG->Passband = filter;
|
|
|
|
if (RIG->PORT->PortType == ICOM) // Needs a Filter
|
|
sprintf(Resp, "%d %s %s 1\n", 0, RIG->Valchar, mode);
|
|
else
|
|
sprintf(Resp, "%d %s %s\n", 0, RIG->Valchar, mode);
|
|
|
|
GetSemaphore(&Semaphore, 60);
|
|
Rig_CommandEx(RIG->PORT, RIG, (TRANSPORTENTRY *) -1, Resp);
|
|
FreeSemaphore(&Semaphore);
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "set_mode: %s %d%cRPRT 0\n", mode, filter, sep);
|
|
else
|
|
Len = sprintf(Resp, "RPRT 0\n");
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
}
|
|
|
|
|
|
void HLSetFreq(SOCKET Sock, struct RIGINFO * RIG, unsigned char * Msg, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
int freq = atoi(&Msg[1]);
|
|
|
|
// Send to RIGCommand
|
|
|
|
sprintf(Resp, "%d %f\n", 0, freq/1000000.0);
|
|
GetSemaphore(&Semaphore, 60);
|
|
Rig_CommandEx(RIG->PORT, RIG, (TRANSPORTENTRY *) -1, Resp);
|
|
FreeSemaphore(&Semaphore);
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "set_freq: %d%cRPRT 0\n", freq, sep);
|
|
else
|
|
Len = sprintf(Resp, "RPRT 0\n");
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
}
|
|
|
|
|
|
void HLGetPTT(SOCKET Sock, struct RIGINFO * RIG, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
int ptt = 0;
|
|
|
|
if (RIG->PTTTimer)
|
|
ptt = 1;
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "get_ptt:%cPTT: %d%cRPRT 0\n", sep, ptt, sep);
|
|
else
|
|
Len = sprintf(Resp, "%d\n", ptt);
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
}
|
|
|
|
void HLSetPTT(SOCKET Sock, struct RIGINFO * RIG, unsigned char * Msg, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
int ptt = atoi(&Msg[1]);
|
|
|
|
if (ptt)
|
|
Rig_PTTEx(RIG, 1, NULL);
|
|
else
|
|
Rig_PTTEx(RIG, 0, NULL);
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "set_ptt: %d%cRPRT 0\n", ptt, sep);
|
|
else
|
|
Len = sprintf(Resp, "RPRT 0\n");
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
}
|
|
|
|
void HLGetMode(SOCKET Sock, struct RIGINFO * RIG, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "get_mode:%cMode: %s%cPassband: %d%cRPRT 0\n", sep, RIG->ModeString, sep, RIG->Passband, sep);
|
|
else
|
|
Len = sprintf(Resp, "%s\n%d\n", RIG->ModeString, RIG->Passband);
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
|
|
}
|
|
|
|
void HLGetFreq(SOCKET Sock, struct RIGINFO * RIG, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
char freqval[64];
|
|
double freq = atof(RIG->Valchar) * 1000000.0;
|
|
|
|
sprintf(freqval, "%f", freq);
|
|
strlop(freqval, '.');
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "get_freq:%cFrequency: %s%cRPRT 0\n", sep, freqval, sep);
|
|
else
|
|
Len = sprintf(Resp, "%s\n", freqval);
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
}
|
|
|
|
void HLGetVFO(SOCKET Sock, struct RIGINFO * RIG, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "get_vfo:%s%cRPRT 0\n", "VFOA", sep);
|
|
else
|
|
Len = sprintf(Resp, "%s\n", "VFOA");
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
}
|
|
|
|
void HLGetSplit(SOCKET Sock, struct RIGINFO * RIG, char sep)
|
|
{
|
|
char Resp[80];
|
|
int Len;
|
|
|
|
if (sep)
|
|
Len = sprintf(Resp, "get_vfo:%s%cRPRT 0\n", "VFOA", sep);
|
|
else
|
|
Len = sprintf(Resp, "0\n%s\n", "VFOA");
|
|
|
|
send(Sock, Resp, Len, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ProcessHAMLIBSlaveMessage(SOCKET Sock, struct RIGINFO * RIG, unsigned char * Msg, int MsgLen)
|
|
{
|
|
// We only process a pretty small subset of rigctl messages
|
|
|
|
// commands are generally a single character, upper case for set
|
|
// and lower case for get. If preceeded by + ; | or , response will
|
|
// be in extended form. + adds an LF between field, other values the
|
|
// supplied char is used as seperator.
|
|
|
|
// At the moments we support freq (F) mode (m) and PTT (T)
|
|
|
|
char sep = 0;
|
|
|
|
if (Msg[0] == '#')
|
|
return 0; // Comment
|
|
|
|
strlop(Msg, 13);
|
|
strlop(Msg, 10);
|
|
|
|
// \ on front is used for long mode. Hopefully not used much
|
|
|
|
// WSJT seems ro need \chk_vfo and \dump_state
|
|
|
|
if (Msg[0] == '\\')
|
|
{
|
|
if (strcmp(&Msg[1], "chk_vfo") == 0)
|
|
{
|
|
char Reply[80];
|
|
int Len = sprintf(Reply, "CHKVFO 0\n");
|
|
send(Sock, Reply, Len, 0);
|
|
return 0;
|
|
}
|
|
|
|
if (strcmp(&Msg[1], "dump_state") == 0)
|
|
{
|
|
char Reply[4096];
|
|
int Len = sprintf(Reply,
|
|
"0\n"
|
|
"1\n"
|
|
"2\n"
|
|
"150000.000000 1500000000.000000 0x1ff -1 -1 0x10000003 0x3\n"
|
|
"0 0 0 0 0 0 0\n"
|
|
"0 0 0 0 0 0 0\n"
|
|
"0x1ff 1\n"
|
|
"0x1ff 0\n"
|
|
"0 0\n"
|
|
"0x1e 2400\n"
|
|
"0x2 500\n"
|
|
"0x1 8000\n"
|
|
"0x1 2400\n"
|
|
"0x20 15000\n"
|
|
"0x20 8000\n"
|
|
"0x40 230000\n"
|
|
"0 0\n"
|
|
"9990\n"
|
|
"9990\n"
|
|
"10000\n"
|
|
"0\n"
|
|
"10 \n"
|
|
"10 20 30 \n"
|
|
"0xffffffff\n"
|
|
"0xffffffff\n"
|
|
"0xf7ffffff\n"
|
|
"0x83ffffff\n"
|
|
"0xffffffff\n"
|
|
"0xffffffbf\n");
|
|
|
|
send(Sock, Reply, Len, 0);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (Msg[0] == 'q' || Msg[0] == 'Q')
|
|
{
|
|
// close connection
|
|
|
|
return 1;
|
|
}
|
|
|
|
if (Msg[0] == '+')
|
|
{
|
|
sep = 10;
|
|
Msg++;
|
|
MsgLen --;
|
|
}
|
|
else if (Msg[0] == '_' || Msg[0] == '?')
|
|
{
|
|
}
|
|
else if (ispunct(Msg[0]))
|
|
{
|
|
sep = Msg[0];
|
|
Msg++;
|
|
MsgLen --;
|
|
}
|
|
|
|
switch (Msg[0])
|
|
{
|
|
case 'f': // Get Frequency
|
|
|
|
HLGetFreq(Sock, RIG, sep);
|
|
return 0;
|
|
|
|
case 'm': // Get Mode
|
|
|
|
HLGetMode(Sock, RIG, sep);
|
|
return 0;
|
|
|
|
case 't': // Get PTT
|
|
|
|
HLGetPTT(Sock, RIG, sep);
|
|
return 0;
|
|
|
|
case 'v': // Get VFO
|
|
|
|
HLGetVFO(Sock, RIG, sep);
|
|
return 0;
|
|
|
|
case 's': // Get Split
|
|
|
|
HLGetSplit(Sock, RIG, sep);
|
|
return 0;
|
|
|
|
case 'F':
|
|
|
|
HLSetFreq(Sock, RIG, Msg, sep);
|
|
return 0;
|
|
|
|
case 'M':
|
|
|
|
HLSetMode(Sock, RIG, Msg, sep);
|
|
return 0;
|
|
|
|
case 'T':
|
|
|
|
HLSetPTT(Sock, RIG, Msg, sep);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int DecodeHAMLIBAddr(struct RIGPORTINFO * PORT, char * ptr)
|
|
{
|
|
// Param is IPADDR:PORT. Only Allow numeric addresses
|
|
|
|
struct sockaddr_in * destaddr = (SOCKADDR_IN *)&PORT->remoteDest;
|
|
|
|
char * port = strlop(ptr, ':');
|
|
|
|
if (port == NULL)
|
|
return 0;
|
|
|
|
destaddr->sin_family = AF_INET;
|
|
destaddr->sin_addr.s_addr = inet_addr(ptr);
|
|
destaddr->sin_port = htons(atoi(port));
|
|
|
|
return 1;
|
|
}
|
|
|
|
VOID HAMLIBThread(struct RIGPORTINFO * PORT);
|
|
|
|
VOID ConnecttoHAMLIB(struct RIGPORTINFO * PORT)
|
|
{
|
|
if (HAMLIBMasterRunning)
|
|
_beginthread(HAMLIBThread, 0, (void *)PORT);
|
|
|
|
return ;
|
|
}
|
|
|
|
VOID HAMLIBThread(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Opens sockets and looks for data
|
|
|
|
char Msg[255];
|
|
int err, i, ret;
|
|
u_long param=1;
|
|
BOOL bcopt=TRUE;
|
|
fd_set readfs;
|
|
fd_set errorfs;
|
|
struct timeval timeout;
|
|
|
|
if (PORT->remoteSock)
|
|
{
|
|
closesocket(PORT->remoteSock);
|
|
}
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->remoteSock = socket(AF_INET,SOCK_STREAM,0);
|
|
|
|
if (PORT->remoteSock == INVALID_SOCKET)
|
|
{
|
|
i=sprintf(Msg, "Socket Failed for HAMLIB socket - error code = %d\r\n", WSAGetLastError());
|
|
WritetoConsole(Msg);
|
|
|
|
PORT->CONNECTING = FALSE;
|
|
return;
|
|
}
|
|
|
|
setsockopt(PORT->remoteSock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
|
|
setsockopt(PORT->remoteSock, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&bcopt, 4);
|
|
|
|
if (connect(PORT->remoteSock,(LPSOCKADDR) &PORT->remoteDest,sizeof(PORT->remoteDest)) == 0)
|
|
{
|
|
//
|
|
// Connected successful
|
|
//
|
|
|
|
ioctl(PORT->remoteSock, FIONBIO, ¶m);
|
|
}
|
|
else
|
|
{
|
|
if (PORT->Alerted == FALSE)
|
|
{
|
|
struct sockaddr_in * destaddr = (SOCKADDR_IN * )&PORT->remoteDest;
|
|
|
|
err = WSAGetLastError();
|
|
|
|
sprintf(Msg, "Connect Failed for HAMLIB socket - error code = %d Addr %s\r\n", err, PORT->IOBASE);
|
|
|
|
WritetoConsole(Msg);
|
|
PORT->Alerted = TRUE;
|
|
}
|
|
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTING = FALSE;
|
|
return;
|
|
}
|
|
|
|
PORT->CONNECTED = TRUE;
|
|
PORT->hDevice = (HANDLE)1; // simplifies check code
|
|
|
|
PORT->Alerted = TRUE;
|
|
|
|
while (PORT->CONNECTED)
|
|
{
|
|
FD_ZERO(&readfs);
|
|
FD_ZERO(&errorfs);
|
|
|
|
FD_SET(PORT->remoteSock,&readfs);
|
|
FD_SET(PORT->remoteSock,&errorfs);
|
|
|
|
timeout.tv_sec = 5;
|
|
timeout.tv_usec = 0;
|
|
|
|
ret = select((int)PORT->remoteSock + 1, &readfs, NULL, &errorfs, &timeout);
|
|
|
|
if (HAMLIBMasterRunning == 0)
|
|
return;
|
|
|
|
if (ret == SOCKET_ERROR)
|
|
{
|
|
Debugprintf("HAMLIB Select failed %d ", WSAGetLastError());
|
|
goto Lost;
|
|
}
|
|
|
|
if (ret > 0)
|
|
{
|
|
// See what happened
|
|
|
|
if (FD_ISSET(PORT->remoteSock, &readfs))
|
|
{
|
|
HAMLIBProcessMessage(PORT);
|
|
}
|
|
|
|
if (FD_ISSET(PORT->remoteSock, &errorfs))
|
|
{
|
|
Lost:
|
|
sprintf(Msg, "HAMLIB Connection lost for Addr %s\r\n", PORT->IOBASE);
|
|
WritetoConsole(Msg);
|
|
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->Alerted = FALSE;
|
|
PORT->hDevice = 0; // simplifies check code
|
|
|
|
closesocket(PORT->remoteSock);
|
|
PORT->remoteSock = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
sprintf(Msg, "HAMLIB Thread Terminated Addr %s\r\n", PORT->IOBASE);
|
|
WritetoConsole(Msg);
|
|
}
|
|
|
|
|
|
|
|
void HAMLIBSlaveThread(struct RIGINFO * RIG)
|
|
{
|
|
// Wait for connections and messages from HAMLIB Clients
|
|
|
|
fd_set readfs;
|
|
fd_set errorfs;
|
|
struct timeval timeout;
|
|
int ret;
|
|
unsigned int maxsock;
|
|
|
|
HAMLIBSlaveRunning = 1;
|
|
|
|
Consoleprintf("HAMLIB Slave Thread %d Running", RIG->HAMLIBPORT);
|
|
|
|
while (HAMLIBSlaveRunning)
|
|
{
|
|
struct HAMLIBSOCK * Entry = RIG->Sockets;
|
|
struct HAMLIBSOCK * Prev;
|
|
|
|
FD_ZERO(&readfs);
|
|
FD_ZERO(&errorfs);
|
|
|
|
FD_SET(RIG->ListenSocket, &readfs);
|
|
FD_SET(RIG->ListenSocket, &errorfs);
|
|
|
|
maxsock = RIG->ListenSocket;
|
|
|
|
while (Entry && HAMLIBSlaveRunning)
|
|
{
|
|
FD_SET(Entry->Sock, &readfs);
|
|
FD_SET(Entry->Sock, &errorfs);
|
|
|
|
if (Entry->Sock > maxsock)
|
|
maxsock = Entry->Sock;
|
|
|
|
Entry = Entry->Next;
|
|
}
|
|
|
|
timeout.tv_sec = 5;
|
|
timeout.tv_usec = 0;
|
|
|
|
ret = select(maxsock + 1, &readfs, NULL, &errorfs, &timeout);
|
|
|
|
if (HAMLIBSlaveRunning == 0)
|
|
return;
|
|
|
|
if (ret == -1)
|
|
{
|
|
perror("listen select");
|
|
continue;
|
|
}
|
|
|
|
if (ret)
|
|
{
|
|
if (FD_ISSET(RIG->ListenSocket, &readfs))
|
|
{
|
|
// Connection. Accept it and create a socket enty
|
|
|
|
int addrlen = sizeof(struct sockaddr_in6);
|
|
struct sockaddr_in6 sin6;
|
|
struct HAMLIBSOCK * Entry = zalloc(sizeof(struct HAMLIBSOCK));
|
|
|
|
Entry->Sock = accept(RIG->ListenSocket, (struct sockaddr *)&sin6, &addrlen);
|
|
|
|
if (RIG->Sockets)
|
|
Entry->Next = RIG->Sockets;
|
|
|
|
RIG->Sockets = Entry;
|
|
}
|
|
|
|
// See if any Data Sockets
|
|
|
|
Entry = RIG->Sockets;
|
|
Prev = 0;
|
|
|
|
while (Entry)
|
|
{
|
|
unsigned char MsgBuf[256];
|
|
unsigned char * Msg = MsgBuf;
|
|
int MsgLen;
|
|
|
|
if (FD_ISSET(Entry->Sock, &readfs))
|
|
{
|
|
MsgLen = recv(Entry->Sock, Msg, 256, 0);
|
|
|
|
if (MsgLen <= 0)
|
|
{
|
|
// Closed - close socket and remove from chain
|
|
|
|
closesocket(Entry->Sock);
|
|
|
|
if (Prev == 0)
|
|
RIG->Sockets = Entry->Next;
|
|
else
|
|
Prev->Next = Entry->Next;
|
|
|
|
free (Entry);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Could have multiple messages in packet
|
|
// Terminator can be CR LF or CRLF
|
|
|
|
char * ptr;
|
|
int Len;
|
|
|
|
Msg[MsgLen] = 0;
|
|
Loop:
|
|
ptr = strlop(Msg, 10);
|
|
if (ptr == NULL)
|
|
strlop(Msg, 13);
|
|
|
|
Len = strlen(Msg);
|
|
|
|
if (ProcessHAMLIBSlaveMessage(Entry->Sock, RIG, Msg, Len) == 1)
|
|
{
|
|
// close request
|
|
|
|
closesocket(Entry->Sock);
|
|
|
|
if (Prev == 0)
|
|
RIG->Sockets = Entry->Next;
|
|
else
|
|
Prev->Next = Entry->Next;
|
|
|
|
free (Entry);
|
|
break;
|
|
}
|
|
Msg = ptr;
|
|
|
|
if (Msg)
|
|
{
|
|
while (Msg[0] == 10 || Msg[0] == 13)
|
|
Msg++;
|
|
|
|
if (Msg[0])
|
|
goto Loop;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FD_ISSET(Entry->Sock, &errorfs))
|
|
{
|
|
// Closed - close socket and remove from chai
|
|
|
|
closesocket(Entry->Sock);
|
|
|
|
if (Prev == 0)
|
|
RIG->Sockets = Entry->Next;
|
|
else
|
|
Prev->Next = Entry->Next;
|
|
|
|
free (Entry);
|
|
break;
|
|
}
|
|
|
|
// Check Next Client
|
|
|
|
Prev = Entry;
|
|
Entry = Entry->Next;
|
|
}
|
|
}
|
|
}
|
|
Consoleprintf("HAMLIB Slave Thread %d Exited", RIG->HAMLIBPORT);
|
|
}
|
|
|
|
|
|
VOID FLRIGPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0];
|
|
int Len;
|
|
char ReqBuf[256];
|
|
char SendBuff[256];
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
SetWindowText(RIG->hFREQ, "------------------");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
RIG->RIGOK = FALSE;
|
|
return;
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
char cmd[80];
|
|
double freq;
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
// Send the Set Freq here, send set mode when we get a response
|
|
|
|
memcpy(&PORT->ScanEntry, PORT->FreqPtr, sizeof(struct ScanEntry));
|
|
|
|
sprintf(cmd, "<double>%s</double>", PORT->FreqPtr->Cmd1Msg);
|
|
FLRIGSendCommand(PORT, "rig.set_vfo", cmd);
|
|
|
|
// Update display as we don't get a response
|
|
|
|
freq = atof(PORT->FreqPtr->Cmd1Msg) / 1000000.0;
|
|
|
|
if (freq > 0.0)
|
|
{
|
|
RIG->RigFreq = freq;
|
|
_gcvt(RIG->RigFreq, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
MySetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
}
|
|
|
|
|
|
PORT->CmdSent = 1;
|
|
PORT->Retries = 0;
|
|
PORT->Timeout = 10;
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
// There isn't a response to a set command, so clear Scan Lock here
|
|
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter > 1)
|
|
return;
|
|
}
|
|
|
|
if (RIG->RIGOK && (RIG->ScanStopped == 0) && RIG->NumberofBands)
|
|
return; // no point in reading freq if we are about to change it
|
|
|
|
RIG->PollCounter = 10; // Once Per Sec
|
|
|
|
// Read Frequency
|
|
|
|
strcpy(Poll, "rig.get_vfo");
|
|
|
|
Len = sprintf(ReqBuf, Req, Poll, "");
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
|
|
if (PORT->CONNECTED)
|
|
{
|
|
if (send(PORT->remoteSock, SendBuff, Len, 0) != Len)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
PORT->Timeout = 10;
|
|
PORT->CmdSent = 0;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
VOID FLRIGSendCommand(struct RIGPORTINFO * PORT, char * Command, char * Value)
|
|
{
|
|
int Len;
|
|
char ReqBuf[512];
|
|
char SendBuff[512];
|
|
char ValueString[256] ="";
|
|
|
|
if (!PORT->CONNECTED)
|
|
return;
|
|
|
|
sprintf(ValueString, "<params><param><value>%s</value></param></params\r\n>", Value);
|
|
|
|
strcpy(PORT->TXBuffer, Command);
|
|
Len = sprintf(ReqBuf, Req, PORT->TXBuffer, ValueString);
|
|
Len = sprintf(SendBuff, MsgHddr, Len, ReqBuf);
|
|
if (send(PORT->remoteSock, SendBuff, Len, 0) != Len)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
VOID FLRIGThread(struct RIGPORTINFO * PORT);
|
|
|
|
VOID ConnecttoFLRIG(struct RIGPORTINFO * PORT)
|
|
{
|
|
if (FLRIGRunning)
|
|
_beginthread(FLRIGThread, 0, (void *)PORT);
|
|
return ;
|
|
}
|
|
|
|
VOID FLRIGThread(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Opens sockets and looks for data
|
|
|
|
char Msg[255];
|
|
int err, i, ret;
|
|
u_long param=1;
|
|
BOOL bcopt=TRUE;
|
|
fd_set readfs;
|
|
fd_set errorfs;
|
|
struct timeval timeout;
|
|
|
|
if (PORT->remoteSock)
|
|
{
|
|
closesocket(PORT->remoteSock);
|
|
}
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->remoteSock = socket(AF_INET,SOCK_STREAM,0);
|
|
|
|
if (PORT->remoteSock == INVALID_SOCKET)
|
|
{
|
|
i=sprintf(Msg, "Socket Failed for FLRIG socket - error code = %d\r\n", WSAGetLastError());
|
|
WritetoConsole(Msg);
|
|
|
|
PORT->CONNECTING = FALSE;
|
|
return;
|
|
}
|
|
|
|
setsockopt(PORT->remoteSock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
|
|
setsockopt(PORT->remoteSock, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&bcopt, 4);
|
|
|
|
if (connect(PORT->remoteSock,(LPSOCKADDR) &PORT->remoteDest, sizeof(PORT->remoteDest)) == 0)
|
|
{
|
|
//
|
|
// Connected successful
|
|
//
|
|
|
|
ioctl(PORT->remoteSock, FIONBIO, ¶m);
|
|
}
|
|
else
|
|
{
|
|
if (PORT->Alerted == FALSE)
|
|
{
|
|
struct sockaddr_in * destaddr = (SOCKADDR_IN * )&PORT->remoteDest;
|
|
|
|
err = WSAGetLastError();
|
|
|
|
sprintf(Msg, "Connect Failed for FLRIG socket - error code = %d Port %d\r\n",
|
|
err, htons(destaddr->sin_port));
|
|
|
|
WritetoConsole(Msg);
|
|
PORT->Alerted = TRUE;
|
|
}
|
|
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTING = FALSE;
|
|
return;
|
|
}
|
|
|
|
PORT->CONNECTED = TRUE;
|
|
PORT->hDevice = (HANDLE)1; // simplifies check code
|
|
|
|
PORT->Alerted = TRUE;
|
|
|
|
while (PORT->CONNECTED && FLRIGRunning)
|
|
{
|
|
FD_ZERO(&readfs);
|
|
FD_ZERO(&errorfs);
|
|
|
|
FD_SET(PORT->remoteSock,&readfs);
|
|
FD_SET(PORT->remoteSock,&errorfs);
|
|
|
|
timeout.tv_sec = 5;
|
|
timeout.tv_usec = 0;
|
|
|
|
ret = select((int)PORT->remoteSock + 1, &readfs, NULL, &errorfs, &timeout);
|
|
|
|
if (FLRIGRunning == 0)
|
|
return;
|
|
|
|
if (ret == SOCKET_ERROR)
|
|
{
|
|
Debugprintf("FLRIG Select failed %d ", WSAGetLastError());
|
|
goto Lost;
|
|
}
|
|
|
|
if (ret > 0)
|
|
{
|
|
// See what happened
|
|
|
|
if (FD_ISSET(PORT->remoteSock, &readfs))
|
|
{
|
|
FLRIGProcessMessage(PORT);
|
|
}
|
|
|
|
if (FD_ISSET(PORT->remoteSock, &errorfs))
|
|
{
|
|
Lost:
|
|
sprintf(Msg, "FLRIG Connection lost for Port %s\r\n", PORT->IOBASE);
|
|
WritetoConsole(Msg);
|
|
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->Alerted = FALSE;
|
|
PORT->hDevice = 0; // simplifies check code
|
|
|
|
closesocket(PORT->remoteSock);
|
|
PORT->remoteSock = 0;
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
sprintf(Msg, "FLRIG Thread Terminated Port %s\r\n", PORT->IOBASE);
|
|
WritetoConsole(Msg);
|
|
}
|
|
|
|
|
|
|
|
|
|
// HID Support Code
|
|
|
|
int HID_Read_Block(struct RIGPORTINFO * PORT)
|
|
{
|
|
int Len;
|
|
unsigned char Msg[65] = "";
|
|
|
|
if (PORT->RXLen > 400)
|
|
PORT->RXLen = 0;
|
|
|
|
// Don't try to read more than 64
|
|
|
|
#ifdef WIN32
|
|
Len = rawhid_recv(0, Msg, 64, 100);
|
|
#else
|
|
Len = read(PORT->hDevice, Msg, 64);
|
|
#endif
|
|
|
|
if (Len <= 0)
|
|
return 0;
|
|
|
|
// First byte is actual length
|
|
|
|
Len = Msg[0];
|
|
|
|
if (Len > 0)
|
|
{
|
|
if (Len < 64) // Max in HID Packet
|
|
{
|
|
memcpy(&PORT->RXBuffer[PORT->RXLen], Msg + 1, Len);
|
|
return Len;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void rawhid_close(int num);
|
|
|
|
BOOL HID_Write_Block(struct RIGPORTINFO * PORT)
|
|
{
|
|
int n = PORT->TXLen;
|
|
UCHAR * ptr = PORT->TXBuffer;
|
|
UCHAR Msg[64] = "";
|
|
int ret, i;
|
|
|
|
while (n)
|
|
{
|
|
i = n;
|
|
if (i > 63)
|
|
i = 63;
|
|
|
|
Msg[0] = i; // Length on front
|
|
memcpy(&Msg[1], ptr, i);
|
|
ptr += i;
|
|
n -= i;
|
|
// n = hid_write(PORT->hDevice, PORT->TXBuffer, PORT->TXLen);
|
|
#ifdef WIN32
|
|
ret = rawhid_send(0, Msg, 64, 100); // Always send 64
|
|
|
|
if (ret < 0)
|
|
{
|
|
Debugprintf("Rigcontrol HID Write Failed %d", errno);
|
|
rawhid_close(0);
|
|
PORT->hDevice = NULL;
|
|
return FALSE;
|
|
}
|
|
#else
|
|
ret = write(PORT->hDevice, Msg, 64);
|
|
|
|
if (ret != 64)
|
|
{
|
|
printf ("Write to %s failed, n=%d, errno=%d\n", PORT->HIDDevice, ret, errno);
|
|
close (PORT->hDevice);
|
|
PORT->hDevice = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
// printf("HID Write %d\n", i);
|
|
#endif
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL OpenHIDPort(struct RIGPORTINFO * PORT, VOID * Port, int Speed)
|
|
{
|
|
#ifdef WIN32
|
|
|
|
if (PORT->HIDDevice== NULL)
|
|
return FALSE;
|
|
|
|
PORT->hDevice = rawhid_open(PORT->HIDDevice);
|
|
|
|
if (PORT->hDevice)
|
|
Debugprintf("Rigcontrol HID Device %s opened", PORT->HIDDevice);
|
|
|
|
/*
|
|
handle = hid_open_path(PORT->HIDDevice);
|
|
|
|
if (handle)
|
|
hid_set_nonblocking(handle, 1);
|
|
|
|
PORT->hDevice = handle;
|
|
*/
|
|
#else
|
|
int fd;
|
|
unsigned int param = 1;
|
|
|
|
if (PORT->HIDDevice== NULL)
|
|
return FALSE;
|
|
|
|
fd = open (PORT->HIDDevice, O_RDWR);
|
|
|
|
if (fd == -1)
|
|
{
|
|
printf ("Could not open %s, errno=%d\n", PORT->HIDDevice, errno);
|
|
return FALSE;
|
|
}
|
|
|
|
ioctl(fd, FIONBIO, ¶m);
|
|
printf("Rigcontrol HID Device %s opened", PORT->HIDDevice);
|
|
|
|
PORT->hDevice = fd;
|
|
#endif
|
|
if (PORT->hDevice == 0)
|
|
return (FALSE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void CM108_set_ptt(struct RIGINFO *RIG, int PTTState)
|
|
{
|
|
char io[5];
|
|
hid_device *handle;
|
|
int n;
|
|
|
|
io[0] = 0;
|
|
io[1] = 0;
|
|
io[2] = 1 << (3 - 1);
|
|
io[3] = PTTState << (3 - 1);
|
|
io[4] = 0;
|
|
|
|
if (RIG->CM108Device == NULL)
|
|
return;
|
|
|
|
#ifdef WIN32
|
|
handle = hid_open_path(RIG->CM108Device);
|
|
|
|
if (!handle) {
|
|
printf("unable to open device\n");
|
|
return;
|
|
}
|
|
|
|
n = hid_write(handle, io, 5);
|
|
if (n < 0)
|
|
{
|
|
Debugprintf("Unable to write()\n");
|
|
Debugprintf("Error: %ls\n", hid_error(RIG->PORT->hDevice));
|
|
}
|
|
|
|
hid_close(handle);
|
|
|
|
#else
|
|
|
|
int fd;
|
|
|
|
fd = open (RIG->CM108Device, O_WRONLY);
|
|
|
|
if (fd == -1)
|
|
{
|
|
printf ("Could not open %s for write, errno=%d\n", RIG->CM108Device, errno);
|
|
return;
|
|
}
|
|
|
|
io[0] = 0;
|
|
io[1] = 0;
|
|
io[2] = 1 << (3 - 1);
|
|
io[3] = PTTState << (3 - 1);
|
|
io[4] = 0;
|
|
|
|
n = write (fd, io, 5);
|
|
if (n != 5)
|
|
{
|
|
printf ("Write to %s failed, n=%d, errno=%d\n", RIG->CM108Device, n, errno);
|
|
}
|
|
|
|
close (fd);
|
|
#endif
|
|
return;
|
|
|
|
}
|
|
|
|
/*
|
|
int CRow;
|
|
|
|
HANDLE hComPort, hSpeed, hRigType, hButton, hAddr, hLabel, hTimes, hFreqs, hBPQPort;
|
|
|
|
VOID CreateRigConfigLine(HWND hDlg, struct RIGPORTINFO * PORT, struct RIGINFO * RIG)
|
|
{
|
|
char Port[10];
|
|
|
|
hButton = CreateWindow(WC_BUTTON , "", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_TABSTOP,
|
|
10, CRow+5, 10,10, hDlg, NULL, hInstance, NULL);
|
|
|
|
if (PORT->PortType == ICOM)
|
|
{
|
|
char Addr[10];
|
|
|
|
sprintf(Addr, "%X", RIG->RigAddr);
|
|
|
|
hAddr = CreateWindow(WC_EDIT , Addr, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
|
|
305, CRow, 30,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
}
|
|
hLabel = CreateWindow(WC_EDIT , RIG->RigName, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
|
|
340, CRow, 60,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
sprintf(Port, "%d", RIG->PortRecord->PORTCONTROL.PORTNUMBER);
|
|
hBPQPort = CreateWindow(WC_EDIT , Port, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL,
|
|
405, CRow, 20, 20, hDlg, NULL, hInstance, NULL);
|
|
|
|
hTimes = CreateWindow(WC_COMBOBOX , "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN |
|
|
WS_VSCROLL | WS_TABSTOP,
|
|
430, CRow, 100,80, hDlg, NULL, hInstance, NULL);
|
|
|
|
hFreqs = CreateWindow(WC_EDIT , RIG->FreqText, WS_CHILD | WS_VISIBLE| WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL,
|
|
535, CRow, 300, 20, hDlg, NULL, hInstance, NULL);
|
|
|
|
SendMessage(hTimes, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "0000:1159");
|
|
SendMessage(hTimes, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "1200:2359");
|
|
SendMessage(hTimes, CB_SETCURSEL, 0, 0);
|
|
|
|
CRow += 30;
|
|
|
|
}
|
|
|
|
VOID CreatePortConfigLine(HWND hDlg, struct RIGPORTINFO * PORT)
|
|
{
|
|
char Port[20];
|
|
int i;
|
|
|
|
hComPort = CreateWindow(WC_COMBOBOX , "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN |
|
|
WS_VSCROLL | WS_TABSTOP,
|
|
30, CRow, 90, 160, hDlg, NULL, hInstance, NULL);
|
|
|
|
for (i = 1; i < 256; i++)
|
|
{
|
|
sprintf(Port, "COM%d", i);
|
|
SendMessage(hComPort, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) Port);
|
|
}
|
|
|
|
sprintf(Port, "COM%d", PORT->IOBASE);
|
|
|
|
i = SendMessage(hComPort, CB_FINDSTRINGEXACT, 0,(LPARAM) Port);
|
|
|
|
SendMessage(hComPort, CB_SETCURSEL, i, 0);
|
|
|
|
|
|
hSpeed = CreateWindow(WC_COMBOBOX , "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN |
|
|
WS_VSCROLL | WS_TABSTOP,
|
|
120, CRow, 75, 80, hDlg, NULL, hInstance, NULL);
|
|
|
|
SendMessage(hSpeed, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "1200");
|
|
SendMessage(hSpeed, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "2400");
|
|
SendMessage(hSpeed, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "4800");
|
|
SendMessage(hSpeed, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "9600");
|
|
SendMessage(hSpeed, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "19200");
|
|
SendMessage(hSpeed, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "38400");
|
|
|
|
sprintf(Port, "%d", PORT->SPEED);
|
|
|
|
i = SendMessage(hSpeed, CB_FINDSTRINGEXACT, 0, (LPARAM)Port);
|
|
|
|
SendMessage(hSpeed, CB_SETCURSEL, i, 0);
|
|
|
|
hRigType = CreateWindow(WC_COMBOBOX , "", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP,
|
|
200, CRow, 100,80, hDlg, NULL, hInstance, NULL);
|
|
|
|
SendMessage(hRigType, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "ICOM");
|
|
SendMessage(hRigType, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "YAESU");
|
|
SendMessage(hRigType, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR) "KENWOOD");
|
|
|
|
SendMessage(hRigType, CB_SETCURSEL, PORT->PortType -1, 0);
|
|
|
|
}
|
|
|
|
INT_PTR CALLBACK ConfigDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int Cmd = LOWORD(wParam);
|
|
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
struct RIGPORTINFO * PORT;
|
|
struct RIGINFO * RIG;
|
|
int i, p;
|
|
|
|
CRow = 40;
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
{
|
|
PORT = PORTInfo[p];
|
|
|
|
CreatePortConfigLine(hDlg, PORT);
|
|
|
|
for (i=0; i < PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
CreateRigConfigLine(hDlg, PORT, RIG);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
// 90, Row, 40,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
// CreateWindow(WC_STATIC , "", WS_CHILD | WS_VISIBLE,
|
|
// 135, Row, 100,20, hDlg, NULL, hInstance, NULL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_SIZING:
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_ACTIVATE:
|
|
|
|
// SendDlgItemMessage(hDlg, IDC_MESSAGE, EM_SETSEL, -1, 0);
|
|
|
|
break;
|
|
|
|
|
|
case WM_COMMAND:
|
|
|
|
if (Cmd == IDCANCEL)
|
|
{
|
|
EndDialog(hDlg, LOWORD(wParam));
|
|
return (INT_PTR)TRUE;
|
|
}
|
|
|
|
return (INT_PTR)TRUE;
|
|
|
|
break;
|
|
}
|
|
return (INT_PTR)FALSE;
|
|
}
|
|
|
|
*/
|
|
|
|
#ifdef WIN32
|
|
|
|
/* Simple Raw HID functions for Windows - for use with Teensy RawHID example
|
|
* http://www.pjrc.com/teensy/rawhid.html
|
|
* Copyright (c) 2009 PJRC.COM, LLC
|
|
*
|
|
* rawhid_open - open 1 or more devices
|
|
* rawhid_recv - receive a packet
|
|
* rawhid_send - send a packet
|
|
* rawhid_close - close a device
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above description, website URL and copyright notice and this permission
|
|
* notice shall be included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*
|
|
* Version 1.0: Initial Release
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
//
|
|
//#include <windows.h>
|
|
#include <setupapi.h>
|
|
//#include <ddk/hidsdi.h>
|
|
//#include <ddk/hidclass.h>
|
|
|
|
typedef USHORT USAGE;
|
|
|
|
|
|
typedef struct _HIDD_CONFIGURATION {
|
|
PVOID cookie;
|
|
ULONG size;
|
|
ULONG RingBufferSize;
|
|
} HIDD_CONFIGURATION, *PHIDD_CONFIGURATION;
|
|
|
|
typedef struct _HIDD_ATTRIBUTES {
|
|
ULONG Size;
|
|
USHORT VendorID;
|
|
USHORT ProductID;
|
|
USHORT VersionNumber;
|
|
} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
|
|
|
|
|
|
typedef struct _HIDP_CAPS {
|
|
USAGE Usage;
|
|
USAGE UsagePage;
|
|
USHORT InputReportByteLength;
|
|
USHORT OutputReportByteLength;
|
|
USHORT FeatureReportByteLength;
|
|
USHORT Reserved[17];
|
|
USHORT NumberLinkCollectionNodes;
|
|
USHORT NumberInputButtonCaps;
|
|
USHORT NumberInputValueCaps;
|
|
USHORT NumberInputDataIndices;
|
|
USHORT NumberOutputButtonCaps;
|
|
USHORT NumberOutputValueCaps;
|
|
USHORT NumberOutputDataIndices;
|
|
USHORT NumberFeatureButtonCaps;
|
|
USHORT NumberFeatureValueCaps;
|
|
USHORT NumberFeatureDataIndices;
|
|
} HIDP_CAPS, *PHIDP_CAPS;
|
|
|
|
|
|
typedef struct _HIDP_PREPARSED_DATA * PHIDP_PREPARSED_DATA;
|
|
|
|
|
|
|
|
// a list of all opened HID devices, so the caller can
|
|
// simply refer to them by number
|
|
typedef struct hid_struct hid_t;
|
|
static hid_t *first_hid = NULL;
|
|
static hid_t *last_hid = NULL;
|
|
struct hid_struct {
|
|
HANDLE handle;
|
|
int open;
|
|
struct hid_struct *prev;
|
|
struct hid_struct *next;
|
|
};
|
|
static HANDLE rx_event=NULL;
|
|
static HANDLE tx_event=NULL;
|
|
static CRITICAL_SECTION rx_mutex;
|
|
static CRITICAL_SECTION tx_mutex;
|
|
|
|
|
|
// private functions, not intended to be used from outside this file
|
|
static void add_hid(hid_t *h);
|
|
static hid_t * get_hid(int num);
|
|
static void free_all_hid(void);
|
|
void print_win32_err(void);
|
|
|
|
|
|
|
|
|
|
// rawhid_recv - receive a packet
|
|
// Inputs:
|
|
// num = device to receive from (zero based)
|
|
// buf = buffer to receive packet
|
|
// len = buffer's size
|
|
// timeout = time to wait, in milliseconds
|
|
// Output:
|
|
// number of bytes received, or -1 on error
|
|
//
|
|
int rawhid_recv(int num, void *buf, int len, int timeout)
|
|
{
|
|
hid_t *hid;
|
|
unsigned char tmpbuf[516];
|
|
OVERLAPPED ov;
|
|
DWORD r;
|
|
int n;
|
|
|
|
if (sizeof(tmpbuf) < len + 1) return -1;
|
|
hid = get_hid(num);
|
|
if (!hid || !hid->open) return -1;
|
|
EnterCriticalSection(&rx_mutex);
|
|
ResetEvent(&rx_event);
|
|
memset(&ov, 0, sizeof(ov));
|
|
ov.hEvent = rx_event;
|
|
if (!ReadFile(hid->handle, tmpbuf, len + 1, NULL, &ov)) {
|
|
if (GetLastError() != ERROR_IO_PENDING) goto return_error;
|
|
r = WaitForSingleObject(rx_event, timeout);
|
|
if (r == WAIT_TIMEOUT) goto return_timeout;
|
|
if (r != WAIT_OBJECT_0) goto return_error;
|
|
}
|
|
if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) goto return_error;
|
|
LeaveCriticalSection(&rx_mutex);
|
|
if (n <= 0) return -1;
|
|
n--;
|
|
if (n > len) n = len;
|
|
memcpy(buf, tmpbuf + 1, n);
|
|
return n;
|
|
return_timeout:
|
|
CancelIo(hid->handle);
|
|
LeaveCriticalSection(&rx_mutex);
|
|
return 0;
|
|
return_error:
|
|
print_win32_err();
|
|
LeaveCriticalSection(&rx_mutex);
|
|
return -1;
|
|
}
|
|
|
|
// rawhid_send - send a packet
|
|
// Inputs:
|
|
// num = device to transmit to (zero based)
|
|
// buf = buffer containing packet to send
|
|
// len = number of bytes to transmit
|
|
// timeout = time to wait, in milliseconds
|
|
// Output:
|
|
// number of bytes sent, or -1 on error
|
|
//
|
|
int rawhid_send(int num, void *buf, int len, int timeout)
|
|
{
|
|
hid_t *hid;
|
|
unsigned char tmpbuf[516];
|
|
OVERLAPPED ov;
|
|
DWORD n, r;
|
|
|
|
if (sizeof(tmpbuf) < len + 1) return -1;
|
|
hid = get_hid(num);
|
|
if (!hid || !hid->open) return -1;
|
|
EnterCriticalSection(&tx_mutex);
|
|
ResetEvent(&tx_event);
|
|
memset(&ov, 0, sizeof(ov));
|
|
ov.hEvent = tx_event;
|
|
tmpbuf[0] = 0;
|
|
memcpy(tmpbuf + 1, buf, len);
|
|
if (!WriteFile(hid->handle, tmpbuf, len + 1, NULL, &ov)) {
|
|
if (GetLastError() != ERROR_IO_PENDING) goto return_error;
|
|
r = WaitForSingleObject(tx_event, timeout);
|
|
if (r == WAIT_TIMEOUT) goto return_timeout;
|
|
if (r != WAIT_OBJECT_0) goto return_error;
|
|
}
|
|
if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) goto return_error;
|
|
LeaveCriticalSection(&tx_mutex);
|
|
if (n <= 0) return -1;
|
|
return n - 1;
|
|
return_timeout:
|
|
CancelIo(hid->handle);
|
|
LeaveCriticalSection(&tx_mutex);
|
|
return 0;
|
|
return_error:
|
|
print_win32_err();
|
|
LeaveCriticalSection(&tx_mutex);
|
|
return -1;
|
|
}
|
|
|
|
HANDLE rawhid_open(char * Device)
|
|
{
|
|
DWORD index=0;
|
|
HANDLE h;
|
|
hid_t *hid;
|
|
int count=0;
|
|
|
|
if (first_hid) free_all_hid();
|
|
|
|
if (!rx_event)
|
|
{
|
|
rx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
|
tx_event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
|
InitializeCriticalSection(&rx_mutex);
|
|
InitializeCriticalSection(&tx_mutex);
|
|
}
|
|
h = CreateFile(Device, GENERIC_READ|GENERIC_WRITE,
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
|
|
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
if (h == INVALID_HANDLE_VALUE)
|
|
return 0;
|
|
|
|
hid = (struct hid_struct *)malloc(sizeof(struct hid_struct));
|
|
if (!hid)
|
|
{
|
|
CloseHandle(h);
|
|
return 0;
|
|
}
|
|
hid->handle = h;
|
|
hid->open = 1;
|
|
add_hid(hid);
|
|
|
|
return h;
|
|
}
|
|
|
|
|
|
// rawhid_close - close a device
|
|
//
|
|
// Inputs:
|
|
// num = device to close (zero based)
|
|
// Output
|
|
// (nothing)
|
|
//
|
|
void rawhid_close(int num)
|
|
{
|
|
hid_t *hid;
|
|
|
|
hid = get_hid(num);
|
|
if (!hid || !hid->open) return;
|
|
|
|
CloseHandle(hid->handle);
|
|
hid->handle = NULL;
|
|
hid->open = FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
static void add_hid(hid_t *h)
|
|
{
|
|
if (!first_hid || !last_hid) {
|
|
first_hid = last_hid = h;
|
|
h->next = h->prev = NULL;
|
|
return;
|
|
}
|
|
last_hid->next = h;
|
|
h->prev = last_hid;
|
|
h->next = NULL;
|
|
last_hid = h;
|
|
}
|
|
|
|
|
|
static hid_t * get_hid(int num)
|
|
{
|
|
hid_t *p;
|
|
for (p = first_hid; p && num > 0; p = p->next, num--) ;
|
|
return p;
|
|
}
|
|
|
|
|
|
static void free_all_hid(void)
|
|
{
|
|
hid_t *p, *q;
|
|
|
|
for (p = first_hid; p; p = p->next)
|
|
{
|
|
CloseHandle(p->handle);
|
|
p->handle = NULL;
|
|
p->open = FALSE;
|
|
}
|
|
p = first_hid;
|
|
while (p) {
|
|
q = p;
|
|
p = p->next;
|
|
free(q);
|
|
}
|
|
first_hid = last_hid = NULL;
|
|
}
|
|
|
|
|
|
|
|
void print_win32_err(void)
|
|
{
|
|
char buf[256];
|
|
DWORD err;
|
|
|
|
err = GetLastError();
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
|
|
0, buf, sizeof(buf), NULL);
|
|
Debugprintf("err %ld: %s\n", err, buf);
|
|
}
|
|
|
|
#endif
|
|
|
|
// RTL_SDR support code
|
|
|
|
char RTLModes[5][6] = {"FM", "AM", "USB", "LSB", "????"};
|
|
|
|
|
|
void CheckAndProcessRTLUDP(struct RIGPORTINFO * PORT)
|
|
{
|
|
int Length;
|
|
struct sockaddr_in rxaddr;
|
|
int addrlen = sizeof(struct sockaddr_in);
|
|
int Freq;
|
|
unsigned char RXBuffer[16];
|
|
|
|
struct RIGINFO * RIG = &PORT->Rigs[0];
|
|
|
|
Length = recvfrom(PORT->remoteSock, RXBuffer, 16, 0, (struct sockaddr *)&rxaddr, &addrlen);
|
|
|
|
if (Length == 6)
|
|
{
|
|
long long MHz, Hz;
|
|
char CharMHz[16] = "";
|
|
char CharHz[16] = "";
|
|
int i;
|
|
int Mode;
|
|
|
|
PORT->Timeout = 0;
|
|
RIG->RIGOK = TRUE;
|
|
|
|
Freq = (RXBuffer[4] << 24) + (RXBuffer[3] << 16) + (RXBuffer[2] << 8) + RXBuffer[1];
|
|
Mode = RXBuffer[5];
|
|
|
|
Freq += RIG->rxOffset;
|
|
|
|
RIG->RigFreq = Freq / 1000000.0;
|
|
|
|
// If we convert to float to display we get rounding errors, so convert to MHz and Hz to display
|
|
|
|
MHz = Freq / 1000000;
|
|
|
|
Hz = Freq - MHz * 1000000;
|
|
|
|
sprintf(CharMHz, "%lld", MHz);
|
|
sprintf(CharHz, "%06lld", Hz);
|
|
|
|
for (i = 5; i > 2; i--)
|
|
{
|
|
if (CharHz[i] == '0')
|
|
CharHz[i] = 0;
|
|
else
|
|
break;
|
|
}
|
|
|
|
sprintf(RIG->WEB_FREQ,"%lld.%s", MHz, CharHz);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
strcpy(RIG->Valchar, RIG->WEB_FREQ);
|
|
|
|
sprintf(RIG->WEB_MODE,"%s", RTLModes[Mode]);
|
|
|
|
strcpy(RIG->ModeString, Modes[Mode]);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
|
|
}
|
|
}
|
|
|
|
VOID RTLUDPPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
struct RIGINFO * RIG = &PORT->Rigs[0]; // Only one on HAMLIB
|
|
char cmd[80];
|
|
int len;
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
SetWindowText(RIG->hFREQ, "------------------");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
RIG->RIGOK = FALSE;
|
|
return;
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
int n;
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
memcpy(PORT->TXBuffer, PORT->FreqPtr->Cmd1, PORT->FreqPtr->Cmd1Len);
|
|
PORT->TXLen = PORT->FreqPtr->Cmd1Len;
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
n = sendto(PORT->remoteSock, PORT->TXBuffer, 5, 0, &PORT->remoteDest, sizeof(struct sockaddr));
|
|
|
|
if (PORT->TXLen == 10)
|
|
n = sendto(PORT->remoteSock, PORT->TXBuffer + 5, 5, 0, &PORT->remoteDest, sizeof(struct sockaddr));
|
|
|
|
PORT->TXBuffer[0] = 'P'; // Send Poll
|
|
|
|
n = sendto(PORT->remoteSock, PORT->TXBuffer, 5, 0, &PORT->remoteDest, sizeof(struct sockaddr));
|
|
|
|
PORT->CmdSent = 1;
|
|
PORT->Retries = 0;
|
|
PORT->Timeout = 0;
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
// There isn't a response to a set command, so clear Scan Lock here
|
|
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter > 1)
|
|
return;
|
|
}
|
|
|
|
if (RIG->RIGOK && (RIG->ScanStopped == 0) && RIG->NumberofBands)
|
|
return; // no point in reading freq if we are about to change it
|
|
|
|
RIG->PollCounter = 10; // Once Per Sec
|
|
|
|
// Read Frequency
|
|
|
|
cmd[0] = 'P';
|
|
|
|
len = sendto(PORT->remoteSock, cmd, 5, 0, &PORT->remoteDest, sizeof(struct sockaddr));
|
|
|
|
PORT->Timeout = 10;
|
|
PORT->CmdSent = 0;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT)
|
|
{
|
|
char Msg[255];
|
|
int i;
|
|
u_long param=1;
|
|
BOOL bcopt=TRUE;
|
|
struct sockaddr_in sinx;
|
|
|
|
if (PORT->remoteSock)
|
|
{
|
|
closesocket(PORT->remoteSock);
|
|
}
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->remoteSock = socket(AF_INET,SOCK_DGRAM,0);
|
|
|
|
if (PORT->remoteSock == INVALID_SOCKET)
|
|
{
|
|
i=sprintf(Msg, "Socket Failed for RTLUDP socket - error code = %d\r\n", WSAGetLastError());
|
|
WritetoConsole(Msg);
|
|
|
|
PORT->CONNECTING = FALSE;
|
|
return;
|
|
}
|
|
|
|
ioctl(PORT->remoteSock, FIONBIO, ¶m);
|
|
|
|
sinx.sin_family = AF_INET;
|
|
sinx.sin_addr.s_addr = INADDR_ANY;
|
|
sinx.sin_port = 0;
|
|
|
|
PORT->CONNECTED = TRUE;
|
|
PORT->hDevice = (HANDLE)1; // simplifies check code
|
|
PORT->Alerted = TRUE;
|
|
}
|
|
|
|
char * getObjectFromArray(char * Msg); // This gets the next object from an array ({} = object, [] = array
|
|
|
|
|
|
|
|
char * getArrayFromMsg(char * Msg)
|
|
{
|
|
// This gets the next object from an array ({} = object, [] = array
|
|
// We look for the end of the object same number of { and }, teminate after } and return pointer to next object
|
|
// So we have terminated Msg, and returned next object in array
|
|
|
|
// Only call if Msg is the next array in Msg
|
|
|
|
|
|
char * ptr = Msg;
|
|
char c;
|
|
|
|
int Open = 0;
|
|
int Close = 0;
|
|
|
|
while (c = *(ptr++))
|
|
{
|
|
if (c == '[') Open ++; else if (c == ']') Close ++;
|
|
|
|
if (Open == Close)
|
|
{
|
|
*(ptr++) = 0;
|
|
return ptr;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//----- G7TAJ -----
|
|
|
|
void ProcessSDRANGELFrame(struct RIGPORTINFO * PORT)
|
|
{
|
|
|
|
int Length;
|
|
|
|
char * msg;
|
|
|
|
struct RIGINFO * RIG;
|
|
char * ptr, * ptr1, * ptr2, * ptr3, * pos;
|
|
char cmd[80];
|
|
int chunklength;
|
|
int headerlen;
|
|
int i, n = 0;
|
|
char * Sets;
|
|
char * Rest;
|
|
char * Set;
|
|
int channelcount;
|
|
char * channels;
|
|
char * channel;
|
|
char * samplingDevice;
|
|
char * save;
|
|
|
|
//Debugprintf("Process SDRANGEL Frame %d\n", PORT->RXLen);
|
|
|
|
msg = PORT->RXBuffer;
|
|
Length = PORT->RXLen;
|
|
|
|
msg[Length] = 0;
|
|
|
|
ptr1 = strstr(msg, "Transfer-Encoding: chunked" );
|
|
|
|
if (ptr1 == NULL)
|
|
return;
|
|
|
|
ptr2 = strstr(ptr1, "\r\n\r\n");
|
|
|
|
if (ptr2 == NULL)
|
|
return;
|
|
|
|
// ptr2 +4 points to the length of the first chunk (in hex), terminated by crlf
|
|
|
|
chunklength = (int)strtol(ptr2 + 4, &ptr3, 16);
|
|
ptr3 += 2; // pointer to first chunk data
|
|
headerlen = ptr3 - msg;
|
|
|
|
// make sure we have first chunk
|
|
|
|
if (chunklength + headerlen > Length)
|
|
return;
|
|
|
|
PORT->RXLen = 0; //we have all the frame now
|
|
PORT->Timeout = 0;
|
|
|
|
if (strstr(ptr3, "deviceSets") == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Message has info for all rigs
|
|
|
|
// As we mess with the message, save a copy and restore for each Rig
|
|
|
|
save = _strdup(ptr3);
|
|
|
|
for (i = 0; i < PORT->ConfiguredRigs; i++)
|
|
{
|
|
strcpy(ptr3, save);
|
|
n = 0;
|
|
|
|
RIG = &PORT->Rigs[i];
|
|
RIG->RIGOK = 1;
|
|
|
|
// we can have one or more sampling devices (eg rltsdr) each with one or
|
|
// more channels (eg ssb demod, ssb mod). each set of sampling device = channel(s) is a device set.
|
|
|
|
// Find Device Set for this device (in RIG->
|
|
|
|
// Message Structure is
|
|
|
|
//{
|
|
// "deviceSets": [...].
|
|
// "devicesetcount": 2,
|
|
// "devicesetfocus": 0
|
|
//}
|
|
|
|
// Get the device sets (JSON [..] is an array
|
|
|
|
Sets = strchr(ptr3, '[');
|
|
|
|
if (Sets == 0)
|
|
continue;
|
|
|
|
Rest = getArrayFromMsg(Sets);
|
|
|
|
// Do we need to check devicesetcount ??. Maybe use to loop through sets, or just stop at end
|
|
|
|
// get the set for our device
|
|
|
|
while (RIG->RigAddr >= n)
|
|
{
|
|
Set = strchr(Sets, '{'); // Position to start of first Object
|
|
|
|
if (Set == 0)
|
|
break;
|
|
|
|
Sets = getObjectFromArray(Set);
|
|
n++;
|
|
}
|
|
|
|
if (Set == 0)
|
|
continue;
|
|
|
|
|
|
// Now get the channel. looking for key "index":
|
|
|
|
// we could have a number of sampling devices and channels but for now get sampling device freq
|
|
// and first channel freq. Channels are in an Array
|
|
|
|
if ((ptr = strstr(Set, "channelcount")) == 0)
|
|
continue;
|
|
|
|
channelcount = atoi(&ptr[15]);
|
|
|
|
if ((channels = strchr(Set, '[')) == 0)
|
|
continue;
|
|
|
|
samplingDevice = getArrayFromMsg(channels);
|
|
|
|
while(channelcount--)
|
|
{
|
|
channel = strchr(channels, '{');
|
|
channels = getObjectFromArray(channel);
|
|
|
|
if ((ptr = strstr(channel, "index")))
|
|
{
|
|
n = atoi(&ptr[7]);
|
|
if (n == RIG->Channel)
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (pos = strstr(samplingDevice, "centerFrequency")) //"centerFrequency": 10489630000,
|
|
{
|
|
pos += 18;
|
|
strncpy(cmd, pos, 20);
|
|
RIG->RigFreq = atof(cmd) / 1000000.0;
|
|
}
|
|
|
|
if (pos = strstr(channel, "deltaFrequency"))
|
|
{
|
|
pos += 17;
|
|
strncpy(cmd, pos, 20);
|
|
RIG->RigFreq += (atof(cmd) + RIG->rxOffset) / 1000000.0;;
|
|
}
|
|
|
|
|
|
_gcvt(RIG->RigFreq, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
|
|
// we could get mode from Title line:
|
|
//"title": "SSB Demodulator",
|
|
|
|
if (pos = strstr(channel, "title"))
|
|
{
|
|
pos += 9;
|
|
strncpy(cmd, pos, 20);
|
|
strlop(pos, ' ');
|
|
strncpy(RIG->ModeString, pos, 15);
|
|
sprintf(RIG->WEB_MODE, "%s", RIG->ModeString);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
while (msg && msg[0])
|
|
{
|
|
rest = strlop(msg, ',');
|
|
|
|
if ( pos = strstr(msg, "centerFrequency")) //"centerFrequency": 10489630000,
|
|
{
|
|
pos += 18;
|
|
strncpy(cmd, pos,20);
|
|
|
|
RIG->RigFreq = atof(cmd) / 1000000.0;
|
|
|
|
// printf("FREQ=%f\t%s\n", RIG->RigFreq, cmd);
|
|
|
|
_gcvt(RIG->RigFreq, 9, RIG->Valchar);
|
|
|
|
sprintf(RIG->WEB_FREQ,"%s", RIG->Valchar);
|
|
SetWindowText(RIG->hFREQ, RIG->WEB_FREQ);
|
|
}
|
|
|
|
else if (memcmp(msg, "Mode:", 5) == 0)
|
|
{
|
|
if (strlen(&msg[6]) < 15)
|
|
strcpy(RIG->ModeString, &msg[6]);
|
|
}
|
|
|
|
else if (memcmp(msg, "Passband:", 9) == 0)
|
|
{
|
|
RIG->Passband = atoi(&msg[10]);
|
|
sprintf(RIG->WEB_MODE, "%s/%d", RIG->ModeString, RIG->Passband);
|
|
SetWindowText(RIG->hMODE, RIG->WEB_MODE);
|
|
}
|
|
|
|
msg = rest;
|
|
}
|
|
*/
|
|
free (save);
|
|
}
|
|
|
|
|
|
|
|
VOID SDRANGELThread(struct RIGPORTINFO * PORT);
|
|
|
|
VOID ConnecttoSDRANGEL(struct RIGPORTINFO * PORT)
|
|
{
|
|
if (SDRANGELRunning)
|
|
_beginthread(SDRANGELThread, 0, (void *)PORT);
|
|
return ;
|
|
}
|
|
|
|
VOID SDRANGELThread(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Opens sockets and looks for data
|
|
char Msg[255];
|
|
int err, i, ret;
|
|
u_long param=1;
|
|
BOOL bcopt=TRUE;
|
|
fd_set readfs;
|
|
fd_set errorfs;
|
|
struct timeval timeout;
|
|
|
|
if (PORT->CONNECTING)
|
|
return;
|
|
|
|
PORT->RXLen = 0;
|
|
|
|
PORT->CONNECTING = 1;
|
|
|
|
if (PORT->remoteSock)
|
|
{
|
|
closesocket(PORT->remoteSock);
|
|
}
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->remoteSock = socket(AF_INET,SOCK_STREAM,0);
|
|
|
|
if (PORT->remoteSock == INVALID_SOCKET)
|
|
{
|
|
i=sprintf(Msg, "Socket Failed for SDRAngel socket - error code = %d\r\n", WSAGetLastError());
|
|
WritetoConsole(Msg);
|
|
|
|
PORT->CONNECTING = FALSE;
|
|
return;
|
|
}
|
|
|
|
setsockopt(PORT->remoteSock, SOL_SOCKET, SO_REUSEADDR, (const char FAR *)&bcopt, 4);
|
|
setsockopt(PORT->remoteSock, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&bcopt, 4);
|
|
|
|
if (connect(PORT->remoteSock,(LPSOCKADDR) &PORT->remoteDest,sizeof(PORT->remoteDest)) == 0)
|
|
{
|
|
//
|
|
// Connected successful
|
|
//
|
|
|
|
ioctl(PORT->remoteSock, FIONBIO, ¶m);
|
|
}
|
|
else
|
|
{
|
|
if (PORT->Alerted == FALSE)
|
|
{
|
|
struct sockaddr_in * destaddr = (SOCKADDR_IN * )&PORT->remoteDest;
|
|
|
|
err = WSAGetLastError();
|
|
|
|
sprintf(Msg, "Connect Failed for SDRAngel socket - error code = %d Port %d\r\n",
|
|
err, htons(destaddr->sin_port));
|
|
|
|
WritetoConsole(Msg);
|
|
PORT->Alerted = TRUE;
|
|
}
|
|
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTING = FALSE;
|
|
return;
|
|
}
|
|
|
|
PORT->CONNECTED = TRUE;
|
|
PORT->CONNECTING = 0;
|
|
|
|
PORT->hDevice = (HANDLE)1; // simplifies check code
|
|
|
|
PORT->Alerted = TRUE;
|
|
|
|
while (PORT->CONNECTED && SDRANGELRunning)
|
|
{
|
|
FD_ZERO(&readfs);
|
|
FD_ZERO(&errorfs);
|
|
|
|
FD_SET(PORT->remoteSock,&readfs);
|
|
FD_SET(PORT->remoteSock,&errorfs);
|
|
|
|
timeout.tv_sec = 5;
|
|
timeout.tv_usec = 0;
|
|
|
|
ret = select((int)PORT->remoteSock + 1, &readfs, NULL, &errorfs, &timeout);
|
|
|
|
if (SDRANGELRunning == 0)
|
|
return;
|
|
|
|
if (ret == SOCKET_ERROR)
|
|
{
|
|
Debugprintf("SDRAngel Select failed %d ", WSAGetLastError());
|
|
goto Lost;
|
|
}
|
|
|
|
if (ret > 0)
|
|
{
|
|
// See what happened
|
|
|
|
if (FD_ISSET(PORT->remoteSock, &readfs))
|
|
{
|
|
SDRANGELProcessMessage(PORT);
|
|
}
|
|
|
|
if (FD_ISSET(PORT->remoteSock, &errorfs))
|
|
{
|
|
Lost:
|
|
sprintf(Msg, "SDRAngel Connection lost for Port %s\r\n", PORT->IOBASE);
|
|
WritetoConsole(Msg);
|
|
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->Alerted = FALSE;
|
|
PORT->hDevice = 0; // simplifies check code
|
|
|
|
closesocket(PORT->remoteSock);
|
|
PORT->remoteSock = 0;
|
|
return;
|
|
}
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
sprintf(Msg, "SDRAngel Thread Terminated Port %s\r\n", PORT->IOBASE);
|
|
WritetoConsole(Msg);
|
|
}
|
|
|
|
/*
|
|
# 10489630000
|
|
|
|
CURL_DATA='{
|
|
"deviceHwType": "RTLSDR",
|
|
"direction": 0,
|
|
"rtlSdrSettings": {
|
|
"centerFrequency": "'$1'"
|
|
}
|
|
|
|
}';
|
|
|
|
|
|
curl -X PATCH "http://127.0.0.1:8091/sdrangel/deviceset/0/device/settings" \
|
|
-H "accept: application/json" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$CURL_DATA"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
VOID SDRANGELPoll(struct RIGPORTINFO * PORT)
|
|
{
|
|
UCHAR * Poll = PORT->TXBuffer;
|
|
|
|
// SDRAngel can have muliple rigs but we only need to poll once to get info for all rigs so just use first entry
|
|
|
|
struct RIGINFO * RIG = &PORT->Rigs[0];
|
|
int Len, i;
|
|
char SendBuff[256];
|
|
//char * SDRANGEL_GETheader = "GET /sdrangel/deviceset/%d/device/settings "
|
|
// "HTTP/1.1\nHost: %s\nConnection: keep-alive\n\r\n";
|
|
|
|
char * SDRANGEL_GETheader = "GET /sdrangel/devicesets "
|
|
"HTTP/1.1\nHost: %s\nConnection: keep-alive\n\r\n";
|
|
|
|
|
|
if (RIG->ScanStopped == 0)
|
|
if (RIG->ScanCounter)
|
|
RIG->ScanCounter--;
|
|
|
|
if (PORT->Timeout)
|
|
{
|
|
PORT->Timeout--;
|
|
|
|
if (PORT->Timeout) // Still waiting
|
|
return;
|
|
|
|
// Loop through all Rigs
|
|
|
|
for (i = 0; i < PORT->ConfiguredRigs; i++)
|
|
{
|
|
RIG = &PORT->Rigs[i];
|
|
|
|
SetWindowText(RIG->hFREQ, "------------------");
|
|
SetWindowText(RIG->hMODE, "----------");
|
|
strcpy(RIG->WEB_FREQ, "-----------");;
|
|
strcpy(RIG->WEB_MODE, "------");
|
|
|
|
RIG->RIGOK = FALSE;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Send Data if avail, else send poll
|
|
|
|
if (RIG->NumberofBands && RIG->RIGOK && (RIG->ScanStopped == 0))
|
|
{
|
|
if (RIG->ScanCounter <= 0)
|
|
{
|
|
// Send Next Freq
|
|
|
|
if (GetPermissionToChange(PORT, RIG))
|
|
{
|
|
char cmd[80];
|
|
|
|
if (RIG->RIG_DEBUG)
|
|
Debugprintf("BPQ32 Change Freq to %9.4f", PORT->FreqPtr->Freq);
|
|
|
|
_gcvt(PORT->FreqPtr->Freq / 1000000.0, 9, RIG->Valchar); // For MH
|
|
|
|
// Send the Set Freq here, send set mode when we get a response
|
|
|
|
memcpy(&PORT->ScanEntry, PORT->FreqPtr, sizeof(struct ScanEntry));
|
|
|
|
//TODO
|
|
sprintf(cmd, "%.0f", PORT->FreqPtr->Freq);
|
|
SDRANGELSendCommand(PORT, "SETFREQ", cmd);
|
|
|
|
|
|
PORT->CmdSent = 1;
|
|
PORT->Retries = 0;
|
|
PORT->Timeout = 10;
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
// There isn't a response to a set command, so clear Scan Lock here
|
|
ReleasePermission(RIG); // Release Perrmission
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (RIG->PollCounter)
|
|
{
|
|
RIG->PollCounter--;
|
|
if (RIG->PollCounter > 1)
|
|
return;
|
|
}
|
|
|
|
if (RIG->RIGOK && (RIG->ScanStopped == 0) && RIG->NumberofBands)
|
|
return; // no point in reading freq if we are about to change it
|
|
|
|
RIG->PollCounter = 40;
|
|
|
|
// Read Frequency
|
|
//TODO
|
|
|
|
|
|
// Len = sprintf(SendBuff, SDRANGEL_GETheader, 0, &PORT->remoteDest ); // devicenum, host:port
|
|
Len = sprintf(SendBuff, SDRANGEL_GETheader, &PORT->remoteDest ); // devicenum, host:port
|
|
|
|
if (PORT->CONNECTED)
|
|
{
|
|
if (send(PORT->remoteSock, SendBuff, Len, 0) != Len)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
PORT->Timeout = 10;
|
|
PORT->CmdSent = 0;
|
|
|
|
PORT->AutoPoll = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
VOID SDRANGELSendCommand(struct RIGPORTINFO * PORT, char * Command, char * Value)
|
|
{
|
|
int Len, ret;
|
|
char SendBuff[512];
|
|
char ValueString[256] ="";
|
|
char * SDRANGEL_PATCHheader = "PATCH /sdrangel/deviceset/%d/device/settings "
|
|
"HTTP/1.1\nHost: %s\n"
|
|
"accept: application/json\n"
|
|
"Content-Type: application/json\n"
|
|
"Connection: keep-alive\n"
|
|
"Content-length: %d\r\n"
|
|
"\r\n%s";
|
|
|
|
if (!PORT->CONNECTED)
|
|
return;
|
|
|
|
sprintf(ValueString, SDRANGEL_FREQ_DATA, "RTLSDR", Value);
|
|
|
|
Len = sprintf(SendBuff, SDRANGEL_PATCHheader, 0, &PORT->remoteDest, strlen(ValueString), ValueString);
|
|
|
|
ret = send(PORT->remoteSock, SendBuff, Len, 0);
|
|
|
|
if (ret != Len)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void SDRANGELProcessMessage(struct RIGPORTINFO * PORT)
|
|
{
|
|
// Called from Background thread
|
|
|
|
int InputLen = recv(PORT->remoteSock, &PORT->RXBuffer[PORT->RXLen], 8192 - PORT->RXLen, 0);
|
|
|
|
if (InputLen == 0 || InputLen == SOCKET_ERROR)
|
|
{
|
|
if (PORT->remoteSock)
|
|
closesocket(PORT->remoteSock);
|
|
|
|
PORT->remoteSock = 0;
|
|
|
|
PORT->CONNECTED = FALSE;
|
|
PORT->hDevice = 0;
|
|
return;
|
|
}
|
|
|
|
PORT->RXLen += InputLen;
|
|
ProcessSDRANGELFrame(PORT);
|
|
}
|
|
|
|
|
|
|
|
// ---- G7TAJ ----
|