kopia lustrzana https://github.com/Hamlib/Hamlib
Fix multicast receiver shutdown by using non-blocking sockets and select(). Use the same port number 4532 for both state snapshots and commands -- it is enough to have different multicast groups for them. Publish multicast state snapshots more often (change detection interval now set to 50ms), but at least at interval defined by poll_interval.
rodzic
5b86d4efff
commit
41c891251f
|
@ -208,7 +208,7 @@ static const struct confparams frontend_cfg_params[] =
|
|||
{
|
||||
TOK_MULTICAST_CMD_PORT, "multicast_cmd_port", "Multicast command server UDP port",
|
||||
"Multicast data UDP port for sending commands to rig",
|
||||
"4531", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } }
|
||||
"4532", RIG_CONF_NUMERIC, { .n = { 0, 1000000, 1 } }
|
||||
},
|
||||
|
||||
{ RIG_CONF_END, NULL, }
|
||||
|
|
15
src/event.c
15
src/event.c
|
@ -87,6 +87,10 @@ void *rig_poll_routine(void *arg)
|
|||
// Rig cache time should be equal to rig poll interval (should be set automatically by rigctld at least)
|
||||
rig_set_cache_timeout_ms(rig, HAMLIB_CACHE_ALL, rs->poll_interval);
|
||||
|
||||
// Attempt to detect changes with the interval below (in milliseconds)
|
||||
int change_detection_interval = 50;
|
||||
int interval_count = 0;
|
||||
|
||||
update_occurred = 0;
|
||||
|
||||
while (rs->poll_routine_thread_run)
|
||||
|
@ -333,9 +337,18 @@ void *rig_poll_routine(void *arg)
|
|||
{
|
||||
network_publish_rig_poll_data(rig);
|
||||
update_occurred = 0;
|
||||
interval_count = 0;
|
||||
}
|
||||
|
||||
hl_usleep(rs->poll_interval * 1000);
|
||||
hl_usleep(change_detection_interval * 1000);
|
||||
interval_count++;
|
||||
|
||||
// Publish updates every poll_interval if no changes have been detected
|
||||
if (interval_count >= (rs->poll_interval / change_detection_interval))
|
||||
{
|
||||
interval_count = 0;
|
||||
network_publish_rig_poll_data(rig);
|
||||
}
|
||||
}
|
||||
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d): Stopping rig poll routine thread\n",
|
||||
|
|
|
@ -1047,9 +1047,43 @@ void *multicast_receiver(void *arg)
|
|||
|
||||
while (rs->multicast_receiver_run == 1)
|
||||
{
|
||||
ssize_t result;
|
||||
struct sockaddr_in client_addr;
|
||||
socklen_t client_len = sizeof(client_addr);
|
||||
fd_set rfds, efds;
|
||||
struct timeval timeout;
|
||||
int select_result;
|
||||
ssize_t result;
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(socket_fd, &rfds);
|
||||
efds = rfds;
|
||||
|
||||
select_result = select(socket_fd + 1, &rfds, NULL, &efds, &timeout);
|
||||
if (select_result == 0)
|
||||
{
|
||||
// Select timed out
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select_result < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s(): select() failed when reading UDP multicast socket data: %s\n",
|
||||
__func__,
|
||||
strerror(errno));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(socket_fd, &efds))
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR,
|
||||
"%s(): fd error when reading UDP multicast socket data\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
result = recvfrom(socket_fd, data, sizeof(data), 0, (struct sockaddr *) &client_addr, &client_len);
|
||||
|
||||
|
@ -1057,9 +1091,8 @@ void *multicast_receiver(void *arg)
|
|||
{
|
||||
if (result < 0)
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
if (errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
{
|
||||
hl_usleep(100 * 1000);
|
||||
continue;
|
||||
}
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error receiving from UDP socket %s:%d: %s\n", __func__,
|
||||
|
@ -1128,13 +1161,6 @@ int network_multicast_publisher_start(RIG *rig, const char *multicast_addr,
|
|||
}
|
||||
|
||||
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
u_long mode = 1; // Enable non-blocking mode
|
||||
#ifdef __MINGW32__
|
||||
ioctlsocket(socket_fd, FIONBIO, &mode);
|
||||
#else
|
||||
ioctl(socket_fd, FIONBIO, &mode);
|
||||
#endif
|
||||
|
||||
|
||||
if (socket_fd < 0)
|
||||
{
|
||||
|
@ -1143,6 +1169,24 @@ int network_multicast_publisher_start(RIG *rig, const char *multicast_addr,
|
|||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
|
||||
// Enable non-blocking mode
|
||||
u_long mode = 1;
|
||||
#ifdef __MINGW32__
|
||||
if (ioctlsocket(socket_fd, FIONBIO, &mode) == SOCKET_ERROR)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#else
|
||||
if (ioctl(socket_fd, FIONBIO, &mode) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (items & RIG_MULTICAST_TRANSCEIVE)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_TRANSCEIVE enabled\n", __FILE__,
|
||||
|
@ -1310,6 +1354,24 @@ int network_multicast_receiver_start(RIG *rig, const char *multicast_addr, int m
|
|||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
|
||||
// Enable non-blocking mode
|
||||
u_long mode = 1;
|
||||
#ifdef __MINGW32__
|
||||
if (ioctlsocket(socket_fd, FIONBIO, &mode) == SOCKET_ERROR)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#else
|
||||
if (ioctl(socket_fd, FIONBIO, &mode) < 0)
|
||||
{
|
||||
rig_debug(RIG_DEBUG_ERR, "%s: error enabling non-blocking mode for socket: %s", __func__,
|
||||
strerror(errno));
|
||||
RETURNFUNC(-RIG_EIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
rs->multicast_receiver_run = 1;
|
||||
rs->multicast_receiver_priv_data = calloc(1,
|
||||
sizeof(multicast_receiver_priv_data));
|
||||
|
@ -1371,6 +1433,11 @@ int network_multicast_receiver_stop(RIG *rig)
|
|||
// Close the socket first to stop the routine
|
||||
if (mcast_receiver_priv->args.socket_fd >= 0)
|
||||
{
|
||||
#ifdef __MINGW32__
|
||||
shutdown(mcast_receiver_priv->args.socket_fd, SD_BOTH);
|
||||
#else
|
||||
shutdown(mcast_receiver_priv->args.socket_fd, SHUT_RDWR);
|
||||
#endif
|
||||
close(mcast_receiver_priv->args.socket_fd);
|
||||
}
|
||||
|
||||
|
|
|
@ -674,7 +674,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model)
|
|||
rs->multicast_data_addr = "224.0.0.1"; // enable multicast data publishing by default
|
||||
rs->multicast_data_port = 4532;
|
||||
rs->multicast_cmd_addr = "224.0.0.2"; // enable multicast command server by default
|
||||
rs->multicast_cmd_port = 4531;
|
||||
rs->multicast_cmd_port = 4532;
|
||||
rs->lo_freq = 0;
|
||||
rs->cache.timeout_ms = 500; // 500ms cache timeout by default
|
||||
rs->cache.ptt = 0;
|
||||
|
|
Ładowanie…
Reference in New Issue