Refactor WIN32 I/O port routines to be hopefully compatible with async data reader (not tested). Fix some incomplete data fields in UDP snapshot packets.

pull/892/head
Mikael Nousiainen 2021-11-30 09:25:51 +02:00
rodzic d857f18163
commit c20f397c24
6 zmienionych plików z 112 dodań i 77 usunięć

Wyświetl plik

@ -211,12 +211,14 @@ typedef struct s_rig RIG;
#define HAMLIB_MAX_SPECTRUM_MODES 5 /* max number of spectrum modes supported */
#define HAMLIB_MAX_SPECTRUM_AVG_MODES 12 /* max number of spectrum averaging modes supported */
#define HAMLIB_MAX_SPECTRUM_SPANS 20 /* max number of spectrum modes supported */
#define HAMLIB_MAX_SPECTRUM_DATA 2048 /* max number of data bytes in a single spectrum line */
#define HAMLIB_MAX_CAL_LENGTH 32 /* max calibration plots in cal_table_t */
#define HAMLIB_MAX_MODES 63
#define HAMLIB_MAX_VFOS 31
#define HAMLIB_MAX_ROTORS 63
#define HAMLIB_MAX_VFO_OPS 31
#define HAMLIB_MAX_RSCANS 31
#define HAMLIB_MAX_SNAPSHOT_PACKET_SIZE 16384 /* maximum number of bytes in a UDP snapshot packet */
//! @endcond

Wyświetl plik

