From 34f20cc970af8ea5cc113a9df58f4ed7f1de08bc Mon Sep 17 00:00:00 2001 From: Mike Black W9MDB Date: Sat, 27 May 2023 12:51:24 -0500 Subject: [PATCH] Add thread to anytone.c to do the keep alive it needs https://github.com/Hamlib/Hamlib/issues/1303 --- rigs/anytone/anytone.c | 51 ++++++++++++++++++++++++++++++++++++++---- rigs/anytone/anytone.h | 13 +++++++++++ simulators/simatd578.c | 22 +++++++++++------- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/rigs/anytone/anytone.c b/rigs/anytone/anytone.c index 7b95f0a28..44486b617 100644 --- a/rigs/anytone/anytone.c +++ b/rigs/anytone/anytone.c @@ -29,6 +29,7 @@ #include #include #include +#include // --------------------------------------------------------------------------- // HAMLIB INCLUDES @@ -117,6 +118,30 @@ DECLARE_PROBERIG_BACKEND(anytone) return retval; } +// AnyTone needs a keep-alive to emulate the MIC +// Apparently to keep the rig from getting stuck in PTT if mic disconnects +void *anytone_thread(void *vrig) +{ + RIG *rig = (RIG *)vrig; + anytone_priv_data_t *p = rig->state.priv; + rig_debug(RIG_DEBUG_TRACE, "%s: anytone_thread started\n", __func__); + p->runflag = 1; + + while (p->runflag) + { + char c = 0x06; + MUTEX_LOCK(p->priv.mutex); + write_block(&rig->state.rigport, (unsigned char *)&c, 1); + hl_usleep(100 * 1000); + rig_flush(&rig->state.rigport); + MUTEX_UNLOCK(p->priv.mutex); + hl_usleep(1000 * 1000); // 1-second loop + + } + + return NULL; +} + // --------------------------------------------------------------------------- // anytone_send // --------------------------------------------------------------------------- @@ -174,6 +199,7 @@ int anytone_transaction(RIG *rig, char *cmd, int cmd_len) } else { + MUTEX_LOCK(p->priv.mutex); retval = anytone_send(rig, cmd, cmd_len); if (retval == RIG_OK) @@ -181,6 +207,8 @@ int anytone_transaction(RIG *rig, char *cmd, int cmd_len) char buf[16]; anytone_receive(rig, buf, sizeof(buf), 1); } + + MUTEX_LOCK(p->priv.mutex); } RETURNFUNC(retval); @@ -212,6 +240,9 @@ int anytone_init(RIG *rig) rig->state.priv = pPriv; anytone_priv_data_t *p = rig->state.priv; p->vfo_curr = RIG_VFO_NONE; +#ifdef HAVE_PTHREAD + pthread_mutex_init(&p->mutex, NULL); +#endif } RETURNFUNC(retval); @@ -265,6 +296,17 @@ int anytone_open(RIG *rig) // can we ask for any information? Maybe just toggle A/B? } + pthread_t id; + int err = pthread_create(&id, NULL, anytone_thread, (void *)rig); + + if (err) + { + rig_debug(RIG_DEBUG_ERR, "%s: pthread_create error: %s\n", __func__, + strerror(errno)); + RETURNFUNC(-RIG_EINTERNAL); + } + + RETURNFUNC(retval); } @@ -333,18 +375,19 @@ int anytone_set_vfo(RIG *rig, vfo_t vfo) } else { + // can we use status reponse to deteremin which VFO is active? if (vfo == RIG_VFO_A) { - char buf1[8] = { 0x41, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x06 }; - char buf2[8] = { 0x41, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x06 }; + char buf1[8] = { 0x41, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x06 }; + char buf2[8] = { 0x41, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x06 }; anytone_transaction(rig, buf1, 8); hl_usleep(100 * 1000); anytone_transaction(rig, buf2, 8); } else { - char buf1[8] = { 0x41, 0x00, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x06 }; - char buf2[8] = { 0x41, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x06 }; + char buf1[8] = { 0x41, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x06 }; + char buf2[8] = { 0x41, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x06 }; anytone_transaction(rig, buf1, 8); hl_usleep(100 * 1000); anytone_transaction(rig, buf2, 8); diff --git a/rigs/anytone/anytone.h b/rigs/anytone/anytone.h index bafa6f60c..2388f3c54 100644 --- a/rigs/anytone/anytone.h +++ b/rigs/anytone/anytone.h @@ -9,10 +9,23 @@ extern const struct rig_caps anytone_d578_caps; +#ifdef PTHREAD +#include +#define MUTEX(var) static pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER +#define MUTEX_LOCK(var) pthread_mutex_lock(var) +#define MUTEX_UNLOCK(var) pthread_mutex_unlock(var) +#else +#define MUTEX(var) +#define MUTEX_LOCK(var) +#define MUTEX_UNLOCK(var) +#endif + typedef struct _anytone_priv_data { int ptt; vfo_t vfo_curr; + int runflag; // thread control + pthread_mutex_t mutex; } anytone_priv_data_t, * anytone_priv_data_ptr; diff --git a/simulators/simatd578.c b/simulators/simatd578.c index ca95b2dc6..53560b23a 100644 --- a/simulators/simatd578.c +++ b/simulators/simatd578.c @@ -38,13 +38,14 @@ getmyline(int fd, unsigned char *buf) // seemd the anytone only gives 8-byte commands and 1-byte responses while (i < 8 && read(fd, &c, 1) > 0) { - if (i==0 && buf[i]==0x06) + if (i == 0 && c == 0x06) { - write(fd, buf, 1); + write(fd, &c, 1); } - else { - buf[i++] = c; - n++; + else + { + buf[i++] = c; + n++; } } @@ -96,10 +97,8 @@ int openPort(char *comport) // doesn't matter for using pts devices int main(int argc, char *argv[]) { unsigned char buf[256]; - unsigned char *pbuf; int n; - again: int fd = openPort(argv[1]); @@ -136,8 +135,15 @@ again: n = write(fd, buf, 1); break; - default: printf("Unknown cmd=%02x\n", buf[0]); + case 0x06: + buf[0] = 0x06; + n = write(fd, buf, 1); + break; + + default: printf("Unknown cmd=%02x\n", buf[0]); continue; } + + printf("%d bytes returned\n", n); } return 0;