Merge branch 'master' into initial-spectrum-scope-support

pull/712/head
Mikael Nousiainen 2021-05-26 23:41:38 +03:00
commit a7de662937
15 zmienionych plików z 419 dodań i 109 usunięć

Wyświetl plik

@ -18,7 +18,7 @@ Split=0 SatMode=0
PTT=1 (1=On, 0=Off)
Rig=Dummy (name of connected rig)
App=Hamlib (name of application providing the packet)
Version=20210429 (version YYYYMMDD) -- reverse compatibilty will be maintained
Version=20210429 1.0.0 (version YYYYMMDD)
Status=OK (possible values OK, Offline, Error)
ErrorMsg=msg text (pipe delimited multi-line error message)
CRC=0xf49f4708 (this is just an example CRC and not accurate for this example)
@ -45,8 +45,10 @@ Example JSON
"TX": false
}],
"__comment_spectrum__": "Rigs that have spectrum output may include this data",
"Spectrum": {
"__comment_spectra__": "Rigs that have spectrum output may include this array data",
"Spectra": [
{
"Name": "Main",
"Length": 475,
"__comment_spectrum_data__": "2-char hex bytes so data len=2*Length",
"Data": "00AAFF75BD2AAA...",
@ -64,16 +66,42 @@ Example JSON
"LowFreq": 14000000,
"HighFreq": 14250000
},
{
"Name": "Sub",
"Length": 475,
"__comment_spectrum_data__": "2-char hex bytes so data len=2*Length",
"Data": "00AAFF75BD2AAA...",
"Type": "FIXED|CENTER",
"MinLevel": 0,
"MaxLevel": 140,
"MinStrength": -100,
"MaxStrength": 0,
"__comment_spectrum_center__": "If Type=CENTER, the following fields will be present:",
"CenterFreq": 14267000,
"Span": 25000,
"__comment_spectrum_fixed__": "If SpectrumType=FIXED, the following fields will be present:",
"LowFreq": 14000000,
"HighFreq": 14250000
}],
LastCommand {
"ID": "MyApp 123",
"Command": "set_freq VFOA 14074000".
"Status": "OK"
},
"PTT" : false,
"Split": true,
"SatMode": false,
"Rig": "Dummy",
"App": "Hamlib",
"__comment_version__": "protocol version date YYYYMMDD",
"Version": "20210520",
"__comment_version__": "protocol version YYYYMMDD x.x.x, 1.0.0 will be used when this is implemented",
"Version": "20210521 0.0.0",
"Status": "OK";
"__comment_seq__": "Seq is 1-up sequence number 32-bit -- wraps around to 1 from 2^32-1",
"Seq": 1,
"__comment_crc__": "32-bit CRC of entire JSON record replacing the CRC value with 0x00000000",
"ErrorMsg": "OK",
"CRC": "0x00000000"
}
@ -115,16 +143,24 @@ namespace HamlibMultiCast
public double LowFreq;
public double HighFreq;
}
LastCommand {
public string ID; // an application name plus sequence number recommended
public string Command;
public string Status;
}
public string ID;
public List<VFO> VFOs { get; set; }
public bool PTT;
public bool Split;
public bool SatMode;
public string Rig;
public string App;
public string Version;
public string Status;
public UInt32 Seq;
public string CRC;
public SpectrumClass Spectrum { get; set; }
public string ErrorMsg;
}
class Program
{

Wyświetl plik

@ -20,6 +20,7 @@ namespace HamlibMultiCast
}
public class SpectrumClass
{
public string Name;
public int Length;
public string Data;
public string Type;
@ -32,6 +33,11 @@ namespace HamlibMultiCast
public double LowFreq;
public double HighFreq;
}
public class LastCommand {
public string ID;
public string Command;
public string Status;
}
public string ID;
public List<VFO> VFOs { get; set; }
public bool Split;
@ -41,7 +47,7 @@ namespace HamlibMultiCast
public string Version;
public UInt32 Seq;
public string CRC;
public SpectrumClass Spectrum { get; set; }
public List<SpectrumClass> Spectra { get; set; }
}
class Program
{

Wyświetl plik

@ -20,7 +20,9 @@
}],
"__comment_spectrum__": "Rigs that have spectrum output may include this data",
"Spectrum": {
"Spectra": [
{
"Name": "Main",
"Length": 475,
"__comment_spectrum_data__": "2-char hex bytes so data len=2*Length",
"Data": "00AAFF75BD2AAA...",
@ -38,6 +40,30 @@
"LowFreq": 14000000,
"HighFreq": 14250000
},
{
"Name": "Sub",
"Length": 475,
"__comment_spectrum_data__": "2-char hex bytes so data len=2*Length",
"Data": "00AAFF75BD2AAA...",
"Type": "FIXED|CENTER",
"MinLevel": 0,
"MaxLevel": 140,
"MinStrength": -100,
"MaxStrength": 0,
"__comment_spectrum_center__": "If Type=CENTER, the following fields will be present:",
"CenterFreq": 14267000,
"Span": 25000,
"__comment_spectrum_fixed__": "If SpectrumType=FIXED, the following fields will be present:",
"LowFreq": 14000000,
"HighFreq": 14250000
}],
"LastCommand": {
"ID": "MyApp 123",
"Command": "set_freq VFOA 14074000",
"Status": "OK"
},
"Split": true,
"SatMode": false,

Wyświetl plik

@ -106,6 +106,14 @@
__BEGIN_DECLS
/**
* \brief size of cookie request buffer
* Minimum size of cookie buffer to pass to rig_cookie
*/
// cookie is 26-char time code plus 10-char (2^31-1) random number
#define HAMLIB_COOKIE_SIZE 37
extern int cookie_use; // this is global as once one client requests it everybody needs to honor it
//! @cond Doxygen_Suppress
extern HAMLIB_EXPORT_VAR(const char) hamlib_version[];
extern HAMLIB_EXPORT_VAR(const char) hamlib_copyright[];
@ -995,6 +1003,16 @@ enum cookie_e {
RIG_COOKIE_RENEW,
};
/**
* \brief Multicast data items
* 3 different data item can be included in the multicast JSON
*/
enum multicast_item_e {
RIG_MULTICAST_POLL, // hamlib will be polling the rig for all rig items
RIG_MULTICAST_TRANSCEIVE, // transceive will be turned on and processed
RIG_MULTICAST_SPECTRUM // spectrum data will be included
};
//! @cond Doxygen_Suppress
#define RIG_PARM_FLOAT_LIST (RIG_PARM_BACKLIGHT|RIG_PARM_BAT|RIG_PARM_KEYLIGHT)
#define RIG_PARM_READONLY_LIST (RIG_PARM_BAT)
@ -3133,7 +3151,7 @@ extern HAMLIB_EXPORT(int) rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int *
typedef unsigned long rig_useconds_t;
extern HAMLIB_EXPORT(int) hl_usleep(rig_useconds_t msec);
extern HAMLIB_EXPORT(char *) rig_cookie(char *cookie, enum cookie_e cookie_cmd);
extern HAMLIB_EXPORT(int) rig_cookie(RIG *rig, enum cookie_e cookie_cmd, char *cookie, int cookie_len);
//! @endcond

Wyświetl plik

@ -186,22 +186,6 @@ void HAMLIB_API rig_set_debug_time_stamp(int flag)
rig_debug_time_stamp = flag;
}
//! @cond Doxygen_Suppress
char *date_strget(char *buf, int buflen)
{
char tmp[16];
struct tm *mytm;
time_t t;
struct timeval tv;
t = time(NULL);
mytm = gmtime(&t);
strftime(buf, buflen, "%Y-%m-%d:%H:%M:%S.", mytm);
gettimeofday(&tv, NULL);
sprintf(tmp, "%06ld", (long)tv.tv_usec);
strcat(buf, tmp);
return buf;
}
//! @endcond

