Skip to content

Commit 8ebac5c

Browse files
add get_component_versions
1 parent f943339 commit 8ebac5c

File tree

4 files changed

+133
-23
lines changed

4 files changed

+133
-23
lines changed

include/methods.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ extern "C"
101101
PyObject* meth_flash_accessory_firmware(PyObject* self, PyObject* args);
102102
PyObject* meth_get_accessory_firmware_version(PyObject* self, PyObject* args);
103103
PyObject* meth_set_safe_boot_mode(PyObject* self, PyObject* args);
104-
PyObject* meth_get_device_name(PyObject* self, PyObject* args); // icsneoGetDeviceName
105-
PyObject* meth_get_imei(PyObject* self, PyObject* args); // icsneoGetIMEI
104+
PyObject* meth_get_device_name(PyObject* self, PyObject* args); // icsneoGetDeviceName
105+
PyObject* meth_get_imei(PyObject* self, PyObject* args); // icsneoGetIMEI
106+
PyObject* meth_get_component_versions(PyObject* self, PyObject* args); // icsneoGetComponentVersions
106107

107108
#ifdef _cplusplus
108109
}
@@ -1959,6 +1960,21 @@ extern "C"
19591960
"\tint\n" \
19601961
"\n"
19611962

1963+
#define _DOC_GET_COMPONENT_VERSIONS \
1964+
MODULE_NAME ".get_component_versions(device[, force, length]) -> (ics.structures.version_report.version_report)\n" \
1965+
"\n" \
1966+
"Gets the component versions from the device.\n" \
1967+
"\n" \
1968+
"Args:\n" \
1969+
"\tdevice (:class:`" MODULE_NAME ".PyNeoDeviceEx`): :class:`" MODULE_NAME ".PyNeoDeviceEx`\n\n" \
1970+
"\n" \
1971+
"Raises:\n" \
1972+
"\t:class:`" MODULE_NAME ".RuntimeError`\n" \
1973+
"\n" \
1974+
"Returns:\n" \
1975+
"\ttuple of ics.structures.version_report.version_report\n" \
1976+
"\n"
1977+
19621978
extern PyMethodDef IcsMethods[];
19631979

19641980
#endif // _METHODS_H_

src/ics/py_neo_device_ex.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,8 @@ def get_device_name(self, *args, **kwargs):
497497

498498
def get_imei(self, *args, **kwargs):
499499
"see ics.get_imei for details on arguments."
500-
return ics.get_imei(self, *args, **kwargs)
500+
return ics.get_imei(self, *args, **kwargs)
501+
502+
def get_component_versions(self, *args, **kwargs):
503+
"see ics.get_component_versions for details on arguments."
504+
return ics.get_component_versions(self, *args, **kwargs)

src/icsdebug.py

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
1+
import os
2+
3+
input(os.getpid())
4+
15
import ics
6+
import struct
7+
8+
ics.override_library_name(r"C:\dev\vspy3\Binaries\win64\icsneo40.dll")
9+
10+
CHIP_IDs = {
11+
82: "FIRE3_ZCHIP_ID",
12+
109: "NEOVI_FIRE3_LINUX_ID",
13+
121: "NEOVI_CONNECT_ZCHIP_ID",
14+
126: "NEOVI_FIRE3_LINUX_ID",
15+
}
216

3-
def show_clients():
4-
for d in ics.find_devices():
5-
print(d, d.NumberOfClients)
17+
def dot_version(version: int) -> str:
18+
version = '.'.join(str(x) for x in struct.unpack("4B", version.to_bytes(4, byteorder='big')))
19+
return version.lstrip('0.')
620

7-
print("Find...")
8-
devices = ics.find_devices()
9-
show_clients()
10-
print("Devices: ", devices)
11-
d = ics.open_device(devices[0])
12-
show_clients()
13-
print("Opened", d)
14-
print("Loading default settings...", d)
15-
ics.load_default_settings(d)
16-
print("Closing...")
17-
print(ics.close_device(d))
18-
print("Done.")
21+
def linux_state(component_info: int) -> str:
22+
match component_info:
23+
case 1:
24+
return "SD Card/MMC Partition 2"
25+
case 2:
26+
return "SD Card/MMC Partition 3"
27+
case 3:
28+
return "RAM"
29+
case _:
30+
return f"Unknown {component_info}"
1931

