kopia lustrzana https://github.com/Hamlib/Hamlib
Add ability for rigctld client to turn vfo mode on/off with (,)
https://github.com/Hamlib/Hamlib/issues/232 Add caching of some limited rig information Can be adjusted or turned off with rig_cache_set_timeout_ms or in rigctl with \set_cache_timeout https://github.com/Hamlib/Hamlib/issues/228pull/234/head
rodzic
2991d43e26
commit
9e710156e3
2
NEWS
2
NEWS
|
@ -22,6 +22,8 @@ Version 4.0
|
||||||
under their own subdirectories. Mike, W9MDB
|
under their own subdirectories. Mike, W9MDB
|
||||||
* rig_get_channel changed to add read_only flag
|
* rig_get_channel changed to add read_only flag
|
||||||
* rigctl(d) f command also returns VFO now
|
* rigctl(d) f command also returns VFO now
|
||||||
|
* caching of vfo, frequency, mode, and ptt speeds up rigctld for all
|
||||||
|
* caching of kenwood/yaesu "IF" speeds up polling from WSJTX/JTDX
|
||||||
|
|
||||||
Version 3.3
|
Version 3.3
|
||||||
2018-08-12
|
2018-08-12
|
||||||
|
|
|
@ -1854,6 +1854,41 @@ typedef struct hamlib_port {
|
||||||
typedef hamlib_port_t port_t;
|
typedef hamlib_port_t port_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ELAPSED_GET 0
|
||||||
|
#define ELAPSED_SET 1
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CACHE_ALL, // to set all cache timeouts at once
|
||||||
|
CACHE_VFO,
|
||||||
|
CACHE_FREQ,
|
||||||
|
CACHE_MODE,
|
||||||
|
CACHE_PTT,
|
||||||
|
CACHE_SPLIT
|
||||||
|
} cache_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Rig cache data
|
||||||
|
*
|
||||||
|
* This struct contains all the items we cache at the highest level
|
||||||
|
*/
|
||||||
|
struct rig_cache {
|
||||||
|
int timeout_ms; // the cache timeout for invalidating itself
|
||||||
|
vfo_t vfo;
|
||||||
|
freq_t freq;
|
||||||
|
rmode_t mode;
|
||||||
|
pbwidth_t width;
|
||||||
|
ptt_t ptt;
|
||||||
|
split_t split;
|
||||||
|
vfo_t split_vfo; // split caches two values
|
||||||
|
struct timespec time_freq;
|
||||||
|
struct timespec time_vfo;
|
||||||
|
struct timespec time_mode;
|
||||||
|
struct timespec time_ptt;
|
||||||
|
struct timespec time_split;
|
||||||
|
vfo_t vfo_freq; // last vfo cached
|
||||||
|
vfo_t vfo_mode; // last vfo cached
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Rig state containing live data and customized fields.
|
* \brief Rig state containing live data and customized fields.
|
||||||
|
@ -1930,6 +1965,7 @@ struct rig_state {
|
||||||
freq_t lo_freq; /*!< Local oscillator frequency of any transverter */
|
freq_t lo_freq; /*!< Local oscillator frequency of any transverter */
|
||||||
time_t twiddle_time; /*!< time when vfo twiddling was detected */
|
time_t twiddle_time; /*!< time when vfo twiddling was detected */
|
||||||
int twiddle_timeout; /*!< timeout to resume from twiddling */
|
int twiddle_timeout; /*!< timeout to resume from twiddling */
|
||||||
|
struct rig_cache cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! @cond Doxygen_Suppress
|
//! @cond Doxygen_Suppress
|
||||||
|
@ -2638,6 +2674,9 @@ extern HAMLIB_EXPORT(const char *) rig_copyright HAMLIB_PARAMS(());
|
||||||
|
|
||||||
extern HAMLIB_EXPORT(void) rig_no_restore_ai();
|
extern HAMLIB_EXPORT(void) rig_no_restore_ai();
|
||||||
|
|
||||||
|
extern HAMLIB_EXPORT(int) rig_get_cache_timeout_ms(RIG *rig, cache_t selection);
|
||||||
|
extern HAMLIB_EXPORT(int) rig_set_cache_timeout_ms(RIG *rig, cache_t selection, int ms);
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
extern HAMLIB_EXPORT(int) hl_usleep(useconds_t msec);
|
extern HAMLIB_EXPORT(int) hl_usleep(useconds_t msec);
|
||||||
|
|
||||||
|
|
16
src/conf.c
16
src/conf.c
|
@ -123,6 +123,11 @@ static const struct confparams frontend_cfg_params[] =
|
||||||
"Frequency to add to the VFO frequency for use with a transverter",
|
"Frequency to add to the VFO frequency for use with a transverter",
|
||||||
"0", RIG_CONF_NUMERIC, { .n = {0.0, 1e9, .1}}
|
"0", RIG_CONF_NUMERIC, { .n = {0.0, 1e9, .1}}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
TOK_CACHE_TIMEOUT, "cache_timeout", "Cache timeout value in ms",
|
||||||
|
"Cache timeout, value of 0 disables caching",
|
||||||
|
"500", RIG_CONF_NUMERIC, { .n = {0, 5000, 1}}
|
||||||
|
},
|
||||||
|
|
||||||
{ RIG_CONF_END, NULL, }
|
{ RIG_CONF_END, NULL, }
|
||||||
};
|
};
|
||||||
|
@ -543,6 +548,9 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val)
|
||||||
rs->lo_freq = atof(val);
|
rs->lo_freq = atof(val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_CACHE_TIMEOUT:
|
||||||
|
rig_set_cache_timeout_ms(rig,CACHE_ALL,atol(val));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -RIG_EINVAL;
|
return -RIG_EINVAL;
|
||||||
|
@ -848,6 +856,14 @@ static int frontend_get_conf(RIG *rig, token_t token, char *val)
|
||||||
strcpy(val, rs->dcdport.pathname);
|
strcpy(val, rs->dcdport.pathname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TOK_LO_FREQ:
|
||||||
|
sprintf(val,"%g", rs->lo_freq);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TOK_CACHE_TIMEOUT:
|
||||||
|
sprintf(val,"%d", rig_get_cache_timeout_ms(rig, CACHE_ALL));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -RIG_EINVAL;
|
return -RIG_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
20
src/misc.c
20
src/misc.c
|
@ -1260,6 +1260,9 @@ int HAMLIB_API elapsed_ms(struct timespec *start, int flag_start)
|
||||||
struct timespec stop;
|
struct timespec stop;
|
||||||
double elapsed_secs;
|
double elapsed_secs;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: start = %ld,%ld\n",__func__,start->tv_sec,start->tv_nsec);
|
||||||
|
if (!flag_start && start->tv_nsec == 0) return 1000000;
|
||||||
|
|
||||||
if (flag_start)
|
if (flag_start)
|
||||||
{
|
{
|
||||||
clock_gettime(CLOCK_REALTIME, start);
|
clock_gettime(CLOCK_REALTIME, start);
|
||||||
|
@ -1272,9 +1275,26 @@ int HAMLIB_API elapsed_ms(struct timespec *start, int flag_start)
|
||||||
|
|
||||||
elapsed_secs = (stop.tv_sec - start->tv_sec) * 1e6 + (stop.tv_nsec -
|
elapsed_secs = (stop.tv_sec - start->tv_sec) * 1e6 + (stop.tv_nsec -
|
||||||
start->tv_nsec) / 1e3;
|
start->tv_nsec) / 1e3;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: elapse_secs=%g\n",__func__,elapsed_secs);
|
||||||
|
if (elapsed_secs < 0) return 1000000;
|
||||||
|
|
||||||
return elapsed_secs / 1000;
|
return elapsed_secs / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int HAMLIB_API rig_get_cache_timeout_ms(RIG *rig, cache_t selection)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called selection=%d\n", __func__, selection);
|
||||||
|
return rig->state.cache.timeout_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HAMLIB_API rig_set_cache_timeout_ms(RIG *rig, cache_t selection, int ms)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: called selection=%d, ms=%d\n", __func__, selection, ms);
|
||||||
|
rig->state.cache.timeout_ms = ms;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
//! @endcond
|
//! @endcond
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
140
src/rig.c
140
src/rig.c
|
@ -70,6 +70,7 @@
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "cm108.h"
|
#include "cm108.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Hamlib release number
|
* \brief Hamlib release number
|
||||||
|
@ -410,6 +411,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
|
||||||
rs->transceive = RIG_TRN_OFF;
|
rs->transceive = RIG_TRN_OFF;
|
||||||
rs->poll_interval = 500;
|
rs->poll_interval = 500;
|
||||||
rs->lo_freq = 0;
|
rs->lo_freq = 0;
|
||||||
|
rs->cache.timeout_ms = 500; // 500ms cache timeout by default
|
||||||
|
|
||||||
// We are using range_list1 as the default
|
// We are using range_list1 as the default
|
||||||
// Eventually we will have separate model number for different rig variations
|
// Eventually we will have separate model number for different rig variations
|
||||||
|
@ -1293,6 +1295,10 @@ int HAMLIB_API rig_set_freq(RIG *rig, vfo_t vfo, freq_t freq)
|
||||||
rig->state.current_freq = freq;
|
rig->state.current_freq = freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
|
rig->state.cache.freq = freq;
|
||||||
|
rig->state.cache.vfo_freq = vfo;
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1317,14 +1323,30 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
||||||
{
|
{
|
||||||
const struct rig_caps *caps;
|
const struct rig_caps *caps;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
int cache_ms;
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
if (CHECK_RIG_ARG(rig) || !freq)
|
if (CHECK_RIG_ARG(rig) || !freq)
|
||||||
{
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: rig or freq ptr invalid\n", __func__);
|
||||||
return -RIG_EINVAL;
|
return -RIG_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache_ms = elapsed_ms(&rig->state.cache.time_freq, ELAPSED_GET);
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms);
|
||||||
|
|
||||||
|
if (cache_ms < rig->state.cache.timeout_ms && rig->state.cache.vfo_freq == vfo)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms\n", __func__, cache_ms);
|
||||||
|
*freq = rig->state.cache.freq;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms);
|
||||||
|
}
|
||||||
|
|
||||||
caps = rig->caps;
|
caps = rig->caps;
|
||||||
|
|
||||||
if (caps->get_freq == NULL)
|
if (caps->get_freq == NULL)
|
||||||
|
@ -1383,6 +1405,12 @@ int HAMLIB_API rig_get_freq(RIG *rig, vfo_t vfo, freq_t *freq)
|
||||||
*freq += rig->state.lo_freq;
|
*freq += rig->state.lo_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cache_ms = elapsed_ms(&(rig->state.cache.time_freq), ELAPSED_SET);
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache reset age=%dms\n", __func__, cache_ms);
|
||||||
|
rig->state.cache.freq = *freq;
|
||||||
|
rig->state.cache.vfo_freq = vfo;
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1467,6 +1495,10 @@ int HAMLIB_API rig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
|
||||||
rig->state.current_width = width;
|
rig->state.current_width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rig->state.cache.mode = mode;
|
||||||
|
rig->state.cache.vfo_mode = vfo;
|
||||||
|
elapsed_ms(&rig->state.cache.time_mode, ELAPSED_SET);
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1497,6 +1529,7 @@ int HAMLIB_API rig_get_mode(RIG *rig,
|
||||||
{
|
{
|
||||||
const struct rig_caps *caps;
|
const struct rig_caps *caps;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
int cache_ms;
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
@ -1512,6 +1545,21 @@ int HAMLIB_API rig_get_mode(RIG *rig,
|
||||||
return -RIG_ENAVAIL;
|
return -RIG_ENAVAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache_ms = elapsed_ms(&rig->state.cache.time_mode, ELAPSED_GET);
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms);
|
||||||
|
|
||||||
|
if (cache_ms < rig->state.cache.timeout_ms && rig->state.cache.vfo_mode == vfo)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms\n", __func__, cache_ms);
|
||||||
|
*mode = rig->state.cache.mode;
|
||||||
|
*width = rig->state.cache.width;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms);
|
||||||
|
}
|
||||||
|
|
||||||
if ((caps->targetable_vfo & RIG_TARGETABLE_MODE)
|
if ((caps->targetable_vfo & RIG_TARGETABLE_MODE)
|
||||||
|| vfo == RIG_VFO_CURR
|
|| vfo == RIG_VFO_CURR
|
||||||
|| vfo == rig->state.current_vfo)
|
|| vfo == rig->state.current_vfo)
|
||||||
|
@ -1559,6 +1607,11 @@ int HAMLIB_API rig_get_mode(RIG *rig,
|
||||||
*width = rig_passband_normal(rig, *mode);
|
*width = rig_passband_normal(rig, *mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rig->state.cache.mode = *mode;
|
||||||
|
rig->state.cache.width = *width;
|
||||||
|
rig->state.cache.vfo_mode = vfo;
|
||||||
|
cache_ms = elapsed_ms(&rig->state.cache.time_mode, ELAPSED_SET);
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1757,6 +1810,12 @@ int HAMLIB_API rig_set_vfo(RIG *rig, vfo_t vfo)
|
||||||
// we need to update our internal freq to avoid getting detected as twiddling
|
// we need to update our internal freq to avoid getting detected as twiddling
|
||||||
if (caps->get_freq) { retcode = rig_get_freq(rig, RIG_VFO_CURR, &curr_freq); }
|
if (caps->get_freq) { retcode = rig_get_freq(rig, RIG_VFO_CURR, &curr_freq); }
|
||||||
|
|
||||||
|
rig->state.cache.vfo = vfo;
|
||||||
|
// expire several cached items when we switch VFOs
|
||||||
|
elapsed_ms(&rig->state.cache.time_vfo, ELAPSED_SET);
|
||||||
|
elapsed_ms(&rig->state.cache.time_freq, ELAPSED_SET);
|
||||||
|
elapsed_ms(&rig->state.cache.time_mode, ELAPSED_SET);
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1780,6 +1839,7 @@ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo)
|
||||||
{
|
{
|
||||||
const struct rig_caps *caps;
|
const struct rig_caps *caps;
|
||||||
int retcode;
|
int retcode;
|
||||||
|
int cache_ms;
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
@ -1795,6 +1855,20 @@ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo)
|
||||||
return -RIG_ENAVAIL;
|
return -RIG_ENAVAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache_ms = elapsed_ms(&rig->state.cache.time_vfo, ELAPSED_GET);
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms);
|
||||||
|
|
||||||
|
if (cache_ms < rig->state.cache.timeout_ms)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms\n", __func__, cache_ms);
|
||||||
|
*vfo = rig->state.cache.vfo;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms);
|
||||||
|
}
|
||||||
|
|
||||||
retcode = caps->get_vfo(rig, vfo);
|
retcode = caps->get_vfo(rig, vfo);
|
||||||
|
|
||||||
if (retcode == RIG_OK)
|
if (retcode == RIG_OK)
|
||||||
|
@ -1802,6 +1876,8 @@ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo)
|
||||||
rig->state.current_vfo = *vfo;
|
rig->state.current_vfo = *vfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rig->state.cache.vfo = *vfo;
|
||||||
|
cache_ms = elapsed_ms(&rig->state.cache.time_vfo, ELAPSED_SET);
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1998,6 +2074,8 @@ int HAMLIB_API rig_set_ptt(RIG *rig, vfo_t vfo, ptt_t ptt)
|
||||||
rs->transmit = ptt != RIG_PTT_OFF;
|
rs->transmit = ptt != RIG_PTT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rig->state.cache.ptt = ptt;
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2023,6 +2101,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
int retcode = RIG_OK;
|
int retcode = RIG_OK;
|
||||||
int rc2, status;
|
int rc2, status;
|
||||||
vfo_t curr_vfo;
|
vfo_t curr_vfo;
|
||||||
|
int cache_ms;
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
@ -2031,6 +2110,20 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
return -RIG_EINVAL;
|
return -RIG_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache_ms = elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_GET);
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms);
|
||||||
|
|
||||||
|
if (cache_ms < rig->state.cache.timeout_ms)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms\n", __func__, cache_ms);
|
||||||
|
*ptt = rig->state.cache.ptt;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms);
|
||||||
|
}
|
||||||
|
|
||||||
caps = rig->caps;
|
caps = rig->caps;
|
||||||
|
|
||||||
switch (rig->state.pttport.type.ptt)
|
switch (rig->state.pttport.type.ptt)
|
||||||
|
@ -2048,6 +2141,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
|| vfo == rig->state.current_vfo)
|
|| vfo == rig->state.current_vfo)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return caps->get_ptt(rig, vfo, ptt);
|
return caps->get_ptt(rig, vfo, ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2072,6 +2166,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
{
|
{
|
||||||
/* return the first error code */
|
/* return the first error code */
|
||||||
retcode = rc2;
|
retcode = rc2;
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
|
@ -2079,6 +2174,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
case RIG_PTT_SERIAL_RTS:
|
case RIG_PTT_SERIAL_RTS:
|
||||||
if (caps->get_ptt)
|
if (caps->get_ptt)
|
||||||
{
|
{
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return caps->get_ptt(rig, vfo, ptt);
|
return caps->get_ptt(rig, vfo, ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2088,18 +2184,24 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
|
|
||||||
/* port is closed so assume PTT off */
|
/* port is closed so assume PTT off */
|
||||||
*ptt = RIG_PTT_OFF;
|
*ptt = RIG_PTT_OFF;
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
|
rig->state.cache.ptt = *ptt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retcode = ser_get_rts(&rig->state.pttport, &status);
|
retcode = ser_get_rts(&rig->state.pttport, &status);
|
||||||
*ptt = status ? RIG_PTT_ON : RIG_PTT_OFF;
|
*ptt = status ? RIG_PTT_ON : RIG_PTT_OFF;
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
|
rig->state.cache.ptt = *ptt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return retcode;
|
return retcode;
|
||||||
|
|
||||||
case RIG_PTT_SERIAL_DTR:
|
case RIG_PTT_SERIAL_DTR:
|
||||||
if (caps->get_ptt)
|
if (caps->get_ptt)
|
||||||
{
|
{
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return caps->get_ptt(rig, vfo, ptt);
|
return caps->get_ptt(rig, vfo, ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2109,38 +2211,49 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
|
|
||||||
/* port is closed so assume PTT off */
|
/* port is closed so assume PTT off */
|
||||||
*ptt = RIG_PTT_OFF;
|
*ptt = RIG_PTT_OFF;
|
||||||
|
rig->state.cache.ptt = *ptt;
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retcode = ser_get_dtr(&rig->state.pttport, &status);
|
retcode = ser_get_dtr(&rig->state.pttport, &status);
|
||||||
*ptt = status ? RIG_PTT_ON : RIG_PTT_OFF;
|
*ptt = status ? RIG_PTT_ON : RIG_PTT_OFF;
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
|
rig->state.cache.ptt = *ptt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return retcode;
|
return retcode;
|
||||||
|
|
||||||
case RIG_PTT_PARALLEL:
|
case RIG_PTT_PARALLEL:
|
||||||
if (caps->get_ptt)
|
if (caps->get_ptt)
|
||||||
{
|
{
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return caps->get_ptt(rig, vfo, ptt);
|
return caps->get_ptt(rig, vfo, ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return par_ptt_get(&rig->state.pttport, ptt);
|
return par_ptt_get(&rig->state.pttport, ptt);
|
||||||
|
|
||||||
case RIG_PTT_CM108:
|
case RIG_PTT_CM108:
|
||||||
if (caps->get_ptt)
|
if (caps->get_ptt)
|
||||||
{
|
{
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return caps->get_ptt(rig, vfo, ptt);
|
return caps->get_ptt(rig, vfo, ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return cm108_ptt_get(&rig->state.pttport, ptt);
|
return cm108_ptt_get(&rig->state.pttport, ptt);
|
||||||
|
|
||||||
case RIG_PTT_GPIO:
|
case RIG_PTT_GPIO:
|
||||||
case RIG_PTT_GPION:
|
case RIG_PTT_GPION:
|
||||||
if (caps->get_ptt)
|
if (caps->get_ptt)
|
||||||
{
|
{
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return caps->get_ptt(rig, vfo, ptt);
|
return caps->get_ptt(rig, vfo, ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return gpio_ptt_get(&rig->state.pttport, ptt);
|
return gpio_ptt_get(&rig->state.pttport, ptt);
|
||||||
|
|
||||||
case RIG_PTT_NONE:
|
case RIG_PTT_NONE:
|
||||||
|
@ -2150,6 +2263,7 @@ int HAMLIB_API rig_get_ptt(RIG *rig, vfo_t vfo, ptt_t *ptt)
|
||||||
return -RIG_EINVAL;
|
return -RIG_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
|
||||||
return RIG_OK;
|
return RIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3162,6 +3276,9 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
|
||||||
rig->state.tx_vfo = tx_vfo;
|
rig->state.tx_vfo = tx_vfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rig->state.cache.split = split;
|
||||||
|
rig->state.cache.split_vfo = tx_vfo;
|
||||||
|
elapsed_ms(&rig->state.cache.time_split, ELAPSED_SET);
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3189,6 +3306,7 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
||||||
const struct rig_caps *caps;
|
const struct rig_caps *caps;
|
||||||
int retcode, rc2;
|
int retcode, rc2;
|
||||||
vfo_t curr_vfo;
|
vfo_t curr_vfo;
|
||||||
|
int cache_ms;
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
|
||||||
|
|
||||||
|
@ -3204,6 +3322,21 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
||||||
return -RIG_ENAVAIL;
|
return -RIG_ENAVAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cache_ms = elapsed_ms(&rig->state.cache.time_split, ELAPSED_GET);
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache check age=%dms\n", __func__, cache_ms);
|
||||||
|
|
||||||
|
if (cache_ms < rig->state.cache.timeout_ms)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache hit age=%dms\n", __func__, cache_ms);
|
||||||
|
*split = rig->state.cache.split;
|
||||||
|
*tx_vfo = rig->state.cache.split_vfo;
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: cache miss age=%dms\n", __func__, cache_ms);
|
||||||
|
}
|
||||||
|
|
||||||
/* overidden by backend at will */
|
/* overidden by backend at will */
|
||||||
*tx_vfo = rig->state.tx_vfo;
|
*tx_vfo = rig->state.tx_vfo;
|
||||||
|
|
||||||
|
@ -3211,6 +3344,9 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
||||||
|| vfo == RIG_VFO_CURR
|
|| vfo == RIG_VFO_CURR
|
||||||
|| vfo == rig->state.current_vfo)
|
|| vfo == rig->state.current_vfo)
|
||||||
{
|
{
|
||||||
|
rig->state.cache.split = *split;
|
||||||
|
rig->state.cache.split_vfo = *tx_vfo;
|
||||||
|
elapsed_ms(&rig->state.cache.time_split, ELAPSED_SET);
|
||||||
return caps->get_split_vfo(rig, vfo, split, tx_vfo);
|
return caps->get_split_vfo(rig, vfo, split, tx_vfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3237,6 +3373,10 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
|
||||||
retcode = rc2;
|
retcode = rc2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rig->state.cache.split = *split;
|
||||||
|
rig->state.cache.split_vfo = *tx_vfo;
|
||||||
|
elapsed_ms(&rig->state.cache.time_split, ELAPSED_SET);
|
||||||
|
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,8 @@
|
||||||
#define TOK_RANGE_SELECTED TOKEN_FRONTEND(121)
|
#define TOK_RANGE_SELECTED TOKEN_FRONTEND(121)
|
||||||
/** \brief rig: Range Name */
|
/** \brief rig: Range Name */
|
||||||
#define TOK_RANGE_NAME TOKEN_FRONTEND(122)
|
#define TOK_RANGE_NAME TOKEN_FRONTEND(122)
|
||||||
|
/** \brief rig: Cache timeout */
|
||||||
|
#define TOK_CACHE_TIMEOUT TOKEN_FRONTEND(123)
|
||||||
/*
|
/*
|
||||||
* rotator specific tokens
|
* rotator specific tokens
|
||||||
* (strictly, should be documented as rotator_internal)
|
* (strictly, should be documented as rotator_internal)
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
/* This program does a number of iterations of v f m t s
|
||||||
|
* By Michael Black W9MDB
|
||||||
|
* This simulates what WSJT-X and JTDX do
|
||||||
|
* Used in testing caching effects that have been added
|
||||||
|
* Original performance against dummy device with 20ms delays showed
|
||||||
|
* about 50 calls/sec to get frequency. After caching was added can
|
||||||
|
* do about 37,000 calls/sec or about 740 times faster.
|
||||||
|
* To compile:
|
||||||
|
* gcc -I../src -I../include -g -o cachetest cachetest.c -lhamlib
|
||||||
|
* To test dummy device cache effect:
|
||||||
|
* dummy without any cache -- 12 iterations per second
|
||||||
|
* ./cachetest 1 "" 0 12 0
|
||||||
|
* Elapsed:Elapsed 1.004sec
|
||||||
|
*
|
||||||
|
* dummy with 500ms cache (default value) -- 12 iterations in 0.071sec
|
||||||
|
* ./cachetest 1 "" 0 12 500
|
||||||
|
* Elapsed 0.071sec
|
||||||
|
*
|
||||||
|
* dummy with 5700 iterations in less than 1 second with 500ms cache
|
||||||
|
* ./cachetest 1 "" 0 5700 500
|
||||||
|
* Elapsed 0.872sec
|
||||||
|
*
|
||||||
|
* ic-706mkiig -- no cache
|
||||||
|
* ./cachetest 3011 /dev/ttyUSB0 19200 12 0
|
||||||
|
* Elapsed 1.182sec
|
||||||
|
*
|
||||||
|
* ic-706mkiig -- 500ms cache
|
||||||
|
* ./cachetest 3011 /dev/ttyUSB0 19200 12 500
|
||||||
|
* Elapsed 0.13sec
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <hamlib/rig.h>
|
||||||
|
#include <hamlib/riglist.h>
|
||||||
|
#include "sprintflst.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
RIG *my_rig;
|
||||||
|
char *rig_file, *info_buf, *mm;
|
||||||
|
freq_t freq;
|
||||||
|
int retcode;
|
||||||
|
int model;
|
||||||
|
int baud;
|
||||||
|
int loops;
|
||||||
|
int cache_timeout;
|
||||||
|
int i;
|
||||||
|
struct timespec start, startall;
|
||||||
|
|
||||||
|
if (argc < 5)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s model port baud loops [cachetimems]\n", argv[0]);
|
||||||
|
fprintf(stderr,
|
||||||
|
"cachetimems defaults to 500ms, 0 to disable or pick your own cache time\n");
|
||||||
|
fprintf(stderr, "To test rigctld: %s 2 127.0.0.1:4532 0 1000 500\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
model = atoi(argv[1]);
|
||||||
|
baud = atoi(argv[3]);
|
||||||
|
loops = atoi(argv[4]);
|
||||||
|
|
||||||
|
if (argc == 6)
|
||||||
|
{
|
||||||
|
cache_timeout = atoi(argv[5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
rig_set_debug(RIG_DEBUG_NONE);
|
||||||
|
|
||||||
|
/* Instantiate a rig */
|
||||||
|
my_rig = rig_init(model); // your rig model.
|
||||||
|
|
||||||
|
/* Set up serial port, baud rate */
|
||||||
|
rig_file = argv[2]; // your serial device
|
||||||
|
|
||||||
|
strncpy(my_rig->state.rigport.pathname, rig_file, FILPATHLEN - 1);
|
||||||
|
|
||||||
|
my_rig->state.rigport.parm.serial.rate = baud; // your baud rate
|
||||||
|
|
||||||
|
/* Open my rig */
|
||||||
|
retcode = rig_open(my_rig);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: rig_open failed %s\n", __func__,
|
||||||
|
rigerror(retcode));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rig_set_cache_timeout_ms(my_rig, CACHE_ALL, cache_timeout);
|
||||||
|
/* Give me ID info, e.g., firmware version. */
|
||||||
|
info_buf = (char *)rig_get_info(my_rig);
|
||||||
|
|
||||||
|
if (info_buf)
|
||||||
|
{
|
||||||
|
strtok(info_buf, "\r\n");
|
||||||
|
printf("Rig_info: '%s'\n", info_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsed_ms(&startall, 1);
|
||||||
|
|
||||||
|
for (i = 0; i < loops; ++i)
|
||||||
|
{
|
||||||
|
rmode_t mode;
|
||||||
|
pbwidth_t width;
|
||||||
|
vfo_t vfo;
|
||||||
|
ptt_t ptt;
|
||||||
|
split_t split;
|
||||||
|
|
||||||
|
elapsed_ms(&start, 1);
|
||||||
|
|
||||||
|
retcode = rig_get_vfo(my_rig, &vfo);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get vfo failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
printf("%4dms: VFO = %s\n", elapsed_ms(&start, 0), rig_strvfo(vfo));
|
||||||
|
|
||||||
|
elapsed_ms(&start, 1);
|
||||||
|
retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &freq);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get freq failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
printf("%4dms: VFO freq. = %.1f Hz\n", elapsed_ms(&start, 0), freq);
|
||||||
|
elapsed_ms(&start, 1);
|
||||||
|
retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &mode, &width);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get mode failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
printf("%4dms: Current mode = %s, width = %ld\n", elapsed_ms(&start, 0),
|
||||||
|
rig_strrmode(mode), width);
|
||||||
|
|
||||||
|
elapsed_ms(&start, 1);
|
||||||
|
retcode = rig_get_ptt(my_rig, RIG_VFO_A, &ptt);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get ptt failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
printf("%4dms: ptt=%d\n", elapsed_ms(&start, 0), ptt);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
elapsed_ms(&start, 1);
|
||||||
|
retcode = rig_get_split_vfo(my_rig, RIG_VFO_A, &split, &vfo);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get split_vfo failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
printf("%4dms: split=%d, tx_vfo=%s\n", elapsed_ms(&start, 0), split,
|
||||||
|
rig_strvfo(vfo));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Elapsed %gsec\n", elapsed_ms(&startall, 0) / 1000.0);
|
||||||
|
|
||||||
|
rig_close(my_rig);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/bash
|
||||||
|
echo Cache test with multiple clients to rigctld
|
||||||
|
echo Need two rigctld running
|
||||||
|
echo rigctld -t 4532 --set-conf=cache_timeout=0
|
||||||
|
echo rigctld -t 4533
|
||||||
|
rigctlOK4532=`ps ax | grep rigctld | grep 4532`
|
||||||
|
rigctlOK4533=`ps ax | grep rigctld | grep 4533`
|
||||||
|
echo 4532 $rigctlOK4532
|
||||||
|
echo 4533 $rigctlOK4533
|
||||||
|
if [ -z "$rigctlOK4532" ];then
|
||||||
|
echo rigctld port 4532 is not running
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$rigctlOK4533" ];then
|
||||||
|
echo rigctld port 4533 is not running
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
for cachetime in 0 500;do
|
||||||
|
echo ===============================================
|
||||||
|
echo rigctl cachetimeout=$cachetime
|
||||||
|
for port in 4532 4533;do
|
||||||
|
if [ $port == "4532" ];then
|
||||||
|
echo rigctld cachetimeout=0
|
||||||
|
cache="no cache"
|
||||||
|
fi
|
||||||
|
if [ $port == "4533" ];then
|
||||||
|
echo ===============================================
|
||||||
|
echo rigctld cachetimeout=500
|
||||||
|
cache="500ms cache"
|
||||||
|
fi
|
||||||
|
echo With one process, $cache
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2 >&1|egrep "Elapsed"
|
||||||
|
echo With two processes, $cache
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2 >&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"
|
||||||
|
|
||||||
|
echo With ten processes, $cache
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"&
|
||||||
|
./cachetest 2 127.0.0.1:$port 19200 12 $cachetime 2>&1|egrep "Elapsed"
|
||||||
|
wait
|
||||||
|
|
||||||
|
done
|
||||||
|
done
|
|
@ -0,0 +1,140 @@
|
||||||
|
/* This program does a fast iteration of v f m t s
|
||||||
|
* By Michael Black W9MDB
|
||||||
|
* This allows testing of another program using rigctld
|
||||||
|
* to test changin vfo, freq, mode, PTT, or split and see the change immediately in this program.
|
||||||
|
* Used in testing caching effects that have been added
|
||||||
|
* To compile:
|
||||||
|
* gcc -I../src -I../include -g -o cachetest2 cachetest2.c -lhamlib
|
||||||
|
* To run:
|
||||||
|
* rigctld
|
||||||
|
* ./cachetest2
|
||||||
|
* Note: cachtest2 should show immediately when v f m t s are changed
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <hamlib/rig.h>
|
||||||
|
#include <hamlib/riglist.h>
|
||||||
|
#include "sprintflst.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
RIG *my_rig;
|
||||||
|
char *rig_file, *info_buf, *mm;
|
||||||
|
int retcode;
|
||||||
|
int model;
|
||||||
|
int baud;
|
||||||
|
int loops;
|
||||||
|
int cache_timeout;
|
||||||
|
int i;
|
||||||
|
struct timespec start, startall;
|
||||||
|
|
||||||
|
if (argc != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
model = 2;
|
||||||
|
|
||||||
|
rig_set_debug(RIG_DEBUG_NONE);
|
||||||
|
|
||||||
|
/* Instantiate a rig */
|
||||||
|
my_rig = rig_init(model); // your rig model.
|
||||||
|
|
||||||
|
/* Set up serial port, baud rate */
|
||||||
|
rig_file = "127.0.0.1:4532"; // your serial device
|
||||||
|
|
||||||
|
strncpy(my_rig->state.rigport.pathname, rig_file, FILPATHLEN - 1);
|
||||||
|
|
||||||
|
/* Open my rig */
|
||||||
|
retcode = rig_open(my_rig);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: rig_open failed %s\n", __func__,
|
||||||
|
rigerror(retcode));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rig_set_cache_timeout_ms(my_rig, CACHE_ALL, cache_timeout);
|
||||||
|
/* Give me ID info, e.g., firmware version. */
|
||||||
|
info_buf = (char *)rig_get_info(my_rig);
|
||||||
|
|
||||||
|
if (info_buf)
|
||||||
|
{
|
||||||
|
strtok(info_buf, "\r\n");
|
||||||
|
printf("Rig_info: '%s'\n", info_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
static freq_t freq, freq_last = 0;
|
||||||
|
static rmode_t mode, mode_last = 0;
|
||||||
|
static pbwidth_t width, width_last = 0;
|
||||||
|
static vfo_t vfo, vfo_last = RIG_VFO_NONE;
|
||||||
|
static vfo_t txvfo, txvfo_last = RIG_VFO_NONE;
|
||||||
|
static ptt_t ptt, ptt_last = -1;
|
||||||
|
static split_t split, split_last = -1;
|
||||||
|
|
||||||
|
retcode = rig_get_vfo(my_rig, &vfo);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get vfo failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
if (vfo != vfo_last)
|
||||||
|
{
|
||||||
|
printf("VFO = %s\n", rig_strvfo(vfo));
|
||||||
|
vfo_last = vfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
retcode = rig_get_freq(my_rig, RIG_VFO_CURR, &freq);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get freq failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
if (freq != freq_last)
|
||||||
|
{
|
||||||
|
printf("VFO freq. = %.1f Hz\n", freq);
|
||||||
|
freq_last = freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
retcode = rig_get_mode(my_rig, RIG_VFO_CURR, &mode, &width);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get mode failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
if (mode != mode_last || width != width_last)
|
||||||
|
{
|
||||||
|
printf("Current mode = %s, width = %ld\n", rig_strrmode(mode), width);
|
||||||
|
mode_last = mode;
|
||||||
|
width_last = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
retcode = rig_get_ptt(my_rig, RIG_VFO_CURR, &ptt);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get ptt failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
if (ptt != ptt_last)
|
||||||
|
{
|
||||||
|
printf("ptt=%d\n", ptt);
|
||||||
|
ptt_last = ptt;
|
||||||
|
}
|
||||||
|
|
||||||
|
retcode = rig_get_split_vfo(my_rig, RIG_VFO_CURR, &split, &txvfo);
|
||||||
|
|
||||||
|
if (retcode != RIG_OK) { printf("Get split_vfo failed?? Err=%s\n", rigerror(retcode)); }
|
||||||
|
|
||||||
|
if (split != split_last || txvfo != txvfo_last)
|
||||||
|
{
|
||||||
|
printf("split=%d, tx_vfo=%s\n", split,
|
||||||
|
rig_strvfo(vfo));
|
||||||
|
split_last = split;
|
||||||
|
txvfo_last = txvfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rig_close(my_rig);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
};
|
|
@ -631,7 +631,7 @@ int main(int argc, char *argv[])
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
retcode = rigctl_parse(my_rig, stdin, stdout, argv, argc, NULL,
|
retcode = rigctl_parse(my_rig, stdin, stdout, argv, argc, NULL,
|
||||||
interactive, prompt, vfo_mode, send_cmd_term,
|
interactive, prompt, &vfo_mode, send_cmd_term,
|
||||||
&ext_resp, &resp_sep);
|
&ext_resp, &resp_sep);
|
||||||
|
|
||||||
if (retcode == 2)
|
if (retcode == 2)
|
||||||
|
|
|
@ -313,6 +313,8 @@ static struct test_table test_list[] =
|
||||||
{ '3', "dump_conf", ACTION(dump_conf), ARG_NOVFO },
|
{ '3', "dump_conf", ACTION(dump_conf), ARG_NOVFO },
|
||||||
{ 0x8f, "dump_state", ACTION(dump_state), ARG_OUT | ARG_NOVFO },
|
{ 0x8f, "dump_state", ACTION(dump_state), ARG_OUT | ARG_NOVFO },
|
||||||
{ 0xf0, "chk_vfo", ACTION(chk_vfo), ARG_NOVFO, "ChkVFO" }, /* rigctld only--check for VFO mode */
|
{ 0xf0, "chk_vfo", ACTION(chk_vfo), ARG_NOVFO, "ChkVFO" }, /* rigctld only--check for VFO mode */
|
||||||
|
{ '(', "set_vfo_mode_on", ACTION(chk_vfo), ARG_NOVFO, "SetVFOMode 1=On 2=Off" }, /* rigctld only--check for VFO mode */
|
||||||
|
{ ')', "set_vfo_mode_off", ACTION(chk_vfo), ARG_NOVFO, "SetVFOMode 1=On 2=Off" }, /* rigctld only--check for VFO mode */
|
||||||
{ 0xf1, "halt", ACTION(halt), ARG_NOVFO }, /* rigctld only--halt the daemon */
|
{ 0xf1, "halt", ACTION(halt), ARG_NOVFO }, /* rigctld only--halt the daemon */
|
||||||
{ 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" },
|
{ 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" },
|
||||||
{ 0x00, "", NULL },
|
{ 0x00, "", NULL },
|
||||||
|
@ -605,7 +607,7 @@ static int next_word(char *buffer, int argc, char *argv[], int newline)
|
||||||
|
|
||||||
int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
sync_cb_t sync_cb,
|
sync_cb_t sync_cb,
|
||||||
int interactive, int prompt, int vfo_mode, char send_cmd_term,
|
int interactive, int prompt, int *vfo_mode, char send_cmd_term,
|
||||||
int *ext_resp_ptr, char *resp_sep_ptr)
|
int *ext_resp_ptr, char *resp_sep_ptr)
|
||||||
{
|
{
|
||||||
int retcode; /* generic return code from functions */
|
int retcode; /* generic return code from functions */
|
||||||
|
@ -667,6 +669,8 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
if (cmd != '\\'
|
if (cmd != '\\'
|
||||||
&& cmd != '_'
|
&& cmd != '_'
|
||||||
&& cmd != '#'
|
&& cmd != '#'
|
||||||
|
&& cmd != '('
|
||||||
|
&& cmd != ')'
|
||||||
&& ispunct(cmd)
|
&& ispunct(cmd)
|
||||||
&& !prompt)
|
&& !prompt)
|
||||||
{
|
{
|
||||||
|
@ -684,6 +688,8 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
&& cmd != '?'
|
&& cmd != '?'
|
||||||
&& cmd != '_'
|
&& cmd != '_'
|
||||||
&& cmd != '#'
|
&& cmd != '#'
|
||||||
|
&& cmd != '('
|
||||||
|
&& cmd != ')'
|
||||||
&& ispunct(cmd)
|
&& ispunct(cmd)
|
||||||
&& prompt)
|
&& prompt)
|
||||||
{
|
{
|
||||||
|
@ -752,6 +758,10 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd == '(') {rig_debug(RIG_DEBUG_ERR, "%s: vfo_mode on\n", __func__); *vfo_mode = 1; return 0;}
|
||||||
|
|
||||||
|
if (cmd == ')') {rig_debug(RIG_DEBUG_ERR, "%s: vfo_mode off\n", __func__); *vfo_mode = 0; return 0;}
|
||||||
|
|
||||||
if (cmd == 'Q' || cmd == 'q')
|
if (cmd == 'Q' || cmd == 'q')
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -791,13 +801,15 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
|
|
||||||
if (!cmd_entry)
|
if (!cmd_entry)
|
||||||
{
|
{
|
||||||
if (cmd != ' ') {
|
if (cmd != ' ')
|
||||||
|
{
|
||||||
fprintf(stderr, "Command '%c' not found!\n", cmd);
|
fprintf(stderr, "Command '%c' not found!\n", cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cmd_entry->flags & ARG_NOVFO) && vfo_mode)
|
if (!(cmd_entry->flags & ARG_NOVFO) && *vfo_mode)
|
||||||
{
|
{
|
||||||
if (interactive)
|
if (interactive)
|
||||||
{
|
{
|
||||||
|
@ -1206,7 +1218,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
/* If vfo_mode is enabled (-o|--vfo) check if already given
|
/* If vfo_mode is enabled (-o|--vfo) check if already given
|
||||||
* or prompt for it.
|
* or prompt for it.
|
||||||
*/
|
*/
|
||||||
if (!(cmd_entry->flags & ARG_NOVFO) && vfo_mode)
|
if (!(cmd_entry->flags & ARG_NOVFO) && *vfo_mode)
|
||||||
{
|
{
|
||||||
/* Check if VFO was given with command. */
|
/* Check if VFO was given with command. */
|
||||||
result = strtok(NULL, " ");
|
result = strtok(NULL, " ");
|
||||||
|
@ -1302,7 +1314,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
*/
|
*/
|
||||||
result = strtok(NULL, "\0");
|
result = strtok(NULL, "\0");
|
||||||
|
|
||||||
if (vfo_mode && result)
|
if (*vfo_mode && result)
|
||||||
{
|
{
|
||||||
x = 2;
|
x = 2;
|
||||||
parsed_input[x] = result;
|
parsed_input[x] = result;
|
||||||
|
@ -1365,7 +1377,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
{
|
{
|
||||||
result = strtok(NULL, " ");
|
result = strtok(NULL, " ");
|
||||||
|
|
||||||
if (vfo_mode && result)
|
if (*vfo_mode && result)
|
||||||
{
|
{
|
||||||
x = 2;
|
x = 2;
|
||||||
parsed_input[x] = result;
|
parsed_input[x] = result;
|
||||||
|
@ -1431,7 +1443,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
|
|
||||||
result = strtok(NULL, " ");
|
result = strtok(NULL, " ");
|
||||||
|
|
||||||
if (vfo_mode && result)
|
if (*vfo_mode && result)
|
||||||
{
|
{
|
||||||
x = 3;
|
x = 3;
|
||||||
parsed_input[x] = result;
|
parsed_input[x] = result;
|
||||||
|
@ -1497,7 +1509,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
|
|
||||||
result = strtok(NULL, " ");
|
result = strtok(NULL, " ");
|
||||||
|
|
||||||
if (vfo_mode && result)
|
if (*vfo_mode && result)
|
||||||
{
|
{
|
||||||
x = 4;
|
x = 4;
|
||||||
parsed_input[x] = result;
|
parsed_input[x] = result;
|
||||||
|
@ -1593,10 +1605,10 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
char a3[MAXARGSZ + 2];
|
char a3[MAXARGSZ + 2];
|
||||||
char vfo_str[MAXARGSZ + 2];
|
char vfo_str[MAXARGSZ + 2];
|
||||||
|
|
||||||
vfo_mode == 0 ? vfo_str[0] = '\0' : snprintf(vfo_str,
|
*vfo_mode == 0 ? vfo_str[0] = '\0' : snprintf(vfo_str,
|
||||||
sizeof(vfo_str),
|
sizeof(vfo_str),
|
||||||
" %s",
|
" %s",
|
||||||
rig_strvfo(vfo));
|
rig_strvfo(vfo));
|
||||||
|
|
||||||
p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), " %s", p1);
|
p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), " %s", p1);
|
||||||
p2 == NULL ? a2[0] = '\0' : snprintf(a2, sizeof(a2), " %s", p2);
|
p2 == NULL ? a2[0] = '\0' : snprintf(a2, sizeof(a2), " %s", p2);
|
||||||
|
@ -1612,13 +1624,13 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
|
||||||
*resp_sep_ptr);
|
*resp_sep_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_TRACE, "%s: vfo_mode=%d\n", __func__, vfo_mode);
|
rig_debug(RIG_DEBUG_TRACE, "%s: vfo_mode=%d\n", __func__, *vfo_mode);
|
||||||
retcode = (*cmd_entry->rig_routine)(my_rig,
|
retcode = (*cmd_entry->rig_routine)(my_rig,
|
||||||
fout,
|
fout,
|
||||||
fin,
|
fin,
|
||||||
interactive,
|
interactive,
|
||||||
prompt,
|
prompt,
|
||||||
vfo_mode,
|
*vfo_mode,
|
||||||
send_cmd_term,
|
send_cmd_term,
|
||||||
*ext_resp_ptr,
|
*ext_resp_ptr,
|
||||||
*resp_sep_ptr,
|
*resp_sep_ptr,
|
||||||
|
|
|
@ -47,7 +47,7 @@ int set_conf(RIG *my_rig, char *conf_parms);
|
||||||
|
|
||||||
typedef void (*sync_cb_t)(int);
|
typedef void (*sync_cb_t)(int);
|
||||||
int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc, sync_cb_t sync_cb,
|
int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc, sync_cb_t sync_cb,
|
||||||
int interactive, int prompt, int vfo_mode, char send_cmd_term,
|
int interactive, int prompt, int * vfo_mode, char send_cmd_term,
|
||||||
int * ext_resp_ptr, char * resp_sep_ptr);
|
int * ext_resp_ptr, char * resp_sep_ptr);
|
||||||
|
|
||||||
#endif /* RIGCTL_PARSE_H */
|
#endif /* RIGCTL_PARSE_H */
|
||||||
|
|
|
@ -1027,7 +1027,7 @@ void *handle_socket(void *arg)
|
||||||
handle_data_arg->vfo_mode);
|
handle_data_arg->vfo_mode);
|
||||||
retcode = rigctl_parse(handle_data_arg->rig, fsockin, fsockout, NULL, 0,
|
retcode = rigctl_parse(handle_data_arg->rig, fsockin, fsockout, NULL, 0,
|
||||||
sync_callback,
|
sync_callback,
|
||||||
1, 0, handle_data_arg->vfo_mode, send_cmd_term, &ext_resp, &resp_sep);
|
1, 0, &handle_data_arg->vfo_mode, send_cmd_term, &ext_resp, &resp_sep);
|
||||||
|
|
||||||
if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "%s: rigctl_parse retcode=%d\n", __func__, retcode); }
|
if (retcode != 0) { rig_debug(RIG_DEBUG_ERR, "%s: rigctl_parse retcode=%d\n", __func__, retcode); }
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue