Add more detailed rig communication status to rig_state and multicast state data packets. Handle SIGINT and SIGTERM in a consistent way in both rigctl and rigctld.

pull/1415/head
Mikael Nousiainen 2023-11-06 00:42:02 +02:00
rodzic 3107a060f0
commit 43d1fbb323
12 zmienionych plików z 291 dodań i 29 usunięć

Wyświetl plik

@ -2577,6 +2577,15 @@ struct multicast_s
//#endif
};
typedef unsigned int rig_comm_status_t;
#define RIG_COMM_STATUS_OK 0x00
#define RIG_COMM_STATUS_CONNECTING 0x01
#define RIG_COMM_STATUS_DISCONNECTED 0x02
#define RIG_COMM_STATUS_TERMINATED 0x03
#define RIG_COMM_STATUS_WARNING 0x04
#define RIG_COMM_STATUS_ERROR 0x05
/**
* \brief Rig state containing live data and customized fields.
*
@ -2766,6 +2775,8 @@ struct rig_state {
int multicast_cmd_port; /*!< Multicast command server UDP port for sending commands to rig */
volatile int multicast_receiver_run;
void *multicast_receiver_priv_data;
rig_comm_status_t comm_status; /*!< Detailed rig control status */
char device_id[HAMLIB_RIGNAMSIZ];
};
/**
@ -3710,6 +3721,7 @@ extern HAMLIB_EXPORT(const char *) rig_strscan(scan_t scan);
extern HAMLIB_EXPORT(const char *) rig_strstatus(enum rig_status_e status);
extern HAMLIB_EXPORT(const char *) rig_strmtype(chan_type_t mtype);
extern HAMLIB_EXPORT(const char *) rig_strspectrummode(enum rig_spectrum_mode_e mode);
extern HAMLIB_EXPORT(const char *) rig_strcommstatus(rig_comm_status_t vfo);
extern HAMLIB_EXPORT(rmode_t) rig_parse_mode(const char *s);
extern HAMLIB_EXPORT(vfo_t) rig_parse_vfo(const char *s);

Wyświetl plik

@ -89,6 +89,11 @@ static const struct confparams frontend_cfg_params[] =
"The tx/rx range list name",
"Default", RIG_CONF_STRING
},
{
TOK_DEVICE_ID, "device_id", "Device ID",
"User-specified device ID for multicast state data and commands",
"", RIG_CONF_STRING,
},
{
TOK_VFO_COMP, "vfo_comp", "VFO compensation",
@ -627,6 +632,10 @@ static int frontend_set_conf(RIG *rig, token_t token, const char *val)
strncpy(rs->dcdport_deprecated.pathname, val, HAMLIB_FILPATHLEN - 1);
break;
case TOK_DEVICE_ID:
strncpy(rs->device_id, val, HAMLIB_RIGNAMSIZ - 1);
break;
case TOK_VFO_COMP:
rs->vfo_comp = atof(val);
@ -989,6 +998,10 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len)
strcpy(val, s);
break;
case TOK_DEVICE_ID:
SNPRINTF(val, val_len, "%s", rs->device_id);
break;
case TOK_VFO_COMP:
SNPRINTF(val, val_len, "%f", rs->vfo_comp);
break;
@ -1149,6 +1162,22 @@ static int frontend_get_conf2(RIG *rig, token_t token, char *val, int val_len)
SNPRINTF(val, val_len, "%d", rs->rigport.timeout_retry);
break;
case TOK_MULTICAST_DATA_ADDR:
SNPRINTF(val, val_len, "%s", rs->multicast_data_addr);
break;
case TOK_MULTICAST_DATA_PORT:
SNPRINTF(val, val_len, "%d", rs->multicast_data_port);
break;
case TOK_MULTICAST_CMD_ADDR:
SNPRINTF(val, val_len, "%s", rs->multicast_cmd_addr);
break;
case TOK_MULTICAST_CMD_PORT:
SNPRINTF(val, val_len, "%d", rs->multicast_cmd_port);
break;
default:
return -RIG_EINVAL;
}

Wyświetl plik

@ -64,8 +64,6 @@ typedef struct rig_poll_routine_priv_data_s
rig_poll_routine_args args;
} rig_poll_routine_priv_data;
// TODO: Where to start/stop rig poll routine?
void *rig_poll_routine(void *arg)
{
rig_poll_routine_args *args = (rig_poll_routine_args *)arg;
@ -93,6 +91,8 @@ void *rig_poll_routine(void *arg)
update_occurred = 0;
network_publish_rig_poll_data(rig);
while (rs->poll_routine_thread_run)
{
if (rig->state.cache.freqMainA != freq_main_a)
@ -351,6 +351,8 @@ void *rig_poll_routine(void *arg)
}
}
network_publish_rig_poll_data(rig);
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping rig poll routine thread\n",
__FILE__,
__LINE__);
@ -408,6 +410,8 @@ int rig_poll_routine_start(RIG *rig)
RETURNFUNC(-RIG_EINTERNAL);
}
network_publish_rig_poll_data(rig);
RETURNFUNC(RIG_OK);
}
@ -453,6 +457,8 @@ int rig_poll_routine_stop(RIG *rig)
poll_routine_priv->thread_id = 0;
}
network_publish_rig_poll_data(rig);
free(rs->poll_routine_priv_data);
rs->poll_routine_priv_data = NULL;

Wyświetl plik

@ -2707,6 +2707,42 @@ const char *HAMLIB_API rig_get_caps_cptr(rig_model_t rig_model,
}
}
static const struct
{
rig_comm_status_t status;
const char *str;
} comm_status_str[] =
{
{ RIG_COMM_STATUS_OK, "OK" },
{ RIG_COMM_STATUS_CONNECTING, "CONNECTING" },
{ RIG_COMM_STATUS_DISCONNECTED, "DISCONNECTED" },
{ RIG_COMM_STATUS_TERMINATED, "TERMINATIED" },
{ RIG_COMM_STATUS_WARNING, "WARNING" },
{ RIG_COMM_STATUS_ERROR, "ERROR" },
{ 0xffffffff, "" },
};
/**
* \brief Convert enum RIG_COMM_STATUS... to alpha string
* \param vfo RIG_COMM_STATUS_...
* \return alpha string
*/
const char *HAMLIB_API rig_strcommstatus(rig_comm_status_t status)
{
int i;
for (i = 0; comm_status_str[i].str[0] != '\0'; i++)
{
if (status == comm_status_str[i].status)
{
return comm_status_str[i].str;
}
}
return "";
}
void errmsg(int err, char *s, const char *func, const char *file, int line)
{
rig_debug(RIG_DEBUG_ERR, "%s(%s:%d): %s: %s\b", __func__, file, line, s,

Wyświetl plik

@ -921,6 +921,8 @@ void *multicast_publisher(void *arg)
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Starting multicast publisher\n", __FILE__,
__LINE__);
snapshot_init();
memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_addr.s_addr = inet_addr(args->multicast_addr);

Wyświetl plik

@ -34,6 +34,7 @@ void network_flush(hamlib_port_t *rp);
int network_publish_rig_poll_data(RIG *rig);
int network_publish_rig_transceive_data(RIG *rig);
int network_publish_rig_spectrum_data(RIG *rig, struct rig_spectrum_line *line);
int network_publish_rig_status_change(RIG *rig, int32_t status);
HAMLIB_EXPORT(int) network_multicast_publisher_start(RIG *rig, const char *multicast_addr, int multicast_port, enum multicast_item_e items);
HAMLIB_EXPORT(int) network_multicast_publisher_stop(RIG *rig);
HAMLIB_EXPORT(int) network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int multicast_port);

Wyświetl plik

@ -593,6 +593,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
#if defined(HAVE_PTHREAD)
rs->rigport.asyncio = 0;
#endif
rig->state.comm_status = RIG_COMM_STATUS_CONNECTING;
rs->tuner_control_pathname = DEFAULT_TUNER_CONTROL_PATHNAME;
@ -1046,6 +1047,8 @@ int HAMLIB_API rig_open(RIG *rig)
RETURNFUNC2(-RIG_EINVAL);
}
rs->comm_status = RIG_COMM_STATUS_CONNECTING;
rs->rigport.fd = -1;
if (rs->rigport.type.rig == RIG_PORT_SERIAL)
@ -1094,6 +1097,7 @@ int HAMLIB_API rig_open(RIG *rig)
rig_debug(RIG_DEBUG_VERBOSE, "%s: rs->comm_state==0?=%d\n", __func__,
rs->comm_state);
rs->comm_state = 0;
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status);
}
@ -1312,6 +1316,7 @@ int HAMLIB_API rig_open(RIG *rig)
if (status < 0)
{
port_close(&rs->rigport, rs->rigport.type.rig);
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status);
}
@ -1320,11 +1325,10 @@ int HAMLIB_API rig_open(RIG *rig)
if (status < 0)
{
port_close(&rs->rigport, rs->rigport.type.rig);
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status);
}
add_opened_rig(rig);
rs->comm_state = 1;
rig_debug(RIG_DEBUG_VERBOSE, "%s: %p rs->comm_state==1?=%d\n", __func__,
&rs->comm_state,
@ -1377,6 +1381,7 @@ int HAMLIB_API rig_open(RIG *rig)
port_close(&rs->rigport, rs->rigport.type.rig);
memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated));
rs->comm_state = 0;
rig->state.comm_status = RIG_COMM_STATUS_ERROR;
RETURNFUNC2(status);
}
}
@ -1518,6 +1523,10 @@ int HAMLIB_API rig_open(RIG *rig)
// we will consider this non-fatal for now
}
rig->state.comm_status = RIG_COMM_STATUS_OK;
add_opened_rig(rig);
RETURNFUNC2(RIG_OK);
}
@ -1557,6 +1566,10 @@ int HAMLIB_API rig_close(RIG *rig)
RETURNFUNC(-RIG_EINVAL);
}
remove_opened_rig(rig);
rig->state.comm_status = RIG_COMM_STATUS_DISCONNECTED;
morse_data_handler_stop(rig);
async_data_handler_stop(rig);
rig_poll_routine_stop(rig);
@ -1676,8 +1689,6 @@ int HAMLIB_API rig_close(RIG *rig)
port_close(&rs->rigport, rs->rigport.type.rig);
remove_opened_rig(rig);
// zero split so it will allow it to be set again on open for rigctld
rig->state.cache.split = 0;
rs->comm_state = 0;

