|
|
|
|
@ -125,6 +125,16 @@ 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);
|
|
|
|
|
@ -184,6 +194,10 @@ int HAMLIBMasterRunning = 0;
|
|
|
|
|
int HAMLIBSlaveRunning = 0;
|
|
|
|
|
int FLRIGRunning = 0;
|
|
|
|
|
|
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
|
int SDRANGELRunning = 0;
|
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
|
|
|
|
|
|
char * RigWebPage = 0;
|
|
|
|
|
int RigWebPageLen = 0;
|
|
|
|
|
|
|
|
|
|
@ -796,6 +810,26 @@ static char Req[] = "<?xml version=\"1.0\"?>\r\n"
|
|
|
|
|
"</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)
|
|
|
|
|
@ -2074,7 +2108,7 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTR
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
@ -2084,7 +2118,43 @@ int Rig_CommandEx(struct RIGPORTINFO * PORT, struct RIGINFO * RIG, TRANSPORTENTR
|
|
|
|
|
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 ----
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -2271,6 +2341,14 @@ DllExport BOOL APIENTRY Rig_Init()
|
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
@ -2421,7 +2499,10 @@ DllExport BOOL APIENTRY Rig_Close()
|
|
|
|
|
|
|
|
|
|
HAMLIBMasterRunning = 0; // Close HAMLIB thread(s)
|
|
|
|
|
HAMLIBSlaveRunning = 0; // Close HAMLIB thread(s)
|
|
|
|
|
FLRIGRunning = 0; // Close FLRIG thread(s)
|
|
|
|
|
FLRIGRunning = 0; // Close FLRIG thread(s)
|
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
|
SDRANGELRunning = 0; // Close SDRANGEL thread(s)
|
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
|
|
|
|
|
|
for (p = 0; p < NumberofPorts; p++)
|
|
|
|
|
{
|
|
|
|
|
@ -2544,6 +2625,10 @@ BOOL Rig_Poll()
|
|
|
|
|
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
|
|
|
|
|
@ -2632,7 +2717,12 @@ BOOL Rig_Poll()
|
|
|
|
|
|
|
|
|
|
case FLRIG:
|
|
|
|
|
FLRIGPoll(PORT);
|
|
|
|
|
break;
|
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
|
case SDRANGEL:
|
|
|
|
|
SDRANGELPoll(PORT);
|
|
|
|
|
break; }
|
|
|
|
|
// ---- G7TAJ ----
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build page for Web Display
|
|
|
|
|
@ -3014,6 +3104,14 @@ BOOL RigWriteCommBlock(struct RIGPORTINFO * PORT)
|
|
|
|
|
#ifndef WIN32
|
|
|
|
|
BytesWritten = write(PORT->hDevice, PORT->TXBuffer, PORT->TXLen);
|
|
|
|
|
#else
|
|
|
|
|
DWORD Mask = 0;
|
|
|
|
|
int Err;
|
|
|
|
|
|
|
|
|
|
Err = GetCommModemStatus(PORT->hDevice, &Mask);
|
|
|
|
|
|
|
|
|
|
// if ((Mask & MS_CTS_ON) == 0) // trap com0com other end not open
|
|
|
|
|
// return TRUE;
|
|
|
|
|
|
|
|
|
|
fWriteStat = WriteFile(PORT->hDevice, PORT->TXBuffer, PORT->TXLen, &BytesWritten, NULL );
|
|
|
|
|
#endif
|
|
|
|
|
if (PORT->TXLen != BytesWritten)
|
|
|
|
|
@ -5529,6 +5627,78 @@ struct RIGINFO * RigConfig(struct TNCINFO * TNC, char * buf, int Port)
|
|
|
|
|
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;
|
|
|
|
|
@ -9633,8 +9803,616 @@ VOID ConnecttoRTLUDP(struct RIGPORTINFO * PORT)
|
|
|
|
|
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;
|
|
|
|
|
char * rest;
|
|
|
|
|
|
|
|
|
|
struct RIGINFO * RIG;
|
|
|
|
|
char * ptr, * ptr1, * ptr2, * ptr3, * pos;
|
|
|
|
|
int Len, TotalLen;
|
|
|
|
|
char cmd[80];
|
|
|
|
|
char ReqBuf[256];
|
|
|
|
|
char SendBuff[256];
|
|
|
|
|
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) / 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 ReqBuf[256];
|
|
|
|
|
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];
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
//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 ReqBuf[512];
|
|
|
|
|
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 ----
|
|
|
|
|
|