Wyświetl plik

@ -2332,6 +2332,22 @@ uint32_t CRC32_function(uint8_t *buf, uint32_t len)
return crc ^ 0xFFFFFFFF;
}
//! @cond Doxygen_Suppress
char *date_strget(char *buf, int buflen)
{
char tmp[16];
struct tm *mytm;
time_t t;
struct timeval tv;
t = time(NULL);
mytm = gmtime(&t);
strftime(buf, buflen, "%Y-%m-%d:%H:%M:%S.", mytm);
gettimeofday(&tv, NULL);
sprintf(tmp, "%06ld", (long)tv.tv_usec);
strcat(buf, tmp);
return buf;
}
//! @endcond

Wyświetl plik

@ -112,6 +112,8 @@ extern HAMLIB_EXPORT(int) parse_hoststr(char *host, char hoststr[256], char port
extern HAMLIB_EXPORT(uint32_t) CRC32_function(uint8_t *buf, uint32_t len);
extern char *date_strget(char *buf, int buflen);
#ifdef PRId64
/** \brief printf(3) format to be used for long long (64bits) type */
# define PRIll PRId64

Wyświetl plik

@ -44,6 +44,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <signal.h>
#include <pthread.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
@ -396,6 +397,23 @@ int network_close(hamlib_port_t *rp)
}
//! @endcond
volatile int multicast_server_run = 1;
pthread_t multicast_server_threadId;
//! @cond Doxygen_Suppress
// our multicast server loop
static 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__);
return NULL;
}
//! @endcond
/**
* \brief Open multicast server using rig.state data
*
@ -406,7 +424,7 @@ int network_close(hamlib_port_t *rp)
* \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)
int network_multicast_server(RIG *rig, const char *multicast_addr, int default_port, enum multicast_item_e items)
{
int status;
@ -417,6 +435,26 @@ int network_multicast_server(RIG *rig, const char *multicast_addr, int default_p
if (status != RIG_OK) { RETURNFUNC(status); }
if (items && RIG_MULTICAST_TRANSCEIVE)
{
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__);
}
else
{
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);
if (err)
{
rig_debug(RIG_DEBUG_ERR, "%s(%d) pthread_create error %s\n", __FILE__, __LINE__, strerror(errno));
return -RIG_EINTERNAL;
}
RETURNFUNC(RIG_OK);
}

Wyświetl plik

@ -29,7 +29,7 @@ __BEGIN_DECLS
/* Hamlib internal use, see rig.c */
int network_open(hamlib_port_t *p, int default_port);
int network_multicast_server(RIG *rig, const char *multicast_addr, int default_port);
HAMLIB_EXPORT(int) network_multicast_server(RIG *rig, const char *multicast_addr, int default_port, enum multicast_item_e items);
int network_close(hamlib_port_t *rp);
void network_flush(hamlib_port_t *rp);