Wyświetl plik

@ -15,35 +15,21 @@
#define SPECTRUM_MODE_FIXED "FIXED"
#define SPECTRUM_MODE_CENTER "CENTER"
char snapshot_data_pid[20];
static int snapshot_serialize_rig(cJSON *rig_node, RIG *rig)
{
cJSON *node;
char buf[1024];
#if 0
// TODO: need to assign rig an ID, e.g. from command line
snprintf(buf, sizeof(buf), "%s:%s:%d", rig->caps->model_name,
rig->state.rigport.pathname, getpid());
node = cJSON_AddStringToObject(rig_node, "id", buf);
if (node == NULL)
{
goto error;
}
#else
cJSON *id_node = cJSON_CreateObject();
cJSON_AddStringToObject(id_node, "model", rig->caps->model_name);
cJSON_AddStringToObject(id_node, "endpoint", rig->state.rigport.pathname);
char pid[16];
sprintf(pid,"%d",getpid());
cJSON_AddStringToObject(id_node, "process", pid);
cJSON_AddStringToObject(id_node, "process", snapshot_data_pid);
cJSON_AddStringToObject(id_node, "deviceId", rig->state.device_id);
cJSON_AddItemToObject(rig_node, "id", id_node);
#endif
// TODO: what kind of status should this reflect?
node = cJSON_AddStringToObject(rig_node, "status",
rig->state.comm_state ? "OK" : "CLOSED");
node = cJSON_AddStringToObject(rig_node, "status", rig_strcommstatus(rig->state.comm_status));
if (node == NULL)
{
@ -330,6 +316,11 @@ error:
RETURNFUNC2(-RIG_EINTERNAL);
}
void snapshot_init()
{
snprintf(snapshot_data_pid, sizeof(snapshot_data_pid), "%d", getpid());
}
int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig,
struct rig_spectrum_line *spectrum_line)
{

Wyświetl plik

@ -1,6 +1,7 @@
#ifndef _SNAPSHOT_DATA_H
#define _SNAPSHOT_DATA_H
void snapshot_init();
int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, struct rig_spectrum_line *spectrum_line);
#endif

Wyświetl plik

