/* * Hamlib Netrigctl backend - main file * Copyright (c) 2001-2010 by Stephane Fillod * * * 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 #include #include /* String function definitions */ #include /* UNIX standard function definitions */ #include #include #include #include "hamlib/rig.h" #include "network.h" #include "serial.h" #include "iofunc.h" #include "misc.h" #include "num_stdio.h" #include "dummy.h" #define CMD_MAX 32 #define BUF_MAX 96 #define CHKSCN1ARG(a) if ((a) != 1) return -RIG_EPROTO; else do {} while(0) struct netrigctl_priv_data { vfo_t vfo_curr; int rigctld_vfo_mode; }; int netrigctl_get_vfo_mode(RIG *rig) { struct netrigctl_priv_data *priv; priv = (struct netrigctl_priv_data *)rig->state.priv; return priv->rigctld_vfo_mode; } /* * Helper function with protocol return code parsing */ static int netrigctl_transaction(RIG *rig, char *cmd, int len, char *buf) { int ret; rig_debug(RIG_DEBUG_VERBOSE, "%s: called len=%d\n", __func__, len); /* flush anything in the read buffer before command is sent */ if (rig->state.rigport.type.rig == RIG_PORT_NETWORK || rig->state.rigport.type.rig == RIG_PORT_UDP_NETWORK) { network_flush(&rig->state.rigport); } else { serial_flush(&rig->state.rigport); } ret = write_block(&rig->state.rigport, cmd, len); if (ret != RIG_OK) { return ret; } ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret < 0) { return ret; } if (strncmp(buf, NETRIGCTL_RET, strlen(NETRIGCTL_RET)) == 0) { return atoi(buf + strlen(NETRIGCTL_RET)); } return ret; } /* this will fill vfostr with the vfo value if the vfo mode is enabled * otherwise string will be null terminated * this allows us to use the string in snprintf in either mode */ static int netrigctl_vfostr(RIG *rig, char *vfostr, int len, vfo_t vfo) { struct netrigctl_priv_data *priv; if (len < 5) { rig_debug(RIG_DEBUG_ERR, "%s: len must be >=5, len=%d\n", __func__, len); return -RIG_EPROTO; } vfostr[0] = 0; priv = (struct netrigctl_priv_data *)rig->state.priv; if (vfo == RIG_VFO_CURR) { vfo = priv->vfo_curr; } if (priv->rigctld_vfo_mode) { snprintf(vfostr, len, " %s", vfo == RIG_VFO_A ? "VFOA" : "VFOB"); } return RIG_OK; } static int netrigctl_init(RIG *rig) { // cppcheck says leak here but it's freed in cleanup struct netrigctl_priv_data *priv; if (!rig || !rig->caps) { return -RIG_EINVAL; } rig->state.priv = (struct netrigctl_priv_data *)malloc(sizeof( struct netrigctl_priv_data)); if (!rig->state.priv) { return -RIG_ENOMEM; } priv = rig->state.priv; memset(priv, 0, sizeof(struct netrigctl_priv_data)); rig_debug(RIG_DEBUG_TRACE, "%s version %s\n", __func__, rig->caps->version); /* * set arbitrary initial status * VFO will be updated in open call */ priv->vfo_curr = RIG_VFO_A; priv->rigctld_vfo_mode = 0; return RIG_OK; } static int netrigctl_cleanup(RIG *rig) { if (rig->state.priv) { free(rig->state.priv); } rig->state.priv = NULL; return RIG_OK; } static int netrigctl_open(RIG *rig) { int ret, len, i; struct rig_state *rs = &rig->state; int prot_ver; char cmd[CMD_MAX]; char buf[BUF_MAX]; struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct netrigctl_priv_data *)rig->state.priv; len = sprintf(cmd, "\\chk_vfo\n"); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret == RIG_OK) { if (buf[0]) { sscanf(buf, "CHKVFO %d", &priv->rigctld_vfo_mode); } } else if (ret < 0) { rig_debug(RIG_DEBUG_WARN, "%s: chk_vfo error: %s\n", __func__, rigerror(ret)); } rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo_mode=%d\n", __func__, priv->rigctld_vfo_mode); len = sprintf(cmd, "\\dump_state\n"); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } prot_ver = atoi(buf); #define RIGCTLD_PROT_VER 0 if (prot_ver < RIGCTLD_PROT_VER) { return -RIG_EPROTO; } ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->itu_region = atoi(buf); for (i = 0; i < FRQRANGESIZ; i++) { ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &rs->rx_range_list[i].startf, &rs->rx_range_list[i].endf, &rs->rx_range_list[i].modes, &rs->rx_range_list[i].low_power, &rs->rx_range_list[i].high_power, &rs->rx_range_list[i].vfo, &rs->rx_range_list[i].ant ); if (ret != 7) { return -RIG_EPROTO; } if (RIG_IS_FRNG_END(rs->rx_range_list[i])) { break; } } for (i = 0; i < FRQRANGESIZ; i++) { ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = num_sscanf(buf, "%"SCNfreq"%"SCNfreq"%"SCNXll"%d%d%x%x", &rs->tx_range_list[i].startf, &rs->tx_range_list[i].endf, &rs->tx_range_list[i].modes, &rs->tx_range_list[i].low_power, &rs->tx_range_list[i].high_power, &rs->tx_range_list[i].vfo, &rs->tx_range_list[i].ant ); if (ret != 7) { return -RIG_EPROTO; } if (RIG_IS_FRNG_END(rs->tx_range_list[i])) { break; } } for (i = 0; i < TSLSTSIZ; i++) { ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%"SCNXll"%ld", &rs->tuning_steps[i].modes, &rs->tuning_steps[i].ts); if (ret != 2) { return -RIG_EPROTO; } if (RIG_IS_TS_END(rs->tuning_steps[i])) { break; } } for (i = 0; i < FLTLSTSIZ; i++) { ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%"SCNXll"%ld", &rs->filters[i].modes, &rs->filters[i].width); if (ret != 2) { return -RIG_EPROTO; } if (RIG_IS_FLT_END(rs->filters[i])) { break; } } #if 0 /* TODO */ chan_t chan_list[CHANLSTSIZ]; /*!< Channel list, zero ended */ #endif ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->max_rit = atol(buf); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->max_xit = atol(buf); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->max_ifshift = atol(buf); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->announces = atoi(buf); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->preamp[0], &rs->preamp[1], &rs->preamp[2], &rs->preamp[3], &rs->preamp[4], &rs->preamp[5], &rs->preamp[6]); if (ret < 0 || ret >= MAXDBLSTSIZ) { ret = 0; } rs->preamp[ret] = RIG_DBLST_END; ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%d%d%d%d%d%d%d", &rs->attenuator[0], &rs->attenuator[1], &rs->attenuator[2], &rs->attenuator[3], &rs->attenuator[4], &rs->attenuator[5], &rs->attenuator[6]); if (ret < 0 || ret >= MAXDBLSTSIZ) { ret = 0; } rs->attenuator[ret] = RIG_DBLST_END; ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->has_get_func = strtol(buf, NULL, 0); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->has_set_func = strtol(buf, NULL, 0); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->has_get_level = strtol(buf, NULL, 0); if (rs->has_get_level & RIG_LEVEL_RAWSTR) { /* include STRENGTH because the remote rig may be able to provide a front end emulation, if it can't then an -RIG_EINVAL will be returned */ rs->has_get_level |= RIG_LEVEL_STRENGTH; } ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->has_set_level = strtol(buf, NULL, 0); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->has_get_parm = strtol(buf, NULL, 0); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rs->has_set_parm = strtol(buf, NULL, 0); #if 0 gran_t level_gran[RIG_SETTING_MAX]; /*!< level granularity */ gran_t parm_gran[RIG_SETTING_MAX]; /*!< parm granularity */ #endif for (i = 0; i < FRQRANGESIZ && !RIG_IS_FRNG_END(rs->rx_range_list[i]); i++) { rs->mode_list |= rs->rx_range_list[i].modes; rs->vfo_list |= rs->rx_range_list[i].vfo; } for (i = 0; i < FRQRANGESIZ && !RIG_IS_FRNG_END(rs->tx_range_list[i]); i++) { rs->mode_list |= rs->tx_range_list[i].modes; rs->vfo_list |= rs->tx_range_list[i].vfo; } return RIG_OK; } static int netrigctl_close(RIG *rig) { rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); /* clean signoff, no read back */ write_block(&rig->state.rigport, "q\n", 2); return RIG_OK; } static int netrigctl_set_freq(RIG *rig, vfo_t vfo, freq_t freq) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "F%s %"FREQFMT"\n", vfostr, freq); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "f%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, freq)); return RIG_OK; } static int netrigctl_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "M%s %s %li\n", vfostr, rig_strrmode(mode), width); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "m%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > 0 && buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *mode = rig_parse_mode(buf); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *width = atoi(buf); return RIG_OK; } static int netrigctl_set_vfo(RIG *rig, vfo_t vfo) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "V%s %s\n", vfostr, rig_strvfo(vfo)); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_vfo(RIG *rig, vfo_t *vfo) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; struct netrigctl_priv_data *priv; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); priv = (struct netrigctl_priv_data *)rig->state.priv; ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "v%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret == -RIG_ENAVAIL) { return ret; } if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > 0 && buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *vfo = rig_parse_vfo(buf); priv->vfo_curr = *vfo; return RIG_OK; } static int netrigctl_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "T%s %d\n", vfostr, ptt); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "t%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ptt = atoi(buf); return RIG_OK; } static int netrigctl_get_dcd(RIG *rig, vfo_t vfo, dcd_t *dcd) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "\\get_dcd%s\n", vfostr); /* FIXME */ ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *dcd = atoi(buf); return RIG_OK; } static int netrigctl_set_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t rptr_shift) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "R%s %s\n", vfostr, rig_strptrshift(rptr_shift)); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rptr_shift(RIG *rig, vfo_t vfo, rptr_shift_t *rptr_shift) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "r%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > 0 && buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *rptr_shift = rig_parse_rptr_shift(buf); return RIG_OK; } static int netrigctl_set_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t rptr_offs) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "O%s %ld\n", vfostr, rptr_offs); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rptr_offs(RIG *rig, vfo_t vfo, shortfreq_t *rptr_offs) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "o%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rptr_offs = atoi(buf); return RIG_OK; } static int netrigctl_set_ctcss_tone(RIG *rig, vfo_t vfo, tone_t tone) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "C%s %d\n", vfostr, tone); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ctcss_tone(RIG *rig, vfo_t vfo, tone_t *tone) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "c%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int netrigctl_set_dcs_code(RIG *rig, vfo_t vfo, tone_t code) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "D%s %d\n", vfostr, code); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_dcs_code(RIG *rig, vfo_t vfo, tone_t *code) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "d%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int netrigctl_set_ctcss_sql(RIG *rig, vfo_t vfo, tone_t tone) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "\\set_ctcss_sql%s %d\n", vfostr, tone); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ctcss_sql(RIG *rig, vfo_t vfo, tone_t *tone) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "\\get_ctcss_sql%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tone = atoi(buf); return RIG_OK; } static int netrigctl_set_dcs_sql(RIG *rig, vfo_t vfo, unsigned int code) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "\\set_dcs_sql%s %u\n", vfostr, code); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_dcs_sql(RIG *rig, vfo_t vfo, unsigned int *code) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "\\get_dcs_sql%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *code = atoi(buf); return RIG_OK; } static int netrigctl_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "I%s %"FREQFMT"\n", vfostr, tx_freq); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "i%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } CHKSCN1ARG(num_sscanf(buf, "%"SCNfreq, tx_freq)); return RIG_OK; } static int netrigctl_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, pbwidth_t tx_width) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "X%s %s %li\n", vfostr, rig_strrmode(tx_mode), tx_width); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, pbwidth_t *tx_width) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "x%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > 0 && buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_mode = rig_parse_mode(buf); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *tx_width = atoi(buf); return RIG_OK; } static int netrigctl_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "S%s %d %s\n", vfostr, split, rig_strvfo(tx_vfo)); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_split_vfo(RIG *rig, vfo_t vfo, split_t *split, vfo_t *tx_vfo) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "s%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *split = atoi(buf); ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > 0 && buf[ret - 1] == '\n') { buf[ret - 1] = '\0'; } /* chomp */ *tx_vfo = rig_parse_vfo(buf); return RIG_OK; } static int netrigctl_set_rit(RIG *rig, vfo_t vfo, shortfreq_t rit) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "J%s %ld\n", vfostr, rit); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_rit(RIG *rig, vfo_t vfo, shortfreq_t *rit) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "j%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *rit = atoi(buf); return RIG_OK; } static int netrigctl_set_xit(RIG *rig, vfo_t vfo, shortfreq_t xit) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "Z%s %ld\n", vfostr, xit); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_xit(RIG *rig, vfo_t vfo, shortfreq_t *xit) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "z%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *xit = atoi(buf); return RIG_OK; } static int netrigctl_set_ts(RIG *rig, vfo_t vfo, shortfreq_t ts) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "N%s %ld\n", vfostr, ts); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ts(RIG *rig, vfo_t vfo, shortfreq_t *ts) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), RIG_VFO_A); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "n%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ts = atoi(buf); return RIG_OK; } static int netrigctl_set_func(RIG *rig, vfo_t vfo, setting_t func, int status) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "U%s %s %i\n", vfostr, rig_strfunc(func), status); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_func(RIG *rig, vfo_t vfo, setting_t func, int *status) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "u%s %s\n", vfostr, rig_strfunc(func)); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *status = atoi(buf); return RIG_OK; } static int netrigctl_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char lstr[32]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_LEVEL_IS_FLOAT(level)) { sprintf(lstr, "%f", val.f); } else { sprintf(lstr, "%d", val.i); } ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = snprintf(cmd, sizeof(cmd), "L%s %s %s\n", vfostr, rig_strlevel(level), lstr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_level(RIG *rig, vfo_t vfo, setting_t level, value_t *val) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "l%s %s\n", vfostr, rig_strlevel(level)); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_LEVEL_IS_FLOAT(level)) { val->f = atof(buf); } else { val->i = atoi(buf); } return RIG_OK; } static int netrigctl_set_powerstat(RIG *rig, powerstat_t status) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "\\set_powerstat %d\n", status); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_powerstat(RIG *rig, powerstat_t *status) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "\\get_powerstat\n"); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *status = atoi(buf); return RIG_OK; } static int netrigctl_set_parm(RIG *rig, setting_t parm, value_t val) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char pstr[32]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); if (RIG_PARM_IS_FLOAT(parm)) { sprintf(pstr, "%f", val.f); } else { sprintf(pstr, "%d", val.i); } len = snprintf(cmd, sizeof(cmd), "P %s %s\n", rig_strparm(parm), pstr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_parm(RIG *rig, setting_t parm, value_t *val) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "p %s\n", rig_strparm(parm)); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (RIG_PARM_IS_FLOAT(parm)) { val->f = atoi(buf); } else { val->i = atoi(buf); } return RIG_OK; } static int netrigctl_set_ant(RIG *rig, vfo_t vfo, ant_t ant, value_t option) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "Y%s %d %d\n", vfostr, ant, option.i); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_ant(RIG *rig, vfo_t vfo, ant_t *ant, value_t *option) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "y%s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } rig_debug(RIG_DEBUG_TRACE, "%s: buf='%s'\n", __func__, buf); ret = sscanf(buf, "%d\n", ant); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 ant integer in '%s', got %d\n", __func__, buf, ret); } ret = read_string(&rig->state.rigport, buf, BUF_MAX, "\n", 1); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } ret = sscanf(buf, "%d\n",&(option->i)); if (ret != 1) { rig_debug(RIG_DEBUG_ERR, "%s: expected 1 option integer in '%s', got %d\n", __func__, buf, ret); } return RIG_OK; } static int netrigctl_set_bank(RIG *rig, vfo_t vfo, int bank) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "B %d\n", bank); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_mem(RIG *rig, vfo_t vfo, int ch) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "E%s %d\n", vfostr, ch); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_get_mem(RIG *rig, vfo_t vfo, int *ch) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; char vfostr[6] = ""; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); ret = netrigctl_vfostr(rig, vfostr, sizeof(vfostr), vfo); if (ret != RIG_OK) { return ret; } len = sprintf(cmd, "e %s\n", vfostr); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } *ch = atoi(buf); return RIG_OK; } static int netrigctl_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "g %s %d\n", rig_strscan(scan), ch); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) { int ret, len; char cmd[CMD_MAX]; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "J %s\n", rig_strvfop(op)); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_set_channel(RIG *rig, const channel_t *chan) { return -RIG_ENIMPL; } static int netrigctl_get_channel(RIG *rig, channel_t *chan) { return -RIG_ENIMPL; } static const char *netrigctl_get_info(RIG *rig) { int ret, len; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "_\n"); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret < 0) { return NULL; } buf [ret] = '\0'; return buf; } static int netrigctl_send_dtmf(RIG *rig, vfo_t vfo, const char *digits) { int ret, len; char *cmdp, cmd[] = "\\send_dtmf "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + digits + \n + \0) cmdp = malloc(strlen(cmd) + strlen(digits) + 2); if (cmdp == NULL) { return -RIG_ENOMEM; } len = sprintf(cmdp, "%s%s\n", cmd, digits); ret = netrigctl_transaction(rig, cmdp, len, buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } static int netrigctl_recv_dtmf(RIG *rig, vfo_t vfo, char *digits, int *length) { int ret, len; char cmd[CMD_MAX]; static char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); len = sprintf(cmd, "\\recv_dtmf\n"); ret = netrigctl_transaction(rig, cmd, len, buf); if (ret <= 0) { return (ret < 0) ? ret : -RIG_EPROTO; } if (ret > *length) { ret = *length; } strncpy(digits, buf, ret); *length = ret; digits [ret] = '\0'; return RIG_OK; } static int netrigctl_send_morse(RIG *rig, vfo_t vfo, const char *msg) { int ret, len; char *cmdp, cmd[] = "\\send_morse "; char buf[BUF_MAX]; rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__); // allocate memory for size of (cmd + msg + \n + \0) cmdp = malloc(strlen(cmd) + strlen(msg) + 2); if (cmdp == NULL) { return -RIG_ENOMEM; } len = sprintf(cmdp, "%s%s\n", cmd, msg); ret = netrigctl_transaction(rig, cmdp, len, buf); free(cmdp); if (ret > 0) { return -RIG_EPROTO; } else { return ret; } } /* * Netrigctl rig capabilities. */ const struct rig_caps netrigctl_caps = { .rig_model = RIG_MODEL_NETRIGCTL, .model_name = "NET rigctl", .mfg_name = "Hamlib", .version = "1.2", .copyright = "LGPL", .status = RIG_STATUS_STABLE, .rig_type = RIG_TYPE_OTHER, .targetable_vfo = 0, .ptt_type = RIG_PTT_RIG_MICDATA, .dcd_type = RIG_DCD_RIG, .port_type = RIG_PORT_NETWORK, .timeout = 2500, /* enough for a network */ .retry = 1, /* following fields updated in rig_state at openning time */ .has_get_func = RIG_FUNC_NONE, .has_set_func = RIG_FUNC_NONE, .has_get_level = RIG_LEVEL_NONE, .has_set_level = RIG_LEVEL_NONE, .has_get_parm = RIG_PARM_NONE, .has_set_parm = RIG_PARM_NONE, .level_gran = { }, .ctcss_list = NULL, .dcs_list = NULL, .chan_list = { }, .transceive = RIG_TRN_OFF, .attenuator = { }, .preamp = { }, .rx_range_list2 = { RIG_FRNG_END, }, .tx_range_list2 = { RIG_FRNG_END, }, .tuning_steps = { }, .filters = { RIG_FLT_END, }, .max_rit = 0, .max_xit = 0, .max_ifshift = 0, .priv = NULL, .rig_init = netrigctl_init, .rig_cleanup = netrigctl_cleanup, .rig_open = netrigctl_open, .rig_close = netrigctl_close, .set_freq = netrigctl_set_freq, .get_freq = netrigctl_get_freq, .set_mode = netrigctl_set_mode, .get_mode = netrigctl_get_mode, .set_vfo = netrigctl_set_vfo, .get_vfo = netrigctl_get_vfo, .set_powerstat = netrigctl_set_powerstat, .get_powerstat = netrigctl_get_powerstat, .set_level = netrigctl_set_level, .get_level = netrigctl_get_level, .set_func = netrigctl_set_func, .get_func = netrigctl_get_func, .set_parm = netrigctl_set_parm, .get_parm = netrigctl_get_parm, .get_info = netrigctl_get_info, .set_ptt = netrigctl_set_ptt, .get_ptt = netrigctl_get_ptt, .get_dcd = netrigctl_get_dcd, .set_rptr_shift = netrigctl_set_rptr_shift, .get_rptr_shift = netrigctl_get_rptr_shift, .set_rptr_offs = netrigctl_set_rptr_offs, .get_rptr_offs = netrigctl_get_rptr_offs, .set_ctcss_tone = netrigctl_set_ctcss_tone, .get_ctcss_tone = netrigctl_get_ctcss_tone, .set_dcs_code = netrigctl_set_dcs_code, .get_dcs_code = netrigctl_get_dcs_code, .set_ctcss_sql = netrigctl_set_ctcss_sql, .get_ctcss_sql = netrigctl_get_ctcss_sql, .set_dcs_sql = netrigctl_set_dcs_sql, .get_dcs_sql = netrigctl_get_dcs_sql, .set_split_freq = netrigctl_set_split_freq, .get_split_freq = netrigctl_get_split_freq, .set_split_mode = netrigctl_set_split_mode, .get_split_mode = netrigctl_get_split_mode, .set_split_vfo = netrigctl_set_split_vfo, .get_split_vfo = netrigctl_get_split_vfo, .set_rit = netrigctl_set_rit, .get_rit = netrigctl_get_rit, .set_xit = netrigctl_set_xit, .get_xit = netrigctl_get_xit, .set_ts = netrigctl_set_ts, .get_ts = netrigctl_get_ts, .set_ant = netrigctl_set_ant, .get_ant = netrigctl_get_ant, .set_bank = netrigctl_set_bank, .set_mem = netrigctl_set_mem, .get_mem = netrigctl_get_mem, .vfo_op = netrigctl_vfo_op, .scan = netrigctl_scan, .send_dtmf = netrigctl_send_dtmf, .recv_dtmf = netrigctl_recv_dtmf, .send_morse = netrigctl_send_morse, .set_channel = netrigctl_set_channel, .get_channel = netrigctl_get_channel, };