kopia lustrzana https://github.com/jamescoxon/dl-fldigi
960 wiersze
24 KiB
C++
960 wiersze
24 KiB
C++
// =====================================================================
|
|
//
|
|
// xmlrpc_rig.cxx
|
|
//
|
|
// connect to flrig xmlrpc server
|
|
//
|
|
// Copyright (C) 2007-2009
|
|
// Dave Freese, W1HKJ
|
|
//
|
|
// This file is part of fldigi.
|
|
//
|
|
// Fldigi 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.
|
|
//
|
|
// Fldigi 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 fldigi. If not, see <http://www.gnu.org/licenses/>.
|
|
// =====================================================================
|
|
|
|
#include <iostream>
|
|
#include <cmath>
|
|
#include <cstring>
|
|
#include <vector>
|
|
#include <list>
|
|
#include <stdlib.h>
|
|
|
|
#include <FL/Fl.H>
|
|
#include <FL/filename.H>
|
|
#include <FL/fl_ask.H>
|
|
|
|
#include "rigsupport.h"
|
|
#include "modem.h"
|
|
#include "trx.h"
|
|
#include "fl_digi.h"
|
|
#include "configuration.h"
|
|
#include "main.h"
|
|
#include "waterfall.h"
|
|
#include "macros.h"
|
|
#include "qrunner.h"
|
|
#include "debug.h"
|
|
#include "status.h"
|
|
#include "icons.h"
|
|
|
|
LOG_FILE_SOURCE(debug::debug::LOG_XMLRPC_RIG);
|
|
|
|
using namespace XmlRpc;
|
|
using namespace std;
|
|
|
|
int xmlrpc_verbosity = 0;
|
|
|
|
//======================================================================
|
|
// flrig xmlrpc client
|
|
//======================================================================
|
|
|
|
pthread_t *flrig_thread = 0;
|
|
pthread_mutex_t mutex_flrig = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
void movFreq(Fl_Widget *w, void *d);
|
|
void show_freq(void *);
|
|
void flrig_get_vfo();
|
|
void flrig_get_frequency();
|
|
void post_mode(void *);
|
|
void flrig_get_mode();
|
|
void post_modes(void *);
|
|
void flrig_get_modes();
|
|
void post_bw(void *);
|
|
void flrig_get_bw();
|
|
void post_bws(void *);
|
|
void flrig_get_bws();
|
|
void flrig_get_notch();
|
|
void flrig_set_notch(int);
|
|
|
|
bool flrig_get_xcvr();
|
|
void flrig_connection();
|
|
void set_ptt();
|
|
|
|
void connect_to_flrig();
|
|
|
|
XmlRpcClient *flrig_client = (XmlRpcClient *)0;
|
|
|
|
bool bws_posted = false;
|
|
bool bw_posted = false;
|
|
bool mode_posted = false;
|
|
bool modes_posted = false;
|
|
bool freq_posted = true;
|
|
|
|
string xcvr_name;
|
|
string str_freq;
|
|
string mode_result;
|
|
XmlRpcValue modes_result;
|
|
XmlRpcValue bws_result;
|
|
XmlRpcValue bw_result;
|
|
XmlRpcValue notch_result;
|
|
|
|
bool connected_to_flrig = false;
|
|
static double timeout = 2.0;
|
|
//======================================================================
|
|
|
|
void xmlrpc_rig_set_qsy(long long rfc)
|
|
{
|
|
set_flrig_freq(static_cast<long>(rfc));
|
|
wf->rfcarrier(rfc);
|
|
wf->movetocenter();
|
|
show_frequency(rfc);
|
|
LOG_INFO("set qsy: %d", (int)rfc);
|
|
}
|
|
|
|
//======================================================================
|
|
// set / get pairs
|
|
//======================================================================
|
|
|
|
//----------------------------------------------------------------------
|
|
// push to talk
|
|
//----------------------------------------------------------------------
|
|
bool wait_ptt = false; // wait for transceiver to respond
|
|
int wait_ptt_timeout = 5; // 5 polls and then disable wait
|
|
int ptt_state = 0;
|
|
|
|
int new_ptt = -1;
|
|
|
|
void exec_flrig_ptt() {
|
|
if (!connected_to_flrig) {
|
|
new_ptt = -1;
|
|
return;
|
|
}
|
|
|
|
XmlRpcValue val, result;
|
|
int resp, res;
|
|
|
|
// PTT on/off is critical 5 attempts with 10 verify reads per attempt
|
|
for (int i = 0; i < 5; i++) {
|
|
res = flrig_client->execute("rig.set_ptt", new_ptt, result, timeout);
|
|
if (res) {
|
|
for (int j = 0; j < 10; j++) {
|
|
MilliSleep(20);
|
|
res = flrig_client->execute("rig.get_ptt", XmlRpcValue(), result, 10);
|
|
if (res) {
|
|
resp = (int)result;
|
|
if (resp == new_ptt) {
|
|
wait_ptt = true;
|
|
wait_ptt_timeout = 10;
|
|
ptt_state = new_ptt;
|
|
LOG_INFO("ptt %s in %d msec",
|
|
ptt_state ? "ON" : "OFF",
|
|
i*50 + (j + 1)*20);
|
|
new_ptt = -1;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
wait_ptt = false;
|
|
wait_ptt_timeout = 0;
|
|
LOG_ERROR("%s", "rig.set_ptt failed (3)");
|
|
fl_alert2("fldigi/flrig PTT %s failure", new_ptt ? "ON" : "OFF");
|
|
new_ptt = -1;
|
|
return;
|
|
}
|
|
|
|
void set_flrig_ptt(int on) {
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
new_ptt = on;
|
|
}
|
|
|
|
pthread_mutex_t mutex_flrig_ptt = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
void xmlrpc_rig_show_ptt(void *data)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_ptt);
|
|
int on = reinterpret_cast<long>(data);
|
|
if (wf) {
|
|
wf->xmtrcv->value(on);
|
|
wf->xmtrcv->do_callback();
|
|
}
|
|
}
|
|
|
|
void flrig_get_ptt()
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
XmlRpcValue result;
|
|
if (flrig_client->execute("rig.get_ptt", XmlRpcValue(), result, timeout) ) {
|
|
int val = int(result);
|
|
if (!wait_ptt && (val != ptt_state)) {
|
|
ptt_state = val;
|
|
guard_lock flrig_lock(&mutex_flrig_ptt);
|
|
Fl::awake(xmlrpc_rig_show_ptt, reinterpret_cast<void*>(val) );
|
|
LOG_INFO("get_ptt: %s", ptt_state ? "ON" : "OFF");
|
|
} else if (wait_ptt && (val == ptt_state)) {
|
|
wait_ptt = false;
|
|
wait_ptt_timeout = 0;
|
|
} else if (wait_ptt_timeout == 0) {
|
|
wait_ptt = false;
|
|
} else if (wait_ptt_timeout) {
|
|
--wait_ptt_timeout;
|
|
}
|
|
} else {
|
|
connected_to_flrig = false;
|
|
wait_ptt = false;
|
|
wait_ptt_timeout = 5;
|
|
LOG_ERROR("%s", "get_ptt failed!");
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// transceiver radio frequency
|
|
//----------------------------------------------------------------------
|
|
|
|
bool wait_freq = false; // wait for transceiver to respond
|
|
int wait_freq_timeout = 5; // 5 polls and then disable wait
|
|
long int xcvr_freq = 0;
|
|
|
|
pthread_mutex_t mutex_flrig_freq = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
void xmlrpc_rig_show_freq(void * fr)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_freq);
|
|
if (!wf) return;
|
|
long freq = reinterpret_cast<long>(fr);
|
|
wf->rfcarrier(freq);
|
|
wf->movetocenter();
|
|
show_frequency(freq);
|
|
}
|
|
|
|
void set_flrig_freq(long int fr)
|
|
{
|
|
if (!connected_to_flrig) return;
|
|
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
|
|
XmlRpcValue val, result;
|
|
val = double(fr);
|
|
if (!flrig_client->execute("rig.set_vfo", val, result, timeout)) {
|
|
LOG_ERROR("%s", "rig.set_vfo failed");
|
|
wait_freq = false;
|
|
wait_freq_timeout = 0;
|
|
} else {
|
|
wait_freq = true;
|
|
wait_freq_timeout = 5;
|
|
xcvr_freq = fr;
|
|
Fl::awake(xmlrpc_rig_show_freq, reinterpret_cast<void*>(fr));
|
|
LOG_INFO("set freq: %d", (int)fr);
|
|
}
|
|
}
|
|
|
|
void flrig_get_frequency()
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
XmlRpcValue result;
|
|
if (!freq_posted) return;
|
|
if (flrig_client->execute("rig.get_vfo", XmlRpcValue(), result, timeout) ) {
|
|
str_freq = string(result);
|
|
int fr = atoi(str_freq.c_str());
|
|
|
|
if (!wait_freq && (fr != xcvr_freq)) {
|
|
xcvr_freq = fr;
|
|
guard_lock flrig_lock(&mutex_flrig_freq);
|
|
Fl::awake(xmlrpc_rig_show_freq, reinterpret_cast<void*>(fr));
|
|
LOG_INFO("get freq: %d", fr);
|
|
} else if (wait_freq && (fr == xcvr_freq)) {
|
|
wait_freq = false;
|
|
wait_freq_timeout = 0;
|
|
} else if (wait_freq_timeout == 0) {
|
|
wait_freq = false;
|
|
} else if (wait_freq_timeout)
|
|
--wait_freq_timeout;
|
|
} else {
|
|
connected_to_flrig = false;
|
|
wait_freq = false;
|
|
wait_freq_timeout = 5;
|
|
LOG_ERROR("%s", "get freq failed");
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// transceiver set / get mode
|
|
// transceiver get modes (mode table)
|
|
//----------------------------------------------------------------------
|
|
|
|
bool wait_mode = false; // wait for transceiver to respond
|
|
int wait_mode_timeout = 5; // 5 polls and then disable wait
|
|
string posted_mode = "";
|
|
|
|
bool wait_bw = false; // wait for transceiver to respond
|
|
int wait_bw_timeout = 5; // 5 polls and then disable wait
|
|
string posted_bw = "";
|
|
string posted_bw1 = "";
|
|
string posted_bw2 = "";
|
|
|
|
void set_flrig_mode(const char *md)
|
|
{
|
|
if (!connected_to_flrig) return;
|
|
|
|
XmlRpcValue val, result;
|
|
val = string(md);
|
|
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
if (!flrig_client->execute("rig.set_mode", val, result, timeout)) {
|
|
LOG_ERROR("%s", "rig.set_mode failed");
|
|
wait_mode = false;
|
|
wait_mode_timeout = 5;
|
|
} else {
|
|
posted_mode = md;
|
|
bws_posted = false;
|
|
wait_mode = true;
|
|
wait_mode_timeout = 5;
|
|
LOG_INFO("set mode: %s", md);
|
|
}
|
|
}
|
|
|
|
pthread_mutex_t mutex_flrig_mode = PTHREAD_MUTEX_INITIALIZER;
|
|
void xmlrpc_rig_post_mode(void *data)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_mode);
|
|
if (!qso_opMODE) return;
|
|
string *s = reinterpret_cast<string *>(data);
|
|
qso_opMODE->value(s->c_str());
|
|
bws_posted = false;
|
|
}
|
|
|
|
void flrig_get_mode()
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
XmlRpcValue res;
|
|
if (flrig_client->execute("rig.get_mode", XmlRpcValue(), res, timeout) ) {
|
|
static string md;
|
|
md = string(res);
|
|
bool posted = (md == posted_mode);
|
|
if (!wait_mode && !posted) {
|
|
posted_mode = md;
|
|
guard_lock flrig_lock(&mutex_flrig_mode);
|
|
Fl::awake(xmlrpc_rig_post_mode, reinterpret_cast<void*>(&md));
|
|
LOG_INFO("get mode: %s", md.c_str());
|
|
} else if (wait_mode && posted) {
|
|
wait_mode = false;
|
|
wait_mode_timeout = 0;
|
|
} else if (wait_mode_timeout == 0) {
|
|
wait_mode = false;
|
|
} else if (wait_mode_timeout)
|
|
--wait_mode_timeout;
|
|
} else {
|
|
connected_to_flrig = false;
|
|
wait_mode = false;
|
|
wait_freq_timeout = 0;
|
|
LOG_ERROR("%s", "get mode failed");
|
|
}
|
|
}
|
|
|
|
pthread_mutex_t mutex_flrig_modes = PTHREAD_MUTEX_INITIALIZER;
|
|
void xmlrpc_rig_post_modes(void *)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_modes);
|
|
if (!qso_opMODE) return;
|
|
|
|
int nargs = modes_result.size();
|
|
|
|
qso_opMODE->clear();
|
|
|
|
if (nargs == 0) {
|
|
qso_opMODE->add("");
|
|
qso_opMODE->index(0);
|
|
qso_opMODE->deactivate();
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < nargs; i++)
|
|
qso_opMODE->add(string(modes_result[i]).c_str());
|
|
|
|
qso_opMODE->index(0);
|
|
qso_opMODE->activate();
|
|
|
|
modes_posted = true;
|
|
bws_posted = false;
|
|
}
|
|
|
|
void flrig_get_modes()
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
if (flrig_client->execute("rig.get_modes", XmlRpcValue(), modes_result, timeout) ) {
|
|
guard_lock flrig_lock(&mutex_flrig_modes);
|
|
Fl::awake(xmlrpc_rig_post_modes);
|
|
posted_mode = posted_bw = posted_bw1 = posted_bw2 = "GETME";
|
|
{
|
|
int nargs = modes_result.size();
|
|
static string debugstr;
|
|
debugstr.assign("Mode table: ");
|
|
for (int i = 0; i < nargs - 1; i++)
|
|
debugstr.append(modes_result[i]).append(",");
|
|
debugstr.append(modes_result[nargs-1]);
|
|
LOG_INFO("%s", debugstr.c_str());
|
|
}
|
|
} else {
|
|
LOG_ERROR("%s", "get modes failed");
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// transceiver get / set bandwidth
|
|
// transceiver get bandwidth table
|
|
//----------------------------------------------------------------------
|
|
|
|
void set_flrig_bw(int bw2, int bw1)
|
|
{
|
|
if (!connected_to_flrig) return;
|
|
|
|
XmlRpcValue val, result;
|
|
int ival = bw2;
|
|
if (bw1 > 0) ival = 256*(bw1+128) + bw2;
|
|
val = ival;
|
|
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
LOG_INFO("set_flrig_bw %04X", ival);
|
|
if (!flrig_client->execute("rig.set_bw", val, result, timeout)) {
|
|
LOG_ERROR("%s", "rig.set_bw failed");
|
|
wait_bw = false;
|
|
wait_bw_timeout = 0;
|
|
} else {
|
|
wait_bw = true;
|
|
wait_bw_timeout = 5;
|
|
}
|
|
}
|
|
|
|
pthread_mutex_t mutex_flrig_bw = PTHREAD_MUTEX_INITIALIZER;
|
|
void xmlrpc_rig_post_bw(void *)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_bw);
|
|
if (!qso_opBW) return;
|
|
|
|
if (posted_bw != (std::string)(qso_opBW->value())) {
|
|
qso_opBW->value(posted_bw.c_str());
|
|
qso_opBW->redraw();
|
|
LOG_INFO("Update BW %s", posted_bw.c_str());
|
|
}
|
|
}
|
|
|
|
void xmlrpc_rig_post_bw1(void *)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_bw);
|
|
if (!qso_opBW1) return;
|
|
|
|
if (posted_bw1 != (std::string)(qso_opBW1->value())) {
|
|
qso_opBW1->value(posted_bw1.c_str());
|
|
qso_opBW1->redraw();
|
|
LOG_INFO("Update combo BW1 %s", posted_bw1.c_str());
|
|
}
|
|
}
|
|
|
|
void xmlrpc_rig_post_bw2(void *)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_bw);
|
|
if (!qso_opBW2) return;
|
|
if (posted_bw2 != (std::string)(qso_opBW2->value())) {
|
|
qso_opBW2->value(posted_bw2.c_str());
|
|
qso_opBW2->redraw();
|
|
LOG_INFO("Update combo BW2 %s", posted_bw2.c_str());
|
|
}
|
|
}
|
|
|
|
void flrig_get_bw()
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
XmlRpcValue res;
|
|
if (wait_bw_timeout) {
|
|
wait_bw_timeout--;
|
|
return;
|
|
}
|
|
|
|
if (flrig_client->execute("rig.get_bw", XmlRpcValue(), res, timeout) ) {
|
|
static string s1;
|
|
static string s2;
|
|
|
|
s2 = string(res[0]);
|
|
s1 = string(res[1]);
|
|
if (!s1.empty()) {
|
|
posted_bw1 = s1;
|
|
Fl::awake(xmlrpc_rig_post_bw1);
|
|
posted_bw2 = s2;
|
|
Fl::awake(xmlrpc_rig_post_bw2);
|
|
} else {
|
|
if (!s2.empty()) {
|
|
posted_bw = s2;
|
|
Fl::awake(xmlrpc_rig_post_bw);
|
|
}
|
|
}
|
|
wait_bw_timeout = 0;
|
|
} else {
|
|
connected_to_flrig = false;
|
|
wait_bw_timeout = 0;
|
|
LOG_ERROR("%s", "get bw failed!");
|
|
}
|
|
}
|
|
|
|
pthread_mutex_t mutex_flrig_bws = PTHREAD_MUTEX_INITIALIZER;
|
|
void xmlrpc_rig_post_bws(void *)
|
|
{
|
|
if (!qso_opBW) return;
|
|
|
|
int nargs;
|
|
|
|
try { // two BW controls
|
|
nargs = bws_result[1].size();
|
|
|
|
static string bwstr;
|
|
qso_opBW1->clear();
|
|
for (int i = 1; i < nargs; i++) {
|
|
bwstr = string(bws_result[1][i]);
|
|
qso_opBW1->add(bwstr.c_str());
|
|
}
|
|
|
|
string labels1 = bws_result[1][0];
|
|
static char btn1_label[2];
|
|
btn1_label[0] = labels1[0]; btn1_label[1] = 0;
|
|
qso_btnBW1->label(btn1_label);
|
|
qso_btnBW1->redraw_label();
|
|
qso_btnBW1->redraw();
|
|
static char tooltip1[20];
|
|
snprintf(tooltip1,sizeof(tooltip1),"%s",labels1.substr(2).c_str());
|
|
qso_opBW1->tooltip(tooltip1);
|
|
qso_opBW1->index(0);
|
|
qso_opBW1->redraw();
|
|
|
|
{
|
|
static string debugstr;
|
|
debugstr.assign("\nBW1 table: ");
|
|
for (int i = 1; i < nargs-1; i++)
|
|
debugstr.append(string(bws_result[1][i])).append(", ");
|
|
debugstr.append(string(bws_result[1][nargs - 1])).append("\n");
|
|
debugstr.append(labels1);
|
|
LOG_INFO("%s", debugstr.c_str());
|
|
}
|
|
|
|
try {
|
|
nargs = bws_result[0].size();
|
|
|
|
static string bwstr;
|
|
qso_opBW2->clear();
|
|
for (int i = 1; i < nargs; i++) {
|
|
bwstr = string(bws_result[0][i]);
|
|
qso_opBW2->add(bwstr.c_str());
|
|
}
|
|
|
|
string labels2 = bws_result[0][0];
|
|
static char btn2_label[2];
|
|
btn2_label[0] = labels2[0]; btn2_label[1] = 0;
|
|
qso_btnBW2->label(btn2_label);
|
|
qso_btnBW2->redraw_label();
|
|
qso_btnBW2->redraw();
|
|
static char tooltip2[20];
|
|
snprintf(tooltip2,sizeof(tooltip2),"%s",labels2.substr(2).c_str());
|
|
qso_opBW2->tooltip(tooltip2);
|
|
qso_opBW2->index(0);
|
|
qso_opBW2->redraw();
|
|
|
|
{
|
|
static string debugstr;
|
|
debugstr.assign("\nBW2 table: ");
|
|
for (int i = 1; i < nargs-1; i++)
|
|
debugstr.append(string(bws_result[0][i])).append(", ");
|
|
debugstr.append(string(bws_result[0][nargs - 1])).append("\n");
|
|
debugstr.append(labels2);
|
|
LOG_INFO("%s", debugstr.c_str());
|
|
}
|
|
|
|
} catch ( XmlRpcException err) {
|
|
bws_posted = false;
|
|
return;
|
|
}
|
|
qso_opBW->hide();
|
|
qso_opGROUP->show();
|
|
bws_posted = true;
|
|
return;
|
|
} catch (XmlRpcException err) {
|
|
try { // one BW control
|
|
nargs = bws_result[0].size();
|
|
string bwstr;
|
|
qso_opBW->clear();
|
|
for (int i = 1; i < nargs; i++) {
|
|
bwstr = string(bws_result[0][i]);
|
|
qso_opBW->add(bwstr.c_str());
|
|
}
|
|
qso_opBW->index(0);
|
|
qso_opBW->activate();
|
|
qso_opBW->tooltip("xcvr bandwidth");
|
|
qso_opBW->show();
|
|
qso_opGROUP->hide();
|
|
|
|
{
|
|
static string debugstr;
|
|
debugstr.assign("BW table: ");
|
|
for (int i = 1; i < nargs-1; i++)
|
|
debugstr.append(string(bws_result[0][i])).append(", ");
|
|
debugstr.append(string(bws_result[0][nargs - 1]));
|
|
LOG_INFO("%s", debugstr.c_str());
|
|
}
|
|
|
|
} catch (XmlRpcException err) {
|
|
LOG_ERROR("%s", "no bandwidths specified");
|
|
qso_opBW->add("");
|
|
qso_opBW->index(0);
|
|
qso_opBW->deactivate();
|
|
return;
|
|
}
|
|
}
|
|
bws_posted = true;
|
|
}
|
|
|
|
void flrig_get_bws()
|
|
{
|
|
if (bws_posted) return;
|
|
XmlRpcValue result;
|
|
if (flrig_client->execute("rig.get_bws", XmlRpcValue(), bws_result, timeout) ) {
|
|
bws_posted = false;
|
|
wait_bw = true;
|
|
wait_bw_timeout = 5;
|
|
posted_bw.clear();
|
|
Fl::awake(xmlrpc_rig_post_bws);
|
|
} else {
|
|
LOG_ERROR("%s", "get bws failed");
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// transceiver get / set vfo A / B
|
|
//----------------------------------------------------------------------
|
|
|
|
void set_flrig_ab(int n)
|
|
{
|
|
// if (n) btn_vfoA->clear();
|
|
// else btn_vfoB->clear();
|
|
|
|
// if (!connected_to_flrig) return;
|
|
|
|
// XmlRpcValue val = string(n == 0 ? "A" : "B");
|
|
// XmlRpcValue result;
|
|
|
|
// guard_lock flrig_lock(&mutex_flrig);
|
|
// if (!flrig_client->execute("rig.set_AB", val, result, timeout))
|
|
// printf("rig.set_mode failed\n");
|
|
// else {
|
|
// skip = 2;
|
|
// }
|
|
// return;
|
|
}
|
|
|
|
void show_A(void *)
|
|
{
|
|
// btn_vfoA->set();
|
|
// btn_vfoB->clear();
|
|
}
|
|
|
|
void show_B(void *)
|
|
{
|
|
// btn_vfoA->clear();
|
|
// btn_vfoB->set();
|
|
}
|
|
|
|
void flrig_get_vfo()
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
XmlRpcValue result;
|
|
if (flrig_client->execute("rig.get_AB", XmlRpcValue(), result, timeout) ) {
|
|
// string str_vfo = string(result[0]);
|
|
// if (str_vfo == "A" && !btn_vfoA->value()) REQ(FLRIG_show_A);
|
|
// else if (str_vfo == "B" && !btn_vfoB->value()) REQ(FLRIG_show_B);
|
|
} else {
|
|
connected_to_flrig = false;
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
// transceiver set / get notch
|
|
//==============================================================================
|
|
bool wait_notch = false; // wait for transceiver to respond
|
|
int wait_notch_timeout = 5; // 5 polls and then disable wait
|
|
int xcvr_notch = 0;
|
|
|
|
void set_flrig_notch()
|
|
{
|
|
if (!connected_to_flrig) return;
|
|
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
|
|
XmlRpcValue val, result;
|
|
val = (double)(notch_frequency);
|
|
if (flrig_client->execute("rig.set_notch", val, result, timeout)) {
|
|
wait_notch = true;
|
|
wait_notch_timeout = 5;
|
|
xcvr_notch = notch_frequency;
|
|
} else {
|
|
LOG_ERROR("%s", "rig.set_notch failed");
|
|
wait_notch = 0;
|
|
wait_notch_timeout = 0;
|
|
xcvr_notch = 0;
|
|
}
|
|
}
|
|
|
|
void flrig_get_notch()
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
if (flrig_client->execute("rig.get_notch", XmlRpcValue(), notch_result, timeout) ) {
|
|
int nu_notch = (int)(notch_result);
|
|
if (nu_notch != notch_frequency) {
|
|
notch_frequency = nu_notch;
|
|
}
|
|
|
|
bool posted = (nu_notch == xcvr_notch);
|
|
|
|
if (!wait_notch && !posted) {
|
|
xcvr_notch = nu_notch;
|
|
notch_frequency = nu_notch;
|
|
} else if (wait_notch && posted) {
|
|
wait_notch = false;
|
|
wait_notch_timeout = 0;
|
|
} else if (wait_notch_timeout == 0) {
|
|
wait_notch = false;
|
|
} else if (wait_notch_timeout)
|
|
--wait_notch_timeout;
|
|
} else {
|
|
wait_notch = false;
|
|
wait_notch_timeout = 0;
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
// transceiver get smeter
|
|
// transceiver get power meter
|
|
//==============================================================================
|
|
|
|
pthread_mutex_t mutex_flrig_smeter = PTHREAD_MUTEX_INITIALIZER;
|
|
static void xmlrpc_rig_set_smeter(void *data)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_smeter);
|
|
if (!smeter && !pwrmeter) return;
|
|
|
|
if (smeter && progStatus.meters) {
|
|
if (!smeter->visible()) {
|
|
pwrmeter->hide();
|
|
smeter->show();
|
|
}
|
|
int val = reinterpret_cast<long>(data);
|
|
smeter->value(val);
|
|
}
|
|
}
|
|
|
|
void flrig_get_smeter()
|
|
{
|
|
XmlRpcValue val, result;
|
|
if (flrig_client->execute("rig.get_smeter", val, result, timeout)) {
|
|
int val = (int)(result);
|
|
guard_lock flrig_lock(&mutex_flrig_smeter);
|
|
Fl::awake(xmlrpc_rig_set_smeter, reinterpret_cast<void*>(val));
|
|
}
|
|
}
|
|
|
|
pthread_mutex_t mutex_flrig_pwrmeter = PTHREAD_MUTEX_INITIALIZER;
|
|
static void xmlrpc_rig_set_pwrmeter(void *data)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_pwrmeter);
|
|
if (!smeter && !pwrmeter) return;
|
|
|
|
if (pwrmeter && progStatus.meters) {
|
|
if (!pwrmeter->visible()) {
|
|
smeter->hide();
|
|
pwrmeter->show();
|
|
}
|
|
int val = reinterpret_cast<long>(data);
|
|
pwrmeter->value(val);
|
|
}
|
|
}
|
|
|
|
void flrig_get_pwrmeter()
|
|
{
|
|
XmlRpcValue val, result;
|
|
if (flrig_client->execute("rig.get_pwrmeter", val, result, timeout)) {
|
|
int val = (int)(result);
|
|
guard_lock flrig_lock(&mutex_flrig_pwrmeter);
|
|
Fl::awake(xmlrpc_rig_set_pwrmeter, reinterpret_cast<void*>(val));
|
|
}
|
|
}
|
|
|
|
//==============================================================================
|
|
// transceiver get name
|
|
//==============================================================================
|
|
|
|
pthread_mutex_t mutex_flrig_xcvr_name = PTHREAD_MUTEX_INITIALIZER;
|
|
void xmlrpc_rig_show_xcvr_name(void *)
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig_xcvr_name);
|
|
windowTitle = xcvr_name.c_str();
|
|
if (main_window_title.find(windowTitle) == string::npos)
|
|
setTitle();
|
|
}
|
|
|
|
bool flrig_get_xcvr()
|
|
{
|
|
XmlRpcValue result;
|
|
try {
|
|
bool ret;
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
ret = flrig_client->execute("rig.get_xcvr", XmlRpcValue(), result, timeout);
|
|
}
|
|
if (ret) {
|
|
string nuxcvr = string(result);
|
|
if (nuxcvr != xcvr_name) {
|
|
xcvr_name = nuxcvr;
|
|
guard_lock flrig_lock(&mutex_flrig_xcvr_name);
|
|
Fl::awake(xmlrpc_rig_show_xcvr_name);
|
|
modes_posted = false;
|
|
bws_posted = false;
|
|
flrig_get_modes();
|
|
flrig_get_bws();
|
|
flrig_get_mode();
|
|
flrig_get_bw();
|
|
}
|
|
return true;
|
|
} else {
|
|
connected_to_flrig = false;
|
|
}
|
|
} catch (XmlRpcException *err) {
|
|
connected_to_flrig = false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//======================================================================
|
|
// xmlrpc read polling thread
|
|
//======================================================================
|
|
bool run_flrig_thread = true;
|
|
int poll_interval = 1000; // 100 // milliseconds
|
|
|
|
//----------------------------------------------------------------------
|
|
// Set QSY to true if xmlrpc client connection is OK
|
|
//----------------------------------------------------------------------
|
|
|
|
void flrig_setQSY(void *)
|
|
{
|
|
if (!wf) return;
|
|
wf->setQSY(true);
|
|
}
|
|
|
|
void flrig_connection()
|
|
{
|
|
XmlRpcValue noArgs, result;
|
|
try {
|
|
bool ret;
|
|
{
|
|
guard_lock flrig_lock(&mutex_flrig);
|
|
ret = flrig_client->execute("system.listMethods", noArgs, result, timeout);
|
|
}
|
|
if (ret) {
|
|
int nargs = result.size();
|
|
string method_str = "\nMethods:\n";
|
|
for (int i = 0; i < nargs; i++)
|
|
method_str.append(" ").append(result[i]).append("\n");
|
|
LOG_INFO("%s", method_str.c_str());
|
|
connected_to_flrig = true;
|
|
poll_interval = 100;
|
|
flrig_get_xcvr();
|
|
Fl::awake(flrig_setQSY);
|
|
} else {
|
|
LOG_VERBOSE("%s", "Waiting for flrig");
|
|
connected_to_flrig = false;
|
|
poll_interval = 5000;
|
|
}
|
|
} catch (...) {
|
|
// LOG_ERROR("%s", "failure in flrig_client");
|
|
}
|
|
}
|
|
|
|
void connect_to_flrig()
|
|
{
|
|
XmlRpc::setVerbosity(xmlrpc_verbosity);
|
|
if (flrig_client) {
|
|
delete flrig_client;
|
|
flrig_client = (XmlRpcClient *)0;
|
|
}
|
|
try {
|
|
flrig_client = new XmlRpcClient(
|
|
progdefaults.flrig_ip_address.c_str(),
|
|
atol(progdefaults.flrig_ip_port.c_str()));
|
|
LOG_WARN("created flrig client %s, %ld",
|
|
progdefaults.flrig_ip_address.c_str(),
|
|
atol(progdefaults.flrig_ip_port.c_str()));
|
|
flrig_connection();
|
|
} catch (...) {
|
|
LOG_ERROR("Cannot create client %s, %s",
|
|
progdefaults.flrig_ip_address.c_str(),
|
|
progdefaults.flrig_ip_port.c_str());
|
|
}
|
|
}
|
|
|
|
void * flrig_thread_loop(void *d)
|
|
{
|
|
for(;;) {
|
|
MilliSleep(poll_interval );//progStatus.poll_interval);
|
|
|
|
if (!run_flrig_thread) break;
|
|
|
|
if (!flrig_client)
|
|
connect_to_flrig();
|
|
if (!connected_to_flrig) flrig_connection();
|
|
else if (flrig_get_xcvr()) {
|
|
if (new_ptt > -1) {
|
|
exec_flrig_ptt();
|
|
continue;
|
|
}
|
|
flrig_get_ptt();
|
|
if (trx_state == STATE_RX) {
|
|
flrig_get_frequency();
|
|
flrig_get_smeter();
|
|
flrig_get_notch();
|
|
if (!modes_posted) flrig_get_modes();
|
|
if (modes_posted) flrig_get_mode();
|
|
if (!bws_posted) flrig_get_bws();
|
|
if (bws_posted) flrig_get_bw();
|
|
}
|
|
else
|
|
flrig_get_pwrmeter();
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void FLRIG_start_flrig_thread()
|
|
{
|
|
flrig_thread = new pthread_t;
|
|
poll_interval = 1000;
|
|
if (pthread_create(flrig_thread, NULL, flrig_thread_loop, NULL)) {
|
|
LOG_ERROR("%s", "flrig_thread create");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
void stop_flrig_thread()
|
|
{
|
|
flrig_client->close();
|
|
pthread_mutex_lock(&mutex_flrig);
|
|
run_flrig_thread = false;
|
|
pthread_mutex_unlock(&mutex_flrig);
|
|
pthread_join(*flrig_thread, NULL);
|
|
}
|
|
|
|
void reconnect_to_flrig()
|
|
{
|
|
flrig_client->close();
|
|
pthread_mutex_lock(&mutex_flrig);
|
|
delete flrig_client;
|
|
flrig_client = (XmlRpcClient *)0;
|
|
connected_to_flrig = false;
|
|
pthread_mutex_unlock(&mutex_flrig);
|
|
}
|
|
|