@ -98,6 +98,7 @@
/** \brief Number of retries permitted in case of read timeouts */
#define TOK_TIMEOUT_RETRY TOKEN_FRONTEND(39)
#define TOK_POST_PTT_DELAY TOKEN_FRONTEND(40)
#define TOK_DEVICE_ID TOKEN_FRONTEND(41)
/*
* rig specific tokens

Wyświetl plik

@ -30,6 +30,7 @@
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#ifdef HAVE_LIBREADLINE
# if defined(HAVE_READLINE_READLINE_H)
@ -113,11 +114,86 @@ static struct option long_options[] =
extern char rig_resp_sep;
extern powerstat_t rig_powerstat;
static RIG *my_rig; /* handle to rig (instance) */
#ifdef HAVE_SIG_ATOMIC_T
static sig_atomic_t volatile ctrl_c = 0;
#else
static int volatile ctrl_c = 0;
#endif
#define MAXCONFLEN 2048
#ifdef WIN32
static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
rig_debug(RIG_DEBUG_VERBOSE, "%s: called\n", __func__);
switch (fdwCtrlType)
{
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
ctrl_c = 1;
return TRUE;
default:
return FALSE;
}
}
#else
static void signal_handler(int sig)
{
switch (sig)
{
case SIGINT:
case SIGTERM:
fprintf(stderr, "\nTerminating application, caught signal %d\n", sig);
// Close stdin to stop reading input
fclose(stdin);
ctrl_c = 1;
break;
default:
/* do nothing */
break;
}
}
#endif
static void handle_error(enum rig_debug_level_e lvl, const char *msg)
{
int e;
#ifdef __MINGW32__
LPVOID lpMsgBuf;
lpMsgBuf = (LPVOID)"Unknown error";
e = WSAGetLastError();
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, e,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
// Default language
(LPTSTR)&lpMsgBuf, 0, NULL))
{
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, (char *)lpMsgBuf);
LocalFree(lpMsgBuf);
}
else
{
rig_debug(lvl, "%s: Network error %d\n", msg, e);
}
#else
e = errno;
rig_debug(lvl, "%s: Network error %d: %s\n", msg, e, strerror(e));
#endif
}
int main(int argc, char *argv[])
{
RIG *my_rig; /* handle to rig (instance) */
rig_model_t my_model = RIG_MODEL_DUMMY;
int retcode; /* generic return code from functions */
@ -151,6 +227,9 @@ int main(int argc, char *argv[])
char rigstartup[1024];
char vbuf[1024];
rig_powerstat = RIG_POWER_ON; // defaults to power on
#if HAVE_SIGACTION
struct sigaction act;
#endif
int err = setvbuf(stderr, vbuf, _IOFBF, sizeof(vbuf));
@ -648,6 +727,77 @@ int main(int argc, char *argv[])
#endif /* HAVE_LIBREADLINE */
int rig_opened = 1; // our rig is already open
#if HAVE_SIGACTION
#ifdef SIGPIPE
/* Ignore SIGPIPE as we will handle it at the write()/send() calls
that will consequently fail with EPIPE. All child threads will
inherit this disposition which is what we want. */
memset(&act, 0, sizeof act);
act.sa_handler = SIG_IGN;
act.sa_flags = SA_RESTART;
if (sigaction(SIGPIPE, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGPIPE");
}
#endif
#ifdef SIGINT
memset(&act, 0, sizeof act);
act.sa_handler = signal_handler;
if (sigaction(SIGINT, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGINT");
}
#endif
#ifdef SIGTERM
memset(&act, 0, sizeof act);
act.sa_handler = signal_handler;
if (sigaction(SIGTERM, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM");
}
#endif
#elif defined (WIN32)
if (!SetConsoleCtrlHandler(CtrlHandler, TRUE))
{
handle_error(RIG_DEBUG_ERR, "SetConsoleCtrlHandler");
}
#elif HAVE_SIGNAL
#ifdef SIGPIPE
if (SIG_ERR == signal(SIGPIPE, SIG_IGN))
{
handle_error(RIG_DEBUG_ERR, "signal SIGPIPE");
}
#endif
#ifdef SIGINT
if (SIG_ERR == signal(SIGINT, signal_handler))
{
handle_error(RIG_DEBUG_ERR, "signal SIGINT");
}
#endif
#ifdef SIGTERM
if (SIG_ERR == signal(SIGTERM, signal_handler))
{
handle_error(RIG_DEBUG_ERR, "signal SIGTERM");
}
#endif
#endif
do
{
if (!rig_opened)
@ -695,7 +845,7 @@ int main(int argc, char *argv[])
while (retry-- > 0 && retcode != RIG_OK);
}
}
while (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode));
while (!ctrl_c && (retcode == RIG_OK || RIG_IS_SOFT_ERRCODE(-retcode)));
if (interactive && prompt)
{

Wyświetl plik

@ -136,9 +136,9 @@ static volatile int rig_opened = 0;
static int verbose;
#ifdef HAVE_SIG_ATOMIC_T
static sig_atomic_t volatile ctrl_c;
static sig_atomic_t volatile ctrl_c = 0;
#else
static int volatile ctrl_c;
static int volatile ctrl_c = 0;
#endif
const char *portno = "4532";
@ -196,6 +196,10 @@ static void signal_handler(int sig)
switch (sig)
{
case SIGINT:
case SIGTERM:
fprintf(stderr, "\nTerminating application, caught signal %d\n", sig);
// Close stdin to stop reading input
fclose(stdin);
ctrl_c = 1;
break;
@ -949,6 +953,16 @@ int main(int argc, char *argv[])
handle_error(RIG_DEBUG_ERR, "sigaction SIGINT");
}
#endif
#ifdef SIGTERM
memset(&act, 0, sizeof act);
act.sa_handler = signal_handler;
if (sigaction(SIGTERM, &act, NULL))
{
handle_error(RIG_DEBUG_ERR, "sigaction SIGTERM");
}
#endif
#elif defined (WIN32)
@ -973,6 +987,14 @@ int main(int argc, char *argv[])
handle_error(RIG_DEBUG_ERR, "signal SIGINT");
}
#endif
#ifdef SIGTERM
if (SIG_ERR == signal(SIGTERM, signal_handler))
{
handle_error(RIG_DEBUG_ERR, "signal SIGTERM");
}
#endif
#endif