20-
# New Style
21-
d = devices[0]
22-
d.open(config_read=0)
23-
d.load_default_settings()
24-
d.close()
32+
d = ics.open_device()
33+
print(str(d))
34+
versions = d.get_component_versions()
35+
for version in versions:
36+
print(f"\t{version.valid}")
37+
print(f"\t{version.expansionSlot}")
38+
print(f"\t{version.componentInfo}: {linux_state(version.componentInfo)}")
39+
print(f"\t{version.reserved}")
40+
print(f"\t{version.identifier}: {CHIP_IDs[version.identifier]}")
41+
print(f"\t{version.dotVersion}: {dot_version(version.dotVersion)}")
42+
print(f"\t{version.commitHash}")
43+
print()

src/methods.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,15 @@ PyMethodDef IcsMethods[] = {
614614
meth_get_imei,
615615
METH_VARARGS,
616616
_DOC_GET_IMEI),
617+
_EZ_ICS_STRUCT_METHOD("get_component_versions",
618+
"icsneoGetComponentVersions",
619+
"GetComponentVersions",
620+
meth_get_component_versions,
621+
METH_VARARGS,
622+
_DOC_GET_COMPONENT_VERSIONS),
623+
624+
625+
617626

618627
{ "override_library_name", (PyCFunction)meth_override_library_name, METH_VARARGS, _DOC_OVERRIDE_LIBRARY_NAME },
619628
{ "get_library_path", (PyCFunction)meth_get_library_path, METH_NOARGS, "" },
@@ -5486,3 +5495,65 @@ PyObject* meth_get_imei(PyObject* self, PyObject* args) { // icsneoGetIMEI
54865495
return set_ics_exception(exception_runtime_error(), (char*)ex.what());
54875496
}
54885497
}
5498+
5499+
PyObject* meth_get_component_versions(PyObject* self, PyObject* args) // icsneoGetComponentVersions
5500+
{
5501+
(void)self;
5502+
PyObject* obj = NULL;
5503+
bool force_update = true;
5504+
uint64_t length = 25;
5505+
if (!PyArg_ParseTuple(args, arg_parse("O|bK:", __FUNCTION__), &obj, &force_update, &length)) {
5506+
return NULL;
5507+
}
5508+
if (!PyNeoDeviceEx_CheckExact(obj)) {
5509+
return set_ics_exception(exception_runtime_error(), "Argument must be of type " MODULE_NAME ".PyNeoDeviceEx");
5510+
}
5511+
void* handle = NULL;
5512+
if (!PyNeoDeviceEx_GetHandle(obj, &handle)) {
5513+
return NULL;
5514+
}
5515+
try {
5516+
ice::Library* lib = dll_get_library();
5517+
if (!lib) {
5518+
char buffer[512];
5519+
return set_ics_exception(exception_runtime_error(), dll_get_error(buffer));
5520+
}
5521+
uint64_t imei = 0;
5522+
ice::Function<int __stdcall(void*, VersionReport*, uint64_t*, bool)> icsneoGetComponentVersions(lib, "icsneoGetComponentVersions");
5523+
auto gil = PyAllowThreads();
5524+
std::vector<VersionReport> version_reports;
5525+
version_reports.reserve(length);
5526+
version_reports.resize(length);
5527+
if (!icsneoGetComponentVersions(handle, version_reports.data(), &length, force_update)) {
5528+
gil.restore();
5529+
return set_ics_exception(exception_runtime_error(), "icsneoGetComponentVersions() Failed");
5530+
}
5531+
gil.restore();
5532+
5533+
PyObject* tuple = PyTuple_New(length);
5534+
if (!tuple) {
5535+
return NULL;
5536+
}
5537+
for (int i = 0; i < length; ++i) {
5538+
PyObject* obj = _getPythonModuleObject("ics.structures.version_report", "version_report");
5539+
if (!obj) {
5540+
return set_ics_exception(exception_runtime_error(), "Failed to allocate version_report");
5541+
}
5542+
5543+
5544+
5545+
// Get the internal buffer from version_report
5546+
Py_buffer buffer = {};
5547+
if (PyObject_GetBuffer(obj, &buffer, PyBUF_CONTIG) != 0) {
5548+
return NULL;
5549+
}
5550+
memcpy(buffer.buf, &version_reports[i], sizeof(version_reports[i]));
5551+
PyBuffer_Release(&buffer);
5552+
5553+
PyTuple_SetItem(tuple, i, obj);
5554+
}
5555+
return tuple;
5556+
} catch (ice::Exception& ex) {
5557+
return set_ics_exception(exception_runtime_error(), (char*)ex.what());
5558+
}
5559+
}

0 commit comments

Comments
 (0)