Hamlib/dummy/flrig.c

844 wiersze
22 KiB
C

/*
* Hamlib FLRig backend - main file
* Copyright (c) 2017 by Michael Black W9MDB
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <math.h>
#include <hamlib/rig.h>
#include <serial.h>
#include <misc.h>
#include <cal.h>
#include <token.h>
#include <register.h>
#include <network.h>
#include "flrig.h"
#define DEBUG 1
#define MAXCMDLEN 8192
#define DEFAULTPATH "localhost:12345"
#define FLRIG_VFOS (RIG_VFO_A|RIG_VFO_B|RIG_VFO_TX)
#define FLRIG_MODES (RIG_MODE_AM | RIG_MODE_CW | RIG_MODE_RTTY | \
RIG_MODE_SSB | RIG_MODE_FM)
#define RIG_DEBUG_TRACE RIG_DEBUG_VERBOSE
static int flrig_init(RIG *rig);
//int flrig_cleanup(RIG *rig);
static int flrig_set_freq(RIG *rig, vfo_t vfo, freq_t freq);
static int flrig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq);
static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt);
static int flrig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode,
pbwidth_t width);
static int flrig_get_vfo(RIG *rig, vfo_t *vfo);
static int flrig_set_vfo(RIG *rig, vfo_t vfo);
static int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt);
static int flrig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt);
static int flrig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq);
static int flrig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq);
static int flrig_set_split_vfo(RIG *rig, vfo_t vfo, split_t split,
vfo_t tx_vfo);
static int flrig_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split,
vfo_t *tx_vfo);
struct flrig_priv_data {
vfo_t vfo_curr;
};
const struct rig_caps flrig_caps = {
.rig_model = RIG_MODEL_FLRIG,
.model_name = "FLRig",
.mfg_name = "FLRig",
.version = BACKEND_VER,
.copyright = "LGPL",
.status = RIG_STATUS_ALPHA,
.rig_type = RIG_TYPE_TRANSCEIVER,
.targetable_vfo = 0,
.ptt_type = RIG_PTT_RIG,
.port_type = RIG_PORT_NETWORK,
.write_delay = 0,
.post_write_delay = 50,
.timeout = 1000,
.retry = 3,
.has_get_func = RIG_FUNC_NONE,
.has_set_func = RIG_FUNC_NONE,
.has_get_level = (RIG_LEVEL_RAWSTR | RIG_LEVEL_STRENGTH),
.has_set_level = RIG_LEVEL_NONE,
.has_get_parm = RIG_PARM_NONE,
.has_set_parm = RIG_PARM_NONE,
// .level_gran = { [LVL_CWPITCH] = { .step = { .i = 10 } } },
// .ctcss_list = common_ctcss_list,
// .dcs_list = full_dcs_list,
// .chan_list = {
// { 0, 18, RIG_MTYPE_MEM, DUMMY_MEM_CAP },
// { 19, 19, RIG_MTYPE_CALL },
// { 20, NB_CHAN-1, RIG_MTYPE_EDGE },
// RIG_CHAN_END,
// },
// .vfo_ops = DUMMY_VFO_OP,
.transceive = RIG_TRN_RIG,
// .attenuator = { 10, 20, 30, RIG_DBLST_END, },
// .preamp = { 10, RIG_DBLST_END, },
// .rx_range_list1 = {{.start = kHz(150),.end = MHz(1500),.modes = FLRIG_MODES,
// .low_power = -1,.high_power = -1, FLRIG_VFOS, RIG_ANT_1 | RIG_ANT_2},
// RIG_FRNG_END,},
// .tx_range_list1 = {RIG_FRNG_END,},
// .rx_range_list2 = {{.start = kHz(150),.end = MHz(1500),.modes = FLRIG_MODES,
// .low_power = -1,.high_power = -1, FLRIG_VFOS, RIG_ANT_1 | RIG_ANT_2},
// RIG_FRNG_END,},
// .tx_range_list2 = {RIG_FRNG_END,},
// .tuning_steps = { {DUMMY_MODES,1}, {DUMMY_MODES,RIG_TS_ANY}, RIG_TS_END, },
// .filters = {
// {RIG_MODE_SSB | RIG_MODE_CW | RIG_MODE_RTTY, kHz(2.4)},
// {RIG_MODE_CW, Hz(500)},
// {RIG_MODE_AM, kHz(8)},
// {RIG_MODE_AM, kHz(2.4)},
// {RIG_MODE_FM, kHz(15)},
// {RIG_MODE_FM, kHz(8)},
// {RIG_MODE_WFM, kHz(230)},
// RIG_FLT_END,
// },
// .max_rit = 9990,
// .max_xit = 9990,
// .max_ifshift = 10000,
.priv = NULL, /* priv */
// .extlevels = dummy_ext_levels,
// .extparms = dummy_ext_parms,
// .cfgparams = dummy_cfg_params,
.rig_init = flrig_init,
// .rig_cleanup = dummy_cleanup,
// .rig_open = dummy_open,
// .rig_close = dummy_close,
// .set_conf = dummy_set_conf,
// .get_conf = dummy_get_conf,
.set_freq = flrig_set_freq,
.get_freq = flrig_get_freq,
.set_mode = flrig_set_mode,
// .get_mode = dummy_get_mode,
.set_vfo = flrig_set_vfo,
.get_vfo = flrig_get_vfo,
// .set_powerstat = dummy_set_powerstat,
// .get_powerstat = dummy_get_powerstat,
// .set_level = dummy_set_level,
// .get_level = dummy_get_level,
// .set_func = dummy_set_func,
// .get_func = dummy_get_func,
// .set_parm = dummy_set_parm,
// .get_parm = dummy_get_parm,
// .set_ext_level = dummy_set_ext_level,
// .get_ext_level = dummy_get_ext_level,
// .set_ext_parm = dummy_set_ext_parm,
// .get_ext_parm = dummy_get_ext_parm,
// .get_info = dummy_get_info,
.set_ptt = flrig_set_ptt,
.get_ptt = flrig_get_ptt,
.set_split_freq = flrig_set_split_freq,
.get_split_freq = flrig_get_split_freq,
// .set_split_mode = flrig_set_split_mode,
// .get_split_mode = flrig_get_split_mode,
.set_split_vfo = flrig_set_split_vfo,
.get_split_vfo = flrig_get_split_vfo,
// .set_ant = dummy_set_ant,
// .get_ant = dummy_get_ant,
// .set_bank = dummy_set_bank,
// .set_mem = dummy_set_mem,
// .get_mem = dummy_get_mem,
// .vfo_op = dummy_vfo_op,
// .set_trn = dummy_set_trn,
// .get_trn = dummy_get_trn,
};
DECLARE_INITRIG_BACKEND(flrig)
{
rig_debug(RIG_DEBUG_TRACE, "flrig: _init called\n");
rig_register(&flrig_caps);
return RIG_OK;
}
static int check_vfo(vfo_t vfo)
{
switch (vfo) { // Omni VII only has A & B
case RIG_VFO_A:
break;
case RIG_VFO_B:
break;
case RIG_VFO_TX:
break;
case RIG_VFO_CURR:
break; // will default to A in which_vfo
default:
return FALSE;
}
return TRUE;
}
static int vfo_curr(RIG *rig, vfo_t vfo)
{
int retval = 0;
struct flrig_priv_data *priv =
(struct flrig_priv_data *) rig->state.priv;
retval = (vfo == priv->vfo_curr);
return retval;
}
// Rather than use some huge XML library we only need a few things
// So we'll hand craft them
static char *xml_build(char *cmd, char *value)
{
char xml[4096];
char tmp[32];
static char xmlpost[4096];
// Standard 50ms sleep borrowed from ts200.c settings
// Tested with ANAN 100
usleep(50 * 1000);
sprintf(xmlpost,
"POST /RPC2 HTTP/1.1\n" "User-Agent: XMLRPC++ 0.8\n"
"Host: 127.0.0.1:12345\n" "Content-type: text/xml\n");
sprintf(xml, "<?xml version=\"1.0\"?>\n");
strcat(xml, "<methodCall><methodName>");
strcat(xml, cmd);
strcat(xml, "</methodName>");
if (value && strlen(value) > 0) {
strcat(xml, value);
}
strcat(xml, "</methodCall>\n");
strcat(xmlpost, "Content-length: ");
sprintf(tmp, "%d\n\n", (int)strlen(xml));
strcat(xmlpost, tmp);
strcat(xmlpost, xml);
rig_debug(RIG_DEBUG_VERBOSE, "XML:\n%s", xmlpost);
return xmlpost;
}
// This is a very crude xml parse specific to what we need from FLRig
// This will not handle array returns for example yet...only simple values
// It simply grabs the first element before the first closing tag
// This works for strings, doubles, and I4-type values
char *xml_parse2(char *xml, char *value, int valueLen)
{
char *pstart = strchr(xml, '<');
while (pstart[0] == '<' && pstart[1] != '/') {
char *p2 = strchr(pstart, '>') + 1;
pstart = strchr(p2, '<');
strncpy(value, p2, pstart - p2);
value[pstart - p2] = 0;
}
return value;
}
static char *xml_parse(char *xml, char *value, int value_len)
{
/* first off we should have an OK on the 1st line */
if (strstr(xml, " 200 OK") == NULL) {
return NULL;
}
// find the xml skipping the other stuff above it
char *pxml = strstr(xml, "<?xml");
if (pxml == NULL) {
return NULL;
}
char *next = strchr(pxml + 1, '<');
char value2[16384];
xml_parse2(next, value2, sizeof(value2));
strcpy(value, value2);
return value;
}
static int read_transaction(RIG *rig, char *xml, int xml_len)
{
struct rig_state *rs = &rig->state;
int retval;
char cmd_buf[16384]; // plenty big for expected flrig responses
char delim[1];
delim[0] = 0x0a;
xml[0] = cmd_buf[0] = 0;
do {
retval =
read_string(&rs->rigport, cmd_buf, sizeof(cmd_buf), delim,
sizeof(delim));
if (strlen(xml) > 8192 - retval) {
return -RIG_EINVAL;
}
if (retval > 0) {
strcat(xml, cmd_buf);
}
} while (retval > 0 && strstr(cmd_buf, "</methodResponse>") == NULL);
return RIG_OK;
}
int flrig_init(RIG *rig)
{
rig_debug(RIG_DEBUG_TRACE, "%s\n", __FUNCTION__);
struct flrig_priv_data *priv = (struct flrig_priv_data *)malloc(sizeof(struct flrig_priv_data));
if (!priv) {
return -RIG_ENOMEM;
}
memset(priv, 0, sizeof(struct flrig_priv_data));
/*
* set arbitrary initial status
*/
priv->vfo_curr = RIG_VFO_A;
rig->state.priv = (rig_ptr_t) priv;
if (!rig || !rig->caps) {
return -RIG_EINVAL;
}
strncpy(rig->state.rigport.pathname, DEFAULTPATH,
sizeof(rig->state.rigport.pathname));
return RIG_OK;
}
/*
* flrig_get_freq
* Assumes rig!=NULL, rig->state.priv!=NULL, freq!=NULL
*/
int flrig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __FUNCTION__,
rig_strvfo(vfo));
rs = &rig->state;
if (check_vfo(vfo) == FALSE) {
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n",
__FUNCTION__, rig_strvfo(vfo));
return -RIG_EINVAL;
}
if (vfo == RIG_VFO_CURR) {
vfo = RIG_VFO_A;
}
flrig_set_vfo(rig, vfo);
pxml = xml_build("rig.get_vfo", NULL);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
xml_parse(xml, value, sizeof(value));
*freq = atof(value);
rig_debug(RIG_DEBUG_VERBOSE, "%s: '%s'\n", __FUNCTION__, value);
return RIG_OK;
}
/*
* flrig_set_freq
* assumes rig!=NULL, rig->state.priv!=NULL
*/
int flrig_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __FUNCTION__,
rig_strvfo(vfo), freq);
rs = &rig->state;
if (check_vfo(vfo) == FALSE) {
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n",
__FUNCTION__, rig_strvfo(vfo));
return -RIG_EINVAL;
}
if (vfo == RIG_VFO_CURR) {
if ((retval = flrig_get_vfo(rig, &vfo)) != RIG_OK) {
return retval;
}
rig_debug(RIG_DEBUG_VERBOSE, "%s: set_freq2 vfo=%s\n",
__FUNCTION__, rig_strvfo(vfo));
}
if (!vfo_curr(rig, vfo)) {
flrig_set_vfo(rig, vfo);
}
sprintf(value,
"<params><param><value><double>%.6f</double></value></param></params>",
freq);
pxml = xml_build("rig.set_vfo", value);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
//don't care about the response right now
//xml_parse(xml, value, sizeof(value));
flrig_set_vfo(rig, vfo);
return RIG_OK;
}
/*
* flrig_set_ptt
* Assumes rig!=NULL
*/
int flrig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt)
{
int retval;
char cmd_buf[MAXCMDLEN];
char *pxml;
char xml[8192];
struct rig_state *rs;
rig_debug(RIG_DEBUG_TRACE, "%s: ptt=%d\n", __FUNCTION__, ptt);
rs = &rig->state;
if (check_vfo(vfo) == FALSE) {
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n",
__FUNCTION__, rig_strvfo(vfo));
return -RIG_EINVAL;
}
if (vfo == RIG_VFO_CURR) {
vfo = RIG_VFO_A;
}
if (!vfo_curr(rig, vfo)) {
flrig_set_vfo(rig, vfo);
}
sprintf(cmd_buf,
"<params><param><value><i4>%d</i4></value></param></params>",
ptt);
pxml = xml_build("rig.set_ptt", cmd_buf);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
xml_parse(xml, cmd_buf, sizeof(cmd_buf));
return RIG_OK;
}
int flrig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __FUNCTION__,
rig_strvfo(vfo));
rs = &rig->state;
pxml = xml_build("rig.get_ptt", NULL);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
xml_parse(xml, value, sizeof(value));
*ptt = atoi(value);
rig_debug(RIG_DEBUG_VERBOSE, "%s: '%s'\n", __FUNCTION__, value);
return RIG_OK;
}
/*
* flrig_set_mode
* Assumes rig!=NULL
*/
int flrig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
{
char cmd_buf[32], ttmode;
int cmd_len, retval;
struct rig_state *rs;
//struct tt588_priv_data *priv = (struct tt588_priv_data *) rig->state.priv;
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s mode=%d width=%d\n",
__FUNCTION__, rig_strvfo(vfo), mode, width);
rs = &rig->state;
if (check_vfo(vfo) == FALSE) {
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n",
__FUNCTION__, rig_strvfo(vfo));
return -RIG_EINVAL;
}
switch (mode) {
case RIG_MODE_USB:
ttmode = 'U';
break;
case RIG_MODE_LSB:
ttmode = 'L';
break;
case RIG_MODE_CW:
ttmode = 'C';
break;
case RIG_MODE_AM:
ttmode = 'A';
break;
//case RIG_MODE_FSK: ttmode = 'F'; break;
default:
rig_debug(RIG_DEBUG_ERR, "%s: unsupported mode %d\n",
__FUNCTION__, mode);
return -RIG_EINVAL;
}
cmd_len = sprintf((char *) cmd_buf, "XB%c" EOM, ttmode);
retval = write_block(&rs->rigport, cmd_buf, cmd_len);
if (retval < 0) {
return retval;
}
return RIG_OK;
}
#if 0
static int flrig_flush(RIG *rig, vfo_t vfo)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __FUNCTION__,
rig_strvfo(vfo));
rs = &rig->state;
sprintf(value, "<params><param><value>%s</value></param></params>",
vfo == RIG_VFO_A ? "A" : "B");
pxml = xml_build("rig.flush", value);
network_flush(&rs->rigport);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
return RIG_OK;
}
#endif
int flrig_set_vfo(RIG *rig, vfo_t vfo)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __FUNCTION__,
rig_strvfo(vfo));
rs = &rig->state;
if (check_vfo(vfo) == FALSE) {
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n",
__FUNCTION__, rig_strvfo(vfo));
return -RIG_EINVAL;
}
if (vfo == RIG_VFO_CURR) {
struct flrig_priv_data *priv =
(struct flrig_priv_data *) rig->state.priv;
vfo = priv->vfo_curr;
}
sprintf(value, "<params><param><value>%s</value></param></params>",
vfo == RIG_VFO_A ? "A" : "B");
pxml = xml_build("rig.set_AB", value);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
//xml_parse(xml,value,sizeof(value));
vfo_t vfotmp;
flrig_get_vfo(rig, &vfotmp);
return RIG_OK;
}
int flrig_get_vfo(RIG *rig, vfo_t *vfo)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s\n", __FUNCTION__);
rs = &rig->state;
pxml = xml_build("rig.get_AB", NULL);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
xml_parse(xml, value, sizeof(value));
switch (value[0]) {
case 'A':
*vfo = RIG_VFO_A;
break;
case 'B':
*vfo = RIG_VFO_B;
break;
default:
*vfo = RIG_VFO_CURR;
return -RIG_EINVAL;
}
if (check_vfo(*vfo) == FALSE) {
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n",
__FUNCTION__, rig_strvfo(*vfo));
return -RIG_EINVAL;
}
struct flrig_priv_data *priv =
(struct flrig_priv_data *) rig->state.priv;
priv->vfo_curr = *vfo;
rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s\n", __FUNCTION__,
rig_strvfo(*vfo));
return RIG_OK;
}
/*
* flrig_set_split_freq
* Note that split doesn't work for FLRig models that don't have reply codes
* Like most Yaesu rigs. The commands will overrun FLRig in those cases.
* Rigs that do have replies for all cat commands will work with split
*/
int flrig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s freq=%.1f\n", __FUNCTION__,
rig_strvfo(vfo), tx_freq);
rs = &rig->state;
if (vfo == RIG_VFO_SUB) {
vfo = RIG_VFO_B;
}
if (check_vfo(vfo) == FALSE) {
rig_debug(RIG_DEBUG_ERR, "%s: unsupported VFO %s\n",
__FUNCTION__, rig_strvfo(vfo));
return -RIG_EINVAL;
}
if (!vfo_curr(rig, vfo)) {
flrig_set_vfo(rig, vfo);
}
sprintf(value,
"<params><param><value><double>%.6f</double></value></param></params>",
tx_freq);
pxml = xml_build("rig.set_vfo", value);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
xml_parse(xml, value, sizeof(value));
return RIG_OK;
}
/*
* flrig_get_split_freq
* assumes rig!=NULL, tx_freq!=NULL
*/
int flrig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq)
{
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s\n", __FUNCTION__,
rig_strvfo(vfo));
return flrig_get_freq(rig, vfo, tx_freq);
}
/*
* flrig_set_split_vfo
* assumes rig!=NULL, tx_freq!=NULL
*/
int flrig_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s: tx_vfo=%s\n", __FUNCTION__,
rig_strvfo(tx_vfo));
rs = &rig->state;
if (tx_vfo == RIG_VFO_SUB) {
tx_vfo = RIG_VFO_B;
}
if (!vfo_curr(rig, vfo)) {
flrig_set_vfo(rig, vfo);
}
sprintf(value,
"<params><param><value><i4>%d</i4></value></param></params>",
split);
pxml = xml_build("rig.set_split", value);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
//xml_parse(xml, value, sizeof(value));
//flrig_set_vfo(rig,RIG_VFO_A);
return RIG_OK;
}
/*
* flrig_get_split_vfo
* assumes rig!=NULL, tx_freq!=NULL
*/
int flrig_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split,
vfo_t *tx_vfo)
{
char value[MAXCMDLEN];
char *pxml;
int retval;
struct rig_state *rs;
char xml[8192];
rig_debug(RIG_DEBUG_TRACE, "%s\n", __FUNCTION__);
rs = &rig->state;
//flrig_set_vfo(rig,RIG_VFO_B);
pxml = xml_build("rig.get_split", NULL);
retval = write_block(&rs->rigport, pxml, strlen(pxml));
if (retval < 0) {
return retval;
}
read_transaction(rig, xml, sizeof(xml));
xml_parse(xml, value, sizeof(value));
//flrig_set_vfo(rig,RIG_VFO_A);
*tx_vfo = RIG_VFO_B;
*split = atoi(value);
return RIG_OK;
}
/*
.set_split_freq = flrig_set_split_freq,
.get_split_freq = flrig_get_split_freq,
.set_split_mode = flrig_set_split_mode,
.get_split_mode = flrig_get_split_mode,
*/