@ -751,11 +751,11 @@ int rig_fire_spectrum_event(RIG *rig, struct rig_spectrum_line *line)
{
ENTERFUNC;
if (rig_need_debug(RIG_DEBUG_ERR))
if (rig_need_debug(RIG_DEBUG_TRACE))
{
char spectrum_debug[line->spectrum_data_length * 4];
print_spectrum_line(spectrum_debug, sizeof(spectrum_debug), line);
rig_debug(RIG_DEBUG_ERR, "%s: ASCII Spectrum Scope: %s\n", __func__,
rig_debug(RIG_DEBUG_TRACE, "%s: ASCII Spectrum Scope: %s\n", __func__,
spectrum_debug);
}

Wyświetl plik

@ -310,26 +310,26 @@ extern int is_uh_radio_fd(int fd);
/* On MinGW32/MSVC/.. the appropriate accessor must be used
* depending on the port type, sigh.
*/
static ssize_t port_read(hamlib_port_t *p, void *buf, size_t count)
static ssize_t port_read_generic(hamlib_port_t *p, void *buf, size_t count, int direct)
{
int fd = direct ? p->fd : p->fd_sync_read;
int i;
ssize_t ret;
//ENTERFUNC; // too verbose
/*
* Since WIN32 does its special serial read, we have
* to catch the microHam case to do just "read".
* Note that we always have RIG_PORT_SERIAL in the
* microHam case.
*/
if (is_uh_radio_fd(p->fd))
if (direct && is_uh_radio_fd(fd))
{
return read(p->fd, buf, count);
return read(fd, buf, count);
}
if (p->type.rig == RIG_PORT_SERIAL)
if (direct && p->type.rig == RIG_PORT_SERIAL)
{
ret = win32_serial_read(p->fd, buf, count);
ret = win32_serial_read(fd, buf, (int) count);
if (p->parm.serial.data_bits == 7)
{
@ -342,17 +342,15 @@ static ssize_t port_read(hamlib_port_t *p, void *buf, size_t count)
}
}
//RETURNFUNC(ret); // too verbose
return ret;
}
else if (p->type.rig == RIG_PORT_NETWORK
|| p->type.rig == RIG_PORT_UDP_NETWORK)
else if (direct && (p->type.rig == RIG_PORT_NETWORK || p->type.rig == RIG_PORT_UDP_NETWORK))
{
return recv(p->fd, buf, count, 0);
return recv(fd, buf, count, 0);
}
else
{
return read(p->fd, buf, count);
return read(fd, buf, count);
}
}
@ -371,7 +369,7 @@ static ssize_t port_write(hamlib_port_t *p, const void *buf, size_t count)
if (p->type.rig == RIG_PORT_SERIAL)
{
return win32_serial_write(p->fd, buf, count);
return win32_serial_write(p->fd, buf, (int) count);
}
else if (p->type.rig == RIG_PORT_NETWORK
|| p->type.rig == RIG_PORT_UDP_NETWORK)
@ -390,7 +388,8 @@ static int port_select(hamlib_port_t *p,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout)
struct timeval *timeout,
int direct)
{
#if 1
@ -417,12 +416,12 @@ static int port_select(hamlib_port_t *p,
* Note that we always have RIG_PORT_SERIAL in the
* microHam case.
*/
if (is_uh_radio_fd(p->fd))
if (direct && is_uh_radio_fd(p->fd))
{
return select(n, readfds, writefds, exceptfds, timeout);
}
if (p->type.rig == RIG_PORT_SERIAL)
if (direct && p->type.rig == RIG_PORT_SERIAL)
{
return win32_serial_select(n, readfds, writefds, exceptfds, timeout);
}
@ -465,7 +464,7 @@ static ssize_t port_read_generic(hamlib_port_t *p, void *buf, size_t count, int
//! @cond Doxygen_Suppress
#define port_write(p,b,c) write((p)->fd,(b),(c))
#define port_select(p,n,r,w,e,t) select((n),(r),(w),(e),(t))
#define port_select(p,n,r,w,e,t,d) select((n),(r),(w),(e),(t))
//! @endcond
#endif
@ -503,8 +502,6 @@ int HAMLIB_API write_block(hamlib_port_t *p, const unsigned char *txbuffer, size
{
int ret;
//rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
#ifdef WANT_NON_ACTIVE_POST_WRITE_DELAY
if (p->post_write_date.tv_sec != 0)
@ -599,14 +596,22 @@ int HAMLIB_API write_block(hamlib_port_t *p, const unsigned char *txbuffer, size
int HAMLIB_API write_block_sync(hamlib_port_t *p, const unsigned char *txbuffer, size_t count)
{
// TODO: Macro for write()
return (int) write((p)->fd_sync_write, txbuffer, count);
if (!p->async)
{
return -RIG_EINTERNAL;
}
return (int) write(p->fd_sync_write, txbuffer, count);
}
int HAMLIB_API write_block_sync_error(hamlib_port_t *p, const unsigned char *txbuffer, size_t count)
{
// TODO: Macro for write()
return (int) write((p)->fd_sync_error_write, txbuffer, count);
if (!p->async)
{
return -RIG_EINTERNAL;
}
return (int) write(p->fd_sync_error_write, txbuffer, count);
}
static int read_block_generic(hamlib_port_t *p, unsigned char *rxbuffer, size_t count, int direct)
@ -618,6 +623,11 @@ static int read_block_generic(hamlib_port_t *p, unsigned char *rxbuffer, size_t
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __func__);
if (!p->async && !direct)
{
return -RIG_EINTERNAL;
}
fd = direct ? p->fd : p->fd_sync_read;
/*
@ -639,7 +649,7 @@ static int read_block_generic(hamlib_port_t *p, unsigned char *rxbuffer, size_t
FD_SET(fd, &rfds);
efds = rfds;
retval = port_select(p, fd + 1, &rfds, NULL, &efds, &tv);
retval = port_select(p, fd + 1, &rfds, NULL, &efds, &tv, direct);
if (retval == 0)
{
@ -753,7 +763,7 @@ int HAMLIB_API read_block_direct(hamlib_port_t *p, unsigned char *rxbuffer, size
return read_block_generic(p, rxbuffer, count, 1);
}
static int flush_and_read_last_byte(int fd)
static int flush_and_read_last_byte(hamlib_port_t *p, int fd, int direct)
{
fd_set rfds, efds;
ssize_t bytes_read;
@ -769,7 +779,7 @@ static int flush_and_read_last_byte(int fd)
FD_SET(fd, &rfds);
efds = rfds;
retval = port_select(p, fd + 1, &rfds, NULL, &efds, &tv_timeout);
retval = port_select(p, fd + 1, &rfds, NULL, &efds, &tv_timeout, direct);
if (retval < 0)
{
return -RIG_ETIMEOUT;
@ -804,6 +814,11 @@ static int read_string_generic(hamlib_port_t *p,
int total_count = 0;
int i = 0;
if (!p->async && !direct)
{
return -RIG_EINTERNAL;
}
rig_debug(RIG_DEBUG_TRACE, "%s called, rxmax=%d\n", __func__, (int)rxmax);
if (!p || !rxbuffer)
@ -849,7 +864,7 @@ static int read_string_generic(hamlib_port_t *p,
}
efds = rfds;
retval = port_select(p, maxfd + 1, &rfds, NULL, &efds, &tv);
retval = port_select(p, maxfd + 1, &rfds, NULL, &efds, &tv, direct);
if (retval == 0)
{
@ -915,7 +930,7 @@ static int read_string_generic(hamlib_port_t *p,
if (FD_ISSET(errorfd, &rfds))
{
return flush_and_read_last_byte(errorfd);
return flush_and_read_last_byte(p, errorfd, 0);
}
}

Wyświetl plik

@ -658,12 +658,13 @@ static int multicast_publisher_read_packet(int fd, uint8_t *type, struct rig_spe
void *multicast_publisher(void *arg)
{
unsigned char spectrum_data[HAMLIB_MAX_SPECTRUM_DATA];
char snapshot_buffer[HAMLIB_MAX_SNAPSHOT_PACKET_SIZE];
struct multicast_publisher_args_s *args = (struct multicast_publisher_args_s *)arg;
RIG *rig = args->rig;
struct rig_state *rs = &rig->state;
struct rig_spectrum_line spectrum_line;
unsigned char spectrum_data[2048];
char snapshot_buffer[16 * 1024];
uint8_t packet_type;
struct sockaddr_in dest_addr;

Wyświetl plik

@ -6376,7 +6376,7 @@ int HAMLIB_API rig_get_rig_info(RIG *rig, char *response, int max_response_len)
if (ret != RIG_OK) { RETURNFUNC(ret); }
// we need both vfo and mode targtable to avoid vfo swapping
// we need both vfo and mode targetable to avoid vfo swapping
if ((rig->caps->targetable_vfo & RIG_TARGETABLE_FREQ)
&& (rig->caps->targetable_vfo & RIG_TARGETABLE_MODE))
{

Wyświetl plik

@ -9,14 +9,65 @@
#include "cJSON.h"
// Maximum number of data bytes in a single spectrum line
#define SPECTRUM_DATA_MAX_LENGTH 2048
#define MAX_VFO_COUNT 4
#define SPECTRUM_MODE_FIXED "FIXED"
#define SPECTRUM_MODE_CENTER "CENTER"
static int snapshot_serialize_rig(cJSON *rig_node, RIG *rig)
{
cJSON *node;
// TODO: need to assign rig an ID, e.g. from command line
node = cJSON_AddStringToObject(rig_node, "id", "rig_id");
if (node == NULL)
{
goto error;
}
// TODO: what kind of status should this reflect?
node = cJSON_AddStringToObject(rig_node, "status", rig->state.comm_state ? "OK" : "CLOSED");
if (node == NULL)
{
goto error;
}
// TODO: need to store last error code
node = cJSON_AddStringToObject(rig_node, "errorMsg", "");
if (node == NULL)
{
goto error;
}
node = cJSON_AddStringToObject(rig_node, "name", rig->caps->model_name);
if (node == NULL)
{
goto error;
}
node = cJSON_AddBoolToObject(rig_node, "split", rig->state.cache.split == RIG_SPLIT_ON ? 1 : 0);
if (node == NULL)
{
goto error;
}
node = cJSON_AddStringToObject(rig_node, "splitVfo", rig_strvfo(rig->state.cache.split_vfo));
if (node == NULL)
{
goto error;
}
node = cJSON_AddBoolToObject(rig_node, "satMode", rig->state.cache.satmode ? 1 : 0);
if (node == NULL)
{
goto error;
}
RETURNFUNC(RIG_OK);
error:
RETURNFUNC(-RIG_EINTERNAL);
}
static int snapshot_serialize_vfo(cJSON *vfo_node, RIG *rig, vfo_t vfo)
{
freq_t freq;
@ -91,7 +142,7 @@ static int snapshot_serialize_vfo(cJSON *vfo_node, RIG *rig, vfo_t vfo)
static int snapshot_serialize_spectrum(cJSON *spectrum_node, RIG *rig, struct rig_spectrum_line *spectrum_line)
{
// Spectrum data is represented as a hexadecimal ASCII string where each data byte is represented as 2 ASCII letters
char spectrum_data_string[SPECTRUM_DATA_MAX_LENGTH * 2];
char spectrum_data_string[HAMLIB_MAX_SPECTRUM_DATA * 2];
cJSON *node;
int i;
struct rig_spectrum_scope *scopes = rig->caps->spectrum_scopes;
@ -243,49 +294,15 @@ int snapshot_serialize(size_t buffer_length, char *buffer, RIG *rig, struct rig_
goto error;
}
result = snapshot_serialize_rig(rig_node, rig);
if (result != RIG_OK)
{
cJSON_Delete(rig_node);
goto error;
}
cJSON_AddItemToObject(root_node, "rig", rig_node);
node = cJSON_AddStringToObject(rig_node, "id", "rig_id");
if (node == NULL)
{
goto error;
}
node = cJSON_AddStringToObject(rig_node, "status", "");
if (node == NULL)
{
goto error;
}
node = cJSON_AddStringToObject(rig_node, "errorMsg", "");
if (node == NULL)
{
goto error;
}
node = cJSON_AddStringToObject(rig_node, "name", rig->caps->model_name);
if (node == NULL)
{
goto error;
}
node = cJSON_AddBoolToObject(rig_node, "split", rig->state.cache.split == RIG_SPLIT_ON ? 1 : 0);
if (node == NULL)
{
goto error;
}
node = cJSON_AddStringToObject(rig_node, "splitVfo", rig_strvfo(rig->state.cache.split_vfo));
if (node == NULL)
{
goto error;
}
node = cJSON_AddBoolToObject(rig_node, "satMode", 0);
if (node == NULL)
{
goto error;
}
vfos_array = cJSON_CreateArray();
if (vfos_array == NULL)
{