diff --git a/include/hamlib/rig.h b/include/hamlib/rig.h index 62575eed7..359ea3d32 100644 --- a/include/hamlib/rig.h +++ b/include/hamlib/rig.h @@ -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 diff --git a/src/event.c b/src/event.c index e3183acef..eab14978f 100644 --- a/src/event.c +++ b/src/event.c @@ -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); } diff --git a/src/iofunc.c b/src/iofunc.c index c6f14e137..e8d2ad1a1 100644 --- a/src/iofunc.c +++ b/src/iofunc.c @@ -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); } } diff --git a/src/network.c b/src/network.c index 9b5c4a5cc..cc9a4ac97 100644 --- a/src/network.c +++ b/src/network.c @@ -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; diff --git a/src/rig.c b/src/rig.c index 1bb6885bb..fa563857b 100644 --- a/src/rig.c +++ b/src/rig.c @@ -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)) { diff --git a/src/snapshot_data.c b/src/snapshot_data.c index 71876778a..baba1d1d9 100644 --- a/src/snapshot_data.c +++ b/src/snapshot_data.c @@ -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) {