From 4bfd71f91f3a2c4260ea8e499637cebf312d5ffb Mon Sep 17 00:00:00 2001 From: Mike Black W9MDB Date: Mon, 2 Aug 2021 23:37:31 -0500 Subject: [PATCH] Fix Icom split and implement reverse split These should work now from rigctl and via the API S VFOB 1 VFOA S Sub 1 Main https://github.com/Hamlib/Hamlib/issues/754 --- NEWS | 7 ++ include/hamlib/rig.h | 1 + rigs/dummy/dummy.c | 4 +- rigs/icom/icom.c | 63 +++++++++++----- rigs/icom/icom.h | 2 +- src/misc.c | 4 +- src/misc.h | 2 +- src/network.c | 171 +++++++++++++++++++++++++++++++++++++++---- src/rig.c | 40 +++++----- tests/rigctlcom.c | 52 ++++++------- 10 files changed, 264 insertions(+), 82 deletions(-) diff --git a/NEWS b/NEWS index 5232ec5c3..64cbdfe0f 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,13 @@ Please send Hamlib bug reports to hamlib-developer@lists.sourceforge.net Version 4.3 * 2021-??-?? * Generating documentation now requires GNU source-highlighter. + * Added IC-575 + * Overhaul of rig split -- reverse split (VFOA=RX VFOB=TX) should work for rigs capable of it + Starting VFO does not matter -- rig will end up on RX VFO + S VFOA 1 VFOB + S VFOB 1 VFOA + S Main 1 Sub + S Sub 1 Main Version 4.2 * 2021-05-17 diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index a85b7ae6f..876bb723f 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -24,6 +24,7 @@ #ifndef _RIG_H #define _RIG_H 1 +#define TRACE rig_debug(RIG_DEBUG_TRACE,"%s(%d) trace\n", __FILE__, __LINE__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #include diff --git a/rigs/dummy/dummy.c b/rigs/dummy/dummy.c index d7765547a..f2c45f52d 100644 --- a/rigs/dummy/dummy.c +++ b/rigs/dummy/dummy.c @@ -507,7 +507,7 @@ static int dummy_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) rig_debug(RIG_DEBUG_VERBOSE, "%s called: %s %s %s\n", __func__, rig_strvfo(vfo), rig_strrmode(mode), buf); - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); switch (vfo) { case RIG_VFO_MAIN: @@ -522,7 +522,7 @@ static int dummy_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width) RETURNFUNC(-RIG_EINVAL); } - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); if (RIG_PASSBAND_NOCHANGE == width) { RETURNFUNC(RIG_OK); } diff --git a/rigs/icom/icom.c b/rigs/icom/icom.c index 08aa8e816..3707736f9 100644 --- a/rigs/icom/icom.c +++ b/rigs/icom/icom.c @@ -909,6 +909,7 @@ static int icom_set_default_vfo(RIG *rig) RETURNFUNC(retval); } + TRACE; retval = rig_set_vfo(rig, RIG_VFO_A); // we'll default to Main in this case if (retval != RIG_OK) @@ -1257,6 +1258,7 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) { // we default to VFOA/MAIN as appropriate vfo = (rig->state.vfo_list & RIG_VFO_B) ? RIG_VFO_A : RIG_VFO_MAIN; + TRACE; retval = rig_set_vfo(rig, vfo); if (retval != RIG_OK) @@ -1301,6 +1303,7 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) if (priv->x25cmdfails) // then we're doing this the hard way....swap+read { freqbuf_offset = 1; + TRACE; retval = set_vfo_curr(rig, vfo, rig->state.current_vfo); if (retval != RIG_OK) @@ -1311,6 +1314,7 @@ int icom_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) } retval = icom_transaction(rig, cmd, subcmd, NULL, 0, freqbuf, &freq_len); + TRACE; set_vfo_curr(rig, vfo_save, rig->state.current_vfo); } @@ -2143,6 +2147,7 @@ int icom_get_mode(RIG *rig, vfo_t vfo, rmode_t *mode, pbwidth_t *width) if (vfosave != vfo) { // right now forcing VFOA/B arrangement -- reverse not supported yet + TRACE; rig_set_vfo(rig, RIG_VFO_B); retval = icom_get_dsp_flt(rig, *mode); *width = retval; @@ -4773,6 +4778,7 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) } #if 0 + TRACE; retval = set_vfo_curr(rig, RIG_VFO_TX, RIG_VFO_TX); if (retval != RIG_OK) @@ -4900,7 +4906,8 @@ int icom_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) { RETURNFUNC(retval); } - + + TRACE; if (VFO_HAS_MAIN_SUB_A_B_ONLY) { // Then we return the VFO to the rx_vfo @@ -5113,6 +5120,7 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) RETURNFUNC(retval); } + TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); @@ -5123,6 +5131,7 @@ int icom_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) RETURNFUNC(retval); } + TRACE; if (VFO_HAS_MAIN_SUB_A_B_ONLY) { // Then we return the VFO to where it was @@ -5233,6 +5242,7 @@ int icom_set_split_mode(RIG *rig, vfo_t vfo, rmode_t tx_mode, RETURNFUNC(retval); } + TRACE; if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_MODE) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); @@ -5343,6 +5353,7 @@ int icom_get_split_mode(RIG *rig, vfo_t vfo, rmode_t *tx_mode, RETURNFUNC(retval); } + TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); @@ -5493,6 +5504,7 @@ int icom_set_split_freq_mode(RIG *rig, vfo_t vfo, freq_t tx_freq, __func__, rig_strvfo(tx_vfo)); } + TRACE; if (!(rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ) && RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); @@ -5618,6 +5630,7 @@ int icom_get_split_freq_mode(RIG *rig, vfo_t vfo, freq_t *tx_freq, RETURNFUNC(retval); } + TRACE; if (RIG_OK != (retval = rig_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); @@ -5665,17 +5678,18 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) unsigned char ackbuf[MAXFRAMELEN]; int ack_len = sizeof(ackbuf), retval; int split_sc; - vfo_t vfo_final = RIG_VFO_NONE; // where does the VFO end up? + //vfo_t vfo_final = RIG_VFO_NONE; // where does the VFO end up? + /* For Icom which VFO is active for this call is not important + * S VFOA 1 VFOB -- RX on VFOA, TX on VFOB + * S VFOB 1 VFOA -- RX on VFOB, TX on VFOA + * S Main 1 Sub -- RX on Main, TX on Sub + * S Sub 1 Main -- RX on Sub, TX on Main + */ rig_debug(RIG_DEBUG_VERBOSE, "%s called vfo='%s', split=%d, tx_vfo=%s, curr_vfo=%s\n", __func__, rig_strvfo(vfo), split, rig_strvfo(tx_vfo), rig_strvfo(rig->state.current_vfo)); - if (vfo == RIG_VFO_CURR) - { - vfo = rig->state.current_vfo; - } - // This should automatically switch between satmode on/off based on the requested split vfo if (rig->caps->has_get_func & RIG_FUNC_SATMODE) { @@ -5748,34 +5762,37 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) case RIG_SPLIT_ON: split_sc = S_SPLT_ON; - + rig_debug(RIG_DEBUG_TRACE, "trace %s(%d)\n", __func__, __LINE__); + // the VFO adjusting here could probably be done in rig.c for all rigs /* If asking for Sub or Main on rig that doesn't have it map it */ if (VFO_HAS_A_B_ONLY && ((tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB) || vfo == RIG_VFO_MAIN || vfo == RIG_VFO_SUB)) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 1\n", __func__); - if (tx_vfo == RIG_VFO_MAIN) { tx_vfo = RIG_VFO_A; } - else if (tx_vfo == RIG_VFO_SUB) { tx_vfo = RIG_VFO_B; } - - if (vfo == RIG_VFO_MAIN) { vfo = RIG_VFO_A; } - else if (vfo == RIG_VFO_SUB) { vfo = RIG_VFO_B; } + if (tx_vfo == RIG_VFO_MAIN) { tx_vfo = RIG_VFO_A; vfo = RIG_VFO_B; } + else if (tx_vfo == RIG_VFO_SUB) { tx_vfo = RIG_VFO_B; vfo = RIG_VFO_A; } priv->tx_vfo = tx_vfo; - //vfo_final = RIG_VFO_A; // do we need to switch back at all? + priv->rx_vfo = vfo; } /* ensure VFO A is Rx and VFO B is Tx as we assume that elsewhere */ - if (VFO_HAS_A_B && (tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B)) + else if (VFO_HAS_A_B && (tx_vfo == RIG_VFO_A || tx_vfo == RIG_VFO_B)) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo clause 2\n", __func__); rig_debug(RIG_DEBUG_TRACE, "%s: rx_vfo to VFO_A, tx_vfo to VFO_B because tx_vfo=%s\n", __func__, rig_strvfo(tx_vfo)); + if (tx_vfo == RIG_VFO_B) { priv->tx_vfo = RIG_VFO_B; - priv->rx_vfo = RIG_VFO_A; - vfo_final = RIG_VFO_A; + priv->rx_vfo = vfo = RIG_VFO_A; + } + else { + priv->tx_vfo = RIG_VFO_A; + priv->rx_vfo = vfo = RIG_VFO_B; + } } else if (VFO_HAS_MAIN_SUB_A_B_ONLY && (tx_vfo == RIG_VFO_MAIN || tx_vfo == RIG_VFO_SUB)) @@ -5793,11 +5810,13 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) #if 0 // is this needed for satmode? // make sure we're on Main/VFOA + TRACE; if (RIG_OK != (retval = icom_set_vfo(rig, RIG_VFO_MAIN))) { RETURNFUNC(retval); } + TRACE; if (RIG_OK != (retval = icom_set_vfo(rig, RIG_VFO_A))) { RETURNFUNC(retval); @@ -5813,6 +5832,7 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) #if 0 // do we need this for satmode? + TRACE; if (RIG_OK != (retval = icom_set_vfo(rig, tx_vfo))) { RETURNFUNC(retval); @@ -5862,10 +5882,12 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) priv->split_on = RIG_SPLIT_ON == split; +#if 0 // don't think we need this anymore -- 20210731 if (vfo_final != RIG_VFO_NONE && vfo_final != rig->state.current_vfo) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo_final set %s\n", __func__, rig_strvfo(vfo_final)); + TRACE; retval = rig_set_vfo(rig, vfo_final); if (retval != RIG_OK) @@ -5874,6 +5896,7 @@ int icom_set_split_vfo(RIG *rig, vfo_t vfo, split_t split, vfo_t tx_vfo) rigerror(retval)); } } +#endif rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s curr_vfo=%s rx_vfo=%s tx_vfo=%s split=%d\n", @@ -7722,7 +7745,9 @@ int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) scan_sc = S_SCAN_STOP; break; - case RIG_SCAN_MEM: retval = rig_set_vfo(rig, RIG_VFO_MEM); + case RIG_SCAN_MEM: + TRACE; + retval = rig_set_vfo(rig, RIG_VFO_MEM); if (retval != RIG_OK) { @@ -7745,6 +7770,7 @@ int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) break; case RIG_SCAN_SLCT: + TRACE; retval = rig_set_vfo(rig, RIG_VFO_MEM); if (retval != RIG_OK) @@ -7766,6 +7792,7 @@ int icom_scan(RIG *rig, vfo_t vfo, scan_t scan, int ch) RETURNFUNC(retval); } + TRACE; retval = rig_set_vfo(rig, RIG_VFO_VFO); if (retval != RIG_OK) diff --git a/rigs/icom/icom.h b/rigs/icom/icom.h index ceeff632e..11dbcd23a 100644 --- a/rigs/icom/icom.h +++ b/rigs/icom/icom.h @@ -30,7 +30,7 @@ #include #endif -#define BACKEND_VER "20210715" +#define BACKEND_VER "20210801" #define ICOM_IS_SECONDARY_VFO(vfo) ((vfo) & (RIG_VFO_B | RIG_VFO_SUB | RIG_VFO_SUB_B | RIG_VFO_MAIN_B)) #define ICOM_GET_VFO_NUMBER(vfo) (ICOM_IS_SECONDARY_VFO(vfo) ? 0x01 : 0x00) diff --git a/src/misc.c b/src/misc.c index b1b95ec5e..7f979c305 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1724,7 +1724,7 @@ int HAMLIB_API rig_set_cache_timeout_ms(RIG *rig, hamlib_cache_t selection, // we're mappping our VFO here to work with either VFO A/B rigs or Main/Sub // Hamlib uses VFO_A and VFO_B as TX/RX as of 2021-04-13 // So we map these to Main/Sub as required -vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo) +vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo, split_t split) { rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, vfo_curr=%s\n", __func__, rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo)); @@ -1746,6 +1746,7 @@ vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo) else if (vfo == RIG_VFO_TX) { +#if 0 int retval; split_t split = 0; // get split if we can -- it will default to off otherwise @@ -1759,6 +1760,7 @@ vfo_t HAMLIB_API vfo_fixup(RIG *rig, vfo_t vfo) { split = rig->state.cache.split; } +#endif int satmode = rig->state.cache.satmode; diff --git a/src/misc.h b/src/misc.h index 367c75603..4b8f5fc40 100644 --- a/src/misc.h +++ b/src/misc.h @@ -106,7 +106,7 @@ extern HAMLIB_EXPORT(int) hl_usleep(rig_useconds_t usec); extern HAMLIB_EXPORT(double) elapsed_ms(struct timespec *start, int start_flag); -extern HAMLIB_EXPORT(vfo_t) vfo_fixup(RIG *rig, vfo_t vfo); +extern HAMLIB_EXPORT(vfo_t) vfo_fixup(RIG *rig, vfo_t vfo, split_t split); extern HAMLIB_EXPORT(int) parse_hoststr(char *host, char hoststr[256], char port[6]); diff --git a/src/network.c b/src/network.c index 2ab22561e..ee86eca92 100644 --- a/src/network.c +++ b/src/network.c @@ -405,17 +405,132 @@ int network_close(hamlib_port_t *rp) volatile int multicast_server_run = 1; pthread_t multicast_server_threadId; +extern void sync_callback(int lock); + +struct multicast_server_args_s +{ + RIG *rig; +} multicast_server_args; //! @cond Doxygen_Suppress // our multicast server loop -static void *multicast_server(void *arg) +void *multicast_server(void *arg) { - rig_debug(RIG_DEBUG_TRACE, "%s(%d): Starting multicast server\n", __FILE__, __LINE__); - do { - rig_debug(RIG_DEBUG_TRACE, "%s(%d): Multicast server poll\n", __FILE__, __LINE__); - hl_usleep(1000*1000); - } while(multicast_server_run); - rig_debug(RIG_DEBUG_TRACE, "%s(%d): Stopping multicast server\n", __FILE__, __LINE__); + struct multicast_server_args_s *args = (struct multicast_server_args_s *)arg; + RIG *rig = args->rig; + rig_debug(RIG_DEBUG_TRACE, "%s(%d): Starting multicast server\n", __FILE__, + __LINE__); + // we can and should use a really small cache time while we are polling + // rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, 100); + + // this is really verbose since it runs very quickly + // so we only spit out WARN unless CACHE has been selected + //if (!rig_need_debug(RIG_DEBUG_CACHE)) { rig_set_debug(RIG_DEBUG_WARN); } + + + freq_t freqMain = 0, freqSub = 0, freqMainLast = 0, freqSubLast = 0; + rmode_t modeMain = RIG_MODE_NONE, modeSub = RIG_MODE_NONE, + modeMainLast = RIG_MODE_NONE, modeSubLast = RIG_MODE_NONE; + pbwidth_t widthMain = 0, widthSub = 0, widthMainLast = 0, widthSubLast = 0; + split_t split, splitLast = -1; + + do + { + int retval; + int updateOccurred; + + updateOccurred = 0; + + if (rig->caps->get_freq) + { + sync_callback(1); + retval = rig_get_freq(rig, RIG_VFO_A, &freqMain); + sync_callback(0); + + if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): rig_get_freqA error %s\n", __FILE__, __LINE__, rigerror(retval)); } + + sync_callback(1); + retval = rig_get_freq(rig, RIG_VFO_B, &freqSub); + sync_callback(0); + + if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): rig_get_freqB error %s\n", __FILE__, __LINE__, rigerror(retval)); } + + if (freqMain != freqMainLast || freqSub != freqSubLast) + { + rig_debug(RIG_DEBUG_WARN, + "%s(%d) freqMain=%.0f was %.0f, freqSub=%.0f was %.0f\n", __FILE__, __LINE__, + freqMain, freqMainLast, freqSub, freqSubLast); + updateOccurred = 1; + freqMainLast = freqMain; + freqSubLast = freqSub; + } + } + + if (rig->caps->get_mode) + { + sync_callback(1); + retval = rig_get_mode(rig, RIG_VFO_A, &modeMain, &widthMain); + sync_callback(0); + + if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): rig_get_modeA error %s\n", __FILE__, __LINE__, rigerror(retval)); } + + sync_callback(1); + retval = rig_get_mode(rig, RIG_VFO_B, &modeSub, &widthSub); + sync_callback(0); + + if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): rig_get_modeB error %s\n", __FILE__, __LINE__, rigerror(retval)); } + + if (modeMain != modeMainLast || modeSub != modeSubLast) + { + rig_debug(RIG_DEBUG_TRACE, "%s(%d) modeMain=%s was %s, modeSub=%s was %s\n", + __FILE__, __LINE__, rig_strrmode(modeMain), rig_strrmode(modeMainLast), + rig_strrmode(modeSub), rig_strrmode(modeSubLast)); + updateOccurred = 1; + modeMainLast = modeMain; + modeSubLast = modeSub; + } + + if (widthMain != widthMainLast || widthSub != widthSubLast) + { + rig_debug(RIG_DEBUG_WARN, + "%s(%d) widthMain=%ld was %ld, widthSub=%ld was %ld\n", __FILE__, __LINE__, + widthMain, widthMainLast, widthSub, widthSubLast); + updateOccurred = 1; + widthMainLast = widthMain; + widthSubLast = widthSub; + } + } + + if (rig->caps->get_split_vfo) + { + vfo_t tx_vfo; + sync_callback(1); + retval = rig_get_split_vfo(rig, RIG_VFO_A, &split, &tx_vfo); + sync_callback(0); + + if (retval != RIG_OK) { rig_debug(RIG_DEBUG_ERR, "%s(%d): rig_get_modeA error %s\n", __FILE__, __LINE__, rigerror(retval)); } + + if (split != splitLast) + { + rig_debug(RIG_DEBUG_WARN, "%s(%d) split=%d was %d\n", __FILE__, __LINE__, split, + splitLast); + updateOccurred = 1; + splitLast = split; + } + } + + if (updateOccurred) + { + rig_debug(RIG_DEBUG_WARN, "%s(%d): update occurred...time to send multicast\n", + __FILE__, __LINE__); + } + + hl_usleep(100 * 1000); + } + while (multicast_server_run); + + rig_debug(RIG_DEBUG_TRACE, "%s(%d): Stopping multicast server\n", __FILE__, + __LINE__); return NULL; } //! @endcond @@ -430,34 +545,58 @@ static void *multicast_server(void *arg) * \param default_port Default network socket port * \return RIG_OK or < 0 if error */ -int network_multicast_server(RIG *rig, const char *multicast_addr, int default_port, enum multicast_item_e items) +int network_multicast_server(RIG *rig, const char *multicast_addr, + int default_port, enum multicast_item_e items) { int status; - ENTERFUNC; - rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):network_multicast_server under development\n", __FILE__, __LINE__); - rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):ADDR=%s, port=%d\n", __FILE__, __LINE__, multicast_addr, default_port); + //ENTERFUNC; + rig_debug(RIG_DEBUG_VERBOSE, + "%s(%d):network_multicast_server under development\n", __FILE__, __LINE__); + rig_debug(RIG_DEBUG_VERBOSE, "%s(%d):ADDR=%s, port=%d\n", __FILE__, __LINE__, + multicast_addr, default_port); + + if (strcmp(multicast_addr,"0.0.0.0")==0) + { + rig_debug(RIG_DEBUG_TRACE, "%s(%d): not starting multicast\n", __FILE__, __LINE__); + return RIG_OK; // don't start it + } + + if (multicast_server_threadId != 0) + { + rig_debug(RIG_DEBUG_ERR, "%s(%d): multicast_server already running\n", __FILE__, + __LINE__); + } + status = network_init(); if (status != RIG_OK) { RETURNFUNC(status); } if (items && RIG_MULTICAST_TRANSCEIVE) { - rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_TRANSCEIVE enabled\n", __FILE__, __LINE__); + rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_TRANSCEIVE enabled\n", __FILE__, + __LINE__); } + if (items && RIG_MULTICAST_SPECTRUM) { - rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_SPECTRUM enabled\n", __FILE__, __LINE__); + rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_SPECTRUM enabled\n", __FILE__, + __LINE__); } else { - rig_debug(RIG_DEBUG_ERR, "%s(%d) unknown MULTICAST item requested=0x%x\n", __FILE__, __LINE__, items); + rig_debug(RIG_DEBUG_ERR, "%s(%d) unknown MULTICAST item requested=0x%x\n", + __FILE__, __LINE__, items); } - int err = pthread_create(&multicast_server_threadId, NULL, multicast_server, NULL); + multicast_server_args.rig = rig; + int err = pthread_create(&multicast_server_threadId, NULL, multicast_server, + &multicast_server_args); + if (err) { - rig_debug(RIG_DEBUG_ERR, "%s(%d) pthread_create error %s\n", __FILE__, __LINE__, strerror(errno)); + rig_debug(RIG_DEBUG_ERR, "%s(%d) pthread_create error %s\n", __FILE__, __LINE__, + strerror(errno)); return -RIG_EINTERNAL; } diff --git a/src/rig.c b/src/rig.c index 92087699c..c4d5da700 100644 --- a/src/rig.c +++ b/src/rig.c @@ -198,8 +198,6 @@ static const char *rigerror_table[] = #define ERROR_TBL_SZ (sizeof(rigerror_table)/sizeof(char *)) -#define TRACE rig_debug(RIG_DEBUG_TRACE,"%s(%d) trace\n", __FILE__, __LINE__) - /* * track which rig is opened (with rig_open) * needed at least for transceive mode @@ -1052,7 +1050,7 @@ int HAMLIB_API rig_open(RIG *rig) else if (rig->caps->set_vfo == NULL) { // for non-Icom rigs if there's no set_vfo then we need to set one - rs->current_vfo = vfo_fixup(rig, RIG_VFO_A); + rs->current_vfo = vfo_fixup(rig, RIG_VFO_A, rig->state.cache.split); rig_debug(RIG_DEBUG_TRACE, "%s: No set_vfo function rig so default vfo = %s\n", __func__, rig_strvfo(rs->current_vfo)); } @@ -1805,7 +1803,7 @@ int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq) } vfo_save = rig->state.current_vfo; - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); if ((caps->targetable_vfo & RIG_TARGETABLE_FREQ) || vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) @@ -1989,7 +1987,7 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) curr_vfo = rig->state.current_vfo; // save vfo for restore later - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) vfo=%s, curr_vfo=%s\n", __FILE__, __LINE__, rig_strvfo(vfo), rig_strvfo(curr_vfo)); @@ -2076,7 +2074,7 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq) // If rig does not have set_vfo we need to change vfo if (vfo == RIG_VFO_CURR && caps->set_vfo == NULL) { - vfo = vfo_fixup(rig, RIG_VFO_A); + vfo = vfo_fixup(rig, RIG_VFO_A, rig->state.cache.split); rig_debug(RIG_DEBUG_TRACE, "%s: no set_vfo so vfo=%s\n", __func__, rig_strvfo(vfo)); } @@ -2609,10 +2607,11 @@ int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo) RETURNFUNC(-RIG_EIO); } - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); if (vfo == RIG_VFO_CURR) { RETURNFUNC(RIG_OK); } +#if 0 // removing this check 20210801 -- should be mapped already // make sure we are asking for a VFO that the rig actually has if ((vfo == RIG_VFO_A || vfo == RIG_VFO_B) && !VFO_HAS_A_B) { @@ -2627,8 +2626,9 @@ int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo) rig_strvfo(vfo)); RETURNFUNC(-RIG_EINVAL); } +#endif - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); caps = rig->caps; @@ -3750,7 +3750,7 @@ int HAMLIB_API rig_set_split_freq(RIG *rig, vfo_t vfo, freq_t tx_freq) RETURNFUNC(retcode); } - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); /* Assisted mode */ @@ -3874,7 +3874,7 @@ int HAMLIB_API rig_get_split_freq(RIG *rig, vfo_t vfo, freq_t *tx_freq) RETURNFUNC(-RIG_EINVAL); } - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); caps = rig->caps; @@ -4274,9 +4274,7 @@ int HAMLIB_API rig_set_split_freq_mode(RIG *rig, caps = rig->caps; - // in split mode we alwasy use VFOB - // in the future we may start using RIG_VFO_TX and let the backend figure out what VFO to use - vfo = vfo_fixup(rig, RIG_VFO_B); // in split mode we always use VFOB/Sub for TX + vfo = vfo_fixup(rig, RIG_VFO_TX, rig->state.cache.split); // get the TX VFO rig_debug(RIG_DEBUG_VERBOSE, "%s: vfo=%s, tx_freq=%.0f, tx_mode=%s, tx_width=%d\n", __func__, rig_strvfo(vfo), tx_freq, rig_strrmode(tx_mode), (int)tx_width); @@ -4441,7 +4439,15 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig, RETURNFUNC(-RIG_ENAVAIL); } - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, split); + + if (vfo != RIG_VFO_A && vfo != RIG_VFO_B) + { + rig_debug(RIG_DEBUG_ERR, "%s: expected VFOA/B but got %s\n", __func__, rig_strvfo(vfo)); + } + // set rig to the the requested RX VFO + TRACE; + rig_set_vfo(rig, vfo == RIG_VFO_B?RIG_VFO_B:RIG_VFO_A); if (vfo == RIG_VFO_CURR || vfo == rig->state.current_vfo) @@ -6387,8 +6393,8 @@ int HAMLIB_API rig_get_rig_info(RIG *rig, char *response, int max_response_len) int rxa, txa, rxb, txb; response[0] = 0; - vfoA = vfo_fixup(rig, RIG_VFO_A); - vfoB = vfo_fixup(rig, RIG_VFO_B); + vfoA = vfo_fixup(rig, RIG_VFO_A, rig->state.cache.split); + vfoB = vfo_fixup(rig, RIG_VFO_B, rig->state.cache.split); ret = rig_get_vfo_info(rig, vfoA, &freqA, &modeA, &widthA, &split, &satmode); if (ret != RIG_OK) { RETURNFUNC(ret); } @@ -6475,7 +6481,7 @@ int HAMLIB_API rig_get_vfo_info(RIG *rig, vfo_t vfo, freq_t *freq, //if (vfo == RIG_VFO_CURR) { vfo = rig->state.current_vfo; } - vfo = vfo_fixup(rig, vfo); + vfo = vfo_fixup(rig, vfo, rig->state.cache.split); // we can't use the cached values as some clients may only call this function // like Log4OM which mostly does polling TRACE; diff --git a/tests/rigctlcom.c b/tests/rigctlcom.c index bf4eba7c4..11d516293 100644 --- a/tests/rigctlcom.c +++ b/tests/rigctlcom.c @@ -653,7 +653,7 @@ static rmode_t ts2000_get_mode() { rmode_t mode; pbwidth_t width; - rig_get_mode(my_rig, vfo_fixup(my_rig, RIG_VFO_A), &mode, &width); + rig_get_mode(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), &mode, &width); // Perhaps we should emulate a rig that has PKT modes instead?? switch (mode) @@ -740,7 +740,7 @@ static int handle_ts2000(void *arg) int p13 = 0; // P13 Tone dummy value for now int p14 = 0; // P14 Tone Freq dummy value for now int p15 = 0; // P15 Shift status dummy value for now - int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A), &freq); + int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), &freq); char response[64]; char *fmt = // cppcheck-suppress * @@ -752,7 +752,7 @@ static int handle_ts2000(void *arg) } mode = ts2000_get_mode(); - retval = rig_get_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A), &ptt); + retval = rig_get_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), &ptt); if (retval != RIG_OK) { @@ -834,7 +834,7 @@ static int handle_ts2000(void *arg) freq_t freq = 0; char response[32]; - int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A), &freq); + int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), &freq); if (retval != RIG_OK) { @@ -850,7 +850,7 @@ static int handle_ts2000(void *arg) { char response[32]; freq_t freq = 0; - int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_B), &freq); + int retval = rig_get_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split), &freq); if (retval != RIG_OK) { @@ -873,7 +873,7 @@ static int handle_ts2000(void *arg) { char response[32]; - rig_set_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A), 0); + rig_set_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), 0); snprintf(response, sizeof(response), "RX0;"); return write_block2((void *)__func__, &my_com, response, strlen(response)); } @@ -904,7 +904,7 @@ static int handle_ts2000(void *arg) } else if (strcmp(arg, "TX;") == 0) { - return rig_set_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A), 1); + return rig_set_ptt(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), 1); } else if (strcmp(arg, "AI0;") == 0) { @@ -918,11 +918,11 @@ static int handle_ts2000(void *arg) } else if (strcmp(arg, "FR0;") == 0) { - return rig_set_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_A)); + return rig_set_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split)); } else if (strcmp(arg, "FR1;") == 0) { - return rig_set_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_B)); + return rig_set_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split)); } else if (strcmp(arg, "FR;") == 0) { @@ -939,8 +939,8 @@ static int handle_ts2000(void *arg) } - if (vfo == vfo_fixup(my_rig, RIG_VFO_A)) { nvfo = 0; } - else if (vfo == vfo_fixup(my_rig, RIG_VFO_B)) { nvfo = 1; } + if (vfo == vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split)) { nvfo = 0; } + else if (vfo == vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split)) { nvfo = 1; } else { retval = -RIG_EPROTO; @@ -955,7 +955,7 @@ static int handle_ts2000(void *arg) else if (strcmp(arg, "FT;") == 0) { char response[32]; - vfo_t vfo, vfo_curr = vfo_fixup(my_rig, RIG_VFO_A); + vfo_t vfo, vfo_curr = vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split); split_t split; int nvfo = 0; int retval = rig_get_split_vfo(my_rig, vfo_curr, &split, &vfo); @@ -968,8 +968,8 @@ static int handle_ts2000(void *arg) } - if (vfo == vfo_fixup(my_rig, RIG_VFO_A)) { nvfo = 0; } - else if (vfo == vfo_fixup(my_rig, RIG_VFO_B)) { nvfo = 1; } + if (vfo == vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split)) { nvfo = 0; } + else if (vfo == vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split)) { nvfo = 1; } else { retval = -RIG_EPROTO; @@ -1018,7 +1018,7 @@ static int handle_ts2000(void *arg) { char response[32]; int valA; - int retval = rig_get_func(my_rig, vfo_fixup(my_rig, RIG_VFO_A), RIG_FUNC_AIP, + int retval = rig_get_func(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), RIG_FUNC_AIP, &valA); int valB; @@ -1037,7 +1037,7 @@ static int handle_ts2000(void *arg) return retval; } - retval = rig_get_func(my_rig, vfo_fixup(my_rig, RIG_VFO_B), RIG_FUNC_AIP, + retval = rig_get_func(my_rig, vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split), RIG_FUNC_AIP, &valB); if (retval != RIG_OK) @@ -1063,7 +1063,7 @@ static int handle_ts2000(void *arg) (char *)arg); } - retval = rig_set_func(my_rig, vfo_fixup(my_rig, RIG_VFO_A), RIG_FUNC_AIP, valA); + retval = rig_set_func(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), RIG_FUNC_AIP, valA); if (retval != RIG_OK) { @@ -1072,7 +1072,7 @@ static int handle_ts2000(void *arg) return retval; } - retval = rig_set_func(my_rig, vfo_fixup(my_rig, RIG_VFO_B), RIG_FUNC_AIP, valB); + retval = rig_set_func(my_rig, vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split), RIG_FUNC_AIP, valB); if (retval != RIG_OK) { @@ -1437,7 +1437,7 @@ static int handle_ts2000(void *arg) } else if (strcmp(arg, "DC;") == 0) { - vfo_t vfo, vfo_curr = vfo_fixup(my_rig, RIG_VFO_A); + vfo_t vfo, vfo_curr = vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split); split_t split; char response[32]; int retval = rig_get_split_vfo(my_rig, vfo_curr, &split, &vfo); @@ -1456,7 +1456,7 @@ static int handle_ts2000(void *arg) } else if (strncmp(arg, "DC", 2) == 0) { - vfo_t vfo_curr = vfo_fixup(my_rig, RIG_VFO_A); + vfo_t vfo_curr = vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split); split_t split; int isplit; int retval; @@ -1487,27 +1487,27 @@ static int handle_ts2000(void *arg) } else if (strcmp(arg, "FT0;") == 0) { - return rig_set_split_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_A), vfo_fixup(my_rig, - RIG_VFO_A), 0); + return rig_set_split_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), vfo_fixup(my_rig, + RIG_VFO_A, my_rig->state.cache.split), 0); } else if (strcmp(arg, "FT1;") == 0) { - return rig_set_split_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_B), vfo_fixup(my_rig, - RIG_VFO_B), 0); + return rig_set_split_vfo(my_rig, vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split), vfo_fixup(my_rig, + RIG_VFO_B, my_rig->state.cache.split), 0); } else if (strncmp(arg, "FA0", 3) == 0) { freq_t freq; sscanf((char *)arg + 2, "%"SCNfreq, &freq); - return rig_set_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A), freq); + return rig_set_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_A, my_rig->state.cache.split), freq); } else if (strncmp(arg, "FB0", 3) == 0) { freq_t freq; sscanf((char *)arg + 2, "%"SCNfreq, &freq); - return rig_set_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_B), freq); + return rig_set_freq(my_rig, vfo_fixup(my_rig, RIG_VFO_B, my_rig->state.cache.split), freq); } else if (strncmp(arg, "MD", 2) == 0) {