234
src/rig.c
Wyświetl plik

@ -60,6 +60,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <hamlib/rig.h>
@ -88,6 +90,7 @@ const char *hamlib_license = "LGPL";
//! @cond Doxygen_Suppress
const char hamlib_version[21] = "Hamlib " PACKAGE_VERSION;
const char *hamlib_version2 = "Hamlib " PACKAGE_VERSION " " HAMLIBDATETIME;
HAMLIB_EXPORT_VAR (int) cookie_use;
//! @endcond
struct rig_caps caps_test;
@ -861,6 +864,10 @@ int HAMLIB_API rig_open(RIG *rig)
case RIG_PTT_CM108:
rs->pttport.fd = cm108_open(&rs->pttport);
strncpy(rs->rigport.pathname, DEFAULT_CM108_PORT, HAMLIB_FILPATHLEN);
rs->rigport.parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM;
rs->pttport.parm.cm108.ptt_bitnum = DEFAULT_CM108_PTT_BITNUM;
if (rs->pttport.fd < 0)
{
rig_debug(RIG_DEBUG_ERR,
@ -1091,6 +1098,19 @@ int HAMLIB_API rig_close(RIG *rig)
ENTERFUNC;
// terminate the multicast server
extern int multicast_server_run;
multicast_server_run = 0;
extern pthread_t multicast_server_threadId;
int err = pthread_join(multicast_server_threadId, NULL);
if (err)
{
rig_debug(RIG_DEBUG_ERR, "%s(%d): pthread_join error %s\n", __FILE__, __LINE__,
strerror(errno));
// just ignore it
}
if (!rig || !rig->caps)
{
RETURNFUNC(-RIG_EINVAL);
@ -1421,10 +1441,14 @@ static int set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq)
{
int flag = HAMLIB_ELAPSED_SET;
ENTERFUNC;
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, current_vfo=%s\n", __func__,
if (rig_need_debug(RIG_DEBUG_CACHE))
{
ENTERFUNC;
cache_show(rig, __func__, __LINE__);
}
rig_debug(RIG_DEBUG_CACHE, "%s: vfo=%s, current_vfo=%s\n", __func__,
rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
cache_show(rig, __func__, __LINE__);
if (vfo == RIG_VFO_CURR)
{
@ -1440,8 +1464,11 @@ static int set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq)
if (vfo == RIG_VFO_SUB && rig->state.cache.satmode) { vfo = RIG_VFO_SUB_A; };
rig_debug(RIG_DEBUG_TRACE, "%s: set vfo=%s to freq=%.0f\n", __func__,
rig_strvfo(vfo), freq);
if (rig_need_debug(RIG_DEBUG_CACHE))
{
rig_debug(RIG_DEBUG_CACHE, "%s: set vfo=%s to freq=%.0f\n", __func__,
rig_strvfo(vfo), freq);
}
switch (vfo)
{
@ -1510,15 +1537,24 @@ static int set_cache_freq(RIG *rig, vfo_t vfo, freq_t freq)
RETURNFUNC(-RIG_EINVAL);
}
cache_show(rig, __func__, __LINE__);
RETURNFUNC(RIG_OK);
if (rig_need_debug(RIG_DEBUG_CACHE))
{
cache_show(rig, __func__, __LINE__);
RETURNFUNC(RIG_OK);
}
return RIG_OK;
}
int rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq,
rmode_t *mode, int *cache_ms_mode, pbwidth_t *width, int *cache_ms_width)
{
ENTERFUNC;
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, current_vfo=%s\n", __func__,
if (rig_need_debug(RIG_DEBUG_CACHE))
{
ENTERFUNC;
}
rig_debug(RIG_DEBUG_CACHE, "%s: vfo=%s, current_vfo=%s\n", __func__,
rig_strvfo(vfo), rig_strvfo(rig->state.current_vfo));
if (vfo == RIG_VFO_CURR) { vfo = rig->state.current_vfo; }
@ -1624,9 +1660,15 @@ int rig_get_cache(RIG *rig, vfo_t vfo, freq_t *freq, int *cache_ms_freq,
RETURNFUNC(-RIG_EINVAL);
}
rig_debug(RIG_DEBUG_TRACE, "%s: vfo=%s, freq=%.0f\n", __func__, rig_strvfo(vfo),
rig_debug(RIG_DEBUG_CACHE, "%s: vfo=%s, freq=%.0f\n", __func__, rig_strvfo(vfo),
(double)*freq);
RETURNFUNC(RIG_OK);
if (rig_need_debug(RIG_DEBUG_CACHE))
{
RETURNFUNC(RIG_OK);
}
return RIG_OK;
}
// detect if somebody is twiddling the VFO
@ -5189,7 +5231,7 @@ int HAMLIB_API rig_power2mW(RIG *rig,
/*
* freq is not on the tx range!
*/
RETURNFUNC(-RIG_ECONF); /* could be RIG_EINVAL ? */
RETURNFUNC(-RIG_EINVAL);
}
*mwpower = (unsigned int)(power * txrange->high_power);
@ -5243,7 +5285,7 @@ int HAMLIB_API rig_mW2power(RIG *rig,
/*
* freq is not on the tx range!
*/
return (-RIG_ECONF); /* could be RIG_EINVAL ? */
return (-RIG_EINVAL); /* could be RIG_EINVAL ? */
}
if (txrange->high_power == 0)
@ -6290,7 +6332,6 @@ int HAMLIB_API rig_get_rig_info(RIG *rig, char *response, int max_response_len)
int ret;
int rxa, txa, rxb, txb;
response[0] = 0;
char crcstr[16];
vfoA = vfo_fixup(rig, RIG_VFO_A);
vfoB = vfo_fixup(rig, RIG_VFO_B);
@ -6338,7 +6379,13 @@ int HAMLIB_API rig_get_rig_info(RIG *rig, char *response, int max_response_len)
sprintf(p, "CRC=0x%08lx\n", crc);
}
strcat(response, crcstr);
if (strlen(response) >= max_response_len - 1)
{
rig_debug(RIG_DEBUG_ERR, "%s(%d): response len exceeded max %d chars\n",
__FILE__, __LINE__, max_response_len);
RETURNFUNC(RIG_EINTERNAL);
}
RETURNFUNC(RIG_OK);
}
@ -6473,82 +6520,119 @@ const char *HAMLIB_API rig_copyright()
* RIG_COOKIE_GET must have cookie=NULL or NULL returned
* RIG_COOKIE_RENEW must have cookie!=NULL or NULL returned
* RIG_COOKIE_RELEASE must have cookie!=NULL or NULL returned;
* Cookies should only be used when needed to keep commands sequenced correctly
* For example, when setting both VFOA and VFOB frequency and mode
* Example to wait for cookie, do rig commands, and release
* while((cookie=rig_cookie(NULL, RIG_COOKIE_GET)) == NULL) hl_usleep(10*1000);
* set_freq A;set mode A;set freq B;set modeB;
* rig_cookie(cookie,RIG_COOKIE_RELEASE);
*/
char *rig_cookie(char *cookie, enum cookie_e cookie_cmd)
int HAMLIB_API rig_cookie(RIG *rig, enum cookie_e cookie_cmd, char *cookie,
int cookie_len)
{
static char cookie_save[32]; // only one client can have the cookie
double time_curr, time_last_used = 0;
// only 1 client can have the cookie so these can be static
// this should also prevent problems with DLLs & shared libraies
// the debug_msg is another non-thread-safe which this will help fix
// 27 char cookie will last until the year 10000
static char
cookie_save[HAMLIB_COOKIE_SIZE]; // only one client can have the 26-char cookie
static double time_last_used;
double time_curr;
struct timespec tp;
if (cookie_len < 27)
{
rig_debug(RIG_DEBUG_ERR, "%s(%d): cookie_len < 32 so returning NULL!!\n",
__FILE__, __LINE__);
return -RIG_EINTERNAL;
}
switch (cookie_cmd)
{
case RIG_COOKIE_RELEASE:
if (cookie == NULL) {
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): coookie NULL so nothing to do\n", __FILE__, __LINE__);
return NULL; // nothing to do
}
if (strcmp(cookie,cookie_save)==0)
{
cookie_save[0] = 0;
return NULL;
}
break;
}
if (cookie == NULL && cookie_cmd == RIG_COOKIE_GET)
{
// asking for a cookie but somebody may already have it
// if we already have a cookie and somebody asks see if we should expire the old one
printf("%d cookie_cmd=%d\n", (int)strlen(cookie_save), cookie_cmd);
case RIG_COOKIE_RELEASE:
if (cookie == NULL)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): coookie NULL so nothing to do\n",
__FILE__, __LINE__);
return -RIG_EINVAL; // nothing to do
}
if (cookie_save[0] != 0
&& strcmp(cookie, cookie_save) == 0) // matching cookie so we'll clear it
{
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s coookie released\n",
__FILE__, __LINE__, cookie_save);
memset(cookie_save, 0, sizeof(cookie_save));
return RIG_OK;
}
else // not the right cookie!!
{
rig_debug(RIG_DEBUG_ERR,
"%s(%d): %s can't release cookie as cookie %s is active\n", __FILE__, __LINE__,
cookie, cookie_save);
return -RIG_BUSBUSY;
}
break;
case RIG_COOKIE_RENEW:
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s comparing renew request to %s==%d\n",
__FILE__, __LINE__, cookie, cookie_save, strcmp(cookie, cookie_save));
if (cookie_save[0] != 0
&& strcmp(cookie, cookie_save) == 0) // matching cookie so we'll renew it
{
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) %s renew request granted\n", __FILE__,
__LINE__, cookie);
clock_gettime(CLOCK_REALTIME, &tp);
time_last_used = tp.tv_sec + tp.tv_nsec / 1e9;
return RIG_OK;
}
rig_debug(RIG_DEBUG_ERR,
"%s(%d): %s renew request refused %s is active\n",
__FILE__, __LINE__, cookie, cookie_save);
return -RIG_EINVAL; // wrong cookie
break;
case RIG_COOKIE_GET:
// the way we expire cookies is if somebody else asks for one and the last renewal is > 1 second ago
// a polite client will have released the cookie
// we are just allow for a crashed client that fails to release:q
clock_gettime(CLOCK_REALTIME, &tp);
time_curr = tp.tv_sec + tp.tv_nsec / 1e9;
rig_debug(RIG_DEBUG_ERR, "%s(%d): time_curr=%f\n", __FILE__, __LINE__,
time_curr);
if (time_curr - time_last_used < 1)
if (cookie_save[0] != 0 && (strcmp(cookie_save, cookie) == 0)
&& (time_curr - time_last_used < 1)) // then we will deny the request
{
printf("Cookie in use\n");
rig_debug(RIG_DEBUG_ERR, "%s(%d): cookie==NULL but not RIG_COOKIE_GET\n",
__FILE__, __LINE__);
return NULL;
printf("Cookie %s in use\n", cookie_save);
rig_debug(RIG_DEBUG_ERR, "%s(%d): %s cookie is in use\n", __FILE__, __LINE__,
cookie_save);
return -RIG_BUSBUSY;
}
if (cookie_save[0] != 0)
{
rig_debug(RIG_DEBUG_ERR,
"%s(%d): %s cookie has expired after %.3f seconds....overriding with new cookie\n",
__FILE__, __LINE__, cookie_save, time_curr - time_last_used);
}
else if (strlen(cookie_save)!=0)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): cookie expired so we will grant\n", __FILE__, __LINE__);
cookie_save[0] = 0;
}
}
if (strlen(cookie_save) == 0 && cookie_cmd == RIG_COOKIE_GET)
{
date_strget(cookie_save, sizeof(cookie_save));
clock_gettime(CLOCK_REALTIME, &tp);
time_curr = time_last_used = tp.tv_sec + tp.tv_nsec / 1e9;
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): cookie %s granted, time_curr=%f\n",
__FILE__, __LINE__, cookie_save, time_curr);
return cookie_save;
}
else if (strlen(cookie_save) == 0) // NULL should only be for GET
{
rig_debug(RIG_DEBUG_ERR, "%s(%d): cookie==NULL but not RIG_COOKIE_GET\n",
__FILE__, __LINE__);
return NULL;
}
else if (cookie_cmd == RIG_COOKIE_RENEW)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): cookie %s renewed time_curr=%g\n",
__FILE__, __LINE__,
cookie, time_curr);
return cookie;
}
else if (cookie_cmd == RIG_COOKIE_RELEASE)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): cookie %s released\n", __FILE__, __LINE__,
cookie);
cookie_save[0] = 0;
// add on our random number to ensure uniqueness
snprintf(cookie, cookie_len, "%s %d\n", cookie_save, rand());
strcpy(cookie_save, cookie);
time_last_used = time_curr;
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): %s new cookie request granted\n",
__FILE__, __LINE__, cookie_save);
return RIG_OK;
break;
}
rig_debug(RIG_DEBUG_ERR, "%s(%d): unknown condition!!\n'", __FILE__, __LINE__);
return NULL;
return -RIG_EPROTO;
}

