Implement next phase of threaded rig_send_morse

pull/1330/head^2
Mike Black W9MDB 2023-07-07 22:23:28 -05:00
rodzic fda5b984e7
commit af506f8e15
3 zmienionych plików z 144 dodań i 2 usunięć

Wyświetl plik

@ -48,6 +48,7 @@ int main()
// Popping and printing one character at a time
int c;
while ((c = pop(&fifo)) != -1)
{
printf("%c", c);

Wyświetl plik

@ -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)
{

142
src/rig.c
Wyświetl plik

@ -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 <stdlib.h>
#include <string.h>
@ -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
}