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",
|
TOK_MULTICAST_CMD_PORT, "multicast_cmd_port", "Multicast command server UDP port",
|
||||||
"Multicast data UDP port for sending commands to rig",
|
"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, }
|
{ 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 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);
|
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;
|
update_occurred = 0;
|
||||||
|
|
||||||
while (rs->poll_routine_thread_run)
|
while (rs->poll_routine_thread_run)
|
||||||
|
@ -333,9 +337,18 @@ void *rig_poll_routine(void *arg)
|
||||||
{
|
{
|
||||||
network_publish_rig_poll_data(rig);
|
network_publish_rig_poll_data(rig);
|
||||||
update_occurred = 0;
|
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",
|
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)
|
while (rs->multicast_receiver_run == 1)
|
||||||
{
|
{
|
||||||
ssize_t result;
|
|
||||||
struct sockaddr_in client_addr;
|
struct sockaddr_in client_addr;
|
||||||
socklen_t client_len = sizeof(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);
|
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 (result < 0)
|
||||||
{
|
{
|
||||||
if (errno == EAGAIN)
|
if (errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
{
|
{
|
||||||
hl_usleep(100 * 1000);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rig_debug(RIG_DEBUG_ERR, "%s: error receiving from UDP socket %s:%d: %s\n", __func__,
|
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);
|
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)
|
if (socket_fd < 0)
|
||||||
{
|
{
|
||||||
|
@ -1143,6 +1169,24 @@ int network_multicast_publisher_start(RIG *rig, const char *multicast_addr,
|
||||||
RETURNFUNC(-RIG_EIO);
|
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)
|
if (items & RIG_MULTICAST_TRANSCEIVE)
|
||||||
{
|
{
|
||||||
rig_debug(RIG_DEBUG_VERBOSE, "%s(%d) MULTICAST_TRANSCEIVE enabled\n", __FILE__,
|
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);
|
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_run = 1;
|
||||||
rs->multicast_receiver_priv_data = calloc(1,
|
rs->multicast_receiver_priv_data = calloc(1,
|
||||||
sizeof(multicast_receiver_priv_data));
|
sizeof(multicast_receiver_priv_data));
|
||||||
|
@ -1371,6 +1433,11 @@ int network_multicast_receiver_stop(RIG *rig)
|
||||||
// Close the socket first to stop the routine
|
// Close the socket first to stop the routine
|
||||||
if (mcast_receiver_priv->args.socket_fd >= 0)
|
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);
|
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_addr = "224.0.0.1"; // enable multicast data publishing by default
|
||||||
rs->multicast_data_port = 4532;
|
rs->multicast_data_port = 4532;
|
||||||
rs->multicast_cmd_addr = "224.0.0.2"; // enable multicast command server by default
|
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->lo_freq = 0;
|
||||||
rs->cache.timeout_ms = 500; // 500ms cache timeout by default
|
rs->cache.timeout_ms = 500; // 500ms cache timeout by default
|
||||||
rs->cache.ptt = 0;
|
rs->cache.ptt = 0;
|
||||||
|
|
Ładowanie…
Reference in New Issue