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.
pull/1840/head
Daniele Forsi IU5HKX 2025-08-11 12:32:46 +02:00
rodzic 289a3952ce
commit e16f4077e7
3 zmienionych plików z 63 dodań i 0 usunięć

Wyświetl plik

@ -70,6 +70,7 @@ class TestClass:
'scan', 'scan',
'send_dtmf', 'send_dtmf',
'send_morse', 'send_morse',
'send_raw',
'set_ant', 'set_ant',
'set_bank', 'set_bank',
'set_channel', 'set_channel',

Wyświetl plik

@ -190,6 +190,23 @@ class TestClass:
assert rig.set_spectrum_callback(None) is None 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): def test_with_open(self, model, rig_file, serial_speed):
"""Call all the methods that depend on open()""" """Call all the methods that depend on open()"""
rig = Hamlib.Rig(model) rig = Hamlib.Rig(model)
@ -211,6 +228,9 @@ class TestClass:
self.do_test_antenna(rig) self.do_test_antenna(rig)
self.do_test_squelch(rig) self.do_test_squelch(rig)
self.do_test_callback(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.close() is None
assert rig.state.comm_state == 0 assert rig.state.comm_state == 0

Wyświetl plik

@ -735,6 +735,48 @@ int *rig_spectrum_cb_python(RIG *rig, struct rig_spectrum_line *rig_spectrum_lin
return status; 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 //#ifndef SWIGJAVA
/* TODO */ /* TODO */
void get_level(setting_t level, vfo_t vfo = RIG_VFO_CURR) void get_level(setting_t level, vfo_t vfo = RIG_VFO_CURR)