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/228
pull/234/head
mdblack98 2020-05-01 12:03:54 -05:00
rodzic 2991d43e26
commit 9e710156e3
13 zmienionych plików z 598 dodań i 17 usunięć

2
NEWS
Wyświetl plik

@ -22,6 +22,8 @@ Version 4.0
under their own subdirectories. Mike, W9MDB
* rig_get_channel changed to add read_only flag
* 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
2018-08-12

Wyświetl plik

@ -1854,6 +1854,41 @@ typedef struct hamlib_port {
typedef hamlib_port_t port_t;
#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.
@ -1930,6 +1965,7 @@ struct rig_state {
freq_t lo_freq; /*!< Local oscillator frequency of any transverter */
time_t twiddle_time; /*!< time when vfo twiddling was detected */
int twiddle_timeout; /*!< timeout to resume from twiddling */
struct rig_cache cache;
};
//! @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(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>
extern HAMLIB_EXPORT(int) hl_usleep(useconds_t msec);

Wyświetl plik

@ -123,6 +123,11 @@ static const struct confparams frontend_cfg_params[] =
"Frequency to add to the VFO frequency for use with a transverter",
"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, }
};
@ -543,6 +548,9 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val)
rs->lo_freq = atof(val);
break;
case TOK_CACHE_TIMEOUT:
rig_set_cache_timeout_ms(rig,CACHE_ALL,atol(val));
break;
default:
return -RIG_EINVAL;
@ -848,6 +856,14 @@ static int frontend_get_conf(RIG *rig, token_t token, char *val)
strcpy(val, rs->dcdport.pathname);
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:
return -RIG_EINVAL;
}

Wyświetl plik

@ -1260,6 +1260,9 @@ int HAMLIB_API elapsed_ms(struct timespec *start, int flag_start)
struct timespec stop;
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)
{
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 -
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;
}
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
/** @} */

140
src/rig.c
Wyświetl plik

@ -70,6 +70,7 @@
#include "event.h"
#include "cm108.h"
#include "gpio.h"
#include "misc.h"
/**
* \brief Hamlib release number
@ -410,6 +411,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
rs->transceive = RIG_TRN_OFF;
rs->poll_interval = 500;
rs->lo_freq = 0;
rs->cache.timeout_ms = 500; // 500ms cache timeout by default
// We are using range_list1 as the default
// 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;
}
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
rig->state.cache.freq = freq;
rig->state.cache.vfo_freq = vfo;
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;
int retcode;
int cache_ms;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (CHECK_RIG_ARG(rig) || !freq)
{
rig_debug(RIG_DEBUG_TRACE, "%s: rig or freq ptr invalid\n", __func__);
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;
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;
}
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;
}
@ -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.cache.mode = mode;
rig->state.cache.vfo_mode = vfo;
elapsed_ms(&rig->state.cache.time_mode, ELAPSED_SET);
return retcode;
}
@ -1497,6 +1529,7 @@ int HAMLIB_API rig_get_mode(RIG *rig,
{
const struct rig_caps *caps;
int retcode;
int cache_ms;
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
@ -1512,6 +1545,21 @@ int HAMLIB_API rig_get_mode(RIG *rig,
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)
|| vfo == RIG_VFO_CURR
|| vfo == rig->state.current_vfo)
@ -1559,6 +1607,11 @@ int HAMLIB_API rig_get_mode(RIG *rig,
*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;
}
@ -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
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;
}
@ -1780,6 +1839,7 @@ int HAMLIB_API rig_get_vfo(RIG *rig, vfo_t *vfo)
{
const struct rig_caps *caps;
int retcode;
int cache_ms;
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;
}
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);
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.cache.vfo = *vfo;
cache_ms = elapsed_ms(&rig->state.cache.time_vfo, ELAPSED_SET);
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;
}
rig->state.cache.ptt = ptt;
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
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 rc2, status;
vfo_t curr_vfo;
int cache_ms;
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;
}
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;
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)
{
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
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 */
retcode = rc2;
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
}
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:
if (caps->get_ptt)
{
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
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 */
*ptt = RIG_PTT_OFF;
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
rig->state.cache.ptt = *ptt;
}
else
{
retcode = ser_get_rts(&rig->state.pttport, &status);
*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;
case RIG_PTT_SERIAL_DTR:
if (caps->get_ptt)
{
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
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 */
*ptt = RIG_PTT_OFF;
rig->state.cache.ptt = *ptt;
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
}
else
{
retcode = ser_get_dtr(&rig->state.pttport, &status);
*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;
case RIG_PTT_PARALLEL:
if (caps->get_ptt)
{
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
return caps->get_ptt(rig, vfo, ptt);
}
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
return par_ptt_get(&rig->state.pttport, ptt);
case RIG_PTT_CM108:
if (caps->get_ptt)
{
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
return caps->get_ptt(rig, vfo, ptt);
}
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
return cm108_ptt_get(&rig->state.pttport, ptt);
case RIG_PTT_GPIO:
case RIG_PTT_GPION:
if (caps->get_ptt)
{
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
return caps->get_ptt(rig, vfo, ptt);
}
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
return gpio_ptt_get(&rig->state.pttport, ptt);
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;
}
elapsed_ms(&rig->state.cache.time_ptt, ELAPSED_SET);
return RIG_OK;
}
@ -3162,6 +3276,9 @@ int HAMLIB_API rig_set_split_vfo(RIG *rig,
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;
}
@ -3189,6 +3306,7 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
const struct rig_caps *caps;
int retcode, rc2;
vfo_t curr_vfo;
int cache_ms;
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;
}
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 */
*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->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);
}
@ -3237,6 +3373,10 @@ int HAMLIB_API rig_get_split_vfo(RIG *rig,
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;
}

