From 4b8de5f96d548860f4cca1ab6d3db7e0d274cc15 Mon Sep 17 00:00:00 2001 From: Mikael Nousiainen Date: Wed, 10 May 2023 20:53:18 +0300 Subject: [PATCH] Change float level granularity formatting to use %f to avoid E notation. Fix AGC_TIME level range for Icom rigs. Fix listing of AGC levels in \dump_caps. Add \stop_morse and \wait_morse in \dump_caps. Add simulation of responses in \send_cmd_rx and \send_raw for dummy rig (and if rig port type is NONE). Fix other minor issues. --- rigs/dummy/dummy.c | 4 ++ rigs/icom/ic7300.c | 3 -- rigs/icom/icom.c | 4 +- rigs/icom/level_gran_icom.h | 2 +- src/misc.c | 10 ++-- src/rig.c | 99 +++++++++++++++++++++---------------- src/sprintflst.c | 10 ++-- tests/dumpcaps.c | 21 ++------ tests/rigctl_parse.c | 70 ++++++++++++++++++-------- 9 files changed, 127 insertions(+), 96 deletions(-) diff --git a/rigs/dummy/dummy.c b/rigs/dummy/dummy.c index 0479f2d7c..3a4625d91 100644 --- a/rigs/dummy/dummy.c +++ b/rigs/dummy/dummy.c @@ -2287,6 +2287,10 @@ struct rig_caps dummy_caps = .has_get_parm = DUMMY_PARM, .has_set_parm = RIG_PARM_SET(DUMMY_PARM), .level_gran = { + [LVL_RF] = { .min = { .f = 0 }, .max = { .f = 1.0f }, .step = { .f = 1.0f/255.0f } }, + [LVL_RFPOWER] = { .min = { .f = .05f }, .max = { .f = 1 }, .step = { .f = 1.0f/511.0f } }, + [LVL_RFPOWER_METER] = { .min = { .f = .0f }, .max = { .f = 1 }, .step = { .f = 1.0f/255.0f } }, + [LVL_RFPOWER_METER_WATTS] = { .min = { .f = .0f }, .max = { .f = 100 }, .step = { .f = 1.0f/255.0f } }, [LVL_CWPITCH] = { .step = { .i = 10 } }, [LVL_SPECTRUM_SPEED] = {.min = {.i = 0}, .max = {.i = 2}, .step = {.i = 1}}, [LVL_SPECTRUM_REF] = {.min = {.f = -30.0f}, .max = {.f = 10.0f}, .step = {.f = 0.5f}}, diff --git a/rigs/icom/ic7300.c b/rigs/icom/ic7300.c index 7740c18b8..7a5a1c03a 100644 --- a/rigs/icom/ic7300.c +++ b/rigs/icom/ic7300.c @@ -580,7 +580,6 @@ const struct rig_caps ic7300_caps = [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, - [LVL_AGC_TIME] = {.min = {.f = 0.0f}, .max = {.f = 8.0f}, .step = {.f = 0.1f }}, }, .parm_gran = {}, .ext_tokens = ic7300_ext_tokens, @@ -816,7 +815,6 @@ struct rig_caps ic9700_caps = [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, - [LVL_AGC_TIME] = {.min = {.f = 0.0f}, .max = {.f = 8.0f}, .step = {.f = 0.1f }}, }, .parm_gran = {}, .ext_tokens = ic9700_ext_tokens, @@ -1129,7 +1127,6 @@ const struct rig_caps ic705_caps = [LVL_SPECTRUM_REF] = {.min = {.f = -20.0f}, .max = {.f = 20.0f}, .step = {.f = 0.5f}}, [LVL_SPECTRUM_AVG] = {.min = {.i = 0}, .max = {.i = 3}, .step = {.i = 1}}, [LVL_USB_AF] = {.min = {.f = 0.0f}, .max = {.f = 1.0f}, .step = {.f = 1.0f / 255.0f }}, - [LVL_AGC_TIME] = {.min = {.f = 0.0f}, .max = {.f = 8.0f}, .step = {.f = 0.1f }}, }, .parm_gran = {}, .ext_tokens = ic705_ext_tokens, diff --git a/rigs/icom/icom.c b/rigs/icom/icom.c index 07e515d82..2c3bb3ce2 100644 --- a/rigs/icom/icom.c +++ b/rigs/icom/icom.c @@ -3508,13 +3508,13 @@ int icom_set_level(RIG *rig, vfo_t vfo, setting_t level, value_t val) if (rig->state.current_mode == RIG_MODE_AM) { agcp = agc_level2; } - rig_debug(RIG_DEBUG_ERR, "%s: val.f=%g\n", __func__, val.f); + rig_debug(RIG_DEBUG_ERR, "%s: val.f=%f\n", __func__, val.f); for (i = 0; i <= 13; ++i) { if (agcp[i] <= val.f) { - rig_debug(RIG_DEBUG_ERR, "%s: agcp=%g <= val.f=%g at %d\n", __func__, agcp[i], + rig_debug(RIG_DEBUG_ERR, "%s: agcp=%f <= val.f=%f at %d\n", __func__, agcp[i], val.f, i); icom_val = i; } diff --git a/rigs/icom/level_gran_icom.h b/rigs/icom/level_gran_icom.h index 0c8d2cc59..b3f8a5658 100644 --- a/rigs/icom/level_gran_icom.h +++ b/rigs/icom/level_gran_icom.h @@ -30,7 +30,7 @@ LVL_KEYSPD [LVL_VOXDELAY] = { .min = { .i = 0 }, .max = { .i = 20 }, .step = { .i = 1 } }, [LVL_BKINDL] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, [LVL_BKIN_DLYMS] = { .min = { .i = 30 }, .max = { .i = 3000 }, .step = { .i = 1 } }, - [LVL_AGC_TIME] = { .min = { .i = 0 }, .max = { .i = 8000 }, .step = { .i = 1 } }, + [LVL_AGC_TIME] = { .min = { .f = 0.0f }, .max = { .f = 8.0f }, .step = { .f = 0.1f } }, /* level with misc units */ [LVL_SWR] = { .min = { .f = 0 }, .max = { .f = 5.0 }, .step = { .f = 1.0f/255.0f } }, [LVL_BAND_SELECT] = { .min = { .i = 0 }, .max = { .i = 16 }, .step = { .i = 1 } }, diff --git a/src/misc.c b/src/misc.c index 518e8c250..77eaf1e0e 100644 --- a/src/misc.c +++ b/src/misc.c @@ -2156,6 +2156,11 @@ int HAMLIB_API parse_hoststr(char *hoststr, int hoststr_len, char host[256], //#define RIG_FLUSH_REMOVE int HAMLIB_API rig_flush(hamlib_port_t *port) { + if (port->type.rig == RIG_PORT_NONE) + { + return RIG_OK; + } + // Data should never be flushed when using async I/O if (port->asyncio) { @@ -2166,11 +2171,6 @@ int HAMLIB_API rig_flush(hamlib_port_t *port) rig_debug(RIG_DEBUG_TRACE, "%s: called for %s device\n", __func__, port->type.rig == RIG_PORT_SERIAL ? "serial" : "network"); - if (port->type.rig == RIG_PORT_NONE) - { - return RIG_OK; - } - if (port->type.rig == RIG_PORT_NETWORK || port->type.rig == RIG_PORT_UDP_NETWORK) { diff --git a/src/rig.c b/src/rig.c index 41fe231ad..a7ab9bdf5 100644 --- a/src/rig.c +++ b/src/rig.c @@ -7712,70 +7712,85 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, struct rig_state *rs = &rig->state; unsigned char buf[200]; int nbytes; + int retval; + int simulate = rig->caps->rig_model == RIG_MODEL_DUMMY || + rig->caps->rig_model == RIG_MODEL_NONE || + rs->rigport.rig == RIG_PORT_NONE; ENTERFUNC; - if (rig->caps->rig_model == RIG_MODEL_DUMMY - || rig->caps->rig_model == RIG_MODEL_NONE) - { - rig_debug(RIG_DEBUG_ERR, "%s: not implemented for model %s\n", __func__, - rig->caps->model_name); - return -RIG_ENAVAIL; - } - ELAPSED1; rig_debug(RIG_DEBUG_VERBOSE, "%s: writing %d bytes\n", __func__, send_len); - int retval = write_block(&rs->rigport, send, send_len); - if (retval < 0) + if (simulate) { - // TODO: error handling? can writing to a pipe really fail in ways we can recover from? - rig_debug(RIG_DEBUG_ERR, "%s: write_block_sync() failed, result=%d\n", __func__, - retval); + rig_debug(RIG_DEBUG_VERBOSE, "%s: simulating response for model %s\n", + __func__, rig->caps->model_name); + retval = send_len; + } + else + { + retval = write_block(&rs->rigport, send, send_len); + + if (retval < 0) + { + // TODO: error handling? can writing to a pipe really fail in ways we can recover from? + rig_debug(RIG_DEBUG_ERR, "%s: write_block_sync() failed, result=%d\n", __func__, + retval); + } } if (reply) { - if (term == - NULL) // we have to have terminating char or else we can't read the response + // we have to have terminating char or else we can't read the response + if (term == NULL) { rig_debug(RIG_DEBUG_ERR, "%s: term==NULL, must have terminator to read reply\n", __func__); RETURNFUNC(-RIG_EINVAL); } - if (*term == 0xfd) // then we want an Icom frame + if (simulate) { - rig_debug(RIG_DEBUG_VERBOSE, "%s: reading icom frame\n", __func__); - retval = read_icom_frame(&rs->rigport, buf, sizeof(buf)); - nbytes = retval; + // Simulate a response by copying the command + memcpy(buf, send, send_len); + nbytes = send_len + 1; } - else if (term == NULL) + else { - rig_debug(RIG_DEBUG_VERBOSE, "%s: reading binary frame\n", __func__); - nbytes = read_string_direct(&rs->rigport, buf, reply_len, (const char *)term, - 1, 0, 1); - } - else // we'll assume the provided terminator works - { - rig_debug(RIG_DEBUG_VERBOSE, "%s: reading frame terminated by '%s'\n", __func__, - term); - nbytes = read_string_direct(&rs->rigport, buf, sizeof(buf), (const char *)term, - 1, 0, 1); - } + if (*term == 0xfd) // then we want an Icom frame + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: reading icom frame\n", __func__); + retval = read_icom_frame(&rs->rigport, buf, sizeof(buf)); + nbytes = retval; + } + else if (term == NULL) + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: reading binary frame\n", __func__); + nbytes = read_string_direct(&rs->rigport, buf, reply_len, (const char *)term, + 1, 0, 1); + } + else // we'll assume the provided terminator works + { + rig_debug(RIG_DEBUG_VERBOSE, "%s: reading frame terminated by '%s'\n", __func__, + term); + nbytes = read_string_direct(&rs->rigport, buf, sizeof(buf), (const char *)term, + 1, 0, 1); + } - if (retval < RIG_OK) - { - rig_debug(RIG_DEBUG_ERR, "%s: read_string_direct, result=%d\n", __func__, - retval); - RETURNFUNC(retval); - } + if (retval < RIG_OK) + { + rig_debug(RIG_DEBUG_ERR, "%s: read_string_direct, result=%d\n", __func__, + retval); + RETURNFUNC(retval); + } - if (nbytes >= reply_len) - { - rig_debug(RIG_DEBUG_ERR, "%s: reply_len(%d) less than reply from rig(%d)\n", - __func__, reply_len, nbytes); - return -RIG_EINVAL; + if (nbytes >= reply_len) + { + rig_debug(RIG_DEBUG_ERR, "%s: reply_len(%d) less than reply from rig(%d)\n", + __func__, reply_len, nbytes); + return -RIG_EINVAL; + } } memcpy(reply, buf, reply_len - 1); diff --git a/src/sprintflst.c b/src/sprintflst.c index 6a6c870f0..afb344b45 100644 --- a/src/sprintflst.c +++ b/src/sprintflst.c @@ -386,7 +386,7 @@ int rig_sprintf_level_gran(char *str, int nlen, setting_t level, if (RIG_LEVEL_IS_FLOAT(rig_idx2setting(i))) { len += sprintf(str + len, - "%s(%g..%g/%g) ", + "%s(%f..%f/%f) ", ms, gran[i].min.f, gran[i].max.f, @@ -445,7 +445,7 @@ int rot_sprintf_level_gran(char *str, int nlen, setting_t level, if (ROT_LEVEL_IS_FLOAT(rig_idx2setting(i))) { len += sprintf(str + len, - "%s(%g..%g/%g) ", + "%s(%f..%f/%f) ", ms, gran[i].min.f, gran[i].max.f, @@ -564,7 +564,7 @@ int rig_sprintf_parm_gran(char *str, int nlen, setting_t parm, if (RIG_PARM_IS_FLOAT(rig_idx2setting(i))) { len += sprintf(str + len, - "%s(%g..%g/%g) ", + "%s(%f..%f/%f) ", ms, gran[i].min.f, gran[i].max.f, @@ -623,7 +623,7 @@ int rot_sprintf_parm_gran(char *str, int nlen, setting_t parm, if (ROT_PARM_IS_FLOAT(rig_idx2setting(i))) { len += sprintf(str + len, - "%s(%g..%g/%g) ", + "%s(%f..%f/%f) ", ms, gran[i].min.f, gran[i].max.f, @@ -877,7 +877,7 @@ int print_ext_param(const struct confparams *cfp, rig_ptr_t ptr) switch (cfp->type) { case RIG_CONF_NUMERIC: - fprintf((FILE *)ptr, "\t\tRange: %g..%g/%g\n", cfp->u.n.min, cfp->u.n.max, + fprintf((FILE *)ptr, "\t\tRange: %f..%f/%f\n", cfp->u.n.min, cfp->u.n.max, cfp->u.n.step); break; diff --git a/tests/dumpcaps.c b/tests/dumpcaps.c index ae6874436..5b911fba6 100644 --- a/tests/dumpcaps.c +++ b/tests/dumpcaps.c @@ -301,7 +301,7 @@ int dumpcaps(RIG *rig, FILE *fout) if (priv_caps && RIG_BACKEND_NUM(rig->caps->rig_model) == RIG_ICOM && priv_caps->agc_levels_present) { - for (i = 0; i <= RIG_AGC_LAST && priv_caps->agc_levels[i].level != RIG_AGC_LAST + for (i = 0; i < HAMLIB_MAX_AGC_LEVELS && priv_caps->agc_levels[i].level != RIG_AGC_LAST && priv_caps->agc_levels[i].icom_level >= 0; i++) { fprintf(fout, " %d=%s", priv_caps->agc_levels[i].level, @@ -310,31 +310,16 @@ int dumpcaps(RIG *rig, FILE *fout) } else { - for (i = 0; i < HAMLIB_MAX_AGC_LEVELS && i < caps->agc_level_count; i++) { fprintf(fout, " %d=%s", caps->agc_levels[i], rig_stragclevel(caps->agc_levels[i])); } - - if (i == 0) - { - fprintf(fout, " %d=%s", RIG_AGC_NONE, rig_stragclevel(RIG_AGC_NONE)); - } } - fprintf(fout, "\n"); - if (i == 0) { - rig_debug(RIG_DEBUG_WARN, - "%s: defaulting to all levels since rig does not have any\n", __func__); - - // Fall back to printing out all levels for backwards-compatibility - for (i = RIG_AGC_OFF; i <= RIG_AGC_LAST; i++) - { - fprintf(fout, " %d=%s", i, rig_stragclevel(i)); - } + fprintf(fout, " %d=%s", RIG_AGC_NONE, rig_stragclevel(RIG_AGC_NONE)); } fprintf(fout, "\n"); @@ -903,6 +888,8 @@ int dumpcaps(RIG *rig, FILE *fout) fprintf(fout, "Can send DTMF:\t%c\n", caps->send_dtmf != NULL ? 'Y' : 'N'); fprintf(fout, "Can recv DTMF:\t%c\n", caps->recv_dtmf != NULL ? 'Y' : 'N'); fprintf(fout, "Can send Morse:\t%c\n", caps->send_morse != NULL ? 'Y' : 'N'); + fprintf(fout, "Can stop Morse:\t%c\n", caps->stop_morse != NULL ? 'Y' : 'N'); + fprintf(fout, "Can wait Morse:\t%c\n", caps->wait_morse != NULL ? 'Y' : 'N'); fprintf(fout, "Can send Voice:\t%c\n", caps->send_voice_mem != NULL ? 'Y' : 'N'); diff --git a/tests/rigctl_parse.c b/tests/rigctl_parse.c index 331363ed0..f32678ab8 100644 --- a/tests/rigctl_parse.c +++ b/tests/rigctl_parse.c @@ -1747,8 +1747,7 @@ readline_repeat: rig_debug(RIG_DEBUG_WARN, "%s: command %s not allowed when rig is powered off\n", __func__, cmd_entry->name); -// retcode = -RIG_EPOWER; - retcode = RIG_OK; + retcode = -RIG_EPOWER; } else { @@ -4787,6 +4786,9 @@ declare_proto_rig(send_cmd) char eom_buf[4] = { 0xa, 0xd, 0, 0 }; int binary = 0; int rxbytes = BUFSZ; + int simulate = rig->caps->rig_model == RIG_MODEL_DUMMY || + rig->caps->rig_model == RIG_MODEL_NONE || + rs->rigport.rig == RIG_PORT_NONE; ENTERFUNC; @@ -4890,19 +4892,28 @@ declare_proto_rig(send_cmd) rs = &rig->state; - rig_flush(&rs->rigport); - rig_debug(RIG_DEBUG_TRACE, "%s: rigport=%d, bufcmd=%s, cmd_len=%d\n", __func__, rs->rigport.fd, hasbinary(bufcmd, cmd_len) ? "BINARY" : bufcmd, cmd_len); - // we don't want the 'w' command to wait too long - int save_retry = rs->rigport.retry; - rs->rigport.retry = 0; - retval = write_block(&rs->rigport, (unsigned char *) bufcmd, cmd_len); - rs->rigport.retry = save_retry; - if (retval != RIG_OK) + if (simulate) { - RETURNFUNC(retval); + rig_debug(RIG_DEBUG_VERBOSE, "%s: simulating response for model %s\n", + __func__, rig->caps->model_name); + } + else + { + rig_flush(&rs->rigport); + + // we don't want the 'w' command to wait too long + int save_retry = rs->rigport.retry; + rs->rigport.retry = 0; + retval = write_block(&rs->rigport, (unsigned char *) bufcmd, cmd_len); + rs->rigport.retry = save_retry; + + if (retval != RIG_OK) + { + RETURNFUNC(retval); + } } if ((interactive && prompt) || (interactive && !prompt && ext_resp)) @@ -4912,6 +4923,7 @@ declare_proto_rig(send_cmd) fwrite(": ", 1, 2, fout); /* i.e. "Frequency" */ } + retval = 0; do { if (arg2) { sscanf(arg2, "%d", &rxbytes); } @@ -4924,17 +4936,33 @@ declare_proto_rig(send_cmd) if (arg2[0] == ';') { eom_buf[0] = ';'; } - /* Assumes CR or LF is end of line char for all ASCII protocols. */ - retval = read_string(&rs->rigport, buf, rxbytes, eom_buf, - strlen(eom_buf), 0, 1); - - if (retval < 0) + if (simulate) { - rig_debug(RIG_DEBUG_ERR, "%s: read_string error %s\n", __func__, - rigerror(retval)); - - break; + if (retval == 0) + { + // Simulate a response by copying the command + memcpy(buf, bufcmd, cmd_len); + retval = cmd_len; + } + else + { + retval = 0; + } } + else + { + /* Assumes CR or LF is end of line char for all ASCII protocols. */ + retval = read_string(&rs->rigport, buf, rxbytes, eom_buf, + strlen(eom_buf), 0, 1); + + if (retval < 0) + { + rig_debug(RIG_DEBUG_ERR, "%s: read_string error %s\n", __func__, + rigerror(retval)); + break; + } + } + if (retval < BUFSZ) { @@ -4990,7 +5018,7 @@ declare_proto_rig(send_cmd) } while (retval > 0 && rxbytes == BUFSZ); -// we use fwrite in case of any nulls in binary return + // we use fwrite in case of any nulls in binary return if (binary) { fwrite(buf, 1, retval, fout); } if (binary)