diff --git a/src/fifo.c b/src/fifo.c index 44b00c8a9..3272188e0 100644 --- a/src/fifo.c +++ b/src/fifo.c @@ -48,6 +48,7 @@ int main() // Popping and printing one character at a time int c; + while ((c = pop(&fifo)) != -1) { printf("%c", c); diff --git a/src/iofunc.c b/src/iofunc.c index 42942b3f6..0fc8551d2 100644 --- a/src/iofunc.c +++ b/src/iofunc.c @@ -1337,7 +1337,10 @@ static int read_string_generic(hamlib_port_t *p, { ssize_t rd_count = 0; int result; + int timeout_save = p->timeout; + p->timeout = 2; result = port_wait_for_data(p, direct); + p->timeout = timeout_save; if (result == -RIG_ETIMEOUT) { diff --git a/src/rig.c b/src/rig.c index 7bc854191..21cec3a13 100644 --- a/src/rig.c +++ b/src/rig.c @@ -1,3 +1,4 @@ +Add current_vfo to cache debug statementy /* * Hamlib Interface - main file * Copyright (c) 2021 by Mikael Nousiainen @@ -51,6 +52,7 @@ #include "hamlib/rig.h" #include "hamlib/config.h" +#include "fifo.h" #include #include @@ -240,6 +242,22 @@ static int async_data_handler_stop(RIG *rig); void *async_data_handler(void *arg); #endif +typedef struct morse_data_handler_args_s +{ + RIG *rig; +} morse_data_handler_args; + +typedef struct morse_data_handler_priv_data_s +{ + pthread_t thread_id; + morse_data_handler_args args; + FIFO fifo; +} morse_data_handler_priv_data; + +static int morse_data_handler_start(RIG *rig); +static int morse_data_handler_stop(RIG *rig); +void *morse_data_handler(void *arg); + /* * track which rig is opened (with rig_open) * needed at least for transceive mode @@ -563,7 +581,7 @@ RIG *HAMLIB_API rig_init(rig_model_t rig_model) rs->rig_model = caps->rig_model; rs->priv = NULL; - rs->async_data_enabled = 1; +// rs->async_data_enabled = 1; rs->rigport.fd = -1; rs->pttport.fd = -1; rs->comm_state = 0; @@ -1303,6 +1321,16 @@ int HAMLIB_API rig_open(RIG *rig) rs->comm_state); hl_usleep(100 * 1000); // wait a bit after opening to give some serial ports time + status = morse_data_handler_start(rig); + + if (status < 0) + { + rig_debug(RIG_DEBUG_ERR, "%s: cw_data_handler_start failed: %s\n", __func__, rigerror(status)); + port_close(&rs->rigport, rs->rigport.type.rig); + RETURNFUNC2(status); + } + + /* * Maybe the backend has something to initialize * In case of failure, just close down and report error code. @@ -1344,6 +1372,7 @@ int HAMLIB_API rig_open(RIG *rig) { remove_opened_rig(rig); async_data_handler_stop(rig); + morse_data_handler_stop(rig); port_close(&rs->rigport, rs->rigport.type.rig); memcpy(&rs->rigport_deprecated, &rs->rigport, sizeof(hamlib_port_t_deprecated)); rs->comm_state = 0; @@ -1494,6 +1523,7 @@ int HAMLIB_API rig_close(RIG *rig) caps->rig_close(rig); } + morse_data_handler_stop(rig); async_data_handler_stop(rig); /* @@ -7741,6 +7771,39 @@ static int async_data_handler_start(RIG *rig) RETURNFUNC(RIG_OK); } +static int morse_data_handler_start(RIG *rig) +{ + struct rig_state *rs = &rig->state; + morse_data_handler_priv_data *morse_data_handler_priv; + + ENTERFUNC; + + rs->morse_data_handler_thread_run = 1; + rs->morse_data_handler_priv_data = calloc(1, + sizeof(morse_data_handler_priv_data)); + + if (rs->morse_data_handler_priv_data == NULL) + { + RETURNFUNC(-RIG_ENOMEM); + } + + morse_data_handler_priv = (morse_data_handler_priv_data *) + rs->morse_data_handler_priv_data; + morse_data_handler_priv->args.rig = rig; + int err = pthread_create(&morse_data_handler_priv->thread_id, NULL, + morse_data_handler, &morse_data_handler_priv->args); + + if (err) + { + rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, + strerror(errno)); + RETURNFUNC(-RIG_EINTERNAL); + } + + RETURNFUNC(RIG_OK); +} + + static int async_data_handler_stop(RIG *rig) { struct rig_state *rs = &rig->state; @@ -7782,6 +7845,45 @@ static int async_data_handler_stop(RIG *rig) RETURNFUNC(RIG_OK); } +static int morse_data_handler_stop(RIG *rig) +{ + struct rig_state *rs = &rig->state; + morse_data_handler_priv_data *morse_data_handler_priv; + + ENTERFUNC; + + rs->morse_data_handler_thread_run = 0; + + morse_data_handler_priv = (morse_data_handler_priv_data *) + rs->morse_data_handler_priv_data; + + if (morse_data_handler_priv != NULL) + { + if (morse_data_handler_priv->thread_id != 0) + { + // all cleanup is done in this function so we can kill thread + // Windows was taking 30 seconds to stop without this + pthread_cancel(morse_data_handler_priv->thread_id); + int err = pthread_join(morse_data_handler_priv->thread_id, NULL); + + if (err) + { + rig_debug(RIG_DEBUG_ERR, "%s: pthread_join error: %s\n", __func__, + strerror(errno)); + // just ignore the error + } + + morse_data_handler_priv->thread_id = 0; + } + + free(rs->morse_data_handler_priv_data); + rs->morse_data_handler_priv_data = NULL; + } + + RETURNFUNC(RIG_OK); +} + + void *async_data_handler(void *arg) { struct async_data_handler_args_s *args = (struct async_data_handler_args_s *) @@ -7822,7 +7924,7 @@ void *async_data_handler(void *arg) __func__, result); hl_usleep(500 * 1000); } - + hl_usleep(10*1000); continue; } @@ -7867,6 +7969,40 @@ void *async_data_handler(void *arg) } #endif +void *morse_data_handler(void *arg) +{ + struct morse_data_handler_args_s *args = (struct morse_data_handler_args_s *) + arg; + RIG *rig = args->rig; + struct rig_state *rs = &rig->state; + int result; + FIFO fifo; + + rig_debug(RIG_DEBUG_VERBOSE, "%s: Starting morse data handler thread\n", + __func__); + + initFIFO(&fifo); + while (rs->morse_data_handler_thread_run) + { + char c[2]; + c[1] = 0; + while((c[0]=pop(&fifo)!=-1)) + { + result = rig_send_morse(rig, RIG_VFO_CURR, c); + if (result != RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s: error: %s\n", __func__, rigerror(result)); + push(&fifo, c); + hl_usleep(20*1000); + } + } + hl_usleep(20*1000); + } + pthread_exit(NULL); + return NULL; +} + + HAMLIB_EXPORT(int) rig_password(RIG *rig, const char *key1) { int retval = -RIG_EPROTO; @@ -8034,3 +8170,5 @@ HAMLIB_EXPORT(int) rig_is_model(RIG *rig, rig_model_t model) return (is_rig); // RETURN is too verbose here } + +