Wyświetl plik

@ -8,7 +8,7 @@ DISTCLEANFILES = rigctl.log rigctl.sum testbcd.log testbcd.sum
bin_PROGRAMS = rigctl rigctld rigmem rigsmtr rigswr rotctl rotctld rigctlcom ampctl ampctld
check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2
check_PROGRAMS = dumpmem testrig testrigopen testrigcaps testtrn testbcd testfreq listrigs testloc rig_bench testcache cachetest cachetest2 testcookie
RIGCOMMONSRC = rigctl_parse.c rigctl_parse.h dumpcaps.c uthash.h
ROTCOMMONSRC = rotctl_parse.c rotctl_parse.h dumpcaps_rot.c uthash.h
@ -76,7 +76,7 @@ endif
EXTRA_DIST = rigmatrix_head.html rig_split_lst.awk testctld.pl testrotctld.pl
# Support 'make check' target for simple tests
check_SCRIPTS = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh
check_SCRIPTS = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh testcookie.sh
TESTS = $(check_SCRIPTS)
@ -105,4 +105,8 @@ testcache.sh:
echo './testcache 1' > testcache.sh
chmod +x ./testcache.sh
CLEANFILES = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh
testcookie.sh:
echo './testcookie 1' > testcookie.sh
chmod +x ./testcookie.sh
CLEANFILES = testrig.sh testfreq.sh testbcd.sh testloc.sh testrigcaps.sh testcache.sh testcookie.sh