Wyświetl plik

@ -102,6 +102,8 @@
#define TOK_RANGE_SELECTED TOKEN_FRONTEND(121)
/** \brief rig: Range Name */
#define TOK_RANGE_NAME TOKEN_FRONTEND(122)
/** \brief rig: Cache timeout */
#define TOK_CACHE_TIMEOUT TOKEN_FRONTEND(123)
/*
* rotator specific tokens
* (strictly, should be documented as rotator_internal)

159
tests/cachetest.c 100644
Wyświetl plik

@ -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;
};

51
tests/cachetest.sh 100755
Wyświetl plik

@ -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

140
tests/cachetest2.c 100644
Wyświetl plik

@ -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;
};

Wyświetl plik

@ -631,7 +631,7 @@ int main(int argc, char *argv[])
do
{
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);
if (retcode == 2)

Wyświetl plik

@ -313,6 +313,8 @@ static struct test_table test_list[] =
{ '3', "dump_conf", ACTION(dump_conf), 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 */
{ '(', "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 */
{ 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" },
{ 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,
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 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 != '\\'
&& cmd != '_'
&& cmd != '#'
&& cmd != '('
&& cmd != ')'
&& ispunct(cmd)
&& !prompt)
{
@ -684,6 +688,8 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
&& cmd != '?'
&& cmd != '_'
&& cmd != '#'
&& cmd != '('
&& cmd != ')'
&& ispunct(cmd)
&& prompt)
{
@ -752,6 +758,10 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
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')
{
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 != ' ') {
if (cmd != ' ')
{
fprintf(stderr, "Command '%c' not found!\n", cmd);
}
return 0;
}
if (!(cmd_entry->flags & ARG_NOVFO) && vfo_mode)
if (!(cmd_entry->flags & ARG_NOVFO) && *vfo_mode)
{
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
* 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. */
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");
if (vfo_mode && result)
if (*vfo_mode && result)
{
x = 2;
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, " ");
if (vfo_mode && result)
if (*vfo_mode && result)
{
x = 2;
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, " ");
if (vfo_mode && result)
if (*vfo_mode && result)
{
x = 3;
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, " ");
if (vfo_mode && result)
if (*vfo_mode && result)
{
x = 4;
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 vfo_str[MAXARGSZ + 2];
vfo_mode == 0 ? vfo_str[0] = '\0' : snprintf(vfo_str,
sizeof(vfo_str),
" %s",
rig_strvfo(vfo));
*vfo_mode == 0 ? vfo_str[0] = '\0' : snprintf(vfo_str,
sizeof(vfo_str),
" %s",
rig_strvfo(vfo));
p1 == NULL ? a1[0] = '\0' : snprintf(a1, sizeof(a1), " %s", p1);
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);
}
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,
fout,
fin,
interactive,
prompt,
vfo_mode,
*vfo_mode,
send_cmd_term,
*ext_resp_ptr,
*resp_sep_ptr,

Wyświetl plik

@ -47,7 +47,7 @@ int set_conf(RIG *my_rig, char *conf_parms);
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 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);
#endif /* RIGCTL_PARSE_H */

Wyświetl plik

@ -1027,7 +1027,7 @@ void *handle_socket(void *arg)
handle_data_arg->vfo_mode);
retcode = rigctl_parse(handle_data_arg->rig, fsockin, fsockout, NULL, 0,
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); }