[Hamlib-commits] Hamlib -- Ham radio control libraries branch master updated. 5e13d102af3f90a165159
Library to control radio transceivers and receivers
Brought to you by:
n0nb
From: n0nb <n0...@us...> - 2025-08-12 12:04:02
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Hamlib -- Ham radio control libraries". The branch, master has been updated via 5e13d102af3f90a16515982ccf5f23b93ea6a2dc (commit) via e16f4077e75e70b461bbeb8608af17aa62c642b5 (commit) via 289a3952cefb259da0e39bc3db8b58a31001581c (commit) via 12ec55c3d7493c60a3444beb2a976fe12de2c650 (commit) via 5e336b90c1bef2b972e9e5c0b68177b47554d3c3 (commit) from 0d1481d86f9ebf889525cc53b0f02e14d340361a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5e13d102af3f90a16515982ccf5f23b93ea6a2dc Merge: 0d1481d86 e16f4077e Author: Nate Bargmann <n0...@n0...> Date: Mon Aug 11 08:31:20 2025 -0500 Merge merge GitHub PR #1840 commit e16f4077e75e70b461bbeb8608af17aa62c642b5 Author: Daniele Forsi IU5HKX <iu...@gm...> Date: Mon Aug 11 12:32:46 2025 +0200 Implement the Python bindings and the tests for rig_send_raw() Allows to send either string or bytes and to receive a response converted to the same datatype. Also the "term" argument can be of either type (but it can't contain NULs, it's a single char or byte anyway). Closes #1624. diff --git a/bindings/python/test_Hamlib_Rig_class.py b/bindings/python/test_Hamlib_Rig_class.py index 3f60f0ce6..83387836f 100755 --- a/bindings/python/test_Hamlib_Rig_class.py +++ b/bindings/python/test_Hamlib_Rig_class.py @@ -70,6 +70,7 @@ class TestClass: 'scan', 'send_dtmf', 'send_morse', +'send_raw', 'set_ant', 'set_bank', 'set_channel', diff --git a/bindings/python/test_rig.py b/bindings/python/test_rig.py index 5c0c305ec..ee3c28e31 100755 --- a/bindings/python/test_rig.py +++ b/bindings/python/test_rig.py @@ -190,6 +190,23 @@ class TestClass: assert rig.set_spectrum_callback(None) is None + def do_test_send_raw(self, rig): + """rig_send_raw() tests""" + + # When using the Dummy driver, rig.c replies with a copy of the data + test_string_1 = "test string 012\n" + test_string_2 = test_string_1 * 2 + assert rig.send_raw(test_string_1) == test_string_1 + assert rig.send_raw(test_string_2, "\n") == test_string_1 + assert rig.send_raw(test_string_2, bytes([10])) == test_string_1 + + test_bytes_1 = bytes("test bytes\x00\x01\x02", "ASCII") + test_bytes_2 = test_bytes_1 * 2 + assert rig.send_raw(test_bytes_1) == test_bytes_1 + assert rig.send_raw(test_bytes_1, "s") == b"tes" + assert rig.send_raw(test_bytes_2, b"\x02") == test_bytes_1 + + def test_with_open(self, model, rig_file, serial_speed): """Call all the methods that depend on open()""" rig = Hamlib.Rig(model) @@ -211,6 +228,9 @@ class TestClass: self.do_test_antenna(rig) self.do_test_squelch(rig) self.do_test_callback(rig) + # When using the Dummy driver, rig.c replies with a copy of the data + if model == Hamlib.RIG_MODEL_DUMMY: + self.do_test_send_raw(rig) assert rig.close() is None assert rig.state.comm_state == 0 diff --git a/bindings/rig.swg b/bindings/rig.swg index a062bcfef..7d577afc3 100644 --- a/bindings/rig.swg +++ b/bindings/rig.swg @@ -735,6 +735,48 @@ int *rig_spectrum_cb_python(RIG *rig, struct rig_spectrum_line *rig_spectrum_lin return status; } +#ifdef SWIGPYTHON + PyObject *send_raw(PyObject *send_obj, PyObject *term_obj=NULL) + { + char *send, *term; + size_t send_len; + int reply_len = MAX_RETURNSTR; + unsigned char reply_buffer[MAX_RETURNSTR]; + int count; + + if (PyUnicode_Check(send_obj)) { + send = PyUnicode_AsUTF8AndSize(send_obj, &send_len); + } else if (PyBytes_Check(send_obj)) { + PyBytes_AsStringAndSize(send_obj, &send, &send_len); + } else { + SWIG_Python_RaiseOrModifyTypeError("Expected string or bytes for send argument"); + return NULL; + } + + // Using NULL for length in PyUnicode_AsUTF8AndSize() and PyBytes_AsStringAndSize() + // because we can't accept '\0' because there is no length for term in rig_send_raw() + if (PyUnicode_Check(term_obj)) { + term = PyUnicode_AsUTF8AndSize(term_obj, NULL); + } else if (PyBytes_Check(term_obj)) { + PyBytes_AsStringAndSize(term_obj, &term, NULL); + } else if (term_obj == Py_None) { + term = NULL; + } else { + SWIG_Python_RaiseOrModifyTypeError("Expected string or bytes or NULL for term argument"); + return NULL; + } + + count = rig_send_raw(self->rig, send, send_len, reply_buffer, reply_len, term); + self->error_status = count < 0 ? count : RIG_OK; + + if (PyUnicode_Check(send_obj)) { + return PyUnicode_FromStringAndSize(reply_buffer, count); + } else { + return PyBytes_FromStringAndSize(reply_buffer, count); + } + } +#endif + //#ifndef SWIGJAVA /* TODO */ void get_level(setting_t level, vfo_t vfo = RIG_VFO_CURR) commit 289a3952cefb259da0e39bc3db8b58a31001581c Author: Daniele Forsi IU5HKX <iu...@gm...> Date: Mon Aug 11 12:16:33 2025 +0200 Change the dummy implementation of rig_send_raw() Makes it more similar to the regular version handling also the reply and term arguments. diff --git a/src/rig.c b/src/rig.c index ab800d884..4807011db 100644 --- a/src/rig.c +++ b/src/rig.c @@ -8923,13 +8923,9 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, if (simulate) { - rig_debug(RIG_DEBUG_VERBOSE, "%s: simulating response for model %s\n", - __func__, rig->caps->model_name); - memcpy(reply, send, send_len); - retval = send_len; - set_transaction_inactive(rig); - ELAPSED2; - RETURNFUNC(retval); + rig_debug(RIG_DEBUG_VERBOSE, "%s: simulating write for model %s\n", + __func__, rig->caps->model_name); + retval = RIG_OK; } else { @@ -8950,8 +8946,18 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, if (simulate) { // Simulate a response by copying the command - memcpy(buf, send, send_len); - nbytes = send_len + 1; + rig_debug(RIG_DEBUG_VERBOSE, "%s: simulating response for model %s\n", + __func__, rig->caps->model_name); + + nbytes = send_len < reply_len ? send_len : reply_len; + for (int i = 0; i < nbytes; i++) + { + buf[i] = send[i]; + if (term && memchr(term, send[i], 1)) { + nbytes = i + 1; + break; + } + } } else { commit 12ec55c3d7493c60a3444beb2a976fe12de2c650 Author: Daniele Forsi IU5HKX <iu...@gm...> Date: Sun Aug 10 21:39:15 2025 +0200 Add missing set_transaction_inactive() Otherwise no other command will be executed afterwards. diff --git a/src/rig.c b/src/rig.c index a27e511c7..ab800d884 100644 --- a/src/rig.c +++ b/src/rig.c @@ -8927,6 +8927,7 @@ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, __func__, rig->caps->model_name); memcpy(reply, send, send_len); retval = send_len; + set_transaction_inactive(rig); ELAPSED2; RETURNFUNC(retval); } commit 5e336b90c1bef2b972e9e5c0b68177b47554d3c3 Author: Daniele Forsi IU5HKX <iu...@gm...> Date: Sun Aug 10 11:42:50 2025 +0200 Improve Doxygen comments diff --git a/rigs/tentec/orion.c b/rigs/tentec/orion.c index c2c30d31f..eb635863c 100644 --- a/rigs/tentec/orion.c +++ b/rigs/tentec/orion.c @@ -228,7 +228,7 @@ static int tt565_transaction(RIG *rig, const char *cmd, int cmd_len, char *data, } /** - * \param rig + * \param rig The rig handle * \returns RIG_OK or < 0 * \brief Basically, it just sets up *priv */ @@ -257,7 +257,7 @@ int tt565_close(RIG *rig) } /** - * \param rig + * \param rig The rig handle * \brief tt565_cleanup routine * * the serial port is closed by the frontend @@ -309,7 +309,7 @@ static void start_thread(RIG *rig) } /** - * \param rig + * \param rig The rig handle * \brief tt565_open routine * * Open the rig - check firmware version issues @@ -342,7 +342,7 @@ int tt565_open(RIG *rig) } /** - * \param rig + * \param rig The rig handle * \param vfo RIG_VFO_MAIN or RIG_VFO_SUB * \returns 'M' or 'S' for main or subreceiver or <0 error * \brief vfo must be RIG_VFO_MAIN or RIG_VFO_SUB @@ -375,7 +375,7 @@ static char which_receiver(const RIG *rig, vfo_t vfo) } } /** - * \param rig + * \param rig The rig handle * \param vfo RIG_VFO_A, RIG_VFO_B, or RIG_VFO_NONE * \returns 'A' or 'B' or 'N' for VFO A, B, or null VFO, or <0 error * \brief vfo must be RIG_VFO_A, RIG_VFO_B, or RIG_VFO_NONE. @@ -1972,7 +1972,7 @@ int tt565_vfo_op(RIG *rig, vfo_t vfo, vfo_op_t op) } /** - * \param rig + * \param rig The rig handle * \param vfo * \param msg A message string (<= 20 char) * \returns RIG_OK diff --git a/src/ext.c b/src/ext.c index 710748d4b..7236f1d79 100644 --- a/src/ext.c +++ b/src/ext.c @@ -218,7 +218,7 @@ int HAMLIB_API rig_ext_parm_foreach(RIG *rig, /** - * \param rig + * \param rig The rig handle * \param name * \brief lookup ext token by its name, return pointer to confparams struct. * @@ -267,7 +267,7 @@ const struct confparams *HAMLIB_API rig_ext_lookup(RIG *rig, const char *name) } /** - * \param rig + * \param rig The rig handle * \param token * \brief lookup ext token, return pointer to confparams struct. * @@ -316,7 +316,7 @@ const struct confparams *HAMLIB_API rig_ext_lookup_tok(RIG *rig, /** - * \param rig + * \param rig The rig handle * \param name * \brief Simple lookup returning token id associated with name */ diff --git a/src/misc.c b/src/misc.c index 1e3e3665b..8d448d2a2 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1031,7 +1031,7 @@ static const struct /** * \brief check input to set_level - * \param rig Pointer to rig data + * \param rig The rig handle * \param level RIG_LEVEL_* trying to set * \param val Raw input from the caller * \param gran If not NULL, set to location of level_gran data diff --git a/src/rig.c b/src/rig.c index 8e0ca4e00..a27e511c7 100644 --- a/src/rig.c +++ b/src/rig.c @@ -8887,9 +8887,23 @@ extern int read_icom_frame(hamlib_port_t *p, const unsigned char rxbuffer[], size_t rxbuffer_len); -// Returns # of bytes read -// reply_len should be max bytes expected + 1 -// if term is null then will read reply_len bytes exactly and reply will not be null terminated +/** + * \brief Send verbatim data + * + * \a reply_len should be max bytes expected + 1 + * + * If \a term is NULL then will read \a reply_len bytes exactly and reply will not be '\0' terminated. + * \param rig The rig handle + * \param send The buffer containing the data to be sent + * \param send_len The length of send buffer + * \param reply The buffer that will contain the data to be received + * \param reply_len The length of the reply buffer + * \param term The optional 1-char string that will terminate the read + * + * \return the number of bytes read if the operation has been successful, otherwise + * a negative value if an error occurred (in which case, cause is + * set appropriately). + */ HAMLIB_EXPORT(int) rig_send_raw(RIG *rig, const unsigned char *send, int send_len, unsigned char *reply, int reply_len, unsigned char *term) { ----------------------------------------------------------------------- Summary of changes: bindings/python/test_Hamlib_Rig_class.py | 1 + bindings/python/test_rig.py | 20 +++++++++++++++ bindings/rig.swg | 42 +++++++++++++++++++++++++++++++ rigs/tentec/orion.c | 12 ++++----- src/ext.c | 6 ++--- src/misc.c | 2 +- src/rig.c | 43 ++++++++++++++++++++++++-------- 7 files changed, 105 insertions(+), 21 deletions(-) hooks/post-receive -- Hamlib -- Ham radio control libraries |