From 01fe766742add0fa21affd1fa663ad726f5e7ba4 Mon Sep 17 00:00:00 2001 From: David Rebbe Date: Thu, 20 Nov 2025 10:50:51 -0500 Subject: [PATCH] Add support for icsneoRequestSetNeoVIMiscIO --- include/methods.h | 34 +++++++++++++-- src/ics/py_neo_device_ex.py | 4 ++ src/methods.cpp | 84 ++++++++++++++++++++++++++++++------- 3 files changed, 103 insertions(+), 19 deletions(-) diff --git a/include/methods.h b/include/methods.h index c48fcb6ff..b386f8707 100644 --- a/include/methods.h +++ b/include/methods.h @@ -101,9 +101,10 @@ extern "C" PyObject* meth_flash_accessory_firmware(PyObject* self, PyObject* args); PyObject* meth_get_accessory_firmware_version(PyObject* self, PyObject* args); PyObject* meth_set_safe_boot_mode(PyObject* self, PyObject* args); - PyObject* meth_get_device_name(PyObject* self, PyObject* args); // icsneoGetDeviceName - PyObject* meth_get_imei(PyObject* self, PyObject* args); // icsneoGetIMEI - PyObject* meth_get_component_versions(PyObject* self, PyObject* args); // icsneoGetComponentVersions + PyObject* meth_get_device_name(PyObject* self, PyObject* args); // icsneoGetDeviceName + PyObject* meth_get_imei(PyObject* self, PyObject* args); // icsneoGetIMEI + PyObject* meth_get_component_versions(PyObject* self, PyObject* args); // icsneoGetComponentVersions + PyObject* meth_request_set_neovi_miscio(PyObject* self, PyObject* args); // icsneoRequestSetNeoVIMiscIO #ifdef _cplusplus } @@ -1975,6 +1976,33 @@ extern "C" "\ttuple of ics.structures.version_report.version_report\n" \ "\n" +#define _DOC_REQUEST_SET_NEOVI_MISCIO \ + MODULE_NAME ".request_set_neovi_miscio(device, ddrs, ddrs_mask, states, states_mask, leds, leds_mask) -> None\n" \ + "\n" \ + "Sets MISCIO states for the device.\n" \ + "\n" \ + "Args:\n" \ + "\tdevice (:class:`" MODULE_NAME ".PyNeoDeviceEx`): :class:`" MODULE_NAME ".PyNeoDeviceEx`\n\n" \ + "\n" \ + "\tddrs (:class:`int`): :class:`int`: Bitfield direction of IO. 1 = output.\n\n" \ + "\n" \ + "\tddrs_mask (:class:`int`): :class:`int`: Bitfield mask for ddrs. 1 = set\n\n" \ + "\n" \ + "\tstates (:class:`int`): :class:`int`: Bitfield state of IO. 1 = high.\n\n" \ + "\n" \ + "\tstates_mask (:class:`int`): :class:`int`: Bitfield mask for states. 1 = set\n\n" \ + "\n" \ + "\tleds (:class:`int`): :class:`int`: Bitfield state of LEDs. 1 = on.\n\n" \ + "\n" \ + "\tleds_mask (:class:`int`): :class:`int`: Bitfield mask for LEDs. 1 = set\n\n" \ + "\n" \ + "Raises:\n" \ + "\t:class:`" MODULE_NAME ".RuntimeError`\n" \ + "\n" \ + "Returns:\n" \ + "\tNone\n" \ + "\n" + extern PyMethodDef IcsMethods[]; #endif // _METHODS_H_ diff --git a/src/ics/py_neo_device_ex.py b/src/ics/py_neo_device_ex.py index 2b9b805b4..0f17dbb60 100644 --- a/src/ics/py_neo_device_ex.py +++ b/src/ics/py_neo_device_ex.py @@ -502,3 +502,7 @@ def get_imei(self, *args, **kwargs): def get_component_versions(self, *args, **kwargs): "see ics.get_component_versions for details on arguments." return ics.get_component_versions(self, *args, **kwargs) + + def request_set_neovi_miscio(self, *args, **kwargs): + "see ics.request_set_neovi_miscio for details on arguments." + return ics.request_set_neovi_miscio(self, *args, **kwargs) diff --git a/src/methods.cpp b/src/methods.cpp index 940558ad1..f25d5f2e7 100644 --- a/src/methods.cpp +++ b/src/methods.cpp @@ -608,21 +608,19 @@ PyMethodDef IcsMethods[] = { meth_get_device_name, METH_VARARGS, _DOC_GET_DEVICE_NAME), - _EZ_ICS_STRUCT_METHOD("get_imei", - "icsneoGetIMEI", - "GetIMEI", - meth_get_imei, - METH_VARARGS, - _DOC_GET_IMEI), + _EZ_ICS_STRUCT_METHOD("get_imei", "icsneoGetIMEI", "GetIMEI", meth_get_imei, METH_VARARGS, _DOC_GET_IMEI), _EZ_ICS_STRUCT_METHOD("get_component_versions", "icsneoGetComponentVersions", "GetComponentVersions", meth_get_component_versions, METH_VARARGS, _DOC_GET_COMPONENT_VERSIONS), - - - + _EZ_ICS_STRUCT_METHOD("request_set_neovi_miscio", + "icsneoRequestSetNeoVIMiscIO", + "RequestSetNeoVIMiscIO", + meth_request_set_neovi_miscio, + METH_VARARGS, + _DOC_REQUEST_SET_NEOVI_MISCIO), { "override_library_name", (PyCFunction)meth_override_library_name, METH_VARARGS, _DOC_OVERRIDE_LIBRARY_NAME }, { "get_library_path", (PyCFunction)meth_get_library_path, METH_NOARGS, "" }, @@ -5465,7 +5463,8 @@ PyObject* meth_get_device_name(PyObject* self, PyObject* args) // icsneoGetDevic } } -PyObject* meth_get_imei(PyObject* self, PyObject* args) { // icsneoGetIMEI +PyObject* meth_get_imei(PyObject* self, PyObject* args) +{ // icsneoGetIMEI (void)self; PyObject* obj = NULL; if (!PyArg_ParseTuple(args, arg_parse("O:", __FUNCTION__), &obj)) { @@ -5503,8 +5502,7 @@ PyObject* meth_get_component_versions(PyObject* self, PyObject* args) // icsneoG #ifndef _USE_INTERNAL_HEADER_ (void)self; (void)args; - return set_ics_exception(exception_runtime_error(), - "icsneoGetComponentVersions is not available"); + return set_ics_exception(exception_runtime_error(), "icsneoGetComponentVersions is not available"); #else (void)self; PyObject* obj = NULL; @@ -5526,7 +5524,8 @@ PyObject* meth_get_component_versions(PyObject* self, PyObject* args) // icsneoG char buffer[512]; return set_ics_exception(exception_runtime_error(), dll_get_error(buffer)); } - ice::Function icsneoGetComponentVersions(lib, "icsneoGetComponentVersions"); + ice::Function icsneoGetComponentVersions( + lib, "icsneoGetComponentVersions"); auto gil = PyAllowThreads(); std::vector version_reports; version_reports.reserve(length); @@ -5547,8 +5546,6 @@ PyObject* meth_get_component_versions(PyObject* self, PyObject* args) // icsneoG return set_ics_exception(exception_runtime_error(), "Failed to allocate version_report"); } - - // Get the internal buffer from version_report Py_buffer buffer = {}; if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG) != 0) { @@ -5564,4 +5561,59 @@ PyObject* meth_get_component_versions(PyObject* self, PyObject* args) // icsneoG return set_ics_exception(exception_runtime_error(), (char*)ex.what()); } #endif -} \ No newline at end of file +} + +PyObject* meth_request_set_neovi_miscio(PyObject* self, PyObject* args) // icsneoRequestSetNeoVIMiscIO +{ + (void)self; + PyObject* obj = NULL; + uint32_t ddrs = 0; + uint32_t ddrs_mask = 0; + uint32_t states = 0; + uint32_t states_mask = 0; + uint32_t leds = 0; + uint32_t leds_mask = 0; + if (!PyArg_ParseTuple(args, + arg_parse("OIIIIII:", __FUNCTION__), + &obj, + &ddrs, + &ddrs_mask, + &states, + &states_mask, + &leds, + &leds_mask)) { + return NULL; + } + if (!PyNeoDeviceEx_CheckExact(obj)) { + return set_ics_exception(exception_runtime_error(), "Argument must be of type " MODULE_NAME ".PyNeoDeviceEx"); + } + void* handle = NULL; + if (!PyNeoDeviceEx_GetHandle(obj, &handle)) { + return NULL; + } + try { + ice::Library* lib = dll_get_library(); + if (!lib) { + char buffer[512]; + return set_ics_exception(exception_runtime_error(), dll_get_error(buffer)); + } + // int _stdcall icsneoRequestSetNeoVIMiscIO(void* hObject, + // uint32_t ddrs, + // uint32_t ddrs_mask, + // uint32_t states, + // uint32_t states_mask, + // uint32_t leds, + // uint32_t leds_mask) + ice::Function + icsneoRequestSetNeoVIMiscIO(lib, "icsneoRequestSetNeoVIMiscIO"); + auto gil = PyAllowThreads(); + if (!icsneoRequestSetNeoVIMiscIO(handle, ddrs, ddrs_mask, states, states_mask, leds, leds_mask)) { + gil.restore(); + return set_ics_exception(exception_runtime_error(), "icsneoRequestSetNeoVIMiscIO() Failed"); + } + gil.restore(); + Py_RETURN_NONE; + } catch (ice::Exception& ex) { + return set_ics_exception(exception_runtime_error(), (char*)ex.what()); + } +}