Wyświetl plik

@ -86,7 +86,7 @@ static void usage(void);
* NB: do NOT use -W since it's reserved by POSIX.
* TODO: add an option to read from a file
*/
#define SHORT_OPTIONS "+m:r:p:d:P:D:s:c:t:lC:LuonvhVZ"
#define SHORT_OPTIONS "+m:r:p:d:P:D:s:c:t:lC:LuonvhVZ!"
static struct option long_options[] =
{
{"model", 1, 0, 'm'},
@ -113,6 +113,7 @@ static struct option long_options[] =
{"verbose", 0, 0, 'v'},
{"help", 0, 0, 'h'},
{"version", 0, 0, 'V'},
{"cookie", 0, 0, '!'},
{0, 0, 0, 0}
};
@ -172,6 +173,9 @@ int main(int argc, char *argv[])
switch (c)
{
case '!':
cookie_use = 1;
break;
case 'h':
usage();
exit(0);
@ -716,7 +720,8 @@ void usage(void)
" -Y, --ignore_err ignore rig_open errors\n"
" -Z, --debug-time-stamps enable time stamps for debug messages\n"
" -h, --help display this help and exit\n"
" -V, --version output version information and exit\n\n"
" -V, --version output version information and exit\n"
" -!, --cookie use cookie control\n\n"
);
usage_rig(stdout);

