From 3787bc27a26c1cc65b9f5cffd179315de95251f1 Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Sat, 2 Nov 2024 01:14:15 +0000 Subject: [PATCH] Add Python bindings and the icsneopy package --- .gitignore | 2 +- .gitlab-ci.yml | 93 +++++++++- CMakeLists.txt | 4 + bindings/CMakeLists.txt | 3 + bindings/python/CMakeLists.txt | 24 +++ bindings/python/icsneopy/api/event.cpp | 170 +++++++++++++++++ .../python/icsneopy/api/eventcallback.cpp | 16 ++ bindings/python/icsneopy/api/eventmanager.cpp | 18 ++ bindings/python/icsneopy/api/version.cpp | 28 +++ .../message/callback/messagecallback.cpp | 15 ++ .../communication/message/canmessage.cpp | 22 +++ .../communication/message/ethernetmessage.cpp | 27 +++ .../message/filter/messagefilter.cpp | 15 ++ .../communication/message/message.cpp | 51 +++++ .../message/tc10statusmessage.cpp | 25 +++ .../python/icsneopy/communication/network.cpp | 174 ++++++++++++++++++ bindings/python/icsneopy/device/device.cpp | 43 +++++ .../python/icsneopy/device/devicetype.cpp | 75 ++++++++ bindings/python/icsneopy/icsneocpp.cpp | 45 +++++ ci/bootstrap-libpcap.sh | 18 ++ ci/bootstrap-libusb.sh | 21 +++ ci/build-wheel-posix.sh | 7 + ci/build-wheel-windows.bat | 9 + pyproject.toml | 49 +++++ 24 files changed, 952 insertions(+), 2 deletions(-) create mode 100644 bindings/CMakeLists.txt create mode 100644 bindings/python/CMakeLists.txt create mode 100644 bindings/python/icsneopy/api/event.cpp create mode 100644 bindings/python/icsneopy/api/eventcallback.cpp create mode 100644 bindings/python/icsneopy/api/eventmanager.cpp create mode 100644 bindings/python/icsneopy/api/version.cpp create mode 100644 bindings/python/icsneopy/communication/message/callback/messagecallback.cpp create mode 100644 bindings/python/icsneopy/communication/message/canmessage.cpp create mode 100644 bindings/python/icsneopy/communication/message/ethernetmessage.cpp create mode 100644 bindings/python/icsneopy/communication/message/filter/messagefilter.cpp create mode 100644 bindings/python/icsneopy/communication/message/message.cpp create mode 100644 bindings/python/icsneopy/communication/message/tc10statusmessage.cpp create mode 100644 bindings/python/icsneopy/communication/network.cpp create mode 100644 bindings/python/icsneopy/device/device.cpp create mode 100644 bindings/python/icsneopy/device/devicetype.cpp create mode 100644 bindings/python/icsneopy/icsneocpp.cpp create mode 100644 ci/bootstrap-libpcap.sh create mode 100644 ci/bootstrap-libusb.sh create mode 100644 ci/build-wheel-posix.sh create mode 100644 ci/build-wheel-windows.bat create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore index ff4efa3..0c58819 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ third-party/concurrentqueue/tests *.orig examples/csharp/bin examples/csharp/obj -test/system \ No newline at end of file +test/system diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 154fefd..5d9839d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,6 +5,7 @@ stages: - build - unit_test - hardware_test + - deploy #------------------------------------------------------------------------------- # Windows @@ -416,4 +417,94 @@ hardware_test win10-vcan42-EL: <<: *win10_needs variables: GUEST_OS_TAG: win10 - DEVICE_PORT: USB_C \ No newline at end of file + DEVICE_PORT: USB_C + +#------------------------------------------------------------------------------- +# Python Module +#------------------------------------------------------------------------------- + +build python/linux/amd64: + stage: build + tags: + - linux-build + image: python:3.12 + services: + - name: docker:dind + entrypoint: ["env", "-u", "DOCKER_HOST"] + command: ["dockerd-entrypoint.sh"] + variables: + CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh + CIBW_BUILD: "*manylinux*" # no musl + CIBW_ARCHS: x86_64 + DOCKER_HOST: tcp://docker:2375/ + DOCKER_DRIVER: overlay2 + DOCKER_TLS_CERTDIR: "" + CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install + script: + - curl -sSL https://get.docker.com/ | sh + - sh ci/build-wheel-posix.sh + artifacts: + paths: + - wheelhouse + +build python/linux/arm64: + stage: build + tags: + - arm64-linux-build + variables: + CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh + CIBW_BUILD: "*manylinux*" # no musl + CIBW_ARCHS: aarch64 + CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install + script: + - sh ci/build-wheel-posix.sh + artifacts: + paths: + - wheelhouse + +build python/macos: + stage: build + tags: + - macos-arm64 + variables: + CIBW_BEFORE_ALL: sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh + CIBW_ARCHS: arm64 + CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=$CI_PROJECT_DIR/libpcap/install:$CI_PROJECT_DIR/libusb/install + MACOSX_DEPLOYMENT_TARGET: 10.14 + script: + - sh ci/build-wheel-posix.sh + artifacts: + paths: + - wheelhouse + +build python/windows: + stage: build + tags: + - libicsneo-win-x64 + variables: + CIBW_ARCHS: AMD64 + CIBW_ENVIRONMENT: CMAKE_GENERATOR=Ninja + script: + - cmd /c ci\build-wheel-windows.bat + artifacts: + paths: + - wheelhouse + +deploy python/pypi: + stage: deploy + variables: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: $PYPI_TOKEN + tags: + - linux-build + image: python:3.12 + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + script: + - python3 -m pip install -U twine + - twine upload wheelhouse/* + dependencies: + - build python/linux/amd64 + - build python/linux/arm64 + - build python/macos + - build python/windows diff --git a/CMakeLists.txt b/CMakeLists.txt index a65ae4a..4f4351c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,8 @@ option(LIBICSNEO_ENABLE_FTDI "Enable devices which communicate over USB FTDI2XX" option(LIBICSNEO_ENABLE_TCP "Enable devices which communicate over TCP" OFF) option(LIBICSNEO_ENABLE_FTD3XX "Enable devices which communicate over USB FTD3XX" ON) +option(LIBICSNEO_ENABLE_BINDINGS_PYTHON "Enable Python library" OFF) + if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 17) endif() @@ -494,6 +496,8 @@ if(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC) target_compile_definitions(icsneolegacy-static PUBLIC ICSNEOC_BUILD_STATIC) endif() +add_subdirectory(bindings) + # googletest if(LIBICSNEO_BUILD_UNIT_TESTS) if(WIN32) diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt new file mode 100644 index 0000000..d243d3b --- /dev/null +++ b/bindings/CMakeLists.txt @@ -0,0 +1,3 @@ +if(LIBICSNEO_ENABLE_BINDINGS_PYTHON) + add_subdirectory(python) +endif() \ No newline at end of file diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt new file mode 100644 index 0000000..58b90d5 --- /dev/null +++ b/bindings/python/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.20) + +set(PYBIND11_FINDPYTHON ON) +find_package(pybind11 CONFIG REQUIRED) + +pybind11_add_module(icsneopy + icsneopy/api/event.cpp + icsneopy/api/eventcallback.cpp + icsneopy/api/eventmanager.cpp + icsneopy/api/version.cpp + icsneopy/device/devicetype.cpp + icsneopy/communication/network.cpp + icsneopy/communication/message/message.cpp + icsneopy/communication/message/canmessage.cpp + icsneopy/communication/message/ethernetmessage.cpp + icsneopy/communication/message/tc10statusmessage.cpp + icsneopy/communication/message/callback/messagecallback.cpp + icsneopy/communication/message/filter/messagefilter.cpp + icsneopy/device/device.cpp + icsneopy/icsneocpp.cpp +) +target_link_libraries(icsneopy PRIVATE icsneocpp) + +install(TARGETS icsneopy LIBRARY DESTINATION .) diff --git a/bindings/python/icsneopy/api/event.cpp b/bindings/python/icsneopy/api/event.cpp new file mode 100644 index 0000000..2789651 --- /dev/null +++ b/bindings/python/icsneopy/api/event.cpp @@ -0,0 +1,170 @@ +#include +#include +#include + +#include "icsneo/api/event.h" + +namespace icsneo { + +void init_event(pybind11::module_& m) { + pybind11::class_> apiEvent(m, "APIEvent"); + pybind11::enum_(apiEvent, "Type") + .value("Any", APIEvent::Type::Any) + .value("InvalidNeoDevice", APIEvent::Type::InvalidNeoDevice) + .value("RequiredParameterNull", APIEvent::Type::RequiredParameterNull) + .value("BufferInsufficient", APIEvent::Type::BufferInsufficient) + .value("OutputTruncated", APIEvent::Type::OutputTruncated) + .value("ParameterOutOfRange", APIEvent::Type::ParameterOutOfRange) + .value("DeviceCurrentlyOpen", APIEvent::Type::DeviceCurrentlyOpen) + .value("DeviceCurrentlyClosed", APIEvent::Type::DeviceCurrentlyClosed) + .value("DeviceCurrentlyOnline", APIEvent::Type::DeviceCurrentlyOnline) + .value("DeviceCurrentlyOffline", APIEvent::Type::DeviceCurrentlyOffline) + .value("DeviceCurrentlyPolling", APIEvent::Type::DeviceCurrentlyPolling) + .value("DeviceNotCurrentlyPolling", APIEvent::Type::DeviceNotCurrentlyPolling) + .value("UnsupportedTXNetwork", APIEvent::Type::UnsupportedTXNetwork) + .value("MessageMaxLengthExceeded", APIEvent::Type::MessageMaxLengthExceeded) + .value("ValueNotYetPresent", APIEvent::Type::ValueNotYetPresent) + .value("Timeout", APIEvent::Type::Timeout) + .value("WiVINotSupported", APIEvent::Type::WiVINotSupported) + .value("RestrictedEntryFlag", APIEvent::Type::RestrictedEntryFlag) + .value("NotSupported", APIEvent::Type::NotSupported) + .value("PollingMessageOverflow", APIEvent::Type::PollingMessageOverflow) + .value("NoSerialNumber", APIEvent::Type::NoSerialNumber) + .value("IncorrectSerialNumber", APIEvent::Type::IncorrectSerialNumber) + .value("SettingsReadError", APIEvent::Type::SettingsReadError) + .value("SettingsVersionError", APIEvent::Type::SettingsVersionError) + .value("SettingsLengthError", APIEvent::Type::SettingsLengthError) + .value("SettingsChecksumError", APIEvent::Type::SettingsChecksumError) + .value("SettingsNotAvailable", APIEvent::Type::SettingsNotAvailable) + .value("SettingsReadOnly", APIEvent::Type::SettingsReadOnly) + .value("CANSettingsNotAvailable", APIEvent::Type::CANSettingsNotAvailable) + .value("CANFDSettingsNotAvailable", APIEvent::Type::CANFDSettingsNotAvailable) + .value("LSFTCANSettingsNotAvailable", APIEvent::Type::LSFTCANSettingsNotAvailable) + .value("SWCANSettingsNotAvailable", APIEvent::Type::SWCANSettingsNotAvailable) + .value("BaudrateNotFound", APIEvent::Type::BaudrateNotFound) + .value("UnexpectedNetworkType", APIEvent::Type::UnexpectedNetworkType) + .value("DeviceFirmwareOutOfDate", APIEvent::Type::DeviceFirmwareOutOfDate) + .value("SettingsStructureMismatch", APIEvent::Type::SettingsStructureMismatch) + .value("SettingsStructureTruncated", APIEvent::Type::SettingsStructureTruncated) + .value("NoDeviceResponse", APIEvent::Type::NoDeviceResponse) + .value("MessageFormattingError", APIEvent::Type::MessageFormattingError) + .value("CANFDNotSupported", APIEvent::Type::CANFDNotSupported) + .value("RTRNotSupported", APIEvent::Type::RTRNotSupported) + .value("DeviceDisconnected", APIEvent::Type::DeviceDisconnected) + .value("OnlineNotSupported", APIEvent::Type::OnlineNotSupported) + .value("TerminationNotSupportedDevice", APIEvent::Type::TerminationNotSupportedDevice) + .value("TerminationNotSupportedNetwork", APIEvent::Type::TerminationNotSupportedNetwork) + .value("AnotherInTerminationGroupEnabled", APIEvent::Type::AnotherInTerminationGroupEnabled) + .value("NoSerialNumberFW", APIEvent::Type::NoSerialNumberFW) + .value("NoSerialNumber12V", APIEvent::Type::NoSerialNumber12V) + .value("NoSerialNumberFW12V", APIEvent::Type::NoSerialNumberFW12V) + .value("EthPhyRegisterControlNotAvailable", APIEvent::Type::EthPhyRegisterControlNotAvailable) + .value("DiskNotSupported", APIEvent::Type::DiskNotSupported) + .value("EOFReached", APIEvent::Type::EOFReached) + .value("SettingsDefaultsUsed", APIEvent::Type::SettingsDefaultsUsed) + .value("AtomicOperationRetried", APIEvent::Type::AtomicOperationRetried) + .value("AtomicOperationCompletedNonatomically", APIEvent::Type::AtomicOperationCompletedNonatomically) + .value("WiVIStackRefreshFailed", APIEvent::Type::WiVIStackRefreshFailed) + .value("WiVIUploadStackOverflow", APIEvent::Type::WiVIUploadStackOverflow) + .value("I2CMessageExceedsMaxLength", APIEvent::Type::I2CMessageExceedsMaxLength) + .value("A2BMessageIncompleteFrame", APIEvent::Type::A2BMessageIncompleteFrame) + .value("CoreminiUploadVersionMismatch", APIEvent::Type::CoreminiUploadVersionMismatch) + .value("DiskNotConnected", APIEvent::Type::DiskNotConnected) + .value("UnexpectedResponse", APIEvent::Type::UnexpectedResponse) + .value("LiveDataInvalidHandle", APIEvent::Type::LiveDataInvalidHandle) + .value("LiveDataInvalidCommand", APIEvent::Type::LiveDataInvalidCommand) + .value("LiveDataInvalidArgument", APIEvent::Type::LiveDataInvalidArgument) + .value("LiveDataVersionMismatch", APIEvent::Type::LiveDataVersionMismatch) + .value("LiveDataNoDeviceResponse", APIEvent::Type::LiveDataNoDeviceResponse) + .value("LiveDataMaxSignalsReached", APIEvent::Type::LiveDataMaxSignalsReached) + .value("LiveDataCommandFailed", APIEvent::Type::LiveDataCommandFailed) + .value("LiveDataEncoderError", APIEvent::Type::LiveDataEncoderError) + .value("LiveDataDecoderError", APIEvent::Type::LiveDataDecoderError) + .value("LiveDataNotSupported", APIEvent::Type::LiveDataNotSupported) + .value("LINSettingsNotAvailable", APIEvent::Type::LINSettingsNotAvailable) + .value("ModeNotFound", APIEvent::Type::ModeNotFound) + .value("AppErrorParsingFailed", APIEvent::Type::AppErrorParsingFailed) + .value("FailedToRead", APIEvent::Type::FailedToRead) + .value("FailedToWrite", APIEvent::Type::FailedToWrite) + .value("DriverFailedToOpen", APIEvent::Type::DriverFailedToOpen) + .value("DriverFailedToClose", APIEvent::Type::DriverFailedToClose) + .value("PacketChecksumError", APIEvent::Type::PacketChecksumError) + .value("TransmitBufferFull", APIEvent::Type::TransmitBufferFull) + .value("DeviceInUse", APIEvent::Type::DeviceInUse) + .value("PCAPCouldNotStart", APIEvent::Type::PCAPCouldNotStart) + .value("PCAPCouldNotFindDevices", APIEvent::Type::PCAPCouldNotFindDevices) + .value("PacketDecodingError", APIEvent::Type::PacketDecodingError) + .value("SocketFailedToOpen", APIEvent::Type::SocketFailedToOpen) + .value("FailedToBind", APIEvent::Type::FailedToBind) + .value("ErrorSettingSocketOption", APIEvent::Type::ErrorSettingSocketOption) + .value("GetIfAddrsError", APIEvent::Type::GetIfAddrsError) + .value("SendToError", APIEvent::Type::SendToError) + .value("MDIOMessageExceedsMaxLength", APIEvent::Type::MDIOMessageExceedsMaxLength) + .value("FTOK", APIEvent::Type::FTOK) + .value("FTInvalidHandle", APIEvent::Type::FTInvalidHandle) + .value("FTDeviceNotFound", APIEvent::Type::FTDeviceNotFound) + .value("FTDeviceNotOpened", APIEvent::Type::FTDeviceNotOpened) + .value("FTIOError", APIEvent::Type::FTIOError) + .value("FTInsufficientResources", APIEvent::Type::FTInsufficientResources) + .value("FTInvalidParameter", APIEvent::Type::FTInvalidParameter) + .value("FTInvalidBaudRate", APIEvent::Type::FTInvalidBaudRate) + .value("FTDeviceNotOpenedForErase", APIEvent::Type::FTDeviceNotOpenedForErase) + .value("FTDeviceNotOpenedForWrite", APIEvent::Type::FTDeviceNotOpenedForWrite) + .value("FTFailedToWriteDevice", APIEvent::Type::FTFailedToWriteDevice) + .value("FTEEPROMReadFailed", APIEvent::Type::FTEEPROMReadFailed) + .value("FTEEPROMWriteFailed", APIEvent::Type::FTEEPROMWriteFailed) + .value("FTEEPROMEraseFailed", APIEvent::Type::FTEEPROMEraseFailed) + .value("FTEEPROMNotPresent", APIEvent::Type::FTEEPROMNotPresent) + .value("FTEEPROMNotProgrammed", APIEvent::Type::FTEEPROMNotProgrammed) + .value("FTInvalidArgs", APIEvent::Type::FTInvalidArgs) + .value("FTNotSupported", APIEvent::Type::FTNotSupported) + .value("FTNoMoreItems", APIEvent::Type::FTNoMoreItems) + .value("FTTimeout", APIEvent::Type::FTTimeout) + .value("FTOperationAborted", APIEvent::Type::FTOperationAborted) + .value("FTReservedPipe", APIEvent::Type::FTReservedPipe) + .value("FTInvalidControlRequestDirection", APIEvent::Type::FTInvalidControlRequestDirection) + .value("FTInvalidControlRequestType", APIEvent::Type::FTInvalidControlRequestType) + .value("FTIOPending", APIEvent::Type::FTIOPending) + .value("FTIOIncomplete", APIEvent::Type::FTIOIncomplete) + .value("FTHandleEOF", APIEvent::Type::FTHandleEOF) + .value("FTBusy", APIEvent::Type::FTBusy) + .value("FTNoSystemResources", APIEvent::Type::FTNoSystemResources) + .value("FTDeviceListNotReady", APIEvent::Type::FTDeviceListNotReady) + .value("FTDeviceNotConnected", APIEvent::Type::FTDeviceNotConnected) + .value("FTIncorrectDevicePath", APIEvent::Type::FTIncorrectDevicePath) + .value("FTOtherError", APIEvent::Type::FTOtherError) + .value("VSABufferCorrupted", APIEvent::Type::VSABufferCorrupted) + .value("VSATimestampNotFound", APIEvent::Type::VSATimestampNotFound) + .value("VSABufferFormatError", APIEvent::Type::VSABufferFormatError) + .value("VSAMaxReadAttemptsReached", APIEvent::Type::VSAMaxReadAttemptsReached) + .value("VSAByteParseFailure", APIEvent::Type::VSAByteParseFailure) + .value("VSAExtendedMessageError", APIEvent::Type::VSAExtendedMessageError) + .value("VSAOtherError", APIEvent::Type::VSAOtherError) + .value("NoErrorFound", APIEvent::Type::NoErrorFound) + .value("TooManyEvents", APIEvent::Type::TooManyEvents) + .value("Unknown", APIEvent::Type::Unknown); + + pybind11::enum_(apiEvent, "Severity") + .value("Any", APIEvent::Severity::Any) + .value("EventInfo", APIEvent::Severity::EventInfo) + .value("EventWarning", APIEvent::Severity::EventWarning) + .value("Error", APIEvent::Severity::Error); + + apiEvent + .def("get_type", &APIEvent::getType) + .def("get_severity", &APIEvent::getSeverity) + .def("get_description", &APIEvent::getDescription) + .def("describe", &APIEvent::describe) + .def("__repr__", &APIEvent::describe); + + pybind11::class_>(m, "EventFilter") + .def(pybind11::init()) + .def(pybind11::init()) + .def(pybind11::init()) + .def_readwrite("type", &EventFilter::type) + .def_readwrite("severity", &EventFilter::severity) + .def_readwrite("serial", &EventFilter::serial); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/api/eventcallback.cpp b/bindings/python/icsneopy/api/eventcallback.cpp new file mode 100644 index 0000000..855c43b --- /dev/null +++ b/bindings/python/icsneopy/api/eventcallback.cpp @@ -0,0 +1,16 @@ +#include +#include +#include + +#include "icsneo/api/eventcallback.h" + +namespace icsneo { + +void init_eventcallback(pybind11::module_& m) { + pybind11::class_(m, "EventCallback") + .def(pybind11::init()) + .def(pybind11::init()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/api/eventmanager.cpp b/bindings/python/icsneopy/api/eventmanager.cpp new file mode 100644 index 0000000..4be9237 --- /dev/null +++ b/bindings/python/icsneopy/api/eventmanager.cpp @@ -0,0 +1,18 @@ +#include +#include +#include + +#include "icsneo/api/eventmanager.h" + +namespace icsneo { + +void init_eventmanager(pybind11::module_& m) { + pybind11::class_(m, "EventManager") + .def_static("get_instance", &EventManager::GetInstance, pybind11::return_value_policy::reference) + .def("add_event_callback", &EventManager::addEventCallback) + .def("remove_event_callback", &EventManager::removeEventCallback) + .def("get_last_error", &EventManager::getLastError); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/api/version.cpp b/bindings/python/icsneopy/api/version.cpp new file mode 100644 index 0000000..f580fd3 --- /dev/null +++ b/bindings/python/icsneopy/api/version.cpp @@ -0,0 +1,28 @@ +#include +#include +#include + +#include "icsneo/api/version.h" + +#include + +namespace icsneo { + +void init_version(pybind11::module_& m) { + pybind11::class_(m, "NeoVersion") + .def_readonly("major", &neoversion_t::major) + .def_readonly("minor", &neoversion_t::minor) + .def_readonly("patch", &neoversion_t::patch) + .def_readonly("metadata", &neoversion_t::metadata) + .def_readonly("buildBranch", &neoversion_t::buildBranch) + .def_readonly("buildTag", &neoversion_t::buildTag) + .def("__repr__", [](const neoversion_t& self) -> std::string { + std::stringstream ss; + ss << self; + return ss.str(); + }); + m.def("get_version", &GetVersion); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/callback/messagecallback.cpp b/bindings/python/icsneopy/communication/message/callback/messagecallback.cpp new file mode 100644 index 0000000..656dc39 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/callback/messagecallback.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "icsneo/communication/message/callback/messagecallback.h" + +namespace icsneo { + +void init_messagecallback(pybind11::module_& m) { + pybind11::class_>(m, "MessageCallback") + .def(pybind11::init>()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/canmessage.cpp b/bindings/python/icsneopy/communication/message/canmessage.cpp new file mode 100644 index 0000000..68d36ed --- /dev/null +++ b/bindings/python/icsneopy/communication/message/canmessage.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "icsneo/communication/message/canmessage.h" + +namespace icsneo { + +void init_canmessage(pybind11::module_& m) { + pybind11::class_, Frame>(m, "CANMessage") + .def(pybind11::init()) + .def_readwrite("arbid", &CANMessage::arbid) + .def_readwrite("dlcOnWire", &CANMessage::dlcOnWire) + .def_readwrite("isRemote", &CANMessage::isRemote) + .def_readwrite("isExtended", &CANMessage::isExtended) + .def_readwrite("isCANFD", &CANMessage::isCANFD) + .def_readwrite("baudrateSwitch", &CANMessage::baudrateSwitch) + .def_readwrite("errorStateIndicator", &CANMessage::errorStateIndicator); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/ethernetmessage.cpp b/bindings/python/icsneopy/communication/message/ethernetmessage.cpp new file mode 100644 index 0000000..87a9cc6 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/ethernetmessage.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include "icsneo/communication/message/ethernetmessage.h" + +namespace icsneo { + +void init_ethernetmessage(pybind11::module_& m) { + pybind11::class_(m, "MACAddress") + .def("to_string", &MACAddress::toString) + .def("__repr__", &MACAddress::toString); + + pybind11::class_, Frame>(m, "EthernetMessage") + .def(pybind11::init()) + .def_readwrite("preemptionEnabled", &EthernetMessage::preemptionEnabled) + .def_readwrite("preemptionFlags", &EthernetMessage::preemptionFlags) + .def_readwrite("fcsAvailable", &EthernetMessage::fcsAvailable) + .def_readwrite("frameTooShort", &EthernetMessage::frameTooShort) + .def_readwrite("noPadding", &EthernetMessage::noPadding) + .def("get_destination_mac", &EthernetMessage::getDestinationMAC, pybind11::return_value_policy::reference) + .def("get_source_mac", &EthernetMessage::getSourceMAC, pybind11::return_value_policy::reference) + .def("get_ether_type", &EthernetMessage::getEtherType); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/filter/messagefilter.cpp b/bindings/python/icsneopy/communication/message/filter/messagefilter.cpp new file mode 100644 index 0000000..33c49c3 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/filter/messagefilter.cpp @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "icsneo/communication/message/filter/messagefilter.h" + +namespace icsneo { + +void init_messagefilter(pybind11::module_& m) { + pybind11::class_>(m, "MessageFilter") + .def(pybind11::init()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/message.cpp b/bindings/python/icsneopy/communication/message/message.cpp new file mode 100644 index 0000000..627a7e6 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/message.cpp @@ -0,0 +1,51 @@ +#include +#include +#include + +#include "icsneo/communication/message/message.h" + +namespace icsneo { + +void init_message(pybind11::module_& m) { + pybind11::class_> message(m, "Message"); + pybind11::enum_(message, "Type") + .value("Frame", Message::Type::Frame) + .value("CANErrorCount", Message::Type::CANErrorCount) + .value("LINHeaderOnly", Message::Type::LINHeaderOnly) + .value("LINBreak", Message::Type::LINBreak) + .value("Invalid", Message::Type::Invalid) + .value("RawMessage", Message::Type::RawMessage) + .value("ReadSettings", Message::Type::ReadSettings) + .value("ResetStatus", Message::Type::ResetStatus) + .value("DeviceVersion", Message::Type::DeviceVersion) + .value("Main51", Message::Type::Main51) + .value("FlexRayControl", Message::Type::FlexRayControl) + .value("EthernetPhyRegister", Message::Type::EthernetPhyRegister) + .value("LogicalDiskInfo", Message::Type::LogicalDiskInfo) + .value("ExtendedResponse", Message::Type::ExtendedResponse) + .value("WiVICommandResponse", Message::Type::WiVICommandResponse) + .value("ScriptStatus", Message::Type::ScriptStatus) + .value("ComponentVersions", Message::Type::ComponentVersions) + .value("SupportedFeatures", Message::Type::SupportedFeatures) + .value("GenericBinaryStatus", Message::Type::GenericBinaryStatus) + .value("LiveData", Message::Type::LiveData) + .value("HardwareInfo", Message::Type::HardwareInfo) + .value("TC10Status", Message::Type::TC10Status) + .value("AppError", Message::Type::AppError); + + message.def(pybind11::init()); + message.def_readonly("type", &Message::type); + message.def_readwrite("timestamp", &Message::timestamp); + + pybind11::class_, Message>(m, "RawMessage") + .def_readwrite("network", &RawMessage::network) + .def_readwrite("data", &RawMessage::data); + + pybind11::class_, RawMessage>(m, "Frame") + .def_readwrite("description", &Frame::description) + .def_readwrite("transmitted", &Frame::transmitted) + .def_readwrite("error", &Frame::error); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/communication/message/tc10statusmessage.cpp b/bindings/python/icsneopy/communication/message/tc10statusmessage.cpp new file mode 100644 index 0000000..a3920b3 --- /dev/null +++ b/bindings/python/icsneopy/communication/message/tc10statusmessage.cpp @@ -0,0 +1,25 @@ +#include +#include +#include + +#include "icsneo/communication/message/tc10statusmessage.h" + +namespace icsneo { + +void init_tc10statusmessage(pybind11::module_& m) { + pybind11::enum_(m, "TC10WakeStatus") + .value("NoWakeReceived", TC10WakeStatus::NoWakeReceived) + .value("WakeReceived", TC10WakeStatus::WakeReceived); + + pybind11::enum_(m, "TC10SleepStatus") + .value("NoSleepReceived", TC10SleepStatus::NoSleepReceived) + .value("SleepReceived", TC10SleepStatus::SleepReceived) + .value("SleepFailed", TC10SleepStatus::SleepFailed) + .value("SleepAborted", TC10SleepStatus::SleepAborted); + + pybind11::class_, Message>(m, "TC10StatusMessage") + .def_readonly("wakeStatus", &TC10StatusMessage::wakeStatus) + .def_readonly("sleepStatus", &TC10StatusMessage::sleepStatus); +} + +} // namespace icsneo diff --git a/bindings/python/icsneopy/communication/network.cpp b/bindings/python/icsneopy/communication/network.cpp new file mode 100644 index 0000000..2decc05 --- /dev/null +++ b/bindings/python/icsneopy/communication/network.cpp @@ -0,0 +1,174 @@ +#include +#include +#include + +#include "icsneo/communication/network.h" + +namespace icsneo { + +void init_network(pybind11::module_& m) { + pybind11::class_ network(m, "Network"); + + pybind11::enum_(network, "NetID") + .value("Device", Network::NetID::Device) + .value("HSCAN", Network::NetID::HSCAN) + .value("MSCAN", Network::NetID::MSCAN) + .value("SWCAN", Network::NetID::SWCAN) + .value("LSFTCAN", Network::NetID::LSFTCAN) + .value("FordSCP", Network::NetID::FordSCP) + .value("J1708", Network::NetID::J1708) + .value("Aux", Network::NetID::Aux) + .value("J1850VPW", Network::NetID::J1850VPW) + .value("ISO9141", Network::NetID::ISO9141) + .value("DiskData", Network::NetID::DiskData) + .value("Main51", Network::NetID::Main51) + .value("RED", Network::NetID::RED) + .value("SCI", Network::NetID::SCI) + .value("ISO9141_2", Network::NetID::ISO9141_2) + .value("ISO14230", Network::NetID::ISO14230) + .value("LIN", Network::NetID::LIN) + .value("OP_Ethernet1", Network::NetID::OP_Ethernet1) + .value("OP_Ethernet2", Network::NetID::OP_Ethernet2) + .value("OP_Ethernet3", Network::NetID::OP_Ethernet3) + .value("RED_EXT_MEMORYREAD", Network::NetID::RED_EXT_MEMORYREAD) + .value("RED_INT_MEMORYREAD", Network::NetID::RED_INT_MEMORYREAD) + .value("RED_DFLASH_READ", Network::NetID::RED_DFLASH_READ) + .value("NeoMemorySDRead", Network::NetID::NeoMemorySDRead) + .value("CAN_ERRBITS", Network::NetID::CAN_ERRBITS) + .value("NeoMemoryWriteDone", Network::NetID::NeoMemoryWriteDone) + .value("RED_WAVE_CAN1_LOGICAL", Network::NetID::RED_WAVE_CAN1_LOGICAL) + .value("RED_WAVE_CAN2_LOGICAL", Network::NetID::RED_WAVE_CAN2_LOGICAL) + .value("RED_WAVE_LIN1_LOGICAL", Network::NetID::RED_WAVE_LIN1_LOGICAL) + .value("RED_WAVE_LIN2_LOGICAL", Network::NetID::RED_WAVE_LIN2_LOGICAL) + .value("RED_WAVE_LIN1_ANALOG", Network::NetID::RED_WAVE_LIN1_ANALOG) + .value("RED_WAVE_LIN2_ANALOG", Network::NetID::RED_WAVE_LIN2_ANALOG) + .value("RED_WAVE_MISC_ANALOG", Network::NetID::RED_WAVE_MISC_ANALOG) + .value("RED_WAVE_MISCDIO2_LOGICAL", Network::NetID::RED_WAVE_MISCDIO2_LOGICAL) + .value("RED_NETWORK_COM_ENABLE_EX", Network::NetID::RED_NETWORK_COM_ENABLE_EX) + .value("RED_NEOVI_NETWORK", Network::NetID::RED_NEOVI_NETWORK) + .value("RED_READ_BAUD_SETTINGS", Network::NetID::RED_READ_BAUD_SETTINGS) + .value("RED_OLDFORMAT", Network::NetID::RED_OLDFORMAT) + .value("RED_SCOPE_CAPTURE", Network::NetID::RED_SCOPE_CAPTURE) + .value("RED_HARDWARE_EXCEP", Network::NetID::RED_HARDWARE_EXCEP) + .value("RED_GET_RTC", Network::NetID::RED_GET_RTC) + .value("ISO9141_3", Network::NetID::ISO9141_3) + .value("HSCAN2", Network::NetID::HSCAN2) + .value("HSCAN3", Network::NetID::HSCAN3) + .value("OP_Ethernet4", Network::NetID::OP_Ethernet4) + .value("OP_Ethernet5", Network::NetID::OP_Ethernet5) + .value("ISO9141_4", Network::NetID::ISO9141_4) + .value("LIN2", Network::NetID::LIN2) + .value("LIN3", Network::NetID::LIN3) + .value("LIN4", Network::NetID::LIN4) + .value("RED_App_Error", Network::NetID::RED_App_Error) + .value("CGI", Network::NetID::CGI) + .value("Reset_Status", Network::NetID::Reset_Status) + .value("FB_Status", Network::NetID::FB_Status) + .value("App_Signal_Status", Network::NetID::App_Signal_Status) + .value("Read_Datalink_Cm_Tx_Msg", Network::NetID::Read_Datalink_Cm_Tx_Msg) + .value("Read_Datalink_Cm_Rx_Msg", Network::NetID::Read_Datalink_Cm_Rx_Msg) + .value("Logging_Overflow", Network::NetID::Logging_Overflow) + .value("ReadSettings", Network::NetID::ReadSettings) + .value("HSCAN4", Network::NetID::HSCAN4) + .value("HSCAN5", Network::NetID::HSCAN5) + .value("RS232", Network::NetID::RS232) + .value("UART", Network::NetID::UART) + .value("UART2", Network::NetID::UART2) + .value("UART3", Network::NetID::UART3) + .value("UART4", Network::NetID::UART4) + .value("SWCAN2", Network::NetID::SWCAN2) + .value("Ethernet_DAQ", Network::NetID::Ethernet_DAQ) + .value("Data_To_Host", Network::NetID::Data_To_Host) + .value("TextAPI_To_Host", Network::NetID::TextAPI_To_Host) + .value("SPI1", Network::NetID::SPI1) + .value("OP_Ethernet6", Network::NetID::OP_Ethernet6) + .value("Red_VBat", Network::NetID::Red_VBat) + .value("OP_Ethernet7", Network::NetID::OP_Ethernet7) + .value("OP_Ethernet8", Network::NetID::OP_Ethernet8) + .value("OP_Ethernet9", Network::NetID::OP_Ethernet9) + .value("OP_Ethernet10", Network::NetID::OP_Ethernet10) + .value("OP_Ethernet11", Network::NetID::OP_Ethernet11) + .value("FlexRay1a", Network::NetID::FlexRay1a) + .value("FlexRay1b", Network::NetID::FlexRay1b) + .value("FlexRay2a", Network::NetID::FlexRay2a) + .value("FlexRay2b", Network::NetID::FlexRay2b) + .value("LIN5", Network::NetID::LIN5) + .value("FlexRay", Network::NetID::FlexRay) + .value("FlexRay2", Network::NetID::FlexRay2) + .value("OP_Ethernet12", Network::NetID::OP_Ethernet12) + .value("I2C", Network::NetID::I2C) + .value("MOST25", Network::NetID::MOST25) + .value("MOST50", Network::NetID::MOST50) + .value("MOST150", Network::NetID::MOST150) + .value("Ethernet", Network::NetID::Ethernet) + .value("GMFSA", Network::NetID::GMFSA) + .value("TCP", Network::NetID::TCP) + .value("HSCAN6", Network::NetID::HSCAN6) + .value("HSCAN7", Network::NetID::HSCAN7) + .value("LIN6", Network::NetID::LIN6) + .value("LSFTCAN2", Network::NetID::LSFTCAN2) + .value("LogicalDiskInfo", Network::NetID::LogicalDiskInfo) + .value("WiVICommand", Network::NetID::WiVICommand) + .value("ScriptStatus", Network::NetID::ScriptStatus) + .value("EthPHYControl", Network::NetID::EthPHYControl) + .value("ExtendedCommand", Network::NetID::ExtendedCommand) + .value("ExtendedData", Network::NetID::ExtendedData) + .value("FlexRayControl", Network::NetID::FlexRayControl) + .value("CoreMiniPreLoad", Network::NetID::CoreMiniPreLoad) + .value("HW_COM_Latency_Test", Network::NetID::HW_COM_Latency_Test) + .value("DeviceStatus", Network::NetID::DeviceStatus) + .value("UDP", Network::NetID::UDP) + .value("ForwardedMessage", Network::NetID::ForwardedMessage) + .value("I2C2", Network::NetID::I2C2) + .value("I2C3", Network::NetID::I2C3) + .value("I2C4", Network::NetID::I2C4) + .value("Ethernet2", Network::NetID::Ethernet2) + .value("A2B1", Network::NetID::A2B1) + .value("A2B2", Network::NetID::A2B2) + .value("Ethernet3", Network::NetID::Ethernet3) + .value("WBMS", Network::NetID::WBMS) + .value("DWCAN9", Network::NetID::DWCAN9) + .value("DWCAN10", Network::NetID::DWCAN10) + .value("DWCAN11", Network::NetID::DWCAN11) + .value("DWCAN12", Network::NetID::DWCAN12) + .value("DWCAN13", Network::NetID::DWCAN13) + .value("DWCAN14", Network::NetID::DWCAN14) + .value("DWCAN15", Network::NetID::DWCAN15) + .value("DWCAN16", Network::NetID::DWCAN16) + .value("LIN7", Network::NetID::LIN7) + .value("LIN8", Network::NetID::LIN8) + .value("SPI2", Network::NetID::SPI2) + .value("MDIO1", Network::NetID::MDIO1) + .value("MDIO2", Network::NetID::MDIO2) + .value("MDIO3", Network::NetID::MDIO3) + .value("MDIO4", Network::NetID::MDIO4) + .value("MDIO5", Network::NetID::MDIO5) + .value("MDIO6", Network::NetID::MDIO6) + .value("MDIO7", Network::NetID::MDIO7) + .value("MDIO8", Network::NetID::MDIO8) + .value("OP_Ethernet13", Network::NetID::OP_Ethernet13) + .value("OP_Ethernet14", Network::NetID::OP_Ethernet14) + .value("OP_Ethernet15", Network::NetID::OP_Ethernet15) + .value("OP_Ethernet16", Network::NetID::OP_Ethernet16) + .value("SPI3", Network::NetID::SPI3) + .value("SPI4", Network::NetID::SPI4) + .value("SPI5", Network::NetID::SPI5) + .value("SPI6", Network::NetID::SPI6) + .value("SPI7", Network::NetID::SPI7) + .value("SPI8", Network::NetID::SPI8) + .value("LIN9", Network::NetID::LIN9) + .value("LIN10", Network::NetID::LIN10) + .value("LIN11", Network::NetID::LIN11) + .value("LIN12", Network::NetID::LIN12) + .value("LIN13", Network::NetID::LIN13) + .value("LIN14", Network::NetID::LIN14) + .value("LIN15", Network::NetID::LIN15) + .value("LIN16", Network::NetID::LIN16) + .value("Any", Network::NetID::Any) + .value("Invalid", Network::NetID::Invalid); + + network.def(pybind11::init()); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/device/device.cpp b/bindings/python/icsneopy/device/device.cpp new file mode 100644 index 0000000..0f3ef50 --- /dev/null +++ b/bindings/python/icsneopy/device/device.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "icsneo/device/device.h" + +namespace icsneo { + +void init_device(pybind11::module_& m) { + pybind11::class_>(m, "Device") + .def("get_type", &Device::getType) + .def("get_serial", &Device::getSerial) + .def("get_serial_number", &Device::getSerialNumber) + .def("get_product_name", &Device::getProductName) + .def("open", [](Device& device) { return device.open(); }) + .def("close", &Device::close) + .def("is_open", &Device::isOpen) + .def("go_online", &Device::goOnline) + .def("go_offline", &Device::goOffline) + .def("is_online", &Device::isOnline).def("enable_message_polling", &Device::enableMessagePolling) + .def("disable_message_polling", &Device::disableMessagePolling) + .def("is_message_polling_enabled", &Device::isMessagePollingEnabled) + .def("get_messages", [](Device& device) { return device.getMessages(); }) + .def("get_current_message_count", &Device::getCurrentMessageCount) + .def("get_polling_message_limit", &Device::getPollingMessageLimit) + .def("set_polling_message_limit", &Device::setPollingMessageLimit) + .def("add_message_callback", &Device::addMessageCallback) + .def("remove_message_callback", &Device::removeMessageCallback) + .def("transmit", pybind11::overload_cast>(&Device::transmit)) + .def("get_supported_rx_networks", &Device::getSupportedRXNetworks, pybind11::return_value_policy::reference) + .def("get_supported_tx_networks", &Device::getSupportedTXNetworks, pybind11::return_value_policy::reference) + .def("get_rtc", &Device::getRTC) + .def("set_rtc", &Device::setRTC) + .def("describe", &Device::describe) + .def("is_online_supported", &Device::isOnlineSupported) + .def("supports_tc10", &Device::supportsTC10) + .def("request_tc10_wake", &Device::requestTC10Wake) + .def("request_tc10_sleep", &Device::requestTC10Sleep) + .def("__repr__", &Device::describe); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/device/devicetype.cpp b/bindings/python/icsneopy/device/devicetype.cpp new file mode 100644 index 0000000..931aa7f --- /dev/null +++ b/bindings/python/icsneopy/device/devicetype.cpp @@ -0,0 +1,75 @@ +#include +#include +#include + +#include "icsneo/device/devicetype.h" + +namespace icsneo { + +void init_devicetype(pybind11::module_& m) { + pybind11::class_ deviceType(m, "DeviceType"); + pybind11::enum_(deviceType, "Enum") + .value("Unknown", DeviceType::Enum::Unknown) + .value("BLUE", DeviceType::Enum::BLUE) + .value("ECU_AVB", DeviceType::Enum::ECU_AVB) + .value("RADSupermoon", DeviceType::Enum::RADSupermoon) + .value("DW_VCAN", DeviceType::Enum::DW_VCAN) + .value("RADMoon2", DeviceType::Enum::RADMoon2) + .value("RADMars", DeviceType::Enum::RADMars) + .value("VCAN4_1", DeviceType::Enum::VCAN4_1) + .value("FIRE", DeviceType::Enum::FIRE) + .value("RADPluto", DeviceType::Enum::RADPluto) + .value("VCAN4_2EL", DeviceType::Enum::VCAN4_2EL) + .value("RADIO_CANHUB", DeviceType::Enum::RADIO_CANHUB) + .value("NEOECU12", DeviceType::Enum::NEOECU12) + .value("OBD2_LCBADGE", DeviceType::Enum::OBD2_LCBADGE) + .value("RADMoonDuo", DeviceType::Enum::RADMoonDuo) + .value("FIRE3", DeviceType::Enum::FIRE3) + .value("VCAN3", DeviceType::Enum::VCAN3) + .value("RADJupiter", DeviceType::Enum::RADJupiter) + .value("VCAN4_IND", DeviceType::Enum::VCAN4_IND) + .value("RADGigastar", DeviceType::Enum::RADGigastar) + .value("RED2", DeviceType::Enum::RED2) + .value("EtherBADGE", DeviceType::Enum::EtherBADGE) + .value("RAD_A2B", DeviceType::Enum::RAD_A2B) + .value("RADEpsilon", DeviceType::Enum::RADEpsilon) + .value("RADMoon3", DeviceType::Enum::RADMoon3) + .value("RADComet", DeviceType::Enum::RADComet) + .value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay) + .value("Connect", DeviceType::Enum::Connect) + .value("RADComet3", DeviceType::Enum::RADComet3) + .value("RADMoonT1S", DeviceType::Enum::RADMoonT1S) + .value("RADGigastar2", DeviceType::Enum::RADGigastar2) + .value("RED", DeviceType::Enum::RED) + .value("ECU", DeviceType::Enum::ECU) + .value("IEVB", DeviceType::Enum::IEVB) + .value("Pendant", DeviceType::Enum::Pendant) + .value("OBD2_PRO", DeviceType::Enum::OBD2_PRO) + .value("ECUChip_UART", DeviceType::Enum::ECUChip_UART) + .value("PLASMA", DeviceType::Enum::PLASMA) + .value("DONT_REUSE0", DeviceType::Enum::DONT_REUSE0) + .value("NEOAnalog", DeviceType::Enum::NEOAnalog) + .value("CT_OBD", DeviceType::Enum::CT_OBD) + .value("DONT_REUSE1", DeviceType::Enum::DONT_REUSE1) + .value("DONT_REUSE2", DeviceType::Enum::DONT_REUSE2) + .value("ION", DeviceType::Enum::ION) + .value("RADStar", DeviceType::Enum::RADStar) + .value("DONT_REUSE3", DeviceType::Enum::DONT_REUSE3) + .value("VCAN4_4", DeviceType::Enum::VCAN4_4) + .value("VCAN4_2", DeviceType::Enum::VCAN4_2) + .value("CMProbe", DeviceType::Enum::CMProbe) + .value("EEVB", DeviceType::Enum::EEVB) + .value("VCANrf", DeviceType::Enum::VCANrf) + .value("FIRE2", DeviceType::Enum::FIRE2) + .value("Flex", DeviceType::Enum::Flex) + .value("RADGalaxy", DeviceType::Enum::RADGalaxy) + .value("RADStar2", DeviceType::Enum::RADStar2) + .value("VividCAN", DeviceType::Enum::VividCAN) + .value("OBD2_SIM", DeviceType::Enum::OBD2_SIM); + deviceType.def(pybind11::init()); + deviceType.def("get_device_type", &DeviceType::getDeviceType); + deviceType.def("get_generic_product_name", &DeviceType::getGenericProductName); +} + +} // namespace icsneo + diff --git a/bindings/python/icsneopy/icsneocpp.cpp b/bindings/python/icsneopy/icsneocpp.cpp new file mode 100644 index 0000000..9633067 --- /dev/null +++ b/bindings/python/icsneopy/icsneocpp.cpp @@ -0,0 +1,45 @@ +#include +#include +#include + +#include "icsneo/icsneocpp.h" + +namespace icsneo { + +void init_event(pybind11::module_&); +void init_eventcallback(pybind11::module_&); +void init_eventmanager(pybind11::module_&); +void init_network(pybind11::module_&); +void init_devicetype(pybind11::module_&); +void init_message(pybind11::module_&); +void init_canmessage(pybind11::module_&); +void init_ethernetmessage(pybind11::module_&); +void init_tc10statusmessage(pybind11::module_&); +void init_device(pybind11::module_&); +void init_messagefilter(pybind11::module_&); +void init_messagecallback(pybind11::module_&); +void init_version(pybind11::module_&); + +PYBIND11_MODULE(icsneopy, m) { + m.doc() = "libicsneo Python module"; + + init_event(m); + init_eventcallback(m); + init_eventmanager(m); + init_version(m); + init_devicetype(m); + init_network(m); + init_message(m); + init_canmessage(m); + init_ethernetmessage(m); + init_tc10statusmessage(m); + init_messagefilter(m); + init_messagecallback(m); + init_device(m); + + m.def("find_all_devices", &FindAllDevices); + m.def("get_supported_devices", &GetSupportedDevices); + m.def("get_last_error", &GetLastError); +} + +} // namespace icsneo diff --git a/ci/bootstrap-libpcap.sh b/ci/bootstrap-libpcap.sh new file mode 100644 index 0000000..8e812e5 --- /dev/null +++ b/ci/bootstrap-libpcap.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +VERSION="1.10.5" +ROOT="$PWD/libpcap" +SOURCE="$ROOT/source" +BUILD="$ROOT/build" +INSTALL="$ROOT/install" + +mkdir -p "$ROOT" +cd "$ROOT" || exit 1 + +curl -LO "https://www.tcpdump.org/release/libpcap-$VERSION.tar.xz" || exit 1 +tar -xf "libpcap-$VERSION.tar.xz" || exit 1 +mv "libpcap-$VERSION" "$SOURCE" || exit 1 + +cmake -D CMAKE_POSITION_INDEPENDENT_CODE=ON -D CMAKE_INSTALL_PREFIX="$INSTALL" -D BUILD_SHARED_LIBS=OFF -D BUILD_WITH_LIBNL=OFF -D DISABLE_DBUS=ON -D DISABLE_LINUX_USBMON=ON -D DISABLE_BLUETOOTH=ON -D DISABLE_NETMAP=ON -D DISABLE_DPDK=ON -D DISABLE_RDMA=ON -D DISABLE_DAG=ON -D DISABLE_SEPTEL=ON -D DISABLE_SNF=ON -D DISABLE_TC=ON -B "$BUILD" -S "$SOURCE" || exit 1 +cmake --build "$BUILD" || exit 1 +cmake --install "$BUILD" || exit 1 diff --git a/ci/bootstrap-libusb.sh b/ci/bootstrap-libusb.sh new file mode 100644 index 0000000..9e9987f --- /dev/null +++ b/ci/bootstrap-libusb.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +VERSION="1.0.27" +ROOT="$PWD/libusb" +SOURCE="$ROOT/source" +BUILD="$ROOT/build" +INSTALL="$ROOT/install" + +mkdir -p "$ROOT" +cd "$ROOT" || exit 1 + +curl -LO "https://github.com/libusb/libusb/releases/download/v$VERSION/libusb-$VERSION.tar.bz2" || exit 1 +tar -xf "libusb-$VERSION.tar.bz2" || exit 1 +mv "libusb-$VERSION" "$SOURCE" || exit 1 + +mkdir "$BUILD" || exit 1 +cd "$BUILD" || exit 1 +"$SOURCE/configure" --prefix="$INSTALL" --disable-shared --disable-udev --disable-eventfd --disable-timerfd --with-pic || exit 1 +make || exit 1 +make install || exit 1 + diff --git a/ci/build-wheel-posix.sh b/ci/build-wheel-posix.sh new file mode 100644 index 0000000..46d157e --- /dev/null +++ b/ci/build-wheel-posix.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +python3 -m venv env || exit 1 +. env/bin/activate || exit 1 +python3 -m pip install cibuildwheel || exit 1 +python3 -m cibuildwheel --output-dir wheelhouse || exit 1 + diff --git a/ci/build-wheel-windows.bat b/ci/build-wheel-windows.bat new file mode 100644 index 0000000..80b4c0f --- /dev/null +++ b/ci/build-wheel-windows.bat @@ -0,0 +1,9 @@ +@setlocal +@echo off + +call "%VCVARS64_2022%" + +python.exe -m venv env || exit /b 1 +call env\Scripts\Activate.bat || exit /b 1 +python.exe -m pip install cibuildwheel || exit /b 1 +python.exe -m cibuildwheel --output-dir wheelhouse --platform windows || exit /b 1 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8f33408 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,49 @@ +[build-system] +requires = ["scikit-build-core", "pybind11", "setuptools>=64", "setuptools-scm>=8"] +build-backend = "scikit_build_core.build" + +[project] +name = "icsneopy" +dynamic = ["version"] +requires-python = ">=3.9" +readme = "README.md" +authors = [{name = "Intrepid Control Systems, Inc."}] +maintainers = [ + {name = "Kyle Schwarz", email="kschwarz@intrepidcs.com"}, +] +license = {file = "LICENSE"} +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'Programming Language :: C', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: Implementation :: CPython', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Operating System :: Unix', + 'Operating System :: MacOS', +] + +[project.urls] +homepage = "https://github.com/intrepidcs/libicsneo" +documentation = "https://libicsneo.readthedocs.io" +source = "https://github.com/intrepidcs/libicsneo" +tracker = "https://github.com/intrepidcs/libicsneo/issues" + +[tool.scikit-build] +metadata.version.provider = "scikit_build_core.metadata.setuptools_scm" + +[tool.setuptools_scm] +version_scheme = "no-guess-dev" +local_scheme = "no-local-version" + +[tool.scikit-build.cmake.define] +LIBICSNEO_ENABLE_BINDINGS_PYTHON = true +LIBICSNEO_ENABLE_TCP = true