Wyświetl plik

@ -671,7 +671,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
RETURNFUNC(RIGCTL_PARSE_ERROR);
}
if (cmd != 0xa)
if (cmd != 0xa && cmd !=0xd)
{
rig_debug(RIG_DEBUG_TRACE, "%s: cmd=%c(%02x)\n", __func__,
isprint(cmd) ? cmd : ' ', cmd);
@ -1143,7 +1143,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
* argument is given, it will be parsed out later.
*/
result = strtok(input_line, " ");
readline_repeat:
/* parsed_input stores pointers into input_line where the token strings
* start.
*/
@ -1737,6 +1737,9 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
fflush(fout);
rig_debug(RIG_DEBUG_TRACE, "%s: retcode=%d\n", __func__, retcode);
#ifdef HAVE_LIBREADLINE
if (input_line != NULL && (result = strtok(NULL, " "))) goto readline_repeat;
#endif
if (sync_cb) { sync_cb(0); } /* unlock if necessary */

Wyświetl plik

@ -746,7 +746,8 @@ int main(int argc, char *argv[])
saved_result = result;
retcode = network_multicast_server(my_rig, multicast_addr, 4532);
enum multicast_item_e items = RIG_MULTICAST_POLL|RIG_MULTICAST_TRANSCEIVE|RIG_MULTICAST_SPECTRUM;
retcode = network_multicast_server(my_rig, multicast_addr, 4532, items);
if (retcode != RIG_OK)
{

87
tests/testcookie.c 100644
Wyświetl plik

@ -0,0 +1,87 @@
#include <hamlib/rig.h>
// GET tests
int test1()
{
int retcode;
// Normal get
char cookie[HAMLIB_COOKIE_SIZE];
retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie));
if (retcode == RIG_OK) { printf("Test#1a OK\n"); }
else {printf("Test#1a Failed\n"); return 1;}
// Should be able to release and get it right back
rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie, sizeof(cookie));
retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie));
if (retcode == RIG_OK) { printf("Test#1b OK\n"); }
else {printf("Test#1b Failed\n"); return 1;}
// Doing a get when another cookie is active should fail
char cookie2[HAMLIB_COOKIE_SIZE];
cookie2[0] = 0;
retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie2, sizeof(cookie2));
if (retcode == RIG_OK) { printf("Test#1c OK\n"); }
else {printf("Test#1c Failed\n"); return 1;}
// after 1 second we should be able to get a coookie
// this means the cookie holder did not renew within 1 second
hl_usleep(1500 * 1000); // after 1 second we should be able to get a coookie
retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie2, sizeof(cookie2));
if (retcode == RIG_OK) { printf("Test#1d OK\n"); }
else {printf("Test#1d Failed\n"); return 1;}
retcode = rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie2, sizeof(cookie2));
if (retcode == RIG_OK) { printf("Test#1e OK\n"); }
else {printf("Test#1e Failed\n"); return 1;}
return 0;
}
// RENEW tests
int test2()
{
int retcode;
char cookie[HAMLIB_COOKIE_SIZE];
retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie, sizeof(cookie));
if (retcode == RIG_OK) { printf("Test#2a OK %s\n", cookie); }
else {printf("Test#2a Failed\n"); return 1;}
retcode = rig_cookie(NULL, RIG_COOKIE_RELEASE, cookie, sizeof(cookie));
if (retcode == RIG_OK) { printf("Test#2b OK\n"); }
else {printf("Test#2b Failed\n"); return 1;}
// get another cookie should work
char cookie2[HAMLIB_COOKIE_SIZE];
retcode = rig_cookie(NULL, RIG_COOKIE_GET, cookie2, sizeof(cookie2));
if (retcode == RIG_OK) { printf("Test#2c OK %s\n", cookie2); }
else {printf("Test#2c Failed\n"); return 1;}
// should not be able to renew 1st cookie
retcode = rig_cookie(NULL, RIG_COOKIE_RENEW, cookie, sizeof(cookie));
if (retcode != RIG_OK) { printf("Test#2d OK\n"); }
else {printf("Test#2d Failed cookie=%s\n", cookie); return 1;}
return 0;
}
int main()
{
rig_set_debug(RIG_DEBUG_VERBOSE);
if (test1()) { return 1; }
if (test2()) { return 1; }
return 0;
}