mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-09-23 17:29:46 +02:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e233233b94 |
+114
-159
@@ -4,7 +4,7 @@ variables:
|
||||
stages:
|
||||
- build
|
||||
- unit_test
|
||||
- deploy
|
||||
- hardware_test
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Windows
|
||||
@@ -20,7 +20,7 @@ build windows/x64:
|
||||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
|
||||
unit_test windows/x64:
|
||||
stage: unit_test
|
||||
@@ -31,7 +31,7 @@ unit_test windows/x64:
|
||||
needs:
|
||||
- build windows/x64
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
timeout: 5m
|
||||
|
||||
build windows/x86:
|
||||
@@ -44,7 +44,7 @@ build windows/x86:
|
||||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
|
||||
unit_test windows/x86:
|
||||
stage: unit_test
|
||||
@@ -55,7 +55,7 @@ unit_test windows/x86:
|
||||
needs:
|
||||
- build windows/x86
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
timeout: 5m
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -234,6 +234,54 @@ unit_test linux/ubuntu/2204/amd64/clang:
|
||||
- linux-build
|
||||
timeout: 5m
|
||||
|
||||
build linux/fedora/37/amd64/gcc:
|
||||
<<: *build_linux_fedora_gcc
|
||||
image: fedora:37
|
||||
|
||||
unit_test linux/fedora/37/amd64/gcc:
|
||||
<<: *test_linux_fedora_gcc
|
||||
image: fedora:37
|
||||
dependencies:
|
||||
- build linux/fedora/37/amd64/gcc
|
||||
needs:
|
||||
- build linux/fedora/37/amd64/gcc
|
||||
|
||||
build linux/fedora/37/amd64/clang:
|
||||
<<: *build_linux_fedora_clang
|
||||
image: fedora:37
|
||||
|
||||
unit_test linux/fedora/37/amd64/clang:
|
||||
<<: *test_linux_fedora_clang
|
||||
image: fedora:37
|
||||
dependencies:
|
||||
- build linux/fedora/37/amd64/clang
|
||||
needs:
|
||||
- build linux/fedora/37/amd64/clang
|
||||
|
||||
build linux/fedora/38/amd64/gcc:
|
||||
<<: *build_linux_fedora_gcc
|
||||
image: fedora:38
|
||||
|
||||
unit_test linux/fedora/38/amd64/gcc:
|
||||
<<: *test_linux_fedora_gcc
|
||||
image: fedora:38
|
||||
dependencies:
|
||||
- build linux/fedora/38/amd64/gcc
|
||||
needs:
|
||||
- build linux/fedora/38/amd64/gcc
|
||||
|
||||
build linux/fedora/38/amd64/clang:
|
||||
<<: *build_linux_fedora_clang
|
||||
image: fedora:38
|
||||
|
||||
unit_test linux/fedora/38/amd64/clang:
|
||||
<<: *test_linux_fedora_clang
|
||||
image: fedora:38
|
||||
dependencies:
|
||||
- build linux/fedora/38/amd64/clang
|
||||
needs:
|
||||
- build linux/fedora/38/amd64/clang
|
||||
|
||||
build linux/fedora/39/amd64/gcc:
|
||||
<<: *build_linux_fedora_gcc
|
||||
image: fedora:39
|
||||
@@ -258,162 +306,69 @@ unit_test linux/fedora/39/amd64/clang:
|
||||
needs:
|
||||
- build linux/fedora/39/amd64/clang
|
||||
|
||||
build linux/fedora/40/amd64/gcc:
|
||||
<<: *build_linux_fedora_gcc
|
||||
image: fedora:40
|
||||
|
||||
unit_test linux/fedora/40/amd64/gcc:
|
||||
<<: *test_linux_fedora_gcc
|
||||
image: fedora:40
|
||||
dependencies:
|
||||
- build linux/fedora/40/amd64/gcc
|
||||
needs:
|
||||
- build linux/fedora/40/amd64/gcc
|
||||
|
||||
build linux/fedora/40/amd64/clang:
|
||||
<<: *build_linux_fedora_clang
|
||||
image: fedora:40
|
||||
|
||||
unit_test linux/fedora/40/amd64/clang:
|
||||
<<: *test_linux_fedora_clang
|
||||
image: fedora:40
|
||||
dependencies:
|
||||
- build linux/fedora/40/amd64/clang
|
||||
needs:
|
||||
- build linux/fedora/40/amd64/clang
|
||||
|
||||
build linux/fedora/41/amd64/gcc:
|
||||
<<: *build_linux_fedora_gcc
|
||||
image: fedora:41
|
||||
|
||||
unit_test linux/fedora/41/amd64/gcc:
|
||||
<<: *test_linux_fedora_gcc
|
||||
image: fedora:41
|
||||
dependencies:
|
||||
- build linux/fedora/41/amd64/gcc
|
||||
needs:
|
||||
- build linux/fedora/41/amd64/gcc
|
||||
|
||||
build linux/fedora/41/amd64/clang:
|
||||
<<: *build_linux_fedora_clang
|
||||
image: fedora:41
|
||||
|
||||
unit_test linux/fedora/41/amd64/clang:
|
||||
<<: *test_linux_fedora_clang
|
||||
image: fedora:41
|
||||
dependencies:
|
||||
- build linux/fedora/41/amd64/clang
|
||||
needs:
|
||||
- build linux/fedora/41/amd64/clang
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Python Module
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
build python/linux/amd64:
|
||||
stage: build
|
||||
.hw_test: &hw_test
|
||||
stage: hardware_test
|
||||
tags:
|
||||
- linux-build
|
||||
image: python:3.12
|
||||
services:
|
||||
- name: docker:dind
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
command: ["dockerd-entrypoint.sh"]
|
||||
- libicsneo_hil
|
||||
timeout: 5m
|
||||
script:
|
||||
- echo $GUEST_OS_TAG
|
||||
- echo $DEVICE_PORT
|
||||
- /opt/libvirt-driver/prepare.sh
|
||||
- /opt/libvirt-driver/run.sh
|
||||
after_script:
|
||||
- /opt/libvirt-driver/cleanup.sh
|
||||
|
||||
hardware_test system-test-fedora38-red2:
|
||||
<<: *hw_test
|
||||
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: unix:///var/run/docker.sock
|
||||
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
|
||||
GUEST_OS_TAG: fedora38
|
||||
DEVICE_PORT: ETH_A
|
||||
needs:
|
||||
- build python/linux/amd64
|
||||
- build python/linux/arm64
|
||||
- build python/macos
|
||||
- build python/windows
|
||||
- job: build linux/fedora/38/amd64/clang
|
||||
artifacts: true
|
||||
|
||||
push github:
|
||||
stage: deploy
|
||||
tags:
|
||||
- linux-build
|
||||
image: alpine:latest
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
when: delayed
|
||||
start_in: 10 minutes
|
||||
dependencies:
|
||||
- deploy python/pypi
|
||||
hardware_test system-test-fedora38-vcan42:
|
||||
<<: *hw_test
|
||||
variables:
|
||||
GUEST_OS_TAG: fedora38
|
||||
DEVICE_PORT: USB_D
|
||||
needs:
|
||||
- deploy python/pypi
|
||||
script:
|
||||
- apk add git
|
||||
- git push https://$LIBICSNEO_GITHUB_USERNAME:$LIBICSNEO_GITHUB_TOKEN@github.com/intrepidcs/libicsneo.git HEAD:master
|
||||
- job: build linux/fedora/38/amd64/clang
|
||||
artifacts: true
|
||||
|
||||
hardware_test system-test-ubuntu2204-red2:
|
||||
<<: *hw_test
|
||||
variables:
|
||||
GUEST_OS_TAG: ubuntu22.04
|
||||
DEVICE_PORT: ETH_A
|
||||
needs:
|
||||
- job: build linux/ubuntu/2204/amd64/clang
|
||||
artifacts: true
|
||||
|
||||
hardware_test system-test-ubuntu2204-vcan42:
|
||||
<<: *hw_test
|
||||
variables:
|
||||
GUEST_OS_TAG: ubuntu22.04
|
||||
DEVICE_PORT: USB_D
|
||||
needs:
|
||||
- job: build linux/ubuntu/2204/amd64/clang
|
||||
artifacts: true
|
||||
|
||||
hardware_test system-test-win10-red2:
|
||||
<<: *hw_test
|
||||
variables:
|
||||
GUEST_OS_TAG: win10
|
||||
DEVICE_PORT: ETH_A
|
||||
needs:
|
||||
- job: build windows/x64
|
||||
artifacts: true
|
||||
|
||||
hardware_test system-test-win10-vcan42:
|
||||
<<: *hw_test
|
||||
variables:
|
||||
GUEST_OS_TAG: win10
|
||||
DEVICE_PORT: USB_D
|
||||
needs:
|
||||
- job: build windows/x64
|
||||
artifacts: true
|
||||
@@ -1,15 +0,0 @@
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: "ubuntu-24.04"
|
||||
tools:
|
||||
python: "3.12"
|
||||
apt_packages:
|
||||
- doxygen
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
+35
-32
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(libicsneo VERSION 1.0.0)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(libicsneo VERSION 0.3.0)
|
||||
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
if(POLICY CMP0135)
|
||||
@@ -7,13 +7,14 @@ if(POLICY CMP0135)
|
||||
endif()
|
||||
|
||||
option(LIBICSNEO_BUILD_UNIT_TESTS "Build unit tests." OFF)
|
||||
option(LIBICSNEO_BUILD_SYSTEM_TESTS "Build system tests." OFF)
|
||||
option(LIBICSNEO_BUILD_DOCS "Build documentation. Don't use in Visual Studio." OFF)
|
||||
option(LIBICSNEO_BUILD_EXAMPLES "Build examples." ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC_STATIC "Build static C library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOLEGACY "Build icsnVC40 compatibility library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC "Build static icsnVC40 compatibility library" ON)
|
||||
set(LIBICSNEO_NPCAP_INCLUDE_DIR "" CACHE STRING "Npcap include directory; set to build with Npcap")
|
||||
set(LIBICSNEO_NPCAP_INCLUDE_DIR "C:/Users/Vit/source/repos/npcap-sdk-1.13/Include" CACHE STRING "Npcap include directory; set to build with Npcap")
|
||||
|
||||
# Device Drivers
|
||||
# You almost certainly don't want firmio for your build,
|
||||
@@ -26,8 +27,6 @@ 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()
|
||||
@@ -109,9 +108,7 @@ if(LIBICSNEO_BUILD_DOCS)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN -DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)
|
||||
set(PLATFORM_SRC
|
||||
platform/windows/strings.cpp
|
||||
platform/windows/registry.cpp
|
||||
)
|
||||
|
||||
@@ -175,27 +172,27 @@ if(LIBICSNEO_ENABLE_FTD3XX)
|
||||
if(NOT FTD3XX_ROOT) # allow system override
|
||||
include(FetchContent)
|
||||
if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.3.0.10-win-x64.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=459e635496ab47d6069c9d3515fdd6d82cba3d95e7ae34f794d66ffdf336e9d1")
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.3.0.4-win-x64.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=ee1289cdd5023de67275aaa1712e8e32e73e825a8392efb0a76f161e357fbdc9")
|
||||
elseif(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.3.0.10-win-i686.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=ce4259ae11772d6ede7d217172156fa392f329b29d9455131f4126a2fb89dad1")
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.3.0.4-win-i686.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=bcd31f5c3cb39ecb9b09db5ce722bd79de6e0f813130e7b8f2c86879a60d8ff0")
|
||||
elseif(APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-macos-universal2.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=0904ac5eda8e1dc4b5aac3714383bcc7792b42dfeb585dce6cbfb8b67b8c0c51")
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-macos-universal2.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=74c0d35f04242d0841532c6325eb2932b8f627e3c395382a15d9f39974d27a90")
|
||||
elseif(UNIX)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-x64.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=cf66bf299fc722f050cdd3c36998a670f1df69f7c0df18afa73707277067114b")
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-linux-x64.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=a9dc7eb6948c8977fbd79f6700bec6f882d3da5667aea8f2175b8d1f6f08e456")
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*|aarch64")
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-aarch64.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=66341b5112b9841e959e81400b51711be96fec91894477c5cbfc29b10a0c00a6")
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-linux-aarch64.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=da4b90ea1cbb905874cd159ad2ab8c1bdde65cc22b3aa55bf2b5fd85ca6efd22")
|
||||
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-armhf.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=cec1f959b48a11eb6b829ed43c81b6ba1c0bcf3e797bafcc84a6376e5ffc3c47")
|
||||
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/23.28.0/libftd3xx-1.0.14-linux-armhf.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=d813008117422cae958f7c71a065cdac0d31dca3b24809d3ab5e13604a9c3fb1")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -241,16 +238,11 @@ set(SRC_FILES
|
||||
communication/message/flexray/control/flexraycontrolmessage.cpp
|
||||
communication/message/callback/streamoutput/a2bwavoutput.cpp
|
||||
communication/message/a2bmessage.cpp
|
||||
communication/message/apperrormessage.cpp
|
||||
communication/message/neomessage.cpp
|
||||
communication/message/ethphymessage.cpp
|
||||
communication/message/linmessage.cpp
|
||||
communication/message/livedatamessage.cpp
|
||||
communication/message/logdatamessage.cpp
|
||||
communication/message/tc10statusmessage.cpp
|
||||
communication/message/gptpstatusmessage.cpp
|
||||
communication/message/ethernetstatusmessage.cpp
|
||||
communication/message/macsecmessage.cpp
|
||||
communication/packet/flexraypacket.cpp
|
||||
communication/packet/canpacket.cpp
|
||||
communication/packet/a2bpacket.cpp
|
||||
@@ -278,7 +270,6 @@ set(SRC_FILES
|
||||
communication/driver.cpp
|
||||
communication/livedata.cpp
|
||||
communication/ringbuffer.cpp
|
||||
communication/crc32.cpp
|
||||
device/extensions/flexray/extension.cpp
|
||||
device/extensions/flexray/controller.cpp
|
||||
device/idevicesettings.cpp
|
||||
@@ -308,7 +299,6 @@ set(SRC_FILES
|
||||
disk/vsa/vsa0f.cpp
|
||||
disk/vsa/vsa6a.cpp
|
||||
disk/vsa/vsaparser.cpp
|
||||
platform/servd.cpp
|
||||
${PLATFORM_SRC}
|
||||
)
|
||||
|
||||
@@ -369,7 +359,7 @@ target_include_directories(icsneocpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${LIBICSNEO_EXTENSION_INCLUDE_PATHS}
|
||||
)
|
||||
target_link_libraries(icsneocpp PUBLIC Threads::Threads $<$<BOOL:${WIN32}>:ws2_32 iphlpapi>)
|
||||
target_link_libraries(icsneocpp PUBLIC Threads::Threads)
|
||||
set_property(TARGET icsneocpp PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
target_compile_features(icsneocpp PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||
message("Loaded extensions: " ${LIBICSNEO_EXTENSION_TARGETS})
|
||||
@@ -427,9 +417,10 @@ if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
if(WIN32)
|
||||
if(LIBICSNEO_NPCAP_INCLUDE_DIR STREQUAL "")
|
||||
target_include_directories(icsneocpp PUBLIC AFTER third-party/winpcap/include)
|
||||
add_definitions(-DWPCAP -DHAVE_REMOTE)
|
||||
add_definitions(-DWPCAP -DHAVE_REMOTE -DWIN32_LEAN_AND_MEAN)
|
||||
else()
|
||||
target_include_directories(icsneocpp PUBLIC AFTER ${LIBICSNEO_NPCAP_INCLUDE_DIR})
|
||||
add_definitions(-DNPCAP -DWIN32_LEAN_AND_MEAN)
|
||||
endif()
|
||||
else()
|
||||
find_package(PCAP REQUIRED)
|
||||
@@ -502,8 +493,6 @@ 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)
|
||||
@@ -530,8 +519,6 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
||||
test/unit/mdioencoderdecodertest.cpp
|
||||
test/unit/livedataencoderdecodertest.cpp
|
||||
test/unit/ringbuffertest.cpp
|
||||
test/unit/apperrordecodertest.cpp
|
||||
test/unit/windowsstrings.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
||||
@@ -544,6 +531,22 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
||||
add_test(NAME libicsneo-unit-test-suite COMMAND libicsneo-unit-tests)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_SYSTEM_TESTS)
|
||||
if(DEFINED ENV{LIBICSNEO_SYSTEM_TESTS})
|
||||
include(FetchContent)
|
||||
file(MAKE_DIRECTORY test/system)
|
||||
FetchContent_Declare(
|
||||
SystemTests
|
||||
GIT_REPOSITORY $ENV{LIBICSNEO_SYSTEM_TESTS}
|
||||
GIT_TAG main
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test/system
|
||||
)
|
||||
FetchContent_MakeAvailable(SystemTests)
|
||||
else()
|
||||
message("System test repo not defined!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
include(CPack)
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
# Hardware Support
|
||||
|
||||
- Connecting over Ethernet
|
||||
- neoVI FIRE 2
|
||||
- CAN works
|
||||
- CAN FD works
|
||||
- ValueCAN 4-2EL
|
||||
- CAN works
|
||||
- CAN FD works
|
||||
- Ethernet works
|
||||
- RADGalaxy
|
||||
- CAN works
|
||||
- Ethernet works
|
||||
- RADStar 2
|
||||
- CAN works
|
||||
- Ethernet works
|
||||
- RADA2B
|
||||
- CAN works
|
||||
- Ethernet works
|
||||
- RADComet
|
||||
- CAN works
|
||||
- CAN FD works
|
||||
- Ethernet works
|
||||
- RADComet3
|
||||
- CAN works
|
||||
- Ethernet works
|
||||
- neoVI Connect
|
||||
- CAN works
|
||||
- CAN FD works
|
||||
- Ethernet works
|
||||
|
||||
- Connecting over USB
|
||||
- ValueCAN 4 series
|
||||
- CAN works
|
||||
- CAN FD works
|
||||
- Ethernet works (on 4-2EL)
|
||||
- neoOBD2 PRO
|
||||
- CAN works
|
||||
- neoVI FIRE
|
||||
- CAN works
|
||||
- neoVI FIRE 2
|
||||
- CAN works
|
||||
- CAN FD works
|
||||
- Ethernet works
|
||||
- ValueCAN 3
|
||||
- CAN works
|
||||
- RADStar 2
|
||||
- CAN works
|
||||
- Ethernet works
|
||||
- neoVI PLASMA
|
||||
- CAN works
|
||||
- neoVI ION
|
||||
- CAN works
|
||||
- RADA2B
|
||||
- CAN works
|
||||
- Ethernet works
|
||||
- RADMoon3
|
||||
- RADComet3
|
||||
- CAN works
|
||||
- Ethernet works
|
||||
@@ -1,29 +1,13 @@
|
||||
Copyright (c) 2018-2025 Intrepid Control Systems, Inc.
|
||||
Copyright 2018-2024 Intrepid Control Systems, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
4. It is forbidden to use this library or derivatives to interface with vehicle
|
||||
networking hardware not produced by Intrepid Control Systems, Inc.
|
||||
4. It is forbidden to use this library or derivatives to interface with vehicle networking hardware not produced by Intrepid Control Systems, Inc.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,45 +1,176 @@
|
||||
# libicsneo
|
||||
### The Intrepid Control Systems Open Source Cross-Platform Device Communication API
|
||||
|
||||
libicsneo is the [Intrepid Control Systems](https://intrepidcs.com/) device
|
||||
communication library. Installation and usage documentation can be found within
|
||||
each of the respective APIs.
|
||||
An open source solution to integrate Intrepid Control Systems vehicle networking hardware with your application.
|
||||
|
||||
## Documentation
|
||||
[Read the Full Documentation](https://libicsneo.readthedocs.io/)
|
||||
|
||||
- [C++](https://libicsneo.readthedocs.io/en/latest/icsneocpp/)
|
||||
- [Python](https://libicsneo.readthedocs.io/en/latest/icsneopy/)
|
||||
- [C](https://libicsneo.readthedocs.io/en/latest/icsneoc/)
|
||||
## Getting Started
|
||||
There are two major ways to write a new application using libicsneo. You can use the C++ interface, which will be compiled with your project and statically linked, or you can use the C interface, which can be either statically or dynamically linked.
|
||||
### Integration with CMake (Static Linking)
|
||||
Integrating the library with your current CMake project is extremely easy.
|
||||
1. Checkout the library (or add as a submodule) into a subdirectory of your project.
|
||||
2. Within your `CMakeLists.txt` you can add the line `add_subdirectory("third-party/libicsneo")` to bring in the libicsneo targets. Replace `third-party` with any subdirectory you choose.
|
||||
3. The libicsneo library include paths should automatically be added to your include path.
|
||||
4. Link the library with your target by adding `target_link_libraries(libicsneocpp-example icsneocpp)` after your target, substituting `libicsneocpp-example` with your target application.
|
||||
|
||||
## Hardware Support
|
||||
You can now include either the C++ API with `#include <icsneo/icsneocpp.h>` or the C API with `#include <icsneo/icsneoc.h>`
|
||||
|
||||
- EtherBADGE
|
||||
- neoVI Connect
|
||||
- neoVI FIRE
|
||||
- neoVI FIRE 2
|
||||
- neoVI FIRE 3
|
||||
- neoVI ION
|
||||
- neoVI PLASMA
|
||||
- neoVI RED 2
|
||||
- RAD-A2B
|
||||
- RAD-Comet 2
|
||||
- RAD-Comet 3
|
||||
- RAD-Epsilon
|
||||
- RAD-EpsilonXL
|
||||
- RAD-Galaxy
|
||||
- RAD-Galaxy 2
|
||||
- RAD-Gigastar
|
||||
- RAD-Gigastar 2
|
||||
- RAD-Moon 2
|
||||
- RAD-Moon 3
|
||||
- RAD-Moon T1S
|
||||
- RAD-Pluto
|
||||
- RAD-Star 2
|
||||
- RAD-SuperMoon
|
||||
- RADComet
|
||||
- ValueCAN 3
|
||||
- ValueCAN 4
|
||||
### DLL / SO / DYLIB Releases (Dynamic Linking)
|
||||
It is also possible to use the precompiled binaries with runtime linking. It is not recommended or supported to attempt to use the C++ interface with dynamic linking due to the complexities of C++ compilers.
|
||||
1. Add this repository's `/include` to your include path
|
||||
2. Add `#define ICSNEOC_DYNAMICLOAD` to the top of your source file
|
||||
2. Add `#import <icsneo/icsneoc.h>` below that line
|
||||
3. Call `icsneo_init();` to import the library before using any other libicsneo functions.
|
||||
4. Use the library as normal.
|
||||
5. Call `icsneo_close();` to unload the library.
|
||||
|
||||
## License
|
||||
## Usage
|
||||
### Using the C++ API
|
||||
The C++ API is designed to be modern and easy to use. All library functions and classes are in the namespace `icsneo`. Most applications will start by calling `icsneo::FindAllDevices()`. This will return an `std::vector` of `std::shared_ptr<icsneo::Device>` objects. You will want to keep a copy of the `shared_ptr` to any devices you want to use, as allowing it to go out of scope will automatically close the device and free all memory associated with it.
|
||||
|
||||
libicsneo is licensed as BSD-3 with an extra clause, see [LICENSE](LICENSE)
|
||||
for more details.
|
||||
Any time you get bus traffic from the API, you will receive it as an `std::shared_ptr<icsneo::Message>`. The message will be valid as long as the `shared_ptr` stays in scope. Checking the type of the message allows you to cast it accordingly and access extra data for certain protocols. For instance, casting an `icsneo::Message` to an `icsneo::CANMessage` allows you to access the arbitration ID.
|
||||
|
||||
A barebones example is provided. For a more complete example, check the included `examples`.
|
||||
``` c++
|
||||
std::vector<std::shared_ptr<icsneo::Device>> devices = icsneo::FindAllDevices();
|
||||
std::cout << devices.size() << " found!" << std::endl;
|
||||
for(auto& device : devices)
|
||||
std::cout << "Found " << device->describe() << std::endl; // "Found neoVI FIRE 2 CY2345"
|
||||
std::shared_ptr<icsneo::Device> myDevice = devices[0];
|
||||
|
||||
if(!myDevice->open()) // Device tried and failed to open, print the last error
|
||||
std::cout << icsneo::GetLastError() << std::endl;
|
||||
|
||||
myDevice->goOnline(); // Start receiving messages
|
||||
myDevice->enableMessagePolling(); // Allow the use of myDevice->getMessages() later
|
||||
// Alternatively, assign a callback for new messages
|
||||
std::this_thread::wait_for(std::chrono::seconds(5));
|
||||
std::vector<std::shared_ptr<icsneo::Message>> messages = myDevice->getMessages();
|
||||
std::cout << "We got " << messages.size() << " messages!" << std::endl;
|
||||
for(auto& msg : messages) {
|
||||
switch(msg->network.getType()) {
|
||||
case icsneo::Network::Type::CAN:
|
||||
case icsneo::Network::Type::SWCAN:
|
||||
case icsneo::Network::Type::LSFTCAN: {
|
||||
// A message of type CAN is guaranteed to be a CANMessage, so we can static cast safely
|
||||
auto canmsg = std::static_pointer_cast<icsneo::CANMessage>(msg);
|
||||
// canmsg->arbid is valid here
|
||||
// canmsg->data is an std::vector<uint8_t>, you can check .size() for the DLC of the message
|
||||
// canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT)
|
||||
}
|
||||
default:
|
||||
// Handle others
|
||||
}
|
||||
}
|
||||
myDevice->close();
|
||||
```
|
||||
|
||||
### Using the C API
|
||||
The C API is designed to be a robust and fault tolerant interface which allows easy integration with other languages as well as existing C applications. When calling `icsneo_findAllDevices()` you will provide a buffer of `neodevice_t` structures, which will be written with the found devices. These `neodevice_t` structures can be uses to interface with the API from then on. Once you call `icsneo_close()` with a device, that device and all associated memory will be freed. You will need to run `icsneo_findAllDevices()` again to reconnect.
|
||||
|
||||
Messages are passed in the form of `neomessage_t` structures when calling `icsneo_getMessages()`. These structures contain a `uint8_t*` to the payload data, and this pointer will be valid until the next call to `icsneo_getMessages()` or the device is closed.
|
||||
|
||||
A barebones example is provided. For a more complete example, check the included `examples`.
|
||||
``` c
|
||||
size_t deviceCount = 10; // Pre-set to the size of your buffer before the icsneo_findAllDevices() call
|
||||
neodevice_t devices[10];
|
||||
icsneo_findAllDevices(devices, &deviceCount);
|
||||
printf("We found %ull devices\n", deviceCount);
|
||||
for(size_t i = 0; i < deviceCount; i++) {
|
||||
neodevice_t* myDevice = &devices[i];
|
||||
char desc[ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION];
|
||||
size_t sz = ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION;
|
||||
icsneo_describeDevice(myDevice, desc, &sz);
|
||||
printf("Found %s\n", desc); // "Found neoVI FIRE 2 CY2345"
|
||||
}
|
||||
|
||||
neodevice_t* myDevice = &devices[0];
|
||||
if(!icsneo_openDevice(myDevice)) {
|
||||
neoevent_t error;
|
||||
if(icsneo_getLastError(&error))
|
||||
printf("Error! %s\n", error.description);
|
||||
}
|
||||
icsneo_goOnline(myDevice); // Start receiving messages
|
||||
icsneo_enableMessagePolling(myDevice); // Allow the use of icsneo_getMessages() later
|
||||
sleep(5);
|
||||
neomessage_t messages[50];
|
||||
size_t messageCount = 50;
|
||||
icsneo_getMessages(myDevice, messages, &messageCount, 0 /* non-blocking */);
|
||||
printf("We got %ull messages!\n", messageCount);
|
||||
for(size_t i = 0; i < messageCount; i++) {
|
||||
if(messages[i].type == ICSNEO_NETWORK_TYPE_CAN) {
|
||||
// A message of type CAN should be interperated a neomessage_can_t, so we can cast safely
|
||||
neomessage_can_t* canmsg = (neomessage_can_t*)&messages[i];
|
||||
// canmsg->arbid is valid here
|
||||
// canmsg->data is an uint8_t*, you can check canmsg->length for the length of the payload
|
||||
// canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT)
|
||||
}
|
||||
}
|
||||
icsneo_closeDevice(myDevice);
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
To enable debug printing set the `LIBICSNEO_PRINT_EVENTS` environmental variable to the desired `APIEvent::Severity` level, all `Event`s greater than or equal to that level will be printed to stderr. For example, to print all warnings and errors: `LIBICSNEO_PRINT_EVENTS=32`.
|
||||
|
||||
## Building from Source
|
||||
### FTD3XX
|
||||
Some devices require FTD3XX for USB communication so the [FTDI D3XX library](https://ftdichip.com/drivers/d3xx-drivers/) will be automatically downloaded and included. If you would like to use a system copy of D3XX instead you can set `FTD3XX_ROOT` to the path containing `f3d3xx.h` (`-DFTD3XX_ROOT=<path to directory containing ftd3xx.h>`).
|
||||
### Windows
|
||||
|
||||
- Open a terminal and install the following:
|
||||
```
|
||||
winget install Microsoft.VisualStudio.2022.Community
|
||||
winget install Kitware.CMake
|
||||
winget install Git.Git
|
||||
winget install Ninja-build.Ninja
|
||||
```
|
||||
- Reboot so cmake is in the system path
|
||||
- Open a developer Powershell for VS2022 and run the following:
|
||||
```
|
||||
git clone https://github.com/intrepidcs/libicsneo
|
||||
cd libicsneo
|
||||
cmake -S . -B build -G "Ninja"
|
||||
cmake --build build
|
||||
# All dlls and libs are now inside the build directory
|
||||
```
|
||||
|
||||
|
||||
Building will require MSVC 2017 version 15.7 or newer and CMake to be installed.
|
||||
### macOS
|
||||
Getting the dependencies is easiest with the Homebrew package manager. You will also need XCode installed. You can then install CMake, an up-to-date version of GCC or Clang, and `libusb-1.0`.
|
||||
### Linux
|
||||
#### General Dependencies
|
||||
- CMake 3.12 or above
|
||||
- GCC 7 or above
|
||||
- `libusb-1.0-0-dev`
|
||||
- `libpcap0.8-dev`
|
||||
- `build-essential` is recommended
|
||||
|
||||
#### Fedora
|
||||
```
|
||||
dnf install git @development-tools gcc-c++ libpcap-devel libusb1-devel cmake
|
||||
```
|
||||
#### Debian/Ubuntu
|
||||
```
|
||||
apt install git build-essential libpcap0.8-dev libusb-1.0-0-dev cmake
|
||||
```
|
||||
|
||||
#### Building
|
||||
```
|
||||
git clone https://github.com/intrepidcs/libicsneo
|
||||
cd libicsneo
|
||||
cmake -S . -B build
|
||||
cmake --build build
|
||||
# Optional: Install globally:
|
||||
cp *.so /usr/local/lib/
|
||||
```
|
||||
|
||||
#### udev
|
||||
If you'd like to be able to run programs that use this library without being root, consider using the included udev rules:
|
||||
|
||||
```
|
||||
cp 99-intrepidcs.rules /etc/udev/rules.d/
|
||||
udevadm control --reload-rules && udevadm trigger
|
||||
```
|
||||
|
||||
@@ -29,7 +29,7 @@ BEGIN
|
||||
VALUE "FileDescription", "Intrepid Control Systems Open Device Communication C API"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "icsneoc.dll"
|
||||
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2025"
|
||||
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2024"
|
||||
VALUE "OriginalFilename", "icsneoc.dll"
|
||||
VALUE "ProductName", "libicsneo"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
|
||||
@@ -120,8 +120,6 @@ static constexpr const char* DISK_NOT_CONNECTED = "The program tried to access a
|
||||
static constexpr const char* UNEXPECTED_RESPONSE = "Received an unexpected or invalid response from the device.";
|
||||
static constexpr const char* LIN_SETTINGS_NOT_AVAILABLE = "LIN settings are not available for this device.";
|
||||
static constexpr const char* MODE_NOT_FOUND = "The mode was not found.";
|
||||
static constexpr const char* GPTP_NOT_SUPPORTED = "GPTP clock synchronization is not supported on this device.";
|
||||
static constexpr const char* SETTING_NOT_AVAILABLE = "Requested a setting that is not available on this device";
|
||||
|
||||
// Transport Errors
|
||||
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
||||
@@ -184,23 +182,9 @@ static constexpr const char* VSA_BYTE_PARSE_FAILURE = "Failure to parse record b
|
||||
static constexpr const char* VSA_EXTENDED_MESSAGE_ERROR = "Failure to parse extended message record sequence";
|
||||
static constexpr const char* VSA_OTHER_ERROR = "Unknown error in VSA read API.";
|
||||
|
||||
// Servd
|
||||
static constexpr const char* SERVD_BIND_ERROR = "Error binding socket for Servd communication";
|
||||
static constexpr const char* SERVD_NONBLOCK_ERROR = "Error setting non-blocking mode for Servd socket";
|
||||
static constexpr const char* SERVD_TRANSCEIVE_ERROR = "Error while sending to or receiving from Servd";
|
||||
static constexpr const char* SERVD_OUTDATED_ERROR = "Servd version is lower than client (libicsneo) version, update Servd";
|
||||
static constexpr const char* SERVD_INVALID_RESPONSE_ERROR = "Unexpected response from Servd";
|
||||
static constexpr const char* SERVD_LOCK_ERROR = "Error locking Servd mutex";
|
||||
static constexpr const char* SERVD_SEND_ERROR = "Error sending to Servd";
|
||||
static constexpr const char* SERVD_RECV_ERROR = "Error receiving from Servd";
|
||||
static constexpr const char* SERVD_POLL_ERROR = "Error polling on Servd socket";
|
||||
static constexpr const char* SERVD_NODATA_ERROR = "No data received from Servd";
|
||||
static constexpr const char* SERVD_JOIN_MULTICAST_ERROR = "Error joining Servd multicast group";
|
||||
|
||||
static constexpr const char* TOO_MANY_EVENTS = "Too many events have occurred. The list has been truncated.";
|
||||
static constexpr const char* UNKNOWN = "An unknown internal error occurred.";
|
||||
static constexpr const char* INVALID = "An invalid internal error occurred.";
|
||||
|
||||
const char* APIEvent::DescriptionForType(Type type) {
|
||||
switch(type) {
|
||||
// API Errors
|
||||
@@ -330,8 +314,6 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
return LIN_SETTINGS_NOT_AVAILABLE;
|
||||
case Type::ModeNotFound:
|
||||
return MODE_NOT_FOUND;
|
||||
case Type::SettingNotAvaiableDevice:
|
||||
return SETTING_NOT_AVAILABLE;
|
||||
// Transport Errors
|
||||
case Type::FailedToRead:
|
||||
return FAILED_TO_READ;
|
||||
@@ -363,8 +345,6 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
return GETIFADDRS_ERROR;
|
||||
case Type::SendToError:
|
||||
return SEND_TO_ERROR;
|
||||
case Type::GPTPNotSupported:
|
||||
return GPTP_NOT_SUPPORTED;
|
||||
|
||||
// FTD3XX
|
||||
case Type::FTOK:
|
||||
@@ -450,30 +430,6 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
case Type::VSAOtherError:
|
||||
return VSA_OTHER_ERROR;
|
||||
|
||||
// Servd
|
||||
case Type::ServdBindError:
|
||||
return SERVD_BIND_ERROR;
|
||||
case Type::ServdNonblockError:
|
||||
return SERVD_NONBLOCK_ERROR;
|
||||
case Type::ServdTransceiveError:
|
||||
return SERVD_TRANSCEIVE_ERROR;
|
||||
case Type::ServdOutdatedError:
|
||||
return SERVD_OUTDATED_ERROR;
|
||||
case Type::ServdInvalidResponseError:
|
||||
return SERVD_INVALID_RESPONSE_ERROR;
|
||||
case Type::ServdLockError:
|
||||
return SERVD_LOCK_ERROR;
|
||||
case Type::ServdSendError:
|
||||
return SERVD_SEND_ERROR;
|
||||
case Type::ServdRecvError:
|
||||
return SERVD_RECV_ERROR;
|
||||
case Type::ServdPollError:
|
||||
return SERVD_POLL_ERROR;
|
||||
case Type::ServdNoDataError:
|
||||
return SERVD_NODATA_ERROR;
|
||||
case Type::ServdJoinMulticastError:
|
||||
return SERVD_JOIN_MULTICAST_ERROR;
|
||||
|
||||
// Other Errors
|
||||
case Type::TooManyEvents:
|
||||
return TOO_MANY_EVENTS;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#error "icsneolegacy.cpp must be compiled with a C++ compiler!"
|
||||
#endif
|
||||
|
||||
#define NOMINMAX
|
||||
|
||||
#define ICSNEOC_MAKEDLL
|
||||
#include "icsneo/icsneolegacy.h"
|
||||
#include "icsneo/J2534.h"
|
||||
@@ -27,25 +29,25 @@ static std::map<legacymaphandle_t, neodevice_t> neodevices;
|
||||
static std::map<neodevice_t*, NeoDeviceEx*> openneodevices;
|
||||
|
||||
static const std::map<size_t, size_t> mp_netIDToVnetOffSet = {
|
||||
{NETID_DWCAN_01, 1},
|
||||
{NETID_DWCAN_08, 2},
|
||||
{NETID_DWCAN_02, 18},
|
||||
{NETID_DWCAN_03, 19},
|
||||
{NETID_DWCAN_04, 32},
|
||||
{NETID_DWCAN_05, 33},
|
||||
{NETID_DWCAN_06, 47},
|
||||
{NETID_DWCAN_07, 48},
|
||||
{NETID_HSCAN, 1},
|
||||
{NETID_MSCAN, 2},
|
||||
{NETID_HSCAN2, 18},
|
||||
{NETID_HSCAN3, 19},
|
||||
{NETID_HSCAN4, 32},
|
||||
{NETID_HSCAN5, 33},
|
||||
{NETID_HSCAN6, 47},
|
||||
{NETID_HSCAN7, 48},
|
||||
};
|
||||
|
||||
static const std::map<size_t, size_t> mp_HWnetIDToCMnetID = {
|
||||
{NETID_DWCAN_01, 0},
|
||||
{NETID_DWCAN_08, 1},
|
||||
{NETID_DWCAN_02, 5},
|
||||
{NETID_DWCAN_03, 8},
|
||||
{NETID_DWCAN_04, 14},
|
||||
{NETID_DWCAN_05, 15},
|
||||
{NETID_DWCAN_06, 32},
|
||||
{NETID_DWCAN_07, 33},
|
||||
{NETID_HSCAN, 0},
|
||||
{NETID_MSCAN, 1},
|
||||
{NETID_HSCAN2, 5},
|
||||
{NETID_HSCAN3, 8},
|
||||
{NETID_HSCAN4, 14},
|
||||
{NETID_HSCAN5, 15},
|
||||
{NETID_HSCAN6, 32},
|
||||
{NETID_HSCAN7, 33},
|
||||
};
|
||||
|
||||
static unsigned long vnet_table[] = {0, PLASMA_SLAVE1_OFFSET, PLASMA_SLAVE2_OFFSET};
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
if(LIBICSNEO_ENABLE_BINDINGS_PYTHON)
|
||||
add_subdirectory(python)
|
||||
endif()
|
||||
@@ -1,54 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
set(PYBIND11_FINDPYTHON ON)
|
||||
|
||||
if(PYBIND11_ROOT)
|
||||
find_package(pybind11 CONFIG REQUIRED)
|
||||
else()
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
GIT_REPOSITORY https://github.com/pybind/pybind11.git
|
||||
GIT_TAG v2.13.6
|
||||
)
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
endif()
|
||||
|
||||
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/io.cpp
|
||||
icsneopy/communication/message/message.cpp
|
||||
icsneopy/communication/message/canmessage.cpp
|
||||
icsneopy/communication/message/canerrormessage.cpp
|
||||
icsneopy/communication/message/ethernetmessage.cpp
|
||||
icsneopy/communication/message/linmessage.cpp
|
||||
icsneopy/communication/message/tc10statusmessage.cpp
|
||||
icsneopy/communication/message/mdiomessage.cpp
|
||||
icsneopy/communication/message/gptpstatusmessage.cpp
|
||||
icsneopy/communication/message/ethernetstatusmessage.cpp
|
||||
icsneopy/communication/message/macsecmessage.cpp
|
||||
icsneopy/communication/message/scriptstatusmessage.cpp
|
||||
icsneopy/communication/message/callback/messagecallback.cpp
|
||||
icsneopy/communication/message/filter/messagefilter.cpp
|
||||
icsneopy/communication/message/flexray/flexraymessage.cpp
|
||||
icsneopy/disk/diskdriver.cpp
|
||||
icsneopy/device/device.cpp
|
||||
icsneopy/device/idevicesettings.cpp
|
||||
icsneopy/icsneocpp.cpp
|
||||
)
|
||||
target_link_libraries(icsneopy PRIVATE icsneocpp)
|
||||
|
||||
install(TARGETS icsneopy LIBRARY DESTINATION icsneopy)
|
||||
|
||||
find_program(STUBGEN_EXE stubgen)
|
||||
if(STUBGEN_EXE)
|
||||
add_custom_command(TARGET icsneopy POST_BUILD COMMAND stubgen -v -p icsneopy -o .)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/icsneopy.pyi py.typed DESTINATION icsneopy)
|
||||
endif()
|
||||
|
||||
install(FILES __init__.py DESTINATION icsneopy)
|
||||
@@ -1 +0,0 @@
|
||||
from .icsneopy import *
|
||||
@@ -1,170 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/api/event.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_event(pybind11::module_& m) {
|
||||
pybind11::class_<APIEvent, std::shared_ptr<APIEvent>> apiEvent(m, "APIEvent");
|
||||
pybind11::enum_<APIEvent::Type>(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>(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_<EventFilter, std::shared_ptr<EventFilter>>(m, "EventFilter")
|
||||
.def(pybind11::init())
|
||||
.def(pybind11::init<APIEvent::Type>())
|
||||
.def(pybind11::init<APIEvent::Severity>())
|
||||
.def_readwrite("type", &EventFilter::type)
|
||||
.def_readwrite("severity", &EventFilter::severity)
|
||||
.def_readwrite("serial", &EventFilter::serial);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/api/eventcallback.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_eventcallback(pybind11::module_& m) {
|
||||
pybind11::class_<EventCallback>(m, "EventCallback")
|
||||
.def(pybind11::init<EventCallback::fn_eventCallback, EventFilter>())
|
||||
.def(pybind11::init<EventCallback::fn_eventCallback>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_eventmanager(pybind11::module_& m) {
|
||||
pybind11::class_<EventManager>(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
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/api/version.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_version(pybind11::module_& m) {
|
||||
pybind11::class_<neoversion_t>(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
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/io.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_io(pybind11::module_& m) {
|
||||
pybind11::enum_<IO>(m, "IO")
|
||||
.value("EthernetActivation", IO::EthernetActivation)
|
||||
.value("USBHostPower", IO::USBHostPower)
|
||||
.value("BackupPowerEnabled", IO::BackupPowerEnabled)
|
||||
.value("BackupPowerGood", IO::BackupPowerGood)
|
||||
.value("Misc", IO::Misc)
|
||||
.value("EMisc", IO::EMisc);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,15 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/callback/messagecallback.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_messagecallback(pybind11::module_& m) {
|
||||
pybind11::class_<MessageCallback, std::shared_ptr<MessageCallback>>(m, "MessageCallback")
|
||||
.def(pybind11::init<MessageCallback::fn_messageCallback, std::shared_ptr<MessageFilter>>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_errorcodes(pybind11::module_& m) {
|
||||
pybind11::enum_<CANErrorCode>(m, "CANErrorCode")
|
||||
.value("NoError", CANErrorCode::NoError)
|
||||
.value("StuffError", CANErrorCode::StuffError)
|
||||
.value("FormError", CANErrorCode::FormError)
|
||||
.value("AckError", CANErrorCode::AckError)
|
||||
.value("Bit1Error", CANErrorCode::Bit1Error)
|
||||
.value("Bit0Error", CANErrorCode::Bit0Error)
|
||||
.value("CRCError", CANErrorCode::CRCError)
|
||||
.value("NoChange", CANErrorCode::NoChange);
|
||||
}
|
||||
|
||||
void init_canerrormessage(pybind11::module_& m) {
|
||||
init_errorcodes(m);
|
||||
pybind11::class_<CANErrorMessage, std::shared_ptr<CANErrorMessage>, Message>(m, "CANErrorMessage")
|
||||
.def_readonly("network", &CANErrorMessage::network)
|
||||
.def_readonly("transmitErrorCount", &CANErrorMessage::transmitErrorCount)
|
||||
.def_readonly("receiveErrorCount", &CANErrorMessage::receiveErrorCount)
|
||||
.def_readonly("busOff", &CANErrorMessage::busOff)
|
||||
.def_readonly("errorPassive", &CANErrorMessage::errorPassive)
|
||||
.def_readonly("errorWarn", &CANErrorMessage::errorWarn)
|
||||
.def_readonly("dataErrorCode", &CANErrorMessage::dataErrorCode)
|
||||
.def_readonly("errorCode", &CANErrorMessage::errorCode);
|
||||
|
||||
|
||||
m.attr("CANErrorCountMessage") = m.attr("CANErrorMessage");
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/canmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_canmessage(pybind11::module_& m) {
|
||||
pybind11::class_<CANMessage, std::shared_ptr<CANMessage>, 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
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/ethernetmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_ethernetmessage(pybind11::module_& m) {
|
||||
pybind11::class_<MACAddress>(m, "MACAddress")
|
||||
.def("to_string", &MACAddress::toString)
|
||||
.def("__repr__", &MACAddress::toString);
|
||||
|
||||
pybind11::class_<EthernetMessage, std::shared_ptr<EthernetMessage>, Frame>(m, "EthernetMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("preemptionEnabled", &EthernetMessage::preemptionEnabled)
|
||||
.def_readwrite("preemptionFlags", &EthernetMessage::preemptionFlags)
|
||||
.def_readwrite("fcs", &EthernetMessage::fcs)
|
||||
.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
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_ethernetstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<EthernetStatusMessage, std::shared_ptr<EthernetStatusMessage>, Message> ethernetStatusMessage(m, "EthernetStatusMessage");
|
||||
|
||||
pybind11::enum_<EthernetStatusMessage::LinkSpeed>(ethernetStatusMessage, "LinkSpeed")
|
||||
.value("LinkSpeedAuto", EthernetStatusMessage::LinkSpeed::LinkSpeedAuto)
|
||||
.value("LinkSpeed10", EthernetStatusMessage::LinkSpeed::LinkSpeed10)
|
||||
.value("LinkSpeed100", EthernetStatusMessage::LinkSpeed::LinkSpeed100)
|
||||
.value("LinkSpeed1000", EthernetStatusMessage::LinkSpeed::LinkSpeed1000)
|
||||
.value("LinkSpeed2500", EthernetStatusMessage::LinkSpeed::LinkSpeed2500)
|
||||
.value("LinkSpeed5000", EthernetStatusMessage::LinkSpeed::LinkSpeed5000)
|
||||
.value("LinkSpeed10000", EthernetStatusMessage::LinkSpeed::LinkSpeed10000);
|
||||
|
||||
pybind11::enum_<EthernetStatusMessage::LinkMode>(ethernetStatusMessage, "LinkMode")
|
||||
.value("LinkModeAuto", EthernetStatusMessage::LinkMode::LinkModeAuto)
|
||||
.value("LinkModeMaster", EthernetStatusMessage::LinkMode::LinkModeMaster)
|
||||
.value("LinkModeSlave", EthernetStatusMessage::LinkMode::LinkModeSlave)
|
||||
.value("LinkModeInvalid", EthernetStatusMessage::LinkMode::LinkModeInvalid);
|
||||
|
||||
ethernetStatusMessage
|
||||
.def_readonly("network", &EthernetStatusMessage::network)
|
||||
.def_readonly("state", &EthernetStatusMessage::state)
|
||||
.def_readonly("speed", &EthernetStatusMessage::speed)
|
||||
.def_readonly("duplex", &EthernetStatusMessage::duplex)
|
||||
.def_readonly("mode", &EthernetStatusMessage::mode);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,17 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/filter/messagefilter.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_messagefilter(pybind11::module_& m) {
|
||||
pybind11::class_<MessageFilter, std::shared_ptr<MessageFilter>>(m, "MessageFilter")
|
||||
.def(pybind11::init())
|
||||
.def(pybind11::init<Message::Type>())
|
||||
.def(pybind11::init<Network::NetID>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
||||
#include "icsneo/device/extensions/flexray/symbol.h"
|
||||
#include "icsneo/device/extensions/flexray/channel.h"
|
||||
#include "icsneo/device/extensions/flexray/crcstatus.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct FlexRayNamespace {
|
||||
using Symbol = icsneo::FlexRay::Symbol;
|
||||
using CRCStatus = icsneo::FlexRay::CRCStatus;
|
||||
using Channel = icsneo::FlexRay::Channel;
|
||||
};
|
||||
|
||||
void init_flexraymessage(pybind11::module_& m) {
|
||||
// dummy class to hold the enums
|
||||
pybind11::class_<FlexRayNamespace> flexray(m, "FlexRay");
|
||||
// enumerations
|
||||
pybind11::enum_<FlexRayNamespace::Symbol>(flexray, "Symbol")
|
||||
.value("None", FlexRayNamespace::Symbol::None)
|
||||
.value("Unknown", FlexRayNamespace::Symbol::Unknown)
|
||||
.value("Wakeup", FlexRayNamespace::Symbol::Wakeup)
|
||||
.value("CAS", FlexRayNamespace::Symbol::CAS);
|
||||
pybind11::enum_<FlexRayNamespace::CRCStatus>(flexray, "CRCStatus")
|
||||
.value("OK", FlexRayNamespace::CRCStatus::OK)
|
||||
.value("Error", FlexRayNamespace::CRCStatus::Error)
|
||||
.value("NoCRC", FlexRayNamespace::CRCStatus::NoCRC);
|
||||
pybind11::enum_<FlexRayNamespace::Channel>(flexray, "Channel")
|
||||
.value("None", FlexRayNamespace::Channel::None)
|
||||
.value("A", FlexRayNamespace::Channel::A)
|
||||
.value("B", FlexRayNamespace::Channel::B)
|
||||
.value("AB", FlexRayNamespace::Channel::AB);
|
||||
// read-only until transmit is supported
|
||||
pybind11::class_<FlexRayMessage, std::shared_ptr<FlexRayMessage>, Frame>(m, "FlexRayMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readonly("slotid", &FlexRayMessage::slotid)
|
||||
.def_readonly("tsslen", &FlexRayMessage::tsslen)
|
||||
.def_readonly("framelen", &FlexRayMessage::framelen)
|
||||
.def_readonly("symbol", &FlexRayMessage::symbol)
|
||||
.def_readonly("header_crc_status", &FlexRayMessage::headerCRCStatus)
|
||||
.def_readonly("header_crc", &FlexRayMessage::headerCRC)
|
||||
.def_readonly("frame_crc_status", &FlexRayMessage::crcStatus)
|
||||
.def_readonly("frame_crc", &FlexRayMessage::frameCRC)
|
||||
.def_readonly("channel", &FlexRayMessage::channel)
|
||||
.def_readonly("null_frame", &FlexRayMessage::nullFrame)
|
||||
.def_readonly("payload_preamble", &FlexRayMessage::payloadPreamble)
|
||||
.def_readonly("sync_frame", &FlexRayMessage::sync)
|
||||
.def_readonly("startup_frame", &FlexRayMessage::startup)
|
||||
.def_readonly("dynamic_frame", &FlexRayMessage::dynamic)
|
||||
.def_readonly("cycle", &FlexRayMessage::cycle);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/gptpstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_gptpstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<GPTPStatus, std::shared_ptr<GPTPStatus>, Message> gptpStatus(m, "GPTPStatus");
|
||||
|
||||
pybind11::class_<GPTPStatus::Timestamp>(gptpStatus, "Timestamp")
|
||||
.def_readonly("seconds", &GPTPStatus::Timestamp::seconds)
|
||||
.def_readonly("nanoseconds", &GPTPStatus::Timestamp::nanoseconds)
|
||||
.def("to_seconds", &GPTPStatus::Timestamp::toSeconds, pybind11::call_guard<pybind11::gil_scoped_release>());
|
||||
|
||||
pybind11::class_<GPTPStatus::ScaledNanoSeconds>(gptpStatus, "ScaledNanoSeconds")
|
||||
.def_readonly("nanosecondsMSB", &GPTPStatus::ScaledNanoSeconds::nanosecondsMSB)
|
||||
.def_readonly("nanosecondsLSB", &GPTPStatus::ScaledNanoSeconds::nanosecondsLSB)
|
||||
.def_readonly("fractionalNanoseconds", &GPTPStatus::ScaledNanoSeconds::fractionalNanoseconds);
|
||||
|
||||
pybind11::class_<GPTPStatus::PortID>(gptpStatus, "PortID")
|
||||
.def_readonly("clockIdentity", &GPTPStatus::PortID::clockIdentity)
|
||||
.def_readonly("portNumber", &GPTPStatus::PortID::portNumber);
|
||||
|
||||
pybind11::class_<GPTPStatus::ClockQuality>(gptpStatus, "ClockQuality")
|
||||
.def_readonly("clockClass", &GPTPStatus::ClockQuality::clockClass)
|
||||
.def_readonly("clockAccuracy", &GPTPStatus::ClockQuality::clockAccuracy)
|
||||
.def_readonly("offsetScaledLogVariance", &GPTPStatus::ClockQuality::offsetScaledLogVariance);
|
||||
|
||||
pybind11::class_<GPTPStatus::SystemID>(gptpStatus, "SystemID")
|
||||
.def_readonly("priority1", &GPTPStatus::SystemID::priority1)
|
||||
.def_readonly("clockQuality", &GPTPStatus::SystemID::clockQuality)
|
||||
.def_readonly("priority2", &GPTPStatus::SystemID::priority2)
|
||||
.def_readonly("clockID", &GPTPStatus::SystemID::clockID);
|
||||
|
||||
pybind11::class_<GPTPStatus::PriorityVector>(gptpStatus, "PriorityVector")
|
||||
.def_readonly("sysID", &GPTPStatus::PriorityVector::sysID)
|
||||
.def_readonly("stepsRemoved", &GPTPStatus::PriorityVector::stepsRemoved)
|
||||
.def_readonly("portID", &GPTPStatus::PriorityVector::portID)
|
||||
.def_readonly("portNumber", &GPTPStatus::PriorityVector::portNumber);
|
||||
|
||||
pybind11::class_<GPTPStatus::ParentDS>(gptpStatus, "ParentDS")
|
||||
.def_readonly("parentPortIdentity", &GPTPStatus::ParentDS::parentPortIdentity)
|
||||
.def_readonly("cumulativeRateRatio", &GPTPStatus::ParentDS::cumulativeRateRatio)
|
||||
.def_readonly("grandmasterIdentity", &GPTPStatus::ParentDS::grandmasterIdentity)
|
||||
.def_readonly("gmClockQualityClockClass", &GPTPStatus::ParentDS::gmClockQualityClockClass)
|
||||
.def_readonly("gmClockQualityClockAccuracy", &GPTPStatus::ParentDS::gmClockQualityClockAccuracy)
|
||||
.def_readonly("gmClockQualityOffsetScaledLogVariance", &GPTPStatus::ParentDS::gmClockQualityOffsetScaledLogVariance)
|
||||
.def_readonly("gmPriority1", &GPTPStatus::ParentDS::gmPriority1)
|
||||
.def_readonly("gmPriority2", &GPTPStatus::ParentDS::gmPriority2);
|
||||
|
||||
pybind11::class_<GPTPStatus::CurrentDS>(gptpStatus, "CurrentDS")
|
||||
.def_readonly("stepsRemoved", &GPTPStatus::CurrentDS::stepsRemoved)
|
||||
.def_readonly("offsetFromMaster", &GPTPStatus::CurrentDS::offsetFromMaster)
|
||||
.def_readonly("lastgmPhaseChange", &GPTPStatus::CurrentDS::lastgmPhaseChange)
|
||||
.def_readonly("lastgmFreqChange", &GPTPStatus::CurrentDS::lastgmFreqChange)
|
||||
.def_readonly("gmTimeBaseIndicator", &GPTPStatus::CurrentDS::gmTimeBaseIndicator)
|
||||
.def_readonly("gmChangeCount", &GPTPStatus::CurrentDS::gmChangeCount)
|
||||
.def_readonly("timeOfLastgmChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmChangeEvent)
|
||||
.def_readonly("timeOfLastgmPhaseChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmPhaseChangeEvent)
|
||||
.def_readonly("timeOfLastgmFreqChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmFreqChangeEvent);
|
||||
|
||||
gptpStatus.def_readonly("currentTime", &GPTPStatus::currentTime)
|
||||
.def_readonly("gmPriority", &GPTPStatus::gmPriority)
|
||||
.def_readonly("msOffsetNs", &GPTPStatus::msOffsetNs)
|
||||
.def_readonly("isSync", &GPTPStatus::isSync)
|
||||
.def_readonly("linkStatus", &GPTPStatus::linkStatus)
|
||||
.def_readonly("linkDelayNS", &GPTPStatus::linkDelayNS)
|
||||
.def_readonly("selectedRole", &GPTPStatus::selectedRole)
|
||||
.def_readonly("asCapable", &GPTPStatus::asCapable)
|
||||
.def_readonly("isSyntonized", &GPTPStatus::isSyntonized)
|
||||
.def_readonly("lastRXSyncTS", &GPTPStatus::lastRXSyncTS)
|
||||
.def_readonly("currentDS", &GPTPStatus::currentDS)
|
||||
.def_readonly("parentDS", &GPTPStatus::parentDS);
|
||||
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,59 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/linmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_linmessage(pybind11::module_& m) {
|
||||
pybind11::class_<LINErrorFlags>(m, "LINErrorFlags")
|
||||
.def_readwrite("ErrRxBreakOnly", &LINErrorFlags::ErrRxBreakOnly)
|
||||
.def_readwrite("ErrRxBreakSyncOnly", &LINErrorFlags::ErrRxBreakSyncOnly)
|
||||
.def_readwrite("ErrTxRxMismatch", &LINErrorFlags::ErrTxRxMismatch)
|
||||
.def_readwrite("ErrRxBreakNotZero", &LINErrorFlags::ErrRxBreakNotZero)
|
||||
.def_readwrite("ErrRxBreakTooShort", &LINErrorFlags::ErrRxBreakTooShort)
|
||||
.def_readwrite("ErrRxSyncNot55", &LINErrorFlags::ErrRxSyncNot55)
|
||||
.def_readwrite("ErrRxDataLenOver8", &LINErrorFlags::ErrRxDataLenOver8)
|
||||
.def_readwrite("ErrFrameSync", &LINErrorFlags::ErrFrameSync)
|
||||
.def_readwrite("ErrFrameMessageID", &LINErrorFlags::ErrFrameMessageID)
|
||||
.def_readwrite("ErrFrameResponderData", &LINErrorFlags::ErrFrameResponderData)
|
||||
.def_readwrite("ErrChecksumMatch", &LINErrorFlags::ErrChecksumMatch);
|
||||
|
||||
pybind11::class_<LINStatusFlags>(m, "LINStatusFlags")
|
||||
.def_readwrite("TxChecksumEnhanced", &LINStatusFlags::TxChecksumEnhanced)
|
||||
.def_readwrite("TxCommander", &LINStatusFlags::TxCommander)
|
||||
.def_readwrite("TxResponder", &LINStatusFlags::TxResponder)
|
||||
.def_readwrite("TxAborted", &LINStatusFlags::TxAborted)
|
||||
.def_readwrite("UpdateResponderOnce", &LINStatusFlags::UpdateResponderOnce)
|
||||
.def_readwrite("HasUpdatedResponderOnce", &LINStatusFlags::HasUpdatedResponderOnce)
|
||||
.def_readwrite("BusRecovered", &LINStatusFlags::BusRecovered)
|
||||
.def_readwrite("BreakOnly", &LINStatusFlags::BreakOnly);
|
||||
|
||||
pybind11::class_<LINMessage, std::shared_ptr<LINMessage>, Frame> linMessage(m, "LINMessage");
|
||||
|
||||
pybind11::enum_<LINMessage::Type>(linMessage, "Type")
|
||||
.value("NOT_SET", LINMessage::Type::NOT_SET)
|
||||
.value("LIN_COMMANDER_MSG", LINMessage::Type::LIN_COMMANDER_MSG)
|
||||
.value("LIN_HEADER_ONLY", LINMessage::Type::LIN_HEADER_ONLY)
|
||||
.value("LIN_BREAK_ONLY", LINMessage::Type::LIN_BREAK_ONLY)
|
||||
.value("LIN_SYNC_ONLY", LINMessage::Type::LIN_SYNC_ONLY)
|
||||
.value("LIN_UPDATE_RESPONDER", LINMessage::Type::LIN_UPDATE_RESPONDER)
|
||||
.value("LIN_ERROR", LINMessage::Type::LIN_ERROR);
|
||||
|
||||
linMessage
|
||||
.def(pybind11::init<>())
|
||||
.def(pybind11::init<uint8_t>())
|
||||
.def_static("calc_checksum", &LINMessage::calcChecksum)
|
||||
.def("calc_protected_id", &LINMessage::calcProtectedID)
|
||||
.def_readwrite("ID", &LINMessage::ID)
|
||||
.def_readwrite("protectedID", &LINMessage::protectedID)
|
||||
.def_readwrite("checksum", &LINMessage::checksum)
|
||||
.def_readwrite("linMsgType", &LINMessage::linMsgType)
|
||||
.def_readwrite("isEnhancedChecksum", &LINMessage::isEnhancedChecksum)
|
||||
.def_readwrite("errFlags", &LINMessage::errFlags)
|
||||
.def_readwrite("statusFlags", &LINMessage::statusFlags);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/macsecmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_macsecmessage(pybind11::module_ & m)
|
||||
{
|
||||
pybind11::enum_<MACsecPacketType>(m, "MACsecPacketType")
|
||||
.value("NoVLAN_OrMPLS", MACsecPacketType::NoVLANOrMPLS)
|
||||
.value("SingleVLAN", MACsecPacketType::SingleVLAN)
|
||||
.value("DualVLAN", MACsecPacketType::DualVLAN)
|
||||
.value("MPLS", MACsecPacketType::MPLS)
|
||||
.value("SingleVLAN_FollowByMPLS", MACsecPacketType::SingleVLANFollowedByMPLS)
|
||||
.value("DualVLAN_FollowByMPLS", MACsecPacketType::DualVLANFollowedByMPLS)
|
||||
.value("Unsupported", MACsecPacketType::Unsupported);
|
||||
|
||||
pybind11::enum_<MACsecValidateFrameType>(m, "MACsecValidateFrameType")
|
||||
.value("Disabled", MACsecValidateFrameType::Disabled)
|
||||
.value("Check", MACsecValidateFrameType::Check)
|
||||
.value("Strict", MACsecValidateFrameType::Strict)
|
||||
.value("NA", MACsecValidateFrameType::NA);
|
||||
|
||||
pybind11::enum_<MACsecSecTagIcvStripType>(m, "MACsecSecTagIcvStripType")
|
||||
.value("StripBoth", MACsecSecTagIcvStripType::StripBoth)
|
||||
.value("StripSecTagPreserveICV", MACsecSecTagIcvStripType::StripSecTagPreserveICV)
|
||||
.value("PreserveSecTagStripICV", MACsecSecTagIcvStripType::PreserveSecTagStripICV)
|
||||
.value("PreserveBoth", MACsecSecTagIcvStripType::PreserveBoth);
|
||||
|
||||
pybind11::enum_<MACsecCipherSuiteType>(m, "MACsecCipherSuiteType")
|
||||
.value("AES_128", MACsecCipherSuiteType::GcmAes128)
|
||||
.value("AES_256", MACsecCipherSuiteType::GcmAes256)
|
||||
.value("AES_128_XPN", MACsecCipherSuiteType::GcmAes128Xpn)
|
||||
.value("AES_256_XPN", MACsecCipherSuiteType::GcmAes256Xpn);
|
||||
|
||||
pybind11::class_<MACsecVLANTag, std::shared_ptr<MACsecVLANTag>>(m, "MACsecVLANTag")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("vid", &MACsecVLANTag::vid)
|
||||
.def_readwrite("pri_cfi", &MACsecVLANTag::priCfi);
|
||||
|
||||
pybind11::class_<MACsecMPLSOuter, std::shared_ptr<MACsecMPLSOuter>>(m, "MACsecMPLSOuter")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("mpls_label", &MACsecMPLSOuter::mplsLabel)
|
||||
.def_readwrite("exp", &MACsecMPLSOuter::exp);
|
||||
|
||||
pybind11::class_<MACsecRule, std::shared_ptr<MACsecRule>>(m, "MACsecRule")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecRule::index)
|
||||
.def_readwrite("keyMacDa", &MACsecRule::keyMacDa)
|
||||
.def_readwrite("maskMacDa", &MACsecRule::maskMacDa)
|
||||
.def_readwrite("keyMacSa", &MACsecRule::keyMacSa)
|
||||
.def_readwrite("maskMacSa", &MACsecRule::maskMacSa)
|
||||
.def_readwrite("keyEthertype", &MACsecRule::keyEthertype)
|
||||
.def_readwrite("maskEthertype", &MACsecRule::maskEthertype)
|
||||
.def_readwrite("keyVlanTagOuter1", &MACsecRule::keyVlanTagOuter1)
|
||||
.def_readwrite("keyMplsOuter1", &MACsecRule::keyMplsOuter1)
|
||||
.def_readwrite("maskVlanTagOuter1", &MACsecRule::maskVlanTagOuter1)
|
||||
.def_readwrite("maskMplsOuter1", &MACsecRule::maskMplsOuter1)
|
||||
.def_readwrite("keyVlanTagOuter2", &MACsecRule::keyVlanTagOuter2)
|
||||
.def_readwrite("keyMplsOuter2", &MACsecRule::keyMplsOuter2)
|
||||
.def_readwrite("maskVlanTagOuter2", &MACsecRule::maskVlanTagOuter2)
|
||||
.def_readwrite("maskMplsOuter2", &MACsecRule::maskMplsOuter2)
|
||||
.def_readwrite("keyBonusData", &MACsecRule::keyBonusData)
|
||||
.def_readwrite("maskBonusData", &MACsecRule::maskBonusData)
|
||||
.def_readwrite("keyTagMatchBitmap", &MACsecRule::keyTagMatchBitmap)
|
||||
.def_readwrite("maskTagMatchBitmap", &MACsecRule::maskTagMatchBitmap)
|
||||
.def_readwrite("keyPacketType", &MACsecRule::keyPacketType)
|
||||
.def_readwrite("maskPacketType", &MACsecRule::maskPacketType)
|
||||
.def_readwrite("keyInnerVlanType", &MACsecRule::keyInnerVlanType)
|
||||
.def_readwrite("maskInnerVlanType", &MACsecRule::maskInnerVlanType)
|
||||
.def_readwrite("keyOuterVlanType", &MACsecRule::keyOuterVlanType)
|
||||
.def_readwrite("maskOuterVlanType", &MACsecRule::maskOuterVlanType)
|
||||
.def_readwrite("keyNumTags", &MACsecRule::keyNumTags)
|
||||
.def_readwrite("maskNumTags", &MACsecRule::maskNumTags)
|
||||
.def_readwrite("keyExpress", &MACsecRule::keyExpress)
|
||||
.def_readwrite("maskExpress", &MACsecRule::maskExpress)
|
||||
.def_readwrite("isMpls", &MACsecRule::isMpls)
|
||||
.def_readwrite("enable", &MACsecRule::enable);
|
||||
|
||||
pybind11::class_<MACsecMap, std::shared_ptr<MACsecMap>>(m, "MACsecMap")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecMap::index)
|
||||
.def_readwrite("secTagSci", &MACsecMap::secTagSci)
|
||||
.def_readwrite("secYIndex", &MACsecMap::secYIndex)
|
||||
.def_readwrite("isControlPacket", &MACsecMap::isControlPacket)
|
||||
.def_readwrite("scIndex", &MACsecMap::scIndex)
|
||||
.def_readwrite("auxiliaryPlcy", &MACsecMap::auxiliaryPlcy)
|
||||
.def_readwrite("ruleId", &MACsecMap::ruleId)
|
||||
.def_readwrite("enable", &MACsecMap::enable);
|
||||
|
||||
pybind11::class_<MACsecSecY, std::shared_ptr<MACsecSecY>>(m, "MACsecSecY")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecSecY::index)
|
||||
.def_readwrite("controlledPortEnabled", &MACsecSecY::controlledPortEnabled)
|
||||
.def_readwrite("frameValidationType", &MACsecSecY::frameValidationType)
|
||||
.def_readwrite("secTagIcvStripType", &MACsecSecY::secTagIcvStripType)
|
||||
.def_readwrite("cipher", &MACsecSecY::cipher)
|
||||
.def_readwrite("confidentialOffset", &MACsecSecY::confidentialOffset)
|
||||
.def_readwrite("icvIncludesDaSa", &MACsecSecY::icvIncludesDaSa)
|
||||
.def_readwrite("replayProtect", &MACsecSecY::replayProtect)
|
||||
.def_readwrite("replayWindow", &MACsecSecY::replayWindow)
|
||||
.def_readwrite("protectFrames", &MACsecSecY::protectFrames)
|
||||
.def_readwrite("secTagOffset", &MACsecSecY::secTagOffset)
|
||||
.def_readwrite("secTagTci", &MACsecSecY::secTagTci)
|
||||
.def_readwrite("mtu", &MACsecSecY::mtu)
|
||||
.def_readwrite("enable", &MACsecSecY::enable);
|
||||
|
||||
pybind11::class_<MACsecSc, std::shared_ptr<MACsecSc>>(m, "MACsecSc")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecSc::index)
|
||||
.def_readwrite("secYIndex", &MACsecSc::secYIndex)
|
||||
.def_readwrite("sci", &MACsecSc::sci)
|
||||
.def_readwrite("saIndex0", &MACsecSc::saIndex0)
|
||||
.def_readwrite("saIndex1", &MACsecSc::saIndex1)
|
||||
.def_readwrite("saIndex0InUse", &MACsecSc::saIndex0InUse)
|
||||
.def_readwrite("saIndex1InUse", &MACsecSc::saIndex1InUse)
|
||||
.def_readwrite("enableAutoRekey", &MACsecSc::enableAutoRekey)
|
||||
.def_readwrite("isActiveSa1", &MACsecSc::isActiveSa1)
|
||||
.def_readwrite("enable", &MACsecSc::enable);
|
||||
|
||||
pybind11::class_<MACsecSa, std::shared_ptr<MACsecSa>>(m, "MACsecSa")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecSa::index)
|
||||
.def_readwrite("sak", &MACsecSa::sak)
|
||||
.def_readwrite("hashKey", &MACsecSa::hashKey)
|
||||
.def_readwrite("salt", &MACsecSa::salt)
|
||||
.def_readwrite("ssci", &MACsecSa::ssci)
|
||||
.def_readwrite("an", &MACsecSa::an)
|
||||
.def_readwrite("nextPn", &MACsecSa::nextPn)
|
||||
.def_readwrite("enable", &MACsecSa::enable);
|
||||
|
||||
pybind11::class_<MACSecFlags, std::shared_ptr<MACSecFlags>>(m, "MACSecFlags")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("en", &MACSecFlags::en);
|
||||
|
||||
pybind11::class_<MACsecConfig, std::shared_ptr<MACsecConfig>>(m, "MACsecConfig")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("flags", &MACsecConfig::flags)
|
||||
.def_readwrite("rule", &MACsecConfig::rule)
|
||||
.def_readwrite("map", &MACsecConfig::map)
|
||||
.def_readwrite("secy", &MACsecConfig::secy)
|
||||
.def_readwrite("sc", &MACsecConfig::sc)
|
||||
.def_readwrite("sa", &MACsecConfig::sa);
|
||||
|
||||
pybind11::class_<MACSecGlobalFlags, std::shared_ptr<MACSecGlobalFlags>>(m, "MACSecGlobalFlags")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("en", &MACSecGlobalFlags::en)
|
||||
.def_readwrite("nvm", &MACSecGlobalFlags::nvm);
|
||||
|
||||
pybind11::class_<MACsecMessage, std::shared_ptr<MACsecMessage>>(m, "MACsecMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("flags", &MACsecMessage::flags)
|
||||
.def_readwrite("rx", &MACsecMessage::rx)
|
||||
.def_readwrite("tx", &MACsecMessage::tx);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/mdiomessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_mdiomessage(pybind11::module_& m) {
|
||||
pybind11::class_<MDIOMessage, std::shared_ptr<MDIOMessage>, Frame> mdioMessage(m, "MDIOMessage");
|
||||
pybind11::enum_<MDIOMessage::Clause>(mdioMessage, "Clause")
|
||||
.value("Clause45", MDIOMessage::Clause::Clause45)
|
||||
.value("Clause22", MDIOMessage::Clause::Clause22);
|
||||
pybind11::enum_<MDIOMessage::Direction>(mdioMessage, "Direction")
|
||||
.value("Write", MDIOMessage::Direction::Write)
|
||||
.value("Read", MDIOMessage::Direction::Read);
|
||||
mdioMessage
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("isTXMsg", &MDIOMessage::isTXMsg)
|
||||
.def_readwrite("txTimeout", &MDIOMessage::txTimeout)
|
||||
.def_readwrite("txAborted", &MDIOMessage::txAborted)
|
||||
.def_readwrite("txInvalidBus", &MDIOMessage::txInvalidBus)
|
||||
.def_readwrite("txInvalidPhyAddr", &MDIOMessage::txInvalidPhyAddr)
|
||||
.def_readwrite("txInvalidRegAddr", &MDIOMessage::txInvalidRegAddr)
|
||||
.def_readwrite("txInvalidClause", &MDIOMessage::txInvalidClause)
|
||||
.def_readwrite("txInvalidOpcode", &MDIOMessage::txInvalidOpcode)
|
||||
.def_readwrite("phyAddress", &MDIOMessage::phyAddress)
|
||||
.def_readwrite("devAddress", &MDIOMessage::devAddress)
|
||||
.def_readwrite("regAddress", &MDIOMessage::regAddress)
|
||||
.def_readwrite("direction", &MDIOMessage::direction)
|
||||
.def_readwrite("clause", &MDIOMessage::clause);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_message(pybind11::module_& m) {
|
||||
pybind11::class_<Message, std::shared_ptr<Message>> message(m, "Message");
|
||||
pybind11::enum_<Message::Type>(message, "Type")
|
||||
.value("Frame", Message::Type::Frame)
|
||||
.value("CANErrorCount", Message::Type::CANErrorCount)
|
||||
.value("CANError", Message::Type::CANError)
|
||||
.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)
|
||||
.value("GPTPStatus", Message::Type::GPTPStatus)
|
||||
.value("EthernetStatus", Message::Type::EthernetStatus);
|
||||
|
||||
message.def(pybind11::init<Message::Type>());
|
||||
message.def_readonly("type", &Message::type);
|
||||
message.def_readwrite("timestamp", &Message::timestamp);
|
||||
|
||||
pybind11::class_<RawMessage, std::shared_ptr<RawMessage>, Message>(m, "RawMessage")
|
||||
.def_readwrite("network", &RawMessage::network)
|
||||
.def_readwrite("data", &RawMessage::data);
|
||||
|
||||
pybind11::class_<Frame, std::shared_ptr<Frame>, RawMessage>(m, "Frame")
|
||||
.def_readwrite("description", &Frame::description)
|
||||
.def_readwrite("transmitted", &Frame::transmitted)
|
||||
.def_readwrite("error", &Frame::error);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_scriptstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<ScriptStatusMessage, std::shared_ptr<ScriptStatusMessage>, Message>(m, "ScriptStatusMessage")
|
||||
.def_readonly("isEncrypted", &ScriptStatusMessage::isEncrypted)
|
||||
.def_readonly("isCoreminiRunning", &ScriptStatusMessage::isCoreminiRunning)
|
||||
.def_readonly("sectorOverflows", &ScriptStatusMessage::sectorOverflows)
|
||||
.def_readonly("numRemainingSectorBuffers", &ScriptStatusMessage::numRemainingSectorBuffers)
|
||||
.def_readonly("lastSector", &ScriptStatusMessage::lastSector)
|
||||
.def_readonly("readBinSize", &ScriptStatusMessage::readBinSize)
|
||||
.def_readonly("minSector", &ScriptStatusMessage::minSector)
|
||||
.def_readonly("maxSector", &ScriptStatusMessage::maxSector)
|
||||
.def_readonly("currentSector", &ScriptStatusMessage::currentSector)
|
||||
.def_readonly("coreminiCreateTime", &ScriptStatusMessage::coreminiCreateTime)
|
||||
.def_readonly("fileChecksum", &ScriptStatusMessage::fileChecksum)
|
||||
.def_readonly("coreminiVersion", &ScriptStatusMessage::coreminiVersion)
|
||||
.def_readonly("coreminiHeaderSize", &ScriptStatusMessage::coreminiHeaderSize)
|
||||
.def_readonly("diagnosticErrorCode", &ScriptStatusMessage::diagnosticErrorCode)
|
||||
.def_readonly("diagnosticErrorCodeCount", &ScriptStatusMessage::diagnosticErrorCodeCount)
|
||||
.def_readonly("maxCoreminiSizeKB", &ScriptStatusMessage::maxCoreminiSizeKB);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_tc10statusmessage(pybind11::module_& m) {
|
||||
pybind11::enum_<TC10WakeStatus>(m, "TC10WakeStatus")
|
||||
.value("NoWakeReceived", TC10WakeStatus::NoWakeReceived)
|
||||
.value("WakeReceived", TC10WakeStatus::WakeReceived);
|
||||
|
||||
pybind11::enum_<TC10SleepStatus>(m, "TC10SleepStatus")
|
||||
.value("NoSleepReceived", TC10SleepStatus::NoSleepReceived)
|
||||
.value("SleepReceived", TC10SleepStatus::SleepReceived)
|
||||
.value("SleepFailed", TC10SleepStatus::SleepFailed)
|
||||
.value("SleepAborted", TC10SleepStatus::SleepAborted);
|
||||
|
||||
pybind11::class_<TC10StatusMessage, std::shared_ptr<TC10StatusMessage>, Message>(m, "TC10StatusMessage")
|
||||
.def_readonly("wakeStatus", &TC10StatusMessage::wakeStatus)
|
||||
.def_readonly("sleepStatus", &TC10StatusMessage::sleepStatus);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,197 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/network.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_network(pybind11::module_& m) {
|
||||
pybind11::class_<Network> network(m, "Network");
|
||||
|
||||
pybind11::enum_<Network::NetID>(network, "NetID")
|
||||
.value("Device", Network::NetID::Device)
|
||||
.value("DWCAN_01", Network::NetID::DWCAN_01)
|
||||
.value("DWCAN_08", Network::NetID::DWCAN_08)
|
||||
.value("SWCAN_01", Network::NetID::SWCAN_01)
|
||||
.value("LSFTCAN_01", Network::NetID::LSFTCAN_01)
|
||||
.value("FordSCP", Network::NetID::FordSCP)
|
||||
.value("J1708", Network::NetID::J1708)
|
||||
.value("Aux", Network::NetID::Aux)
|
||||
.value("J1850VPW", Network::NetID::J1850VPW)
|
||||
.value("ISO9141_01", Network::NetID::ISO9141_01)
|
||||
.value("DiskData", Network::NetID::DiskData)
|
||||
.value("Main51", Network::NetID::Main51)
|
||||
.value("RED", Network::NetID::RED)
|
||||
.value("SCI", Network::NetID::SCI)
|
||||
.value("ISO9141_02", Network::NetID::ISO9141_02)
|
||||
.value("ISO14230", Network::NetID::ISO14230)
|
||||
.value("LIN_01", Network::NetID::LIN_01)
|
||||
.value("AE_01", Network::NetID::AE_01)
|
||||
.value("AE_02", Network::NetID::AE_02)
|
||||
.value("AE_03", Network::NetID::AE_03)
|
||||
.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_03", Network::NetID::ISO9141_03)
|
||||
.value("DWCAN_02", Network::NetID::DWCAN_02)
|
||||
.value("DWCAN_03", Network::NetID::DWCAN_03)
|
||||
.value("AE_04", Network::NetID::AE_04)
|
||||
.value("AE_05", Network::NetID::AE_05)
|
||||
.value("ISO9141_04", Network::NetID::ISO9141_04)
|
||||
.value("LIN_02", Network::NetID::LIN_02)
|
||||
.value("LIN_03", Network::NetID::LIN_03)
|
||||
.value("LIN_04", Network::NetID::LIN_04)
|
||||
.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("DWCAN_04", Network::NetID::DWCAN_04)
|
||||
.value("DWCAN_05", Network::NetID::DWCAN_05)
|
||||
.value("RS232", Network::NetID::RS232)
|
||||
.value("UART_01", Network::NetID::UART_01)
|
||||
.value("UART_02", Network::NetID::UART_02)
|
||||
.value("UART_03", Network::NetID::UART_03)
|
||||
.value("UART_04", Network::NetID::UART_04)
|
||||
.value("SWCAN_02", Network::NetID::SWCAN_02)
|
||||
.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("SPI_01", Network::NetID::SPI_01)
|
||||
.value("AE_06", Network::NetID::AE_06)
|
||||
.value("Red_VBat", Network::NetID::Red_VBat)
|
||||
.value("AE_07", Network::NetID::AE_07)
|
||||
.value("AE_08", Network::NetID::AE_08)
|
||||
.value("AE_09", Network::NetID::AE_09)
|
||||
.value("AE_10", Network::NetID::AE_10)
|
||||
.value("AE_11", Network::NetID::AE_11)
|
||||
.value("FLEXRAY_01A", Network::NetID::FLEXRAY_01A)
|
||||
.value("FLEXRAY_01B", Network::NetID::FLEXRAY_01B)
|
||||
.value("FLEXRAY_02A", Network::NetID::FLEXRAY_02A)
|
||||
.value("FLEXRAY_02B", Network::NetID::FLEXRAY_02B)
|
||||
.value("LIN_05", Network::NetID::LIN_05)
|
||||
.value("FLEXRAY_01", Network::NetID::FLEXRAY_01)
|
||||
.value("FLEXRAY_02", Network::NetID::FLEXRAY_02)
|
||||
.value("AE_12", Network::NetID::AE_12)
|
||||
.value("I2C_01", Network::NetID::I2C_01)
|
||||
.value("MOST_25", Network::NetID::MOST_25)
|
||||
.value("MOST_50", Network::NetID::MOST_50)
|
||||
.value("MOST_150", Network::NetID::MOST_150)
|
||||
.value("ETHERNET_01", Network::NetID::ETHERNET_01)
|
||||
.value("GMFSA", Network::NetID::GMFSA)
|
||||
.value("TCP", Network::NetID::TCP)
|
||||
.value("DWCAN_06", Network::NetID::DWCAN_06)
|
||||
.value("DWCAN_07", Network::NetID::DWCAN_07)
|
||||
.value("LIN_06", Network::NetID::LIN_06)
|
||||
.value("LSFTCAN_02", Network::NetID::LSFTCAN_02)
|
||||
.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("I2C_02", Network::NetID::I2C_02)
|
||||
.value("I2C_03", Network::NetID::I2C_03)
|
||||
.value("I2C_04", Network::NetID::I2C_04)
|
||||
.value("ETHERNET_02", Network::NetID::ETHERNET_02)
|
||||
.value("A2B_01", Network::NetID::A2B_01)
|
||||
.value("A2B_02", Network::NetID::A2B_02)
|
||||
.value("ETHERNET_03", Network::NetID::ETHERNET_03)
|
||||
.value("WBMS_01", Network::NetID::WBMS_01)
|
||||
.value("DWCAN_09", Network::NetID::DWCAN_09)
|
||||
.value("DWCAN_10", Network::NetID::DWCAN_10)
|
||||
.value("DWCAN_11", Network::NetID::DWCAN_11)
|
||||
.value("DWCAN_12", Network::NetID::DWCAN_12)
|
||||
.value("DWCAN_13", Network::NetID::DWCAN_13)
|
||||
.value("DWCAN_14", Network::NetID::DWCAN_14)
|
||||
.value("DWCAN_15", Network::NetID::DWCAN_15)
|
||||
.value("DWCAN_16", Network::NetID::DWCAN_16)
|
||||
.value("LIN_07", Network::NetID::LIN_07)
|
||||
.value("LIN_08", Network::NetID::LIN_08)
|
||||
.value("SPI_02", Network::NetID::SPI_02)
|
||||
.value("MDIO_01", Network::NetID::MDIO_01)
|
||||
.value("MDIO_02", Network::NetID::MDIO_02)
|
||||
.value("MDIO_03", Network::NetID::MDIO_03)
|
||||
.value("MDIO_04", Network::NetID::MDIO_04)
|
||||
.value("MDIO_05", Network::NetID::MDIO_05)
|
||||
.value("MDIO_06", Network::NetID::MDIO_06)
|
||||
.value("MDIO_07", Network::NetID::MDIO_07)
|
||||
.value("MDIO_08", Network::NetID::MDIO_08)
|
||||
.value("AE_13", Network::NetID::AE_13)
|
||||
.value("AE_14", Network::NetID::AE_14)
|
||||
.value("AE_15", Network::NetID::AE_15)
|
||||
.value("AE_16", Network::NetID::AE_16)
|
||||
.value("SPI_03", Network::NetID::SPI_03)
|
||||
.value("SPI_04", Network::NetID::SPI_04)
|
||||
.value("SPI_05", Network::NetID::SPI_05)
|
||||
.value("SPI_06", Network::NetID::SPI_06)
|
||||
.value("SPI_07", Network::NetID::SPI_07)
|
||||
.value("SPI_08", Network::NetID::SPI_08)
|
||||
.value("LIN_09", Network::NetID::LIN_09)
|
||||
.value("LIN_10", Network::NetID::LIN_10)
|
||||
.value("LIN_11", Network::NetID::LIN_11)
|
||||
.value("LIN_12", Network::NetID::LIN_12)
|
||||
.value("LIN_13", Network::NetID::LIN_13)
|
||||
.value("LIN_14", Network::NetID::LIN_14)
|
||||
.value("LIN_15", Network::NetID::LIN_15)
|
||||
.value("LIN_16", Network::NetID::LIN_16)
|
||||
.value("Any", Network::NetID::Any)
|
||||
.value("Invalid", Network::NetID::Invalid);
|
||||
|
||||
pybind11::enum_<Network::Type>(network, "Type")
|
||||
.value("Invalid", Network::Type::Invalid)
|
||||
.value("Internal", Network::Type::Internal)
|
||||
.value("CAN", Network::Type::CAN)
|
||||
.value("LIN", Network::Type::LIN)
|
||||
.value("FlexRay", Network::Type::FlexRay)
|
||||
.value("MOST", Network::Type::MOST)
|
||||
.value("Ethernet", Network::Type::Ethernet)
|
||||
.value("LSFTCAN", Network::Type::LSFTCAN)
|
||||
.value("SWCAN", Network::Type::SWCAN)
|
||||
.value("ISO9141", Network::Type::ISO9141)
|
||||
.value("I2C_01", Network::Type::I2C)
|
||||
.value("A2B", Network::Type::A2B)
|
||||
.value("SPI", Network::Type::SPI)
|
||||
.value("MDIO", Network::Type::MDIO)
|
||||
.value("Any", Network::Type::Any)
|
||||
.value("Other", Network::Type::Other);
|
||||
|
||||
network
|
||||
.def(pybind11::init<Network::NetID>())
|
||||
.def("__repr__", [](Network& self) { return Network::GetNetIDString(self.getNetID()); })
|
||||
.def_static("get_net_id_string", &Network::GetNetIDString, pybind11::arg("netid"), pybind11::arg("expand") = true)
|
||||
.def("get_net_id", &Network::getNetID)
|
||||
.def("get_type", &Network::getType);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/chrono.h>
|
||||
|
||||
#include "icsneo/device/device.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_device(pybind11::module_& m) {
|
||||
pybind11::class_<Device, std::shared_ptr<Device>>(m, "Device")
|
||||
.def("__repr__", &Device::describe)
|
||||
.def("add_message_callback", &Device::addMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("clear_script", &Device::clearScript, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("close", &Device::close, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("describe", &Device::describe)
|
||||
.def("disable_message_polling", &Device::disableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("enable_message_polling", &Device::enableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_current_message_count", &Device::getCurrentMessageCount)
|
||||
.def("get_digital_io", &Device::getDigitalIO, pybind11::arg("type"), pybind11::arg("number"), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_gptp_status", &Device::getGPTPStatus, pybind11::arg("timeout") = std::chrono::milliseconds(100), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_polling_message_limit", &Device::getPollingMessageLimit)
|
||||
.def("get_product_name", &Device::getProductName)
|
||||
.def("get_rtc", &Device::getRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_script_status", &Device::getScriptStatus, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_serial_number", &Device::getSerialNumber)
|
||||
.def("get_serial", &Device::getSerial)
|
||||
.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_tc10_status", &Device::getTC10Status, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_type", &Device::getType)
|
||||
.def("go_offline", &Device::goOffline, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("go_online", &Device::goOnline, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("is_message_polling_enabled", &Device::isMessagePollingEnabled)
|
||||
.def("is_online_supported", &Device::isOnlineSupported)
|
||||
.def("is_online", &Device::isOnline)
|
||||
.def("is_open", &Device::isOpen)
|
||||
.def("open", [](Device& device) { return device.open(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("prepare_script_load", &Device::prepareScriptLoad, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("remove_message_callback", &Device::removeMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("request_tc10_sleep", &Device::requestTC10Sleep, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("request_tc10_wake", &Device::requestTC10Wake, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_digital_io", pybind11::overload_cast<IO, size_t, bool>(&Device::setDigitalIO), pybind11::arg("type"), pybind11::arg("number"), pybind11::arg("value"), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_polling_message_limit", &Device::setPollingMessageLimit)
|
||||
.def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("start_script", &Device::startScript, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("stop_script", &Device::stopScript, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("supports_tc10", &Device::supportsTC10)
|
||||
.def("transmit", pybind11::overload_cast<std::shared_ptr<Frame>>(&Device::transmit), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("upload_coremini", [](Device& device, std::string& path, Disk::MemoryType memType) { std::ifstream ifs(path, std::ios::binary); return device.uploadCoremini(ifs, memType); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("write_macsec_config", &Device::writeMACsecConfig, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def_readonly("settings", &Device::settings);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/device/devicetype.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_devicetype(pybind11::module_& m) {
|
||||
pybind11::class_<DeviceType> deviceType(m, "DeviceType");
|
||||
pybind11::enum_<DeviceType::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("RADEpsilonXL", DeviceType::Enum::RADEpsilonXL)
|
||||
.value("RADGalaxy2", DeviceType::Enum::RADGalaxy2)
|
||||
.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::Enum>());
|
||||
deviceType.def("get_device_type", &DeviceType::getDeviceType);
|
||||
deviceType.def("get_generic_product_name", &DeviceType::getGenericProductName);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl_bind.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/chrono.h>
|
||||
|
||||
#include "icsneo/device/idevicesettings.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct DeviceSettingsNamespace {
|
||||
using EthLinkMode = AELinkMode;
|
||||
using LinkSpeed = EthLinkSpeed;
|
||||
};
|
||||
|
||||
void init_idevicesettings(pybind11::module_& m) {
|
||||
pybind11::class_<DeviceSettingsNamespace> settings(m, "Settings");
|
||||
|
||||
pybind11::enum_<DeviceSettingsNamespace::EthLinkMode>(settings, "EthernetLinkMode")
|
||||
.value("Auto", DeviceSettingsNamespace::EthLinkMode::AE_LINK_AUTO)
|
||||
.value("Slave", DeviceSettingsNamespace::EthLinkMode::AE_LINK_SLAVE)
|
||||
.value("Master", DeviceSettingsNamespace::EthLinkMode::AE_LINK_MASTER);
|
||||
|
||||
pybind11::enum_<DeviceSettingsNamespace::LinkSpeed>(settings, "EthernetLinkSpeed")
|
||||
.value("Speed10M", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_10)
|
||||
.value("Speed100M", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_100)
|
||||
.value("Speed1G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_1000)
|
||||
.value("Speed2_5G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_2500)
|
||||
.value("Speed5G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_5000)
|
||||
.value("Speed10G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_10000);
|
||||
|
||||
pybind11::class_<IDeviceSettings, std::shared_ptr<IDeviceSettings>>(m, "IDeviceSettings")
|
||||
.def("apply", &IDeviceSettings::apply, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("apply_defaults", &IDeviceSettings::applyDefaults, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_phy_enable", &IDeviceSettings::getPhyEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_phy_mode", &IDeviceSettings::getPhyMode, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_phy_speed", &IDeviceSettings::getPhySpeed, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_phy_enable", &IDeviceSettings::setPhyEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_phy_mode", &IDeviceSettings::setPhyMode, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_phy_speed", &IDeviceSettings::setPhySpeed, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("refresh", &IDeviceSettings::refresh, pybind11::arg("ignoreChecksum") = 0, pybind11::call_guard<pybind11::gil_scoped_release>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/disk/diskdriver.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
// binding namespace workaround to avoid submodules
|
||||
struct DiskNamespace {
|
||||
using Access = icsneo::Disk::Access;
|
||||
using MemoryType = icsneo::Disk::MemoryType;
|
||||
};
|
||||
|
||||
void init_diskdriver(pybind11::module_& m) {
|
||||
pybind11::class_<DiskNamespace> disk(m, "Disk");
|
||||
pybind11::enum_<Disk::Access>(disk, "Access")
|
||||
.value("None", Disk::Access::None)
|
||||
.value("EntireCard", Disk::Access::EntireCard)
|
||||
.value("VSA", Disk::Access::VSA);
|
||||
pybind11::enum_<Disk::MemoryType>(disk, "MemoryType")
|
||||
.value("Flash", Disk::MemoryType::Flash)
|
||||
.value("SD", Disk::MemoryType::SD);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,69 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#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_io(pybind11::module_&);
|
||||
void init_devicetype(pybind11::module_&);
|
||||
void init_message(pybind11::module_&);
|
||||
void init_canmessage(pybind11::module_&);
|
||||
void init_canerrormessage(pybind11::module_&);
|
||||
void init_ethernetmessage(pybind11::module_&);
|
||||
void init_linmessage(pybind11::module_&);
|
||||
void init_tc10statusmessage(pybind11::module_&);
|
||||
void init_gptpstatusmessage(pybind11::module_&);
|
||||
void init_mdiomessage(pybind11::module_&);
|
||||
void init_ethernetstatusmessage(pybind11::module_&);
|
||||
void init_macsecmessage(pybind11::module_&);
|
||||
void init_scriptstatusmessage(pybind11::module_&);
|
||||
void init_diskdriver(pybind11::module_&);
|
||||
void init_device(pybind11::module_&);
|
||||
void init_messagefilter(pybind11::module_&);
|
||||
void init_messagecallback(pybind11::module_&);
|
||||
void init_version(pybind11::module_&);
|
||||
void init_flexraymessage(pybind11::module_& m);
|
||||
void init_idevicesettings(pybind11::module_&);
|
||||
|
||||
PYBIND11_MODULE(icsneopy, m) {
|
||||
pybind11::options options;
|
||||
options.disable_enum_members_docstring();
|
||||
m.doc() = "libicsneo Python module";
|
||||
|
||||
init_event(m);
|
||||
init_eventcallback(m);
|
||||
init_eventmanager(m);
|
||||
init_version(m);
|
||||
init_devicetype(m);
|
||||
init_network(m);
|
||||
init_io(m);
|
||||
init_message(m);
|
||||
init_canmessage(m);
|
||||
init_canerrormessage(m);
|
||||
init_ethernetmessage(m);
|
||||
init_linmessage(m);
|
||||
init_tc10statusmessage(m);
|
||||
init_gptpstatusmessage(m);
|
||||
init_mdiomessage(m);
|
||||
init_ethernetstatusmessage(m);
|
||||
init_macsecmessage(m);
|
||||
init_scriptstatusmessage(m);
|
||||
init_messagefilter(m);
|
||||
init_messagecallback(m);
|
||||
init_diskdriver(m);
|
||||
init_device(m);
|
||||
init_flexraymessage(m);
|
||||
init_idevicesettings(m);
|
||||
|
||||
m.def("find_all_devices", &FindAllDevices);
|
||||
m.def("get_supported_devices", &GetSupportedDevices);
|
||||
m.def("get_last_error", &GetLastError);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/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
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
#!/bin/sh
|
||||
export CFLAGS="-Wall -Werror"
|
||||
export CXXFLAGS="-Wall -Werror"
|
||||
|
||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_EXAMPLES=ON \
|
||||
-DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_ENABLE_TCP=OFF || exit 1
|
||||
-DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_BUILD_SYSTEM_TESTS=ON -DLIBICSNEO_ENABLE_TCP=OFF || exit 1
|
||||
|
||||
cmake --build build || exit 1
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/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
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
@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
|
||||
@@ -4,9 +4,9 @@ mkdir build
|
||||
|
||||
REM build
|
||||
cd build
|
||||
set CFLAGS=/WX /W4 /wd4127
|
||||
set CXXFLAGS=/WX /W4 /wd4127
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_ENABLE_TCP=ON ..
|
||||
set CFLAGS=/WX
|
||||
set CXXFLAGS=/WX
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_BUILD_SYSTEM_TESTS=ON -DLIBICSNEO_ENABLE_TCP=ON ..
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
cmake --build .
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
call "%VCVARS32_2022%"
|
||||
call "%VCVARS32%"
|
||||
call "ci\build-windows.bat"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
call "%VCVARS64_2022%"
|
||||
call "%VCVARS64%"
|
||||
call "ci\build-windows.bat"
|
||||
|
||||
@@ -37,28 +37,29 @@ bool Communication::open() {
|
||||
}
|
||||
|
||||
void Communication::spawnThreads() {
|
||||
closing = false;
|
||||
readTaskThread = std::thread(&Communication::readTask, this);
|
||||
}
|
||||
|
||||
void Communication::joinThreads() {
|
||||
closing = true;
|
||||
|
||||
if(pauseReadTask) {
|
||||
resumeReads();
|
||||
}
|
||||
|
||||
closing = true;
|
||||
if(readTaskThread.joinable())
|
||||
readTaskThread.join();
|
||||
closing = false;
|
||||
}
|
||||
|
||||
bool Communication::close() {
|
||||
joinThreads();
|
||||
|
||||
if(!isOpen() && !isDisconnected()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
joinThreads();
|
||||
|
||||
return driver->close();
|
||||
}
|
||||
|
||||
@@ -275,7 +276,7 @@ void Communication::readTask() {
|
||||
std::unique_lock<std::mutex> lk(pauseReadTaskMutex);
|
||||
pauseReadTaskCv.wait(lk, [this]() { return !pauseReadTask; });
|
||||
}
|
||||
if(driver->waitForRx(readTaskWakeLimit, readTaskWakeTimeout)) {
|
||||
if(driver->readAvailable()) {
|
||||
if(pauseReadTask) {
|
||||
/**
|
||||
* Reads could have paused while the driver was not available
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* crc32.c
|
||||
*
|
||||
* Created on: Jun 22, 2020
|
||||
* Author: BJones
|
||||
*/
|
||||
#include "icsneo/communication/crc32.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static const unsigned long crc32_table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
|
||||
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
|
||||
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F,
|
||||
0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180,
|
||||
0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
|
||||
0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2,
|
||||
0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
|
||||
0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC,
|
||||
0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525,
|
||||
0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E,
|
||||
0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
|
||||
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
|
||||
0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
||||
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9,
|
||||
0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226,
|
||||
0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
|
||||
0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354,
|
||||
0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
|
||||
0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E,
|
||||
0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
|
||||
|
||||
uint32_t crc32(uint32_t crc, const unsigned char* buf, uint32_t len)
|
||||
{
|
||||
unsigned char octet;
|
||||
const unsigned char* p = buf;
|
||||
|
||||
crc = ~crc;
|
||||
while (len--)
|
||||
{
|
||||
octet = *p++; /* Cast to unsigned octet. */
|
||||
crc = (crc >> 8) ^ crc32_table[(crc & 0xff) ^ octet];
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
static unsigned char rev_crc32_table[256];
|
||||
|
||||
static void revgen(void)
|
||||
{
|
||||
size_t k;
|
||||
|
||||
for (k = 0; k < 256; k++)
|
||||
rev_crc32_table[crc32_table[k] >> 24] = (uint8_t)k;
|
||||
}
|
||||
|
||||
uint32_t revcrc32(uint32_t crc, const unsigned char* buf, uint32_t len)
|
||||
{
|
||||
unsigned char k;
|
||||
revgen();
|
||||
crc = ~crc;
|
||||
while (len--)
|
||||
{
|
||||
k = rev_crc32_table[crc >> 24];
|
||||
crc = ((crc ^ crc32_table[k]) << 8) | (k ^ buf[len]);
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
+18
-66
@@ -3,9 +3,8 @@
|
||||
#include "icsneo/communication/message/serialnumbermessage.h"
|
||||
#include "icsneo/communication/message/resetstatusmessage.h"
|
||||
#include "icsneo/communication/message/readsettingsmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
||||
#include "icsneo/communication/message/flashmemorymessage.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
#include "icsneo/communication/message/wiviresponsemessage.h"
|
||||
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||
@@ -16,13 +15,9 @@
|
||||
#include "icsneo/communication/message/mdiomessage.h"
|
||||
#include "icsneo/communication/message/extendeddatamessage.h"
|
||||
#include "icsneo/communication/message/livedatamessage.h"
|
||||
#include "icsneo/communication/message/logdatamessage.h"
|
||||
#include "icsneo/communication/message/diskdatamessage.h"
|
||||
#include "icsneo/communication/message/hardwareinfo.h"
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
#include "icsneo/communication/message/gptpstatusmessage.h"
|
||||
#include "icsneo/communication/message/apperrormessage.h"
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
@@ -96,7 +91,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
break;
|
||||
}
|
||||
case Message::Type::CANErrorCount: {
|
||||
CANErrorMessage& can = *static_cast<CANErrorMessage*>(result.get());
|
||||
CANErrorCountMessage& can = *static_cast<CANErrorCountMessage*>(result.get());
|
||||
can.network = packet->network;
|
||||
break;
|
||||
}
|
||||
@@ -181,7 +176,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
|
||||
LINMessage& msg = *static_cast<LINMessage*>(result.get());
|
||||
msg.network = packet->network;
|
||||
msg.timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case Network::Type::MDIO: {
|
||||
@@ -240,26 +234,21 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto can = std::dynamic_pointer_cast<CANMessage>(HardwareCANPacket::DecodeToMessage(packet->data));
|
||||
if(!can) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(can->arbid == 0x162) {
|
||||
result = EthernetStatusMessage::DecodeToMessage(can->data);
|
||||
|
||||
result = HardwareCANPacket::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// TODO: move more handleNeoVIMessage handling here, the Decoder layer will parse the message and the Device layer can cache the values
|
||||
can->network = packet->network;
|
||||
result = can;
|
||||
return false; // A nullptr was returned, the packet was malformed
|
||||
}
|
||||
|
||||
result->timestamp *= timestampResolution;
|
||||
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
||||
// The resolution depends on the device
|
||||
auto* raw = dynamic_cast<RawMessage*>(result.get());
|
||||
if(raw == nullptr) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was malformed
|
||||
}
|
||||
raw->timestamp *= timestampResolution;
|
||||
raw->network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::DeviceStatus: {
|
||||
@@ -267,18 +256,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
result = std::make_shared<RawMessage>(packet->network, packet->data);
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::RED_INT_MEMORYREAD: {
|
||||
if(packet->data.size() != 512 + sizeof(uint16_t)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // Should get enough data for a start address and sector
|
||||
}
|
||||
|
||||
const auto msg = std::make_shared<FlashMemoryMessage>();
|
||||
result = msg;
|
||||
msg->startAddress = *reinterpret_cast<uint16_t*>(packet->data.data());
|
||||
msg->data.insert(msg->data.end(), packet->data.begin() + 2, packet->data.end());
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::NeoMemorySDRead: {
|
||||
if(packet->data.size() != 512 + sizeof(uint32_t)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
@@ -293,11 +270,11 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
}
|
||||
case Network::NetID::ExtendedCommand: {
|
||||
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::ResponseHeader))
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::PackedGenericResponse))
|
||||
break; // Handle as a raw message, might not be a generic response
|
||||
|
||||
const auto& resp = *reinterpret_cast<ExtendedResponseMessage::ResponseHeader*>(packet->data.data());
|
||||
switch(resp.command) {
|
||||
const auto& resp = *reinterpret_cast<ExtendedResponseMessage::PackedGenericResponse*>(packet->data.data());
|
||||
switch(resp.header.command) {
|
||||
case ExtendedCommand::GetComponentVersions:
|
||||
result = ComponentVersionPacket::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
@@ -307,23 +284,15 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
case ExtendedCommand::GenericBinaryInfo:
|
||||
result = GenericBinaryStatusPacket::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::GenericReturn: {
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::PackedGenericResponse))
|
||||
break;
|
||||
const auto& packedResp = *reinterpret_cast<ExtendedResponseMessage::PackedGenericResponse*>(packet->data.data());
|
||||
result = std::make_shared<ExtendedResponseMessage>(packedResp.command, packedResp.returnCode);
|
||||
case ExtendedCommand::GenericReturn:
|
||||
result = std::make_shared<ExtendedResponseMessage>(resp.command, resp.returnCode);
|
||||
return true;
|
||||
}
|
||||
case ExtendedCommand::LiveData:
|
||||
result = HardwareLiveDataPacket::DecodeToMessage(packet->data, report);
|
||||
return true;
|
||||
case ExtendedCommand::GetTC10Status:
|
||||
result = TC10StatusMessage::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::GetGPTPStatus: {
|
||||
result = GPTPStatus::DecodeToMessage(packet->data, report);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// No defined handler, treat this as a RawMessage
|
||||
break;
|
||||
@@ -429,14 +398,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
packet->data.resize(length);
|
||||
return decode(result, packet);
|
||||
}
|
||||
case Network::NetID::RED_App_Error: {
|
||||
result = AppErrorMessage::DecodeToMessage(packet->data, report);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::ReadSettings: {
|
||||
auto msg = std::make_shared<ReadSettingsMessage>();
|
||||
msg->response = ReadSettingsMessage::Response(packet->data[0]);
|
||||
@@ -492,16 +453,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
result = std::make_shared<DiskDataMessage>(std::move(packet->data));
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::Data_To_Host: {
|
||||
result = LogDataMessage::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
+10
-12
@@ -11,19 +11,11 @@ using namespace icsneo;
|
||||
bool Driver::pushRx(const uint8_t* buf, size_t numReceived) {
|
||||
bool ret = readBuffer.write(buf, numReceived);
|
||||
|
||||
rxWaitCv.notify_all();
|
||||
|
||||
return ret;
|
||||
if(hasRxWaitRequest) {
|
||||
rxWaitRequestCv.notify_one();
|
||||
}
|
||||
|
||||
void Driver::clearBuffers()
|
||||
{
|
||||
WriteOperation flushop;
|
||||
|
||||
readBuffer.clear();
|
||||
rxWaitCv.notify_all();
|
||||
|
||||
while (writeQueue.try_dequeue(flushop)) {}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Driver::waitForRx(size_t limit, std::chrono::milliseconds timeout) {
|
||||
@@ -34,7 +26,13 @@ bool Driver::waitForRx(size_t limit, std::chrono::milliseconds timeout) {
|
||||
|
||||
bool Driver::waitForRx(std::function<bool()> predicate, std::chrono::milliseconds timeout) {
|
||||
std::unique_lock<std::mutex> lk(rxWaitMutex);
|
||||
return rxWaitCv.wait_for(lk, timeout, predicate);
|
||||
hasRxWaitRequest = true;
|
||||
|
||||
auto ret = rxWaitRequestCv.wait_for(lk, timeout, predicate);
|
||||
|
||||
hasRxWaitRequest = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Driver::readWait(std::vector<uint8_t>& bytes, std::chrono::milliseconds timeout, size_t limit) {
|
||||
|
||||
@@ -265,8 +265,6 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
case Command::GetMainVersion:
|
||||
case Command::GetSecondaryVersions:
|
||||
case Command::NeoReadMemory:
|
||||
case Command::ClearCoreMini:
|
||||
case Command::LoadCoreMini:
|
||||
// There is a firmware handling idiosyncrasy with these commands
|
||||
// They must be encoded in the short format
|
||||
m51msg->forceShortFormat = true;
|
||||
|
||||
@@ -18,59 +18,5 @@ double liveDataValueToDouble(const LiveDataValue& val) {
|
||||
return val.value * liveDataFixedPointToDouble;
|
||||
}
|
||||
|
||||
int liveDataDoubleToValue(LiveDataValue& value, const double& dFloat) {
|
||||
union {
|
||||
struct
|
||||
{
|
||||
uint32_t ValueFractionPart;
|
||||
int32_t ValueInt32;
|
||||
} parts;
|
||||
int64_t ValueLarge;
|
||||
} CminiFixedPt;
|
||||
constexpr double CM_FIXED_POINT_TO_DOUBLEVALUE = (1.0 / (double)(1ULL << 32)); // 2^-32
|
||||
constexpr double CM_DOUBLEVALUE_TO_FIXED_POINT = ((double)(1ULL << 32)); // 2^32
|
||||
// Use const for limits (C++98 compatible)
|
||||
const double INT32_MAX_DOUBLE =
|
||||
static_cast<double>(std::numeric_limits<int32_t>::max()) + (1.0 - std::numeric_limits<double>::epsilon());
|
||||
const double INT32_MIN_DOUBLE = static_cast<double>(std::numeric_limits<int32_t>::min());
|
||||
const double MIN_FIXED_POINT_DOUBLE = (double)(1ull * CM_FIXED_POINT_TO_DOUBLEVALUE);
|
||||
|
||||
// This needs to be assigned separately, otherwise, for dFloat >= 2^31,
|
||||
// long double dBigFloat = dFloat * CM_DOUBLEVALUE_TO_FIXED_POINT overflows
|
||||
// long long (value is >= 2^63) and so the assignment ValueLarge = dBigFloat is undefined
|
||||
|
||||
int32_t intPart; //creating temp variable due to static analysis warning about writing and reading to different union members
|
||||
if (dFloat < 0.0)
|
||||
intPart = (int32_t)floor(dFloat);
|
||||
else
|
||||
intPart = (int32_t)dFloat;
|
||||
|
||||
//using temp varialbes to avoid static analysis warning about read/write to different union members
|
||||
double frac = dFloat - (double)(intPart);
|
||||
uint32_t fracPart = (uint32_t)floor((frac * CM_DOUBLEVALUE_TO_FIXED_POINT) + 0.5);
|
||||
|
||||
//write temp vars back into the union
|
||||
CminiFixedPt.parts.ValueInt32 = intPart;
|
||||
CminiFixedPt.parts.ValueFractionPart = fracPart;
|
||||
value.value = CminiFixedPt.ValueLarge;
|
||||
|
||||
if (dFloat == (double)0.0)
|
||||
return 0;
|
||||
|
||||
//check if double can be stored as 32.32
|
||||
// 0x1 0000 0000 0000 0000 * CM_FIXED_POINT_TO_DOUBLEVALUE = 0x1 0000 0000
|
||||
if (dFloat > INT32_MAX_DOUBLE)
|
||||
return 1;
|
||||
if (dFloat < INT32_MIN_DOUBLE)
|
||||
return -1;
|
||||
|
||||
// Use absolute value for minimum fixed point check
|
||||
double absFloat = (dFloat < 0.0) ? -dFloat : dFloat;
|
||||
if (absFloat < MIN_FIXED_POINT_DOUBLE)
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace LiveDataUtil
|
||||
} // namespace icsneo
|
||||
@@ -1,148 +0,0 @@
|
||||
#include <icsneo/communication/message/apperrormessage.h>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
#pragma pack(push, 2)
|
||||
|
||||
typedef struct {
|
||||
uint16_t error_type;
|
||||
uint16_t network_id;
|
||||
uint32_t uiTimeStamp10uS;
|
||||
uint32_t uiTimeStamp10uSMSB;
|
||||
} AppErrorData;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
std::shared_ptr<Message> AppErrorMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) {
|
||||
const AppErrorData* data = reinterpret_cast<const AppErrorData*>(bytestream.data());
|
||||
if(!data) {
|
||||
report(APIEvent::Type::AppErrorParsingFailed, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
auto appErr = std::make_shared<AppErrorMessage>();
|
||||
appErr->errorType = data->error_type;
|
||||
appErr->errorNetID = static_cast<Network::NetID>(data->network_id);
|
||||
appErr->timestamp10us = data->uiTimeStamp10uS;
|
||||
appErr->timestamp10usMSB = data->uiTimeStamp10uSMSB;
|
||||
appErr->network = Network::NetID::RED_App_Error;
|
||||
return appErr;
|
||||
}
|
||||
|
||||
AppErrorType AppErrorMessage::getAppErrorType() {
|
||||
AppErrorType errType = static_cast<AppErrorType>(errorType);
|
||||
if(errType > AppErrorType::AppNoError) {
|
||||
return AppErrorType::AppNoError;
|
||||
}
|
||||
return errType;
|
||||
}
|
||||
|
||||
std::string AppErrorMessage::getAppErrorString() {
|
||||
auto netIDString = Network::GetNetIDString(errorNetID);
|
||||
AppErrorType errType = static_cast<AppErrorType>(errorType);
|
||||
switch (errType) {
|
||||
case AppErrorType::AppErrorRxMessagesFull:
|
||||
return std::string(netIDString) + ": RX message buffer full";
|
||||
case AppErrorType::AppErrorTxMessagesFull:
|
||||
return std::string(netIDString) + ": TX message buffer full";
|
||||
case AppErrorType::AppErrorTxReportMessagesFull:
|
||||
return std::string(netIDString) + ": TX report buffer full";
|
||||
case AppErrorType::AppErrorBadCommWithDspIC:
|
||||
return "Received bad packet from DSP IC";
|
||||
case AppErrorType::AppErrorDriverOverflow:
|
||||
return std::string(netIDString) + ": Driver overflow";
|
||||
case AppErrorType::AppErrorPCBuffOverflow:
|
||||
return "PC buffer overflow";
|
||||
case AppErrorType::AppErrorPCChksumError:
|
||||
return "PC checksum error";
|
||||
case AppErrorType::AppErrorPCMissedByte:
|
||||
return "PC missed byte";
|
||||
case AppErrorType::AppErrorPCOverrunError:
|
||||
return "PC overrun error";
|
||||
case AppErrorType::AppErrorSettingFailure:
|
||||
return std::string(netIDString) + ": Settings incorrectly set";
|
||||
case AppErrorType::AppErrorTooManySelectedNetworks:
|
||||
return "Too many selected networks";
|
||||
case AppErrorType::AppErrorNetworkNotEnabled:
|
||||
return std::string(netIDString) + ": Network not enabled";
|
||||
case AppErrorType::AppErrorRtcNotCorrect:
|
||||
return "RTC not correct";
|
||||
case AppErrorType::AppErrorLoadedDefaultSettings:
|
||||
return "Loaded default settings";
|
||||
case AppErrorType::AppErrorFeatureNotUnlocked:
|
||||
return "Feature not unlocked";
|
||||
case AppErrorType::AppErrorFeatureRtcCmdDropped:
|
||||
return "RTC command dropped";
|
||||
case AppErrorType::AppErrorTxMessagesFlushed:
|
||||
return "TX message buffer flushed";
|
||||
case AppErrorType::AppErrorTxMessagesHalfFull:
|
||||
return "TX message buffer half full";
|
||||
case AppErrorType::AppErrorNetworkNotValid:
|
||||
return "Network is not valid";
|
||||
case AppErrorType::AppErrorTxInterfaceNotImplemented:
|
||||
return "TX interface is not implemented";
|
||||
case AppErrorType::AppErrorTxMessagesCommEnableIsOff:
|
||||
return "TX message communication is disabled";
|
||||
case AppErrorType::AppErrorRxFilterMatchCountExceeded:
|
||||
return "RX filter match count exceeded";
|
||||
case AppErrorType::AppErrorEthPreemptionNotEnabled:
|
||||
return std::string(netIDString) + ": Ethernet preemption not enabled";
|
||||
case AppErrorType::AppErrorTxNotSupportedInMode:
|
||||
return std::string(netIDString) + ": Transmit is not supported in this mode";
|
||||
case AppErrorType::AppErrorJumboFramesNotSupported:
|
||||
return std::string(netIDString) + ": Jumbo frames not supported";
|
||||
case AppErrorType::AppErrorEthernetIpFragment:
|
||||
return "Ethernet IP fragment received";
|
||||
case AppErrorType::AppErrorTxMessagesUnderrun:
|
||||
return std::string(netIDString) + ": Transmit buffer underrun";
|
||||
case AppErrorType::AppErrorDeviceFanFailure:
|
||||
return "Device fan failure";
|
||||
case AppErrorType::AppErrorDeviceOvertemperature:
|
||||
return "Device overtemperature";
|
||||
case AppErrorType::AppErrorTxMessageIndexOutOfRange:
|
||||
return "Transmit message index out of range";
|
||||
case AppErrorType::AppErrorUndersizedFrameDropped:
|
||||
return std::string(netIDString) + ": Undersized frame dropped";
|
||||
case AppErrorType::AppErrorOversizedFrameDropped:
|
||||
return std::string(netIDString) + ": Oversized frame dropped";
|
||||
case AppErrorType::AppErrorWatchdogEvent:
|
||||
return "Watchdog event occured";
|
||||
case AppErrorType::AppErrorSystemClockFailure:
|
||||
return "Device clock failed";
|
||||
case AppErrorType::AppErrorSystemClockRecovered:
|
||||
return "Device clock recovered";
|
||||
case AppErrorType::AppErrorSystemPeripheralReset:
|
||||
return "Device peripheral reset";
|
||||
case AppErrorType::AppErrorSystemCommunicationFailure:
|
||||
return "Device communication failure";
|
||||
case AppErrorType::AppErrorTxMessagesUnsupportedSourceOrPacketId:
|
||||
return std::string(netIDString) + ": Transmit unsupported source or packet ID";
|
||||
case AppErrorType::AppErrorWbmsManagerConnectFailed:
|
||||
return std::string(netIDString) + ": Failed to connect to managers with settings";
|
||||
case AppErrorType::AppErrorWbmsManagerConnectBadState:
|
||||
return std::string(netIDString) + ": Connected to managers in a invalid state";
|
||||
case AppErrorType::AppErrorWbmsManagerConnectTimeout:
|
||||
return std::string(netIDString) + ": Timeout while attempting to connect to managers";
|
||||
case AppErrorType::AppErrorFailedToInitializeLoggerDisk:
|
||||
return "Device failed to initialize storage disk";
|
||||
case AppErrorType::AppErrorInvalidSetting:
|
||||
return std::string(netIDString) + ": Invalid settings";
|
||||
case AppErrorType::AppErrorSystemFailureRequestedReset:
|
||||
return "Device rebooted to recover from an unexpected error condition";
|
||||
case AppErrorType::AppErrorPortKeyMistmatch:
|
||||
return std::string(netIDString) + ": Mismatch between key in manager and stored key";
|
||||
case AppErrorType::AppErrorBusFailure:
|
||||
return std::string(netIDString) + ": Bus failure";
|
||||
case AppErrorType::AppErrorTapOverflow:
|
||||
return std::string(netIDString) + ": Tap overflow";
|
||||
case AppErrorType::AppErrorEthTxNoLink:
|
||||
return std::string(netIDString) + ": Attempted Ethernet transmit without link";
|
||||
case AppErrorType::AppErrorErrorBufferOverflow:
|
||||
return "Device error buffer overflow";
|
||||
case AppErrorType::AppNoError:
|
||||
return "No error";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,57 +0,0 @@
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
enum LinkSpeed {
|
||||
ethSpeed10,
|
||||
ethSpeed100,
|
||||
ethSpeed1000,
|
||||
ethSpeedAutoNeg,
|
||||
ethSpeed2500,
|
||||
ethSpeed5000,
|
||||
ethSpeed10000,
|
||||
};
|
||||
|
||||
enum LinkMode {
|
||||
AE_LINK_AUTO,
|
||||
AE_LINK_MASTER,
|
||||
AE_LINK_SLAVE,
|
||||
AE_LINK_INVALID = 255,
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
uint8_t state;
|
||||
uint8_t speed;
|
||||
uint8_t duplex;
|
||||
uint16_t network;
|
||||
uint8_t mode;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(Packet)) {
|
||||
return nullptr;
|
||||
}
|
||||
Packet* packet = (Packet*)bytestream.data();
|
||||
LinkSpeed speed;
|
||||
switch(packet->speed) {
|
||||
case ethSpeed10: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10; break;
|
||||
case ethSpeed100: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed100; break;
|
||||
case ethSpeed1000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed1000; break;
|
||||
case ethSpeedAutoNeg: speed = EthernetStatusMessage::LinkSpeed::LinkSpeedAuto; break;
|
||||
case ethSpeed2500: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed2500; break;
|
||||
case ethSpeed5000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed5000; break;
|
||||
case ethSpeed10000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10000; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
LinkMode mode;
|
||||
switch(packet->mode) {
|
||||
case AE_LINK_INVALID: mode = EthernetStatusMessage::LinkMode::LinkModeInvalid; break;
|
||||
case AE_LINK_AUTO: mode = EthernetStatusMessage::LinkMode::LinkModeAuto; break;
|
||||
case AE_LINK_MASTER: mode = EthernetStatusMessage::LinkMode::LinkModeMaster; break;
|
||||
case AE_LINK_SLAVE: mode = EthernetStatusMessage::LinkMode::LinkModeSlave; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state, speed, packet->duplex, mode);
|
||||
}
|
||||
@@ -7,7 +7,8 @@
|
||||
using namespace icsneo;
|
||||
|
||||
std::vector<uint8_t> FlexRayControlMessage::BuildBaseControlArgs(uint8_t controller, FlexRay::Opcode op, const std::vector<uint8_t>& args) {
|
||||
std::vector<uint8_t> ret(args.size() + 4);
|
||||
std::vector<uint8_t> ret;
|
||||
ret.reserve(args.size() + 4);
|
||||
ret.push_back(controller);
|
||||
const uint16_t size = uint16_t((std::min)(args.size() + 1, size_t(std::numeric_limits<uint16_t>::max()))); // Add 1 for the opcode
|
||||
ret.push_back(uint8_t(size));
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
#include <icsneo/communication/message/gptpstatusmessage.h>
|
||||
#include <icsneo/communication/message/extendedresponsemessage.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace icsneo {
|
||||
typedef double float64;
|
||||
typedef int64_t time_interval;
|
||||
typedef uint64_t _clock_identity;
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct port_identity {
|
||||
_clock_identity clock_identity;
|
||||
uint16_t port_number;
|
||||
};
|
||||
|
||||
struct _scaled_ns {
|
||||
int16_t nanoseconds_msb;
|
||||
int64_t nanoseconds_lsb;
|
||||
int16_t fractional_nanoseconds;
|
||||
};
|
||||
|
||||
struct _clock_quality {
|
||||
uint8_t clock_class;
|
||||
uint8_t clock_accuracy;
|
||||
uint16_t offset_scaled_log_variance;
|
||||
};
|
||||
|
||||
struct system_identity {
|
||||
uint8_t priority_1;
|
||||
struct _clock_quality clock_quality;
|
||||
uint8_t priority_2;
|
||||
_clock_identity clock_identity;
|
||||
};
|
||||
|
||||
struct _timestamp {
|
||||
uint16_t seconds_msb;
|
||||
uint32_t seconds_lsb;
|
||||
uint32_t nanoseconds;
|
||||
};
|
||||
|
||||
struct priority_vector {
|
||||
struct system_identity sysid;
|
||||
uint16_t steps_removed;
|
||||
struct port_identity portid;
|
||||
uint16_t port_number;
|
||||
};
|
||||
|
||||
|
||||
// IEEE 802.1AS-2020 14.3
|
||||
// This is a read-only data structure
|
||||
struct _current_ds {
|
||||
uint16_t steps_removed;
|
||||
time_interval offset_from_master;
|
||||
struct _scaled_ns last_gm_phase_change;
|
||||
float64 last_gm_freq_change;
|
||||
uint16_t gm_time_base_indicator;
|
||||
uint32_t gm_change_count;
|
||||
uint32_t time_of_last_gm_change_event;
|
||||
uint32_t time_of_last_gm_phase_change_event;
|
||||
uint32_t time_of_last_gm_freq_change_event;
|
||||
};
|
||||
|
||||
// IEEE 802.1AS-2020 14.4
|
||||
// This is a read-only data structure
|
||||
struct _parent_ds {
|
||||
struct port_identity parent_port_identity;
|
||||
int32_t cumulative_rate_ratio;
|
||||
_clock_identity grandmaster_identity;
|
||||
uint8_t gm_clock_quality_clock_class;
|
||||
uint8_t gm_clock_quality_clock_accuracy;
|
||||
uint16_t gm_clock_quality_offset_scaled_log_variance;
|
||||
uint8_t gm_priority1;
|
||||
uint8_t gm_priority2;
|
||||
};
|
||||
|
||||
struct _GPTPStatus
|
||||
{
|
||||
struct _timestamp current_time;
|
||||
struct priority_vector gm_priority;
|
||||
int64_t ms_offset_ns;
|
||||
uint8_t is_sync;
|
||||
uint8_t link_status;
|
||||
int64_t link_delay_ns;
|
||||
uint8_t selected_role;
|
||||
uint8_t as_capable;
|
||||
uint8_t is_syntonized;
|
||||
struct _timestamp last_rx_sync_ts; // t2 in IEEE 1588-2019 Figure-16
|
||||
struct _current_ds current_ds;
|
||||
struct _parent_ds parent_ds;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
static void SetField(GPTPStatus::Timestamp& output, const _timestamp& input) {
|
||||
output.seconds = ((uint64_t)(input.seconds_msb) << 32) | ((uint64_t)input.seconds_lsb);
|
||||
output.nanoseconds = input.nanoseconds;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::PortID& output, const port_identity& input) {
|
||||
output.clockIdentity = input.clock_identity;
|
||||
output.portNumber = input.port_number;
|
||||
}
|
||||
static void SetField(GPTPStatus::ClockQuality& output, const _clock_quality& input) {
|
||||
output.clockClass = input.clock_class;
|
||||
output.clockAccuracy = input.clock_accuracy;
|
||||
output.offsetScaledLogVariance = input.offset_scaled_log_variance;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::SystemID& output, const system_identity& input) {
|
||||
output.priority1 = input.priority_1;
|
||||
SetField(output.clockQuality, input.clock_quality);
|
||||
output.priority2 = input.priority_2;
|
||||
output.clockID = input.clock_identity;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::ScaledNanoSeconds& output, const _scaled_ns& input) {
|
||||
output.nanosecondsMSB = input.nanoseconds_msb;
|
||||
output.nanosecondsLSB = input.nanoseconds_lsb;
|
||||
output.fractionalNanoseconds = input.fractional_nanoseconds;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::PriorityVector& output, const priority_vector& input) {
|
||||
SetField(output.sysID, input.sysid);
|
||||
output.stepsRemoved = input.steps_removed;
|
||||
SetField(output.portID, input.portid);
|
||||
output.portNumber = input.port_number;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::CurrentDS& output, const _current_ds& input) {
|
||||
output.stepsRemoved = input.steps_removed;
|
||||
output.offsetFromMaster = input.offset_from_master;
|
||||
SetField(output.lastgmPhaseChange, input.last_gm_phase_change);
|
||||
output.lastgmFreqChange = input.last_gm_freq_change;
|
||||
output.gmTimeBaseIndicator = input.gm_time_base_indicator;
|
||||
output.gmChangeCount = input.gm_change_count;
|
||||
output.timeOfLastgmChangeEvent = input.time_of_last_gm_change_event;
|
||||
output.timeOfLastgmPhaseChangeEvent = input.time_of_last_gm_phase_change_event;
|
||||
output.timeOfLastgmFreqChangeEvent = input.time_of_last_gm_freq_change_event;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::ParentDS& output, const _parent_ds& input) {
|
||||
SetField(output.parentPortIdentity, input.parent_port_identity);
|
||||
output.cumulativeRateRatio = input.cumulative_rate_ratio;
|
||||
output.grandmasterIdentity = input.grandmaster_identity;
|
||||
output.gmClockQualityClockClass = input.gm_clock_quality_clock_class;
|
||||
output.gmClockQualityClockAccuracy = input.gm_clock_quality_clock_accuracy;
|
||||
output.gmClockQualityOffsetScaledLogVariance = input.gm_clock_quality_offset_scaled_log_variance;
|
||||
output.gmPriority1 = input.gm_priority1;
|
||||
output.gmPriority2 = input.gm_priority2;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint8_t& output, const uint8_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint16_t& output, const uint16_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint32_t& output, const uint32_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint64_t& output, const uint64_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int8_t& output, const int8_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int16_t& output, const int16_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int32_t& output, const int32_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int64_t& output, const int64_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
std::shared_ptr<GPTPStatus> GPTPStatus::DecodeToMessage(std::vector<uint8_t>& bytes, const device_eventhandler_t&) {
|
||||
|
||||
// The following does not lead to overflow since we only call this function if it has at least ResponseHeader length bytes
|
||||
std::shared_ptr<GPTPStatus> res = std::make_shared<GPTPStatus>();
|
||||
auto* header = reinterpret_cast<ExtendedResponseMessage::ResponseHeader*>(bytes.data());
|
||||
uint16_t length = header->length;
|
||||
_GPTPStatus* input = reinterpret_cast<_GPTPStatus*>(bytes.data() + sizeof(ExtendedResponseMessage::ResponseHeader));
|
||||
|
||||
#define CheckLengthAndSet(output, input) if(length >= sizeof(decltype(input))) { \
|
||||
SetField(output, input); \
|
||||
length -= sizeof(decltype(input)); \
|
||||
} else {\
|
||||
memset(&output, 0, sizeof(decltype(output))); \
|
||||
length = 0; \
|
||||
res->shortFormat = true; \
|
||||
}
|
||||
|
||||
CheckLengthAndSet(res->currentTime, input->current_time);
|
||||
CheckLengthAndSet(res->gmPriority, input->gm_priority);
|
||||
CheckLengthAndSet(res->msOffsetNs, input->ms_offset_ns);
|
||||
CheckLengthAndSet(res->isSync, input->is_sync);
|
||||
CheckLengthAndSet(res->linkStatus, input->link_status);
|
||||
CheckLengthAndSet(res->linkDelayNS, input->link_delay_ns);
|
||||
CheckLengthAndSet(res->selectedRole, input->selected_role);
|
||||
CheckLengthAndSet(res->asCapable, input->as_capable);
|
||||
CheckLengthAndSet(res->isSyntonized, input->is_syntonized);
|
||||
CheckLengthAndSet(res->lastRXSyncTS, input->last_rx_sync_ts);
|
||||
CheckLengthAndSet(res->currentDS, input->current_ds);
|
||||
CheckLengthAndSet(res->parentDS, input->parent_ds);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,14 +12,4 @@ void LiveDataCommandMessage::appendSignalArg(LiveDataValueType valueType) {
|
||||
arg->valueType = valueType;
|
||||
}
|
||||
|
||||
void LiveDataSetValueMessage::appendSetValue(LiveDataValueType valueType, const LiveDataValue& value) {
|
||||
auto& arg = args.emplace_back(std::make_shared<LiveDataArgument>());
|
||||
arg->objectType = LiveDataObjectType::MISC;
|
||||
arg->objectIndex = 0u;
|
||||
arg->signalIndex = 0u;
|
||||
arg->valueType = valueType;
|
||||
|
||||
values.push_back(std::make_shared<LiveDataValue>(value));
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#include "icsneo/communication/message/logdatamessage.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::shared_ptr<LogDataMessage> LogDataMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() % 2 != 0)
|
||||
return nullptr;
|
||||
const auto* begin = (char16_t*)bytestream.data();
|
||||
const auto* end = begin + (bytestream.size() / sizeof(char16_t));
|
||||
return std::make_shared<LogDataMessage>(std::wstring(begin,end));
|
||||
}
|
||||
@@ -1,531 +0,0 @@
|
||||
#include "icsneo/communication/message/macsecmessage.h"
|
||||
|
||||
#include "icsneo/communication/crc32.h"
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
namespace icsneo
|
||||
{
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201) // nameless struct/union
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
/* MACsec Rule */
|
||||
/**
|
||||
* @brief Structure of Vlan tag
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t vid; /*!< 12 bits */
|
||||
uint8_t priCfi; /*!< PRI - 3 bits, CFI - 1bit */
|
||||
} MACSEC_VLANTAG_t;
|
||||
/**
|
||||
* @brief Structure of MPLS
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mplsLabel; /*!< 20 bits */
|
||||
uint8_t exp; /*!< 3 bits */
|
||||
} MACSEC_MPLS_OUTER_t;
|
||||
/**
|
||||
* @brief Define Encoded Packet Type from the parser
|
||||
*
|
||||
*/
|
||||
static constexpr int MACSEC_SETTINGS_RULE_SIZE = 88;
|
||||
typedef union _MACSecRule
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index;
|
||||
uint8_t keyMacDa[6]; /*!< MAC DA field extracted from the packet */
|
||||
uint8_t maskMacDa[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyMacSa[6]; /*!< MAC SA field extracted from the packet */
|
||||
uint8_t maskMacSa[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t keyEthertype; /*!< First E-Type found in the packet that doesn't match one of the preconfigured custom tag. */
|
||||
uint16_t maskEthertype; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_VLANTAG_t keyVlanTagOuter1; /*!< outermost/1st VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACSEC_MPLS_OUTER_t keyMplsOuter1;
|
||||
MACSEC_VLANTAG_t maskVlanTagOuter1; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_MPLS_OUTER_t maskMplsOuter1;
|
||||
MACSEC_VLANTAG_t keyVlanTagOuter2; /*!< 2nd outermost VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACSEC_MPLS_OUTER_t keyMplsOuter2;
|
||||
MACSEC_VLANTAG_t maskVlanTagOuter2; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_MPLS_OUTER_t maskMplsOuter2;
|
||||
uint16_t keyBonusData; /*!< 2 bytes of additional bonus data extracted from one of the custom tags. */
|
||||
uint16_t maskBonusData; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t
|
||||
keyTagMatchBitmap; /*!< 8 bits total. Maps 1 to 1 bitwise with the set of custom tags. (set bit[N]=1 if check Nth custom tag) */
|
||||
uint8_t maskTagMatchBitmap; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyPacketType; /*!< Encoded Packet Type, see MACSEC_PACKET_TYPE */
|
||||
uint8_t maskPacketType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t
|
||||
keyInnerVlanType; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the second outermost VLAN Tag. */
|
||||
uint16_t maskInnerVlanType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t keyOuterVlanType; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the outermost VLAN Tag. */
|
||||
uint16_t maskOuterVlanType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t
|
||||
keyNumTags; /*!< 7 bits total. Number of VLAN/custom tags or MPLS lables detected. Ingress: before SecTag; Egress: total detected. Exclude MCS header tags. i.e. Bit 2: 2 tags/labels before SecTAG...Bit 6: 6 or more tags/labels before SecTAG. */
|
||||
uint8_t maskNumTags; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyExpress; /*!< 1 bits. Express packet. */
|
||||
uint8_t maskExpress; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t isMpls;
|
||||
uint8_t rsvd[5];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_RULE_SIZE];
|
||||
} MACSecRule_t;
|
||||
/* MACsec Map */
|
||||
static constexpr int MACSEC_SETTINGS_MAP_SIZE = 20;
|
||||
typedef union _MACSecMap
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index;
|
||||
uint64_t secTagSci; /*!< Identifies the SecTAG SCI for this Flow. */
|
||||
uint8_t secYIndex; /*!< index for entry in Egress secY Policy */
|
||||
uint8_t isControlPacket; /*!< Identifies all packets matching this index lookup as control packets. */
|
||||
uint8_t scIndex; /*!< Identifies the SC for this Flow. */
|
||||
uint8_t auxiliaryPlcy; /*!< Auxiliary policy bits. */
|
||||
uint8_t ruleId; /*!< Identifies the Rule for this Flow. */
|
||||
uint8_t rsvd[5];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_MAP_SIZE];
|
||||
} MACSecMap_t;
|
||||
/* MACsec SecY */
|
||||
/**
|
||||
* @brief Define the permit police for frames as defined in 802.1ae
|
||||
*
|
||||
*/
|
||||
static constexpr int MACSEC_SETTINGS_SECY_SIZE = 24;
|
||||
typedef union _MACSecSecY
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index; /*!< Identifies the SecY for this Flow. */
|
||||
uint8_t controlledPortEnabled; /*!< Enable (or disable) operation of the Controlled port associated with this SecY */
|
||||
uint8_t frameValidationType; /*!< see MACSEC_VALIDATEFRAME */
|
||||
uint8_t secTagIcvStripType; /*!< see MACSEC_STRIP_SECTAG_ICV */
|
||||
uint8_t cipher; /*!< Define the cipher suite to use for this SecY see MACSEC_CIPHER_SUITE */
|
||||
uint8_t confidentialOffset; /*!< Define the number of bytes that are unencrypted following the SecTag. */
|
||||
uint8_t icvIncludesDaSa; /*!< When set, the outer DA/SA bytes are included in the authentication GHASH calculation */
|
||||
uint8_t replayProtect; /*!< Enables Anti-Replay protection */
|
||||
uint32_t replayWindow; /*!< Unsigned value indicating the size of the anti-replay window. */
|
||||
uint8_t
|
||||
protectFrames; /*!< 0 = do not encrypt or authenticate this packet; 1 = always Authenticate frame and if SecTag.TCI.E = 1 encrypt the packet as well. */
|
||||
uint8_t
|
||||
secTagOffset; /*!< Define the offset in bytes from either the start of the packet or a matching Etype depending on SecTag_Insertion_Mode. */
|
||||
uint8_t secTagTci; /*!< Tag Control Information excluding the AN field which originates from the SA Policy table */
|
||||
uint16_t mtu; /*!< Specifies the outgoing MTU for this SecY */
|
||||
uint8_t rsvd[6];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SECY_SIZE];
|
||||
} MACSecSecY_t;
|
||||
/* MACsec SC */
|
||||
static constexpr int MACSEC_SETTINGS_SC_SIZE = 24;
|
||||
typedef union _MACSecSc
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index; /*!< SC index. */
|
||||
uint8_t secYIndex; /*!< SecY associated with this packet. */
|
||||
uint64_t sci; /*!< The Secure Channel Identifier. */
|
||||
uint8_t saIndex0; /*!< Define the 1st SA to use */
|
||||
uint8_t saIndex1; /*!< Define the 2nd SA to use */
|
||||
uint8_t saIndex0InUse; /*!< Specifies whether 1st SA is in use or not. */
|
||||
uint8_t saIndex1InUse; /*!< Specifies whether 2nd SA is in use or not. */
|
||||
uint8_t enableAutoRekey; /*!< If enabled, then once the pn_threshold is reached, auto rekey will happen. */
|
||||
uint8_t
|
||||
isActiveSa1; /*!< If set, then sa_index1 is the currently active SA index. If cleared, the sa_index0 is the currently active SA index). */
|
||||
uint8_t rsvd[7];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SC_SIZE];
|
||||
} MACSecSc_t;
|
||||
/* MACsec SA */
|
||||
static constexpr int MACSEC_SETTINGS_SA_SIZE = 80;
|
||||
typedef union _MACSecSa
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index; /*!< SA index */
|
||||
uint8_t
|
||||
sak[32]; /*!< 256b SAK: Define the encryption key to be used to encrypte this packet. The lower 128 bits are used for 128-bit ciphers. */
|
||||
uint8_t hashKey[16]; /*!< 128b Hash Key: Key used for authentication. */
|
||||
uint8_t salt[12]; /*!< 96b Salt value: Salt value used in XPN ciphers. */
|
||||
uint32_t ssci; /*!< 32b SSCI value: Short Secure Channel Identifier, used in XPN ciphers. */
|
||||
uint8_t an; /*!< 2b SecTag Association Number (AN) */
|
||||
uint64_t nextPn; /*!< 64b next_pn value: Next packet number to insert into outgoing packet on a particular SA. */
|
||||
uint8_t rsvd[5];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SA_SIZE];
|
||||
} MACSecSa_t;
|
||||
/* MACsec Flags */
|
||||
typedef union _MACSecFlags
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t en : 1; // '1' = enable; '0' = disable
|
||||
uint32_t reserved : 31;
|
||||
};
|
||||
uint32_t flags_32b;
|
||||
} MACSecFlags_t;
|
||||
#define MACSEC_SETTINGS_FLAGS_SIZE (4)
|
||||
/* MACSec Settings for 1 port/phy */
|
||||
typedef struct MACSEC_CONFIG_t
|
||||
{
|
||||
MACSecFlags_t flags;
|
||||
MACSecRule_t rule[MACsecConfig::NumRules];
|
||||
MACSecMap_t map[MACsecConfig::NumMaps];
|
||||
MACSecSecY_t secy[MACsecConfig::NumSecY];
|
||||
MACSecSc_t sc[MACsecConfig::NumSc];
|
||||
MACSecSa_t sa[MACsecConfig::NumSa];
|
||||
} MACSEC_CONFIG;
|
||||
typedef union _MACSecGlobalFlags
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t en : 1; // '1' = enable; '0' = disable
|
||||
uint32_t nvm : 1; // store macsec config in non-volatile memory
|
||||
uint32_t reserved : 30;
|
||||
};
|
||||
uint32_t flags_32b;
|
||||
} MACSecGlobalFlags_t;
|
||||
#define MACSEC_SETTINGS_SIZE (2040) // leave space for expansion and keep nicely aligned for flashing
|
||||
typedef union _MACSEC_SETTINGS
|
||||
{
|
||||
struct
|
||||
{
|
||||
MACSecGlobalFlags_t flags;
|
||||
MACSEC_CONFIG rx;
|
||||
MACSEC_CONFIG tx;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SIZE];
|
||||
} MACSEC_SETTINGS;
|
||||
|
||||
#define MACSEC_SETTINGS_VERSION 1
|
||||
struct MACSEC_SETTINGS_W_HDR
|
||||
{
|
||||
uint16_t version;
|
||||
uint16_t len;
|
||||
uint32_t crc32;
|
||||
MACSEC_SETTINGS macsec;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
std::shared_ptr<MACsecMessage> MACsecMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report)
|
||||
{
|
||||
if (bytestream.empty() || (bytestream.size() < sizeof(MACSEC_SETTINGS_W_HDR)))
|
||||
{
|
||||
report(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MACSEC_SETTINGS_W_HDR* macsecArgs = (MACSEC_SETTINGS_W_HDR*)bytestream.data();
|
||||
if (macsecArgs->version != MACSEC_SETTINGS_VERSION)
|
||||
{
|
||||
report(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
if (macsecArgs->len != sizeof(MACSEC_SETTINGS))
|
||||
{
|
||||
report(APIEvent::Type::SettingsLengthError, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
const auto crcCalculted = crc32(0, (uint8_t*)&macsecArgs->macsec, macsecArgs->len);
|
||||
if (macsecArgs->crc32 != crcCalculted)
|
||||
{
|
||||
report(APIEvent::Type::SettingsChecksumError, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto msg = std::make_shared<MACsecMessage>();
|
||||
|
||||
const auto& copyConfig = [](const MACSEC_CONFIG& source, MACsecConfig& dest)
|
||||
{
|
||||
dest.flags.en = source.flags.en;
|
||||
for (int index = 0; index < MACsecConfig::NumRules; index++)
|
||||
{
|
||||
if(!source.rule[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.rule[index].___name__ = (decltype(dest.rule[index].___name__))source.rule[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.rule[index].___name__.data(), source.rule[index].___name__, dest.rule[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(keyMacDa);
|
||||
__COPY_ARR(maskMacDa);
|
||||
__COPY_ARR(keyMacSa);
|
||||
__COPY_ARR(maskMacSa);
|
||||
__COPY_ITEM(keyVlanTagOuter1.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter1.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter1.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter1.exp);
|
||||
__COPY_ITEM(keyVlanTagOuter2.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter2.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter2.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter2.exp);
|
||||
__COPY_ITEM(keyEthertype);
|
||||
__COPY_ITEM(maskEthertype);
|
||||
__COPY_ITEM(keyBonusData);
|
||||
__COPY_ITEM(maskBonusData);
|
||||
__COPY_ITEM(keyTagMatchBitmap);
|
||||
__COPY_ITEM(maskTagMatchBitmap);
|
||||
__COPY_ITEM(keyPacketType);
|
||||
__COPY_ITEM(maskPacketType);
|
||||
__COPY_ITEM(keyInnerVlanType);
|
||||
__COPY_ITEM(maskInnerVlanType);
|
||||
__COPY_ITEM(keyOuterVlanType);
|
||||
__COPY_ITEM(maskOuterVlanType);
|
||||
__COPY_ITEM(keyNumTags);
|
||||
__COPY_ITEM(maskNumTags);
|
||||
__COPY_ITEM(keyExpress);
|
||||
__COPY_ITEM(maskExpress);
|
||||
__COPY_ITEM(isMpls);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumMaps; index++)
|
||||
{
|
||||
if(!source.map[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.map[index].___name__ = source.map[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secTagSci);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(isControlPacket);
|
||||
__COPY_ITEM(scIndex);
|
||||
__COPY_ITEM(auxiliaryPlcy);
|
||||
__COPY_ITEM(ruleId);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSecY; index++)
|
||||
{
|
||||
if(!source.secy[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.secy[index].___name__ = (decltype(dest.secy[index].___name__))source.secy[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(controlledPortEnabled);
|
||||
__COPY_ITEM(frameValidationType);
|
||||
__COPY_ITEM(secTagIcvStripType);
|
||||
__COPY_ITEM(cipher);
|
||||
__COPY_ITEM(confidentialOffset);
|
||||
__COPY_ITEM(icvIncludesDaSa);
|
||||
__COPY_ITEM(replayProtect);
|
||||
__COPY_ITEM(replayWindow);
|
||||
__COPY_ITEM(protectFrames);
|
||||
__COPY_ITEM(secTagOffset);
|
||||
__COPY_ITEM(secTagTci);
|
||||
__COPY_ITEM(mtu);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSc; index++)
|
||||
{
|
||||
if(!source.sc[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sc[index].___name__ = source.sc[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(sci);
|
||||
__COPY_ITEM(saIndex0);
|
||||
__COPY_ITEM(saIndex1);
|
||||
__COPY_ITEM(saIndex0InUse);
|
||||
__COPY_ITEM(saIndex1InUse);
|
||||
__COPY_ITEM(enableAutoRekey);
|
||||
__COPY_ITEM(isActiveSa1);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSa; index++)
|
||||
{
|
||||
if(!source.sa[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sa[index].___name__ = source.sa[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.sa[index].___name__.data(), source.sa[index].___name__, dest.sa[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(sak);
|
||||
__COPY_ARR(hashKey);
|
||||
__COPY_ARR(salt);
|
||||
__COPY_ITEM(ssci);
|
||||
__COPY_ITEM(an);
|
||||
__COPY_ITEM(nextPn);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
};
|
||||
|
||||
msg->flags.en = macsecArgs->macsec.flags.en;
|
||||
copyConfig(macsecArgs->macsec.rx, msg->rx);
|
||||
copyConfig(macsecArgs->macsec.tx, msg->tx);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool MACsecMessage::EncodeFromMessage(std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) const
|
||||
{
|
||||
MACSEC_SETTINGS_W_HDR* macsecArgs;
|
||||
|
||||
bytestream.resize(sizeof(MACSEC_SETTINGS_W_HDR), 0);
|
||||
macsecArgs = (MACSEC_SETTINGS_W_HDR*)bytestream.data();
|
||||
|
||||
macsecArgs->version = MACSEC_SETTINGS_VERSION;
|
||||
macsecArgs->len = sizeof(MACSEC_SETTINGS_W_HDR);
|
||||
|
||||
const auto& copyConfig = [](const MACsecConfig& source, MACSEC_CONFIG& dest)
|
||||
{
|
||||
dest.flags.en = (uint8_t)source.flags.en;
|
||||
for (int index = 0; index < MACsecConfig::NumRules; index++)
|
||||
{
|
||||
if(!source.rule[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.rule[index].___name__ = (decltype(dest.rule[index].___name__))source.rule[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.rule[index].___name__, source.rule[index].___name__.data(), source.rule[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(keyMacDa);
|
||||
__COPY_ARR(maskMacDa);
|
||||
__COPY_ARR(keyMacSa);
|
||||
__COPY_ARR(maskMacSa);
|
||||
__COPY_ITEM(keyVlanTagOuter1.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter1.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter1.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter1.exp);
|
||||
__COPY_ITEM(keyVlanTagOuter2.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter2.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter2.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter2.exp);
|
||||
__COPY_ITEM(keyEthertype);
|
||||
__COPY_ITEM(maskEthertype);
|
||||
__COPY_ITEM(keyBonusData);
|
||||
__COPY_ITEM(maskBonusData);
|
||||
__COPY_ITEM(keyTagMatchBitmap);
|
||||
__COPY_ITEM(maskTagMatchBitmap);
|
||||
__COPY_ITEM(keyPacketType);
|
||||
__COPY_ITEM(maskPacketType);
|
||||
__COPY_ITEM(keyInnerVlanType);
|
||||
__COPY_ITEM(maskInnerVlanType);
|
||||
__COPY_ITEM(keyOuterVlanType);
|
||||
__COPY_ITEM(maskOuterVlanType);
|
||||
__COPY_ITEM(keyNumTags);
|
||||
__COPY_ITEM(maskNumTags);
|
||||
__COPY_ITEM(keyExpress);
|
||||
__COPY_ITEM(maskExpress);
|
||||
__COPY_ITEM(isMpls);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumMaps; index++)
|
||||
{
|
||||
if(!source.map[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.map[index].___name__ = source.map[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secTagSci);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(isControlPacket);
|
||||
__COPY_ITEM(scIndex);
|
||||
__COPY_ITEM(auxiliaryPlcy);
|
||||
__COPY_ITEM(ruleId);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSecY; index++)
|
||||
{
|
||||
if(!source.secy[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.secy[index].___name__ = (decltype(dest.secy[index].___name__))source.secy[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(controlledPortEnabled);
|
||||
__COPY_ITEM(frameValidationType);
|
||||
__COPY_ITEM(secTagIcvStripType);
|
||||
__COPY_ITEM(cipher);
|
||||
__COPY_ITEM(confidentialOffset);
|
||||
__COPY_ITEM(icvIncludesDaSa);
|
||||
__COPY_ITEM(replayProtect);
|
||||
__COPY_ITEM(replayWindow);
|
||||
__COPY_ITEM(protectFrames);
|
||||
__COPY_ITEM(secTagOffset);
|
||||
__COPY_ITEM(secTagTci);
|
||||
__COPY_ITEM(mtu);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSc; index++)
|
||||
{
|
||||
if(!source.sc[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sc[index].___name__ = source.sc[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(sci);
|
||||
__COPY_ITEM(saIndex0);
|
||||
__COPY_ITEM(saIndex1);
|
||||
__COPY_ITEM(saIndex0InUse);
|
||||
__COPY_ITEM(saIndex1InUse);
|
||||
__COPY_ITEM(enableAutoRekey);
|
||||
__COPY_ITEM(isActiveSa1);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSa; index++)
|
||||
{
|
||||
if(!source.sa[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sa[index].___name__ = source.sa[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.sa[index].___name__, source.sa[index].___name__.data(), source.sa[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(sak);
|
||||
__COPY_ARR(hashKey);
|
||||
__COPY_ARR(salt);
|
||||
__COPY_ITEM(ssci);
|
||||
__COPY_ITEM(an);
|
||||
__COPY_ITEM(nextPn);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
};
|
||||
macsecArgs->macsec.flags.en = this->flags.en;
|
||||
macsecArgs->macsec.flags.nvm = this->flags.nvm;
|
||||
|
||||
copyConfig(this->rx, macsecArgs->macsec.rx);
|
||||
copyConfig(this->tx, macsecArgs->macsec.tx);
|
||||
|
||||
macsecArgs->crc32 = crc32(0, (uint8_t*)&macsecArgs->macsec, sizeof(MACSEC_SETTINGS));
|
||||
|
||||
(void)report;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "icsneo/communication/message/neomessage.h"
|
||||
#include "icsneo/communication/message/canmessage.h"
|
||||
#include "icsneo/communication/message/ethernetmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/linmessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
@@ -51,7 +51,7 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
||||
eth.status.incompleteFrame = ethmsg->frameTooShort;
|
||||
// TODO Fill in extra status bits
|
||||
//eth.status.xyz = ethmsg->preemptionEnabled;
|
||||
//eth.status.xyz = ethmsg->fcs;
|
||||
//eth.status.xyz = ethmsg->fcsAvailable;
|
||||
//eth.status.xyz = ethmsg->noPadding;
|
||||
break;
|
||||
}
|
||||
@@ -75,15 +75,13 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
||||
lin.length = 1;
|
||||
|
||||
lin.linStatus = {
|
||||
linmsg->statusFlags.TxChecksumEnhanced, // .txChecksumEnhanced
|
||||
linmsg->statusFlags.TxCommander, // .txCommander
|
||||
linmsg->statusFlags.TxResponder, // .txResponder
|
||||
0, // .txAborted
|
||||
linmsg->statusFlags.UpdateResponderOnce, // .updateResponderOnce
|
||||
linmsg->statusFlags.HasUpdatedResponderOnce, // .hasUpdatedResponderOnce
|
||||
linmsg->statusFlags.BusRecovered, // .busRecovered
|
||||
linmsg->statusFlags.BreakOnly // .breakOnly
|
||||
|
||||
linmsg->statusFlags.TxChecksumEnhanced,
|
||||
linmsg->statusFlags.TxCommander,
|
||||
linmsg->statusFlags.TxResponder,
|
||||
linmsg->statusFlags.UpdateResponderOnce,
|
||||
linmsg->statusFlags.HasUpdatedResponderOnce,
|
||||
linmsg->statusFlags.BusRecovered,
|
||||
linmsg->statusFlags.BreakOnly
|
||||
};
|
||||
|
||||
lin.status.linJustBreakSync = linmsg->errFlags.ErrRxBreakSyncOnly;
|
||||
@@ -106,7 +104,7 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
||||
}
|
||||
case Message::Type::CANErrorCount: {
|
||||
neomessage_can_error_t& canerror = *(neomessage_can_error_t*)&neomsg;
|
||||
auto canerrormsg = std::static_pointer_cast<CANErrorMessage>(message);
|
||||
auto canerrormsg = std::static_pointer_cast<CANErrorCountMessage>(message);
|
||||
canerror.transmitErrorCount = canerrormsg->transmitErrorCount;
|
||||
canerror.receiveErrorCount = canerrormsg->receiveErrorCount;
|
||||
canerror.status.canBusOff = canerrormsg->busOff;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
@@ -53,18 +53,16 @@ static std::optional<uint8_t> CAN_LengthToDLC(size_t dataLength, bool fd)
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
const HardwareCANPacket* data = (const HardwareCANPacket*)bytestream.data();
|
||||
const HardwareCANErrorPacket* errPacket = (const HardwareCANErrorPacket*)bytestream.data();
|
||||
if(errPacket->ERROR_INDICATOR) {
|
||||
auto msg = std::make_shared<CANErrorMessage>();
|
||||
msg->receiveErrorCount = errPacket->REC;
|
||||
msg->transmitErrorCount = errPacket->TEC;
|
||||
msg->errorWarn = HardwareCANErrorPacket::GetErrorWarn(errPacket->flags);
|
||||
msg->errorPassive = HardwareCANErrorPacket::GetErrorPassive(errPacket->flags);
|
||||
msg->busOff = HardwareCANErrorPacket::GetBusOff(errPacket->flags);
|
||||
msg->errorCode = (CANErrorCode)errPacket->error_code;
|
||||
msg->dataErrorCode = (CANErrorCode)errPacket->brs_data_error_code;
|
||||
|
||||
if(data->dlc.RB1) { // Change counts reporting
|
||||
|
||||
const bool busOff = data->data[0] & 0b00100000;
|
||||
|
||||
auto msg = std::make_shared<CANErrorCountMessage>(data->data[2], data->data[1], busOff);
|
||||
|
||||
// This timestamp is raw off the device (in timestampResolution increments)
|
||||
// Decoder will fix as it has information about the timestampResolution increments
|
||||
msg->timestamp = data->timestamp.TS;
|
||||
|
||||
@@ -31,7 +31,7 @@ std::shared_ptr<ComponentVersionsMessage> ComponentVersionPacket::DecodeToMessag
|
||||
// Get a reference to the payload to fully validate the length
|
||||
const auto& response = *reinterpret_cast<const ComponentVersionsResponse*>(bytes.data());
|
||||
// Expected size is the header, numVersions field, and numVersions ComponentVersion objects.
|
||||
auto expectedSize = sizeof(ExtendedResponseMessage::ResponseHeader) + 2 + (response.numVersions * sizeof(PackedComponentVersion));
|
||||
auto expectedSize = sizeof(ExtendedResponseMessage::ResponseHeader) + 2 + (response.numVersions * sizeof(ComponentVersion));
|
||||
// If the response is malformed (too small), return an empty message.
|
||||
if(bytes.size() < expectedSize) {
|
||||
return msg; // Empty
|
||||
@@ -39,14 +39,7 @@ std::shared_ptr<ComponentVersionsMessage> ComponentVersionPacket::DecodeToMessag
|
||||
// Unpack into the portable class
|
||||
for(unsigned int i = 0; i < response.numVersions; ++i) {
|
||||
const auto& packedVersion = response.versions[i];
|
||||
msg->versions.emplace_back(
|
||||
packedVersion.valid,
|
||||
packedVersion.componentInfo,
|
||||
packedVersion.identifier,
|
||||
packedVersion.dotVersion,
|
||||
packedVersion.commitHash,
|
||||
packedVersion.expansionSlot
|
||||
);
|
||||
msg->versions.emplace_back(packedVersion.valid, packedVersion.componentInfo, packedVersion.identifier, packedVersion.dotVersion, packedVersion.commitHash);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
||||
if(packet->Length < 4)
|
||||
return nullptr;
|
||||
|
||||
const size_t fcsSize = packet->header.FCS_AVAIL ? 4 : 0;
|
||||
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + packet->Length;
|
||||
const size_t ethernetFrameSize = packet->Length - (sizeof(uint16_t) * 2);
|
||||
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + ethernetFrameSize;
|
||||
const size_t bytestreamActualSize = bytestream.size();
|
||||
if(bytestreamActualSize < bytestreamExpectedSize)
|
||||
return nullptr;
|
||||
@@ -37,6 +37,8 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
||||
if(message.preemptionEnabled)
|
||||
message.preemptionFlags = (uint8_t)((rawWords[0] & 0x03F8) >> 4);
|
||||
|
||||
message.fcsAvailable = packet->header.FCS_AVAIL;
|
||||
|
||||
message.frameTooShort = packet->header.RUNT_FRAME;
|
||||
if(message.frameTooShort)
|
||||
message.error = true;
|
||||
@@ -45,14 +47,11 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
||||
// Decoder will fix as it has information about the timestampResolution increments
|
||||
message.timestamp = packet->timestamp.TS;
|
||||
|
||||
const std::vector<uint8_t>::const_iterator databegin = bytestream.begin() + sizeof(HardwareEthernetPacket);
|
||||
const std::vector<uint8_t>::const_iterator dataend = databegin + packet->Length - fcsSize;
|
||||
message.data.insert(message.data.begin(), databegin, dataend);
|
||||
// Network ID is also not set, this will be fixed in the Decoder as well
|
||||
|
||||
if(fcsSize) {
|
||||
uint32_t& fcs = message.fcs.emplace();
|
||||
std::copy(dataend, dataend + fcsSize, (uint8_t*)&fcs);
|
||||
}
|
||||
const std::vector<uint8_t>::const_iterator databegin = bytestream.begin() + (sizeof(HardwareEthernetPacket) - (sizeof(uint16_t) * 2));
|
||||
const std::vector<uint8_t>::const_iterator dataend = databegin + ethernetFrameSize;
|
||||
message.data.insert(message.data.begin(), databegin, dataend);
|
||||
|
||||
return messagePtr;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ std::shared_ptr<Message> HardwareLINPacket::DecodeToMessage(const std::vector<ui
|
||||
auto isChecksumInvalid = [&]() -> bool {
|
||||
/* messages with no data have no checksum (e.g. header only) */
|
||||
if(!msg->data.size())
|
||||
return false;
|
||||
return true;
|
||||
|
||||
uint8_t checkSum = (8 > numDataBytes) ? *(dataStart + numDataBytes) : packet->CoreMiniBitsLIN.LINByte9;
|
||||
LINMessage::calcChecksum(*msg);
|
||||
|
||||
@@ -99,33 +99,6 @@ bool HardwareLiveDataPacket::EncodeFromMessage(LiveDataMessage& message, std::ve
|
||||
clearMsg->cmd = static_cast<uint32_t>(message.cmd);
|
||||
break;
|
||||
}
|
||||
case LiveDataCommand::SET_VALUE: {
|
||||
auto setValMsg = reinterpret_cast<LiveDataSetValueMessage*>(&message);
|
||||
const auto numArgs = setValMsg->args.size();
|
||||
if(numArgs) {
|
||||
payloadSize = static_cast<uint16_t>(sizeof(LiveDataSetValue) + (sizeof(LiveDataSetValueEntry) * (numArgs-1)));
|
||||
bytestream.resize((payloadSize + sizeof(ExtendedCommandHeader)),0);
|
||||
LiveDataSetValue* out = reinterpret_cast<LiveDataSetValue*>(bytestream.data() + sizeof(ExtendedCommandHeader));
|
||||
out->version = icsneo::LiveDataUtil::LiveDataVersion;
|
||||
out->cmd = static_cast<uint32_t>(setValMsg->cmd);
|
||||
if(!setValMsg->handle)
|
||||
setValMsg->handle = LiveDataUtil::getNewHandle();
|
||||
out->handle = setValMsg->handle;
|
||||
out->numArgs = static_cast<uint32_t>(setValMsg->args.size());
|
||||
for(size_t i = 0; i < numArgs; ++i) {
|
||||
out->values[i].arg.objectType = setValMsg->args[i]->objectType;
|
||||
out->values[i].arg.objectIndex = setValMsg->args[i]->objectIndex;
|
||||
out->values[i].arg.signalIndex = setValMsg->args[i]->signalIndex;
|
||||
out->values[i].arg.valueType = setValMsg->args[i]->valueType;
|
||||
out->values[i].value.value = setValMsg->values[i]->value;
|
||||
out->values[i].value.header.length = sizeof(int64_t);
|
||||
}
|
||||
} else {
|
||||
report(APIEvent::Type::LiveDataInvalidArgument, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
report(APIEvent::Type::LiveDataInvalidCommand, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
||||
+64
-295
@@ -88,10 +88,6 @@ Device::~Device() {
|
||||
disableMessagePolling();
|
||||
if(isOpen())
|
||||
close();
|
||||
if(heartbeatThread.joinable()) {
|
||||
stopHeartbeatThread = true;
|
||||
heartbeatThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Device::getTimestampResolution() const {
|
||||
@@ -134,18 +130,6 @@ std::pair<std::vector<std::shared_ptr<Message>>, bool> Device::getMessages() {
|
||||
return std::make_pair(ret, retBool);
|
||||
}
|
||||
|
||||
std::shared_ptr<DeviceExtension> Device::getExtension(const std::string& name) const {
|
||||
std::shared_ptr<DeviceExtension> ret;
|
||||
std::lock_guard<std::mutex> lk(extensionsLock);
|
||||
for(auto& ext : extensions) {
|
||||
if((ext->getName() == name)) {
|
||||
ret = ext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Device::getMessages(std::vector<std::shared_ptr<Message>>& container, size_t limit, std::chrono::milliseconds timeout) {
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
@@ -192,14 +176,6 @@ void Device::enforcePollingMessageLimit() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Device::refreshComponentVersions() {
|
||||
if(auto compVersions = com->getComponentVersionsSync()) {
|
||||
componentVersions = std::move(*compVersions);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
if(!com) {
|
||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
||||
@@ -219,7 +195,6 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
tryAgain = true;
|
||||
return true;
|
||||
});
|
||||
|
||||
if(!tryAgain) {
|
||||
com->close();
|
||||
report(attemptErr, APIEvent::Severity::Error);
|
||||
@@ -243,7 +218,16 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
if(block) // Extensions say no
|
||||
return false;
|
||||
|
||||
refreshComponentVersions();
|
||||
// Get component versions *after* the extension "onDeviceOpen" hooks (e.g. device reflashes)
|
||||
|
||||
if(supportsComponentVersions()) {
|
||||
if(auto compVersions = com->getComponentVersionsSync())
|
||||
componentVersions = std::move(*compVersions);
|
||||
else
|
||||
// It's possible the device is on older firmware so don't return false here
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::EventWarning);
|
||||
}
|
||||
|
||||
if(!settings->disabled) {
|
||||
// Since we will not fail the open if a settings read fails,
|
||||
// downgrade any errors to warnings. Otherwise the error will
|
||||
@@ -262,12 +246,6 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
handleInternalMessage(message);
|
||||
}));
|
||||
|
||||
// Clear the previous heartbeat thread, in case open() was called on this instance more than once
|
||||
if(heartbeatThread.joinable())
|
||||
heartbeatThread.join();
|
||||
|
||||
stopHeartbeatThread = false;
|
||||
|
||||
heartbeatThread = std::thread([this]() {
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
|
||||
@@ -293,12 +271,12 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
}
|
||||
|
||||
while(!stopHeartbeatThread) {
|
||||
std::unique_lock<std::mutex> recvLk(receivedMessageMutex);
|
||||
// Wait for 110ms for a possible heartbeat
|
||||
if(heartbeatCV.wait_for(recvLk, std::chrono::milliseconds(110), [&]() { return receivedMessage; })) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(110));
|
||||
std::unique_lock<std::mutex> recvLk(receivedMessageMutex);
|
||||
if(receivedMessage) {
|
||||
receivedMessage = false;
|
||||
} else if(!stopHeartbeatThread) { // Add this condition here in case the thread was stopped while waiting for the last message
|
||||
|
||||
} else {
|
||||
// Some communication, such as the bootloader and extractor interfaces, must
|
||||
// redirect the input stream from the device as it will no longer be in the
|
||||
// packet format we expect here. As a result, status updates will not reach
|
||||
@@ -307,8 +285,9 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
// otherwise quiet stream. This lock makes sure suppressDisconnects() will
|
||||
// block until we've either gotten our status update or disconnected from
|
||||
// the device.
|
||||
std::unique_lock<std::mutex> lk(heartbeatMutex);
|
||||
if(heartbeatSuppressed()) continue;
|
||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
||||
if(heartbeatSuppressed())
|
||||
continue;
|
||||
|
||||
// No heartbeat received, request a status
|
||||
com->sendCommand(Command::RequestStatusUpdate);
|
||||
@@ -318,8 +297,8 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
receivedMessage = false;
|
||||
} else {
|
||||
if(!stopHeartbeatThread && !isDisconnected()) {
|
||||
close();
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
com->driver->close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -345,7 +324,7 @@ APIEvent::Type Device::attemptToBeginCommunication() {
|
||||
return getCommunicationNotEstablishedError();
|
||||
}
|
||||
|
||||
if(!enableNetworkCommunication(false))
|
||||
if(!com->sendCommand(Command::EnableNetworkCommunication, false))
|
||||
return getCommunicationNotEstablishedError();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
@@ -356,7 +335,6 @@ APIEvent::Type Device::attemptToBeginCommunication() {
|
||||
if(i++ > 5)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!serial) // "Communication could not be established with the device. Perhaps it is not powered with 12 volts?"
|
||||
return getCommunicationNotEstablishedError();
|
||||
|
||||
@@ -370,14 +348,6 @@ APIEvent::Type Device::attemptToBeginCommunication() {
|
||||
else
|
||||
versions = std::move(*maybeVersions);
|
||||
|
||||
// Get component versions before the extension "onDeviceOpen" hooks so that we can properly check verisons
|
||||
if(supportsComponentVersions()) {
|
||||
if(auto compVersions = com->getComponentVersionsSync())
|
||||
componentVersions = std::move(*compVersions);
|
||||
else
|
||||
report(APIEvent::Type::NotSupported, APIEvent::Severity::EventWarning); // outdated firmware
|
||||
}
|
||||
|
||||
return APIEvent::Type::NoErrorFound;
|
||||
}
|
||||
|
||||
@@ -401,20 +371,16 @@ bool Device::close() {
|
||||
|
||||
internalHandlerCallbackID = 0;
|
||||
|
||||
if(heartbeatThread.joinable())
|
||||
heartbeatThread.join();
|
||||
stopHeartbeatThread = false;
|
||||
|
||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onDeviceClose(); return true; });
|
||||
return com->close();
|
||||
}
|
||||
|
||||
bool Device::enableLogData() {
|
||||
return com->sendCommand(Command::EnableLogData, true);
|
||||
}
|
||||
|
||||
bool Device::disableLogData() {
|
||||
return com->sendCommand(Command::EnableLogData, false);
|
||||
}
|
||||
|
||||
bool Device::goOnline() {
|
||||
if(!enableNetworkCommunication(true))
|
||||
if(!com->sendCommand(Command::EnableNetworkCommunication, true))
|
||||
return false;
|
||||
|
||||
auto startTime = std::chrono::system_clock::now();
|
||||
@@ -457,13 +423,29 @@ bool Device::goOffline() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!enableNetworkCommunication(false))
|
||||
if(!com->sendCommand(Command::EnableNetworkCommunication, false))
|
||||
return false;
|
||||
|
||||
auto startTime = std::chrono::system_clock::now();
|
||||
|
||||
ledState = (latestResetStatus && latestResetStatus->cmRunning) ? LEDState::CoreMiniRunning : LEDState::Offline;
|
||||
|
||||
updateLEDState();
|
||||
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Reset_Status);
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
// Wait until communication is disabled or 5 seconds, whichever comes first
|
||||
while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) {
|
||||
if(latestResetStatus && !latestResetStatus->comEnabled)
|
||||
break;
|
||||
|
||||
if(!com->sendCommand(Command::RequestStatusUpdate))
|
||||
return false;
|
||||
|
||||
com->waitForMessageSync(filter, std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
online = false;
|
||||
|
||||
return true;
|
||||
@@ -674,85 +656,6 @@ bool Device::clearScript(Disk::MemoryType memType)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<CoreminiHeader> Device::readCoreminiHeader(Disk::MemoryType memType) {
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto startAddress = getCoreminiStartAddress(memType);
|
||||
if(!startAddress) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto connected = isLogicalDiskConnected();
|
||||
|
||||
if(!connected) {
|
||||
return std::nullopt; // Already added an API error
|
||||
}
|
||||
|
||||
#pragma pack(push, 2)
|
||||
struct RawCoreminiHeader {
|
||||
uint16_t fileType;
|
||||
uint16_t fileVersion;
|
||||
uint32_t storedFileSize;
|
||||
uint32_t fileChecksum;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t skipDecompression : 1;
|
||||
uint32_t encryptedMode : 1;
|
||||
uint32_t reserved : 30;
|
||||
} bits;
|
||||
uint32_t word;
|
||||
} flags;
|
||||
uint8_t fileHash[32];
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t lsb;
|
||||
uint32_t msb;
|
||||
} words;
|
||||
uint64_t time64;
|
||||
} createTime;
|
||||
uint8_t reserved[8];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
RawCoreminiHeader header = {};
|
||||
auto numRead = readLogicalDisk(*startAddress, (uint8_t*)&header, sizeof(header), std::chrono::milliseconds(2000), memType);
|
||||
|
||||
if(!numRead) {
|
||||
return std::nullopt; // Already added an API error
|
||||
}
|
||||
|
||||
if(*numRead != sizeof(header)) {
|
||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(header.fileType != 0x0907) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<CoreminiHeader> ret;
|
||||
ret.emplace();
|
||||
ret->coreminiVersion = header.fileVersion;
|
||||
ret->storedFileSize = header.storedFileSize;
|
||||
ret->fileChecksum = header.fileChecksum;
|
||||
ret->skipDecompression = static_cast<bool>(header.flags.bits.skipDecompression);
|
||||
ret->encryptedMode = static_cast<bool>(header.flags.bits.encryptedMode);
|
||||
std::copy(std::begin(header.fileHash), std::end(header.fileHash), ret->fileHash.begin());
|
||||
static constexpr std::chrono::seconds icsEpochDelta(1167609600);
|
||||
static constexpr uint8_t timestampResolution = 25;
|
||||
static constexpr uint16_t nsInUs = 1'000;
|
||||
ret->timestamp += icsEpochDelta + std::chrono::microseconds(header.createTime.time64 * timestampResolution / nsInUs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Device::transmit(std::shared_ptr<Frame> frame) {
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
@@ -824,6 +727,12 @@ std::shared_ptr<HardwareInfo> Device::getHardwareInfo(std::chrono::milliseconds
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!isOnline()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto filter = std::make_shared<MessageFilter>(Message::Type::HardwareInfo);
|
||||
|
||||
auto response = com->waitForMessageSync([this]() {
|
||||
@@ -1703,10 +1612,7 @@ void Device::stopScriptStatusThreadIfNecessary(std::unique_lock<std::mutex> lk)
|
||||
Lifetime Device::suppressDisconnects() {
|
||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
||||
heartbeatSuppressedByUser++;
|
||||
return Lifetime([this] {
|
||||
std::lock_guard<std::mutex> lk2(heartbeatMutex);
|
||||
heartbeatSuppressedByUser--;
|
||||
});
|
||||
return Lifetime([this] { std::lock_guard<std::mutex> lk2(heartbeatMutex); heartbeatSuppressedByUser--; });
|
||||
}
|
||||
|
||||
void Device::addExtension(std::shared_ptr<DeviceExtension>&& extension) {
|
||||
@@ -1736,6 +1642,15 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
||||
case Message::Type::RawMessage: {
|
||||
auto rawMessage = std::static_pointer_cast<RawMessage>(message);
|
||||
switch(rawMessage->network.getNetID()) {
|
||||
case Network::NetID::Device: {
|
||||
// Device is not guaranteed to be a CANMessage, it might be a RawMessage
|
||||
// if it couldn't be decoded to a CANMessage. We only care about the
|
||||
// CANMessage decoding right now.
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(canmsg)
|
||||
handleNeoVIMessage(std::move(canmsg));
|
||||
break;
|
||||
}
|
||||
case Network::NetID::DeviceStatus:
|
||||
// Device Status format is unique per device, so the devices need to decode it themselves
|
||||
handleDeviceStatus(rawMessage);
|
||||
@@ -1745,15 +1660,6 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Message::Type::Frame: {
|
||||
// Device is not guaranteed to be a CANMessage, it might be a RawMessage
|
||||
// if it couldn't be decoded to a CANMessage. We only care about the
|
||||
// CANMessage decoding right now.
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(canmsg)
|
||||
handleNeoVIMessage(std::move(canmsg));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
forEachExtension([&](const std::shared_ptr<DeviceExtension>& ext) {
|
||||
@@ -1966,7 +1872,7 @@ bool Device::setRTC(const std::chrono::time_point<std::chrono::system_clock>& ti
|
||||
}
|
||||
|
||||
auto m51msg = std::dynamic_pointer_cast<Main51Message>(generic);
|
||||
if(!m51msg || m51msg->data.empty() || m51msg->data.size() > 2) {
|
||||
if(!m51msg || m51msg->data.size() != 1) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
@@ -1999,6 +1905,11 @@ std::optional<size_t> Device::getGenericBinarySize(uint16_t binaryIndex) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(!isOnline()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> args = GenericBinaryStatusPacket::EncodeArguments(binaryIndex);
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
@@ -2061,40 +1972,6 @@ bool Device::readBinaryFile(std::ostream& stream, uint16_t binaryIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::writeBinaryFile(const std::vector<uint8_t>& in, uint16_t binaryIndex)
|
||||
{
|
||||
auto timeout = std::chrono::milliseconds(100);
|
||||
|
||||
auto size = in.size();
|
||||
|
||||
std::vector<uint8_t> arguments(sizeof(ExtendedDataMessage::ExtendedDataHeader) + ExtendedDataMessage::MaxExtendedDataBufferSize);
|
||||
ExtendedDataMessage::ExtendedDataHeader& parameters = *reinterpret_cast<ExtendedDataMessage::ExtendedDataHeader*>(arguments.data());
|
||||
|
||||
auto filter = std::make_shared<MessageFilter>(Network::NetID::ExtendedData);
|
||||
|
||||
for (size_t offset = 0; offset < size; offset += ExtendedDataMessage::MaxExtendedDataBufferSize)
|
||||
{
|
||||
parameters.subCommand = ExtendedDataSubCommand::GenericBinaryWrite;
|
||||
parameters.userValue = static_cast<uint32_t>(binaryIndex);
|
||||
parameters.offset = static_cast<uint32_t>(offset);
|
||||
parameters.length = static_cast<uint32_t>(std::min(ExtendedDataMessage::MaxExtendedDataBufferSize, size - offset));
|
||||
(void)memcpy(&arguments[sizeof(ExtendedDataMessage::ExtendedDataHeader)], &in[offset], parameters.length);
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this, arguments]() {
|
||||
return com->sendCommand(Command::ExtendedData, arguments);
|
||||
},
|
||||
filter,
|
||||
timeout
|
||||
);
|
||||
if (!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::subscribeLiveData(std::shared_ptr<LiveDataCommandMessage> message) {
|
||||
if(!supportsLiveData()) {
|
||||
report(APIEvent::Type::LiveDataNotSupported, APIEvent::Severity::Error);
|
||||
@@ -2235,66 +2112,11 @@ bool Device::clearAllLiveData() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::setValueLiveData(std::shared_ptr<LiveDataSetValueMessage> message) {
|
||||
if(!supportsLiveData()) {
|
||||
report(APIEvent::Type::LiveDataNotSupported, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if((message->args.size() != message->values.size()) || message->args.empty()) {
|
||||
report(APIEvent::Type::LiveDataInvalidArgument, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytes;
|
||||
if(!com->encoder->encode(*com->packetizer, bytes, message)) {
|
||||
report(APIEvent::Type::LiveDataEncoderError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this, &bytes](){ return com->sendPacket(bytes); },
|
||||
std::make_shared<MessageFilter>(Message::Type::LiveData));
|
||||
|
||||
if(response) {
|
||||
auto statusMsg = std::dynamic_pointer_cast<LiveDataStatusMessage>(response);
|
||||
if(statusMsg && statusMsg->requestedCommand == message->cmd) {
|
||||
switch(statusMsg->status) {
|
||||
case LiveDataStatus::SUCCESS:
|
||||
return true;
|
||||
case LiveDataStatus::ERR_DUPLICATE:
|
||||
case LiveDataStatus::ERR_HANDLE:
|
||||
{
|
||||
report(APIEvent::Type::LiveDataInvalidHandle, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
case LiveDataStatus::ERR_FULL:
|
||||
{
|
||||
report(APIEvent::Type::LiveDataMaxSignalsReached, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
case LiveDataStatus::ERR_UNKNOWN_COMMAND:
|
||||
{
|
||||
report(APIEvent::Type::LiveDataCommandFailed, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
report(APIEvent::Type::LiveDataNoDeviceResponse, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Device::readVSA(const VSAExtractionSettings& extractionSettings) {
|
||||
if(isOnline()) {
|
||||
goOffline();
|
||||
}
|
||||
auto innerReadVSA = [&](uint64_t diskSize) -> bool {
|
||||
auto innerReadVSA = [&](uint64_t diskSize) -> const bool {
|
||||
// Adjust driver to offset to start of VSA file
|
||||
const auto& offset = getVSAOffsetInLogicalDisk();
|
||||
if(!offset) {
|
||||
@@ -3434,56 +3256,3 @@ std::optional<TC10StatusMessage> Device::getTC10Status(Network::NetID network) {
|
||||
|
||||
return *typed;
|
||||
}
|
||||
|
||||
std::optional<GPTPStatus> Device::getGPTPStatus(std::chrono::milliseconds timeout) {
|
||||
if(!supportsGPTP()) {
|
||||
report(APIEvent::Type::GPTPNotSupported, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this](){
|
||||
return com->sendCommand(ExtendedCommand::GetGPTPStatus, {});
|
||||
},
|
||||
std::make_shared<MessageFilter>(Message::Type::GPTPStatus),
|
||||
timeout
|
||||
);
|
||||
|
||||
if(!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
auto retMsg = std::static_pointer_cast<GPTPStatus>(response);
|
||||
if(!retMsg) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return *retMsg;
|
||||
}
|
||||
|
||||
bool Device::writeMACsecConfig(const MACsecMessage& message, uint16_t binaryIndex)
|
||||
{
|
||||
std::vector<uint8_t> raw;
|
||||
|
||||
message.EncodeFromMessage(raw, report);
|
||||
|
||||
return writeBinaryFile(raw, binaryIndex);
|
||||
}
|
||||
|
||||
bool Device::enableNetworkCommunication(bool enable) {
|
||||
bool sendMsg = false;
|
||||
if(!com->driver->enableCommunication(enable, sendMsg)) {
|
||||
return false;
|
||||
}
|
||||
if(sendMsg) {
|
||||
if(!com->sendCommand(Command::EnableNetworkCommunication, enable)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "icsneo/platform/devices.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include "generated/extensions/builtin.h"
|
||||
#include "icsneo/platform/servd.h"
|
||||
|
||||
#ifdef ICSNEO_ENABLE_FIRMIO
|
||||
#include "icsneo/platform/firmio.h"
|
||||
@@ -64,9 +63,6 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
static std::vector<FoundDevice> newDriverFoundDevices;
|
||||
newDriverFoundDevices.clear();
|
||||
|
||||
if(Servd::Enabled()) {
|
||||
Servd::Find(newDriverFoundDevices);
|
||||
} else {
|
||||
#ifdef ICSNEO_ENABLE_FIRMIO
|
||||
FirmIO::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
@@ -90,7 +86,6 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
#ifdef ICSNEO_ENABLE_FTD3XX
|
||||
FTD3XX::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Weak because we don't want to keep devices open if they go out of scope elsewhere
|
||||
static std::vector<std::weak_ptr<Device>> foundDevices;
|
||||
@@ -190,26 +185,14 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
makeIfSerialMatches<RADComet3>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONT1S_H_
|
||||
makeIfSerialMatches<RADMoonT1S>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILON_H_
|
||||
makeIfSerialMatches<RADEpsilon>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILONXL_H_
|
||||
makeIfSerialMatches<RADEpsilonXL>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY_H_
|
||||
makeIfSerialMatches<RADGalaxy>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY2_H_
|
||||
makeIfSerialMatches<RADGalaxy2>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_H_
|
||||
makeIfSerialMatches<RADMars>(dev, newFoundDevices);
|
||||
#endif
|
||||
@@ -218,10 +201,6 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
makeIfSerialMatches<RADGigastar>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR2_H_
|
||||
makeIfSerialMatches<RADGigastar2>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADJUPITER_H_
|
||||
makeIfSerialMatches<RADJupiter>(dev, newFoundDevices);
|
||||
#endif
|
||||
@@ -353,26 +332,14 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
RADComet3::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONT1S_H_
|
||||
RADMoonT1S::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILON_H_
|
||||
RADEpsilon::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILONXL_H_
|
||||
RADEpsilonXL::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY_H_
|
||||
RADGalaxy::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY2_H_
|
||||
RADGalaxy2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_H_
|
||||
RADMars::DEVICE_TYPE,
|
||||
#endif
|
||||
@@ -381,10 +348,6 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
RADGigastar::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR2_H_
|
||||
RADGigastar2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#if defined __RADMOON2_H_ || defined __RADMOON2ZL_H_
|
||||
RADMoon2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
||||
#include "icsneo/communication/message/flashmemorymessage.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
@@ -9,8 +8,7 @@ using namespace icsneo::Disk;
|
||||
|
||||
std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t report,
|
||||
uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) {
|
||||
const auto filter = std::make_shared<MessageFilter>((memType == MemoryType::SD ? Network::NetID::NeoMemorySDRead : Network::NetID::RED_INT_MEMORYREAD));
|
||||
filter->includeInternalInAny = true;
|
||||
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead);
|
||||
|
||||
if(pos % SectorSize != 0)
|
||||
return std::nullopt;
|
||||
@@ -35,26 +33,18 @@ std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio
|
||||
uint8_t((numWords >> 16) & 0xFF),
|
||||
uint8_t((numWords >> 24) & 0xFF)
|
||||
});
|
||||
}, filter, timeout);
|
||||
}, NeoMemorySDRead, timeout);
|
||||
|
||||
if(!msg)
|
||||
return 0;
|
||||
|
||||
if(memType == MemoryType::SD) {
|
||||
const auto mem = std::dynamic_pointer_cast<NeoReadMemorySDMessage>(msg);
|
||||
if(!mem || mem->data.size() != SectorSize) {
|
||||
const auto sdmsg = std::dynamic_pointer_cast<NeoReadMemorySDMessage>(msg);
|
||||
if(!sdmsg || sdmsg->data.size() != SectorSize) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
memcpy(into, mem->data.data(), SectorSize);
|
||||
} else { // flash
|
||||
const auto mem = std::dynamic_pointer_cast<FlashMemoryMessage>(msg);
|
||||
if(!mem || mem->data.size() != SectorSize) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
memcpy(into, mem->data.data(), SectorSize);
|
||||
}
|
||||
|
||||
memcpy(into, sdmsg->data.data(), SectorSize);
|
||||
return SectorSize;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,64 @@
|
||||
===============
|
||||
****************
|
||||
**API Usage**
|
||||
****************
|
||||
|
||||
API Concepts
|
||||
================
|
||||
|
||||
Overview
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Events convey information about the API's inner workings to the user. There are 3 severity levels: ``EventInfo``, ``EventWarning``, and ``Error``.
|
||||
**However, the API treats events of severities** ``EventInfo`` **and** ``EventWarning`` **differently than those of severity** ``Error`` **.**
|
||||
From here on out, when we (and the API functions) refer to "events", we refer exclusively to those of severities ``EventInfo`` and ``EventWarning``, which use the events_ system.
|
||||
Those of severity ``Error`` are referred to as "errors", which use a separate errors_ system.
|
||||
|
||||
Events should periodically be read out in order to avoid overflowing, and the last error should be read out immediately after an API function fails.
|
||||
|
||||
Additionally, `event callbacks`_ can be registered, which may remove the need to periodically read events in some cases.
|
||||
|
||||
.. _events:
|
||||
|
||||
Events
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The API stores events in a single buffer that can has a default size of 10,000 events.
|
||||
This limit includes 1 reserved slot at the end of the buffer for a potential Event of type ``TooManyEvents`` and severity ``EventWarning``, which is added when there are too many events for the buffer to hold.
|
||||
This could occur if the events aren't read out by the user often enough, or if the user sets the size of the buffer to a value smaller than the number of existing events.
|
||||
There will only ever be one of these ``TooManyEvents`` events, and it will always be located at the very end of the buffer if it exists.
|
||||
Because of this reserved slot, the buffer by default is able to hold 9,999 events. If capacity is exceeded, the oldest events in the buffer are automatically discarded until the buffer is exactly at capacity again.
|
||||
When events are read out by the user, they are removed from the buffer. If an event filter is used, only the filtered events will be removed from the buffer.
|
||||
|
||||
In a multithreaded environment, all threads will log their events to the same buffer. In this case, the order of events will largely be meaningless, although the behavior of ``TooManyEvents`` is still guaranteed to be as described above.
|
||||
|
||||
.. _event callbacks:
|
||||
|
||||
Event Callbacks
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Users may register event callbacks, which are automatically called whenever a matching event is logged.
|
||||
Message callbacks consist of a user-defined ``std::function< void( std::shared_ptr<APIEvent> ) >`` and optional EventFilter used for matching.
|
||||
If no EventFilter is provided, the default-constructed one will be used, which matches any event.
|
||||
Registering a callback returns an ``int`` representing the id of the callback, which should be stored by the user and later used to remove the callback when desired.
|
||||
Note that this functionality is only available in C and C++. C does not currently support filters.
|
||||
|
||||
Event callbacks are run after the event has been added to the buffer of events. The buffer of events may be safely modified within the callback, such as getting (flushing) the type and severity of the triggering event.
|
||||
Using event callbacks in this manner means that periodically reading events is unnecessary.
|
||||
|
||||
.. _errors:
|
||||
|
||||
Errors
|
||||
~~~~~~~~~
|
||||
|
||||
The error system is threadsafe and separate from the events_ system.
|
||||
Each thread keeps track of the last error logged on it, and getting the last error will return the last error from the calling thread, removing it in the process.
|
||||
Trying to get the last error when there is none will return an event of type ``NoErrorFound`` and severity ``EventInfo``.
|
||||
|
||||
The API also contains some threads for internal use which may potentially log errors of their own and are inaccessible to the user.
|
||||
These threads have been marked to downgrade any errors that occur on them to severity ``EventWarning`` and will log the corresponding event in the events_ system described above.
|
||||
|
||||
Device Concepts
|
||||
===============
|
||||
================
|
||||
|
||||
Open/Close Status
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
+171
-19
@@ -1,36 +1,188 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
# NOTE: The conf.py file is automatically updated by CMake when there are
|
||||
# changes to the version. Update the conf.py.template and then build to
|
||||
# propagate changes here. This file should be committed so that
|
||||
# ReadTheDocs can use it.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import subprocess
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
subprocess.call('cd ..; doxygen docs/icsneocpp/Doxyfile', shell=True)
|
||||
subprocess.call('cd ..; doxygen docs/icsneoc/Doxyfile', shell=True)
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['sphinx.ext.imgmath', 'sphinx.ext.todo', 'breathe' ]
|
||||
|
||||
breathe_projects = { "libicsneo": "build/doxygen/xml" }
|
||||
breathe_default_project = "libicsneo"
|
||||
|
||||
try:
|
||||
os.makedirs('build/sphinx')
|
||||
except FileExistsError:
|
||||
pass
|
||||
try:
|
||||
os.makedirs('build/doxygen')
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
subprocess.call('cd ..; doxygen docs/Doxyfile', shell=True)
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'libicsneo'
|
||||
copyright = '2024-2025, Intrepid Control Systems, Inc.'
|
||||
copyright = '2018-2024, Intrepid Control Systems, Inc.'
|
||||
author = 'Intrepid Control Systems, Inc.'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.2.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.2.0 '
|
||||
|
||||
extensions = ['breathe', 'sphinx.ext.autodoc']
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
templates_path = ['_templates']
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
breathe_projects = {
|
||||
'icsneocpp': 'icsneocpp/doxygen/xml',
|
||||
'icsneoc': 'icsneoc/doxygen/xml',
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
html_theme_options = {
|
||||
|
||||
}
|
||||
|
||||
breathe_default_project = 'icsneocpp'
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# This is required for the alabaster theme
|
||||
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'relations.html', # needs 'show_related': True theme option to display
|
||||
'searchbox.html',
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'libicsneodoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'libicsneo.tex', 'libicsneo Documentation',
|
||||
'Intrepid Control Systems, Inc.', 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'libicsneo', 'libicsneo Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'libicsneo', 'libicsneo Documentation',
|
||||
author, 'libicsneo', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# NOTE: The conf.py file is automatically updated by CMake when there are
|
||||
# changes to the version. Update the conf.py.template and then build to
|
||||
# propagate changes here. This file should be committed so that
|
||||
# ReadTheDocs can use it.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import subprocess
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['sphinx.ext.imgmath', 'sphinx.ext.todo', 'breathe' ]
|
||||
|
||||
breathe_projects = { "libicsneo": "build/doxygen/xml" }
|
||||
breathe_default_project = "libicsneo"
|
||||
|
||||
try:
|
||||
os.makedirs('build/sphinx')
|
||||
except FileExistsError:
|
||||
pass
|
||||
try:
|
||||
os.makedirs('build/doxygen')
|
||||
except FileExistsError:
|
||||
pass
|
||||
|
||||
subprocess.call('cd ..; doxygen docs/Doxyfile', shell=True)
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'libicsneo'
|
||||
copyright = '2018-2024, Intrepid Control Systems, Inc.'
|
||||
author = 'Intrepid Control Systems, Inc.'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@ @BUILD_METADATA@'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
html_theme_options = {
|
||||
|
||||
}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# This is required for the alabaster theme
|
||||
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'relations.html', # needs 'show_related': True theme option to display
|
||||
'searchbox.html',
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'libicsneodoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'libicsneo.tex', 'libicsneo Documentation',
|
||||
'Intrepid Control Systems, Inc.', 'manual'),
|
||||
]
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'libicsneo', 'libicsneo Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'libicsneo', 'libicsneo Documentation',
|
||||
author, 'libicsneo', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
********************
|
||||
**C API** (icsneoc)
|
||||
********************
|
||||
|
||||
.. Usage
|
||||
.. ======
|
||||
|
||||
.. Finding Devices
|
||||
.. ~~~~~~~~~~~~~~~~
|
||||
.. Finding a device is simple
|
||||
|
||||
.. Connecting to Devices
|
||||
.. ~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Reference
|
||||
==========
|
||||
|
||||
Typedefs
|
||||
~~~~~~~~~
|
||||
.. doxygentypedef:: devicehandle_t
|
||||
.. doxygentypedef:: neodevice_handle_t
|
||||
.. doxygentypedef:: devicetype_t
|
||||
|
||||
Structures
|
||||
~~~~~~~~~~~
|
||||
.. doxygenstruct:: neoversion_t
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. doxygenstruct:: neodevice_t
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. doxygenstruct:: neomessage_t
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. doxygenstruct:: neomessage_can_t
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Functions
|
||||
~~~~~~~~~~
|
||||
.. doxygenfile:: icsneoc.h
|
||||
@@ -1,14 +0,0 @@
|
||||
=====
|
||||
C API
|
||||
=====
|
||||
|
||||
.. doxygenfile:: icsneoc.h
|
||||
:project: icsneoc
|
||||
.. doxygenfile:: device/neodevice.h
|
||||
:project: icsneoc
|
||||
.. doxygenfile:: communication/message/neomessage.h
|
||||
:project: icsneoc
|
||||
.. doxygenfile:: api/version.h
|
||||
:project: icsneoc
|
||||
.. doxygenfile:: api/event.h
|
||||
:project: icsneoc
|
||||
@@ -1,43 +0,0 @@
|
||||
==========
|
||||
C Examples
|
||||
==========
|
||||
|
||||
A variety of examples can be found within ``examples/c``, see below for an
|
||||
example that uses the polling API to receive CAN frames.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
size_t deviceCount = 10; // Pre-set to the size of your buffer before the icsneo_findAllDevices() call
|
||||
neodevice_t devices[10];
|
||||
icsneo_findAllDevices(devices, &deviceCount);
|
||||
printf("We found %ull devices\n", deviceCount);
|
||||
for(size_t i = 0; i < deviceCount; i++) {
|
||||
neodevice_t* myDevice = &devices[i];
|
||||
char desc[ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION];
|
||||
size_t sz = ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION;
|
||||
icsneo_describeDevice(myDevice, desc, &sz);
|
||||
printf("Found %s\n", desc); // "Found neoVI FIRE 2 CY2345"
|
||||
}
|
||||
neodevice_t* myDevice = &devices[0];
|
||||
if(!icsneo_openDevice(myDevice)) {
|
||||
neoevent_t error;
|
||||
if(icsneo_getLastError(&error))
|
||||
printf("Error! %s\n", error.description);
|
||||
}
|
||||
icsneo_goOnline(myDevice); // Start receiving messages
|
||||
icsneo_enableMessagePolling(myDevice); // Allow the use of icsneo_getMessages() later
|
||||
sleep(5);
|
||||
neomessage_t messages[50];
|
||||
size_t messageCount = 50;
|
||||
icsneo_getMessages(myDevice, messages, &messageCount, 0 /* non-blocking */);
|
||||
printf("We got %ull messages!\n", messageCount);
|
||||
for(size_t i = 0; i < messageCount; i++) {
|
||||
if(messages[i].type == ICSNEO_NETWORK_TYPE_CAN) {
|
||||
// A message of type CAN should be interperated a neomessage_can_t, so we can cast safely
|
||||
neomessage_can_t* canmsg = (neomessage_can_t*)&messages[i];
|
||||
// canmsg->arbid is valid here
|
||||
// canmsg->data is an uint8_t*, you can check canmsg->length for the length of the payload
|
||||
// canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT)
|
||||
}
|
||||
}
|
||||
icsneo_closeDevice(myDevice);
|
||||
@@ -1,9 +0,0 @@
|
||||
icsneoc
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
installation
|
||||
examples
|
||||
api
|
||||
@@ -1,7 +0,0 @@
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
The installation steps for the C API are the same as the C++ API as the C API is
|
||||
a wrapper for the C++ library. The ``LIBICSNEO_BUILD_ICSNEOC`` CMake option is
|
||||
default ``ON`` but note that the C API depends on this flag to build.
|
||||
@@ -0,0 +1,31 @@
|
||||
************************
|
||||
**C++ API** (icsneocpp)
|
||||
************************
|
||||
|
||||
.. Usage
|
||||
.. ======
|
||||
|
||||
.. Finding Devices
|
||||
.. ~~~~~~~~~~~~~~~~
|
||||
.. Finding a device is simple
|
||||
|
||||
.. Connecting to Devices
|
||||
.. ~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Reference
|
||||
==========
|
||||
|
||||
.. Classes
|
||||
.. ~~~~~~~~
|
||||
|
||||
.. Structures
|
||||
.. ~~~~~~~~~~~
|
||||
|
||||
.. Functions
|
||||
.. ~~~~~~~~~~
|
||||
|
||||
.. doxygennamespace:: icsneo
|
||||
|
||||
.. doxygenclass:: icsneo::Device
|
||||
:members:
|
||||
:undoc-members:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
||||
=======
|
||||
C++ API
|
||||
=======
|
||||
|
||||
.. doxygennamespace:: icsneo
|
||||
:members:
|
||||
:undoc-members:
|
||||
:content-only:
|
||||
@@ -1,55 +0,0 @@
|
||||
============
|
||||
API Concepts
|
||||
============
|
||||
|
||||
Overview
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Events convey information about the API's inner workings to the user. There are 3 severity levels: ``EventInfo``, ``EventWarning``, and ``Error``.
|
||||
**However, the API treats events of severities** ``EventInfo`` **and** ``EventWarning`` **differently than those of severity** ``Error`` **.**
|
||||
From here on out, when we (and the API functions) refer to "events", we refer exclusively to those of severities ``EventInfo`` and ``EventWarning``, which use the events_ system.
|
||||
Those of severity ``Error`` are referred to as "errors", which use a separate errors_ system.
|
||||
|
||||
Events should periodically be read out in order to avoid overflowing, and the last error should be read out immediately after an API function fails.
|
||||
|
||||
Additionally, `event callbacks`_ can be registered, which may remove the need to periodically read events in some cases.
|
||||
|
||||
.. _events:
|
||||
|
||||
Events
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The API stores events in a single buffer that can has a default size of 10,000 events.
|
||||
This limit includes 1 reserved slot at the end of the buffer for a potential Event of type ``TooManyEvents`` and severity ``EventWarning``, which is added when there are too many events for the buffer to hold.
|
||||
This could occur if the events aren't read out by the user often enough, or if the user sets the size of the buffer to a value smaller than the number of existing events.
|
||||
There will only ever be one of these ``TooManyEvents`` events, and it will always be located at the very end of the buffer if it exists.
|
||||
Because of this reserved slot, the buffer by default is able to hold 9,999 events. If capacity is exceeded, the oldest events in the buffer are automatically discarded until the buffer is exactly at capacity again.
|
||||
When events are read out by the user, they are removed from the buffer. If an event filter is used, only the filtered events will be removed from the buffer.
|
||||
|
||||
In a multithreaded environment, all threads will log their events to the same buffer. In this case, the order of events will largely be meaningless, although the behavior of ``TooManyEvents`` is still guaranteed to be as described above.
|
||||
|
||||
.. _event callbacks:
|
||||
|
||||
Event Callbacks
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Users may register event callbacks, which are automatically called whenever a matching event is logged.
|
||||
Message callbacks consist of a user-defined ``std::function< void( std::shared_ptr<APIEvent> ) >`` and optional EventFilter used for matching.
|
||||
If no EventFilter is provided, the default-constructed one will be used, which matches any event.
|
||||
Registering a callback returns an ``int`` representing the id of the callback, which should be stored by the user and later used to remove the callback when desired.
|
||||
Note that this functionality is only available in C and C++. C does not currently support filters.
|
||||
|
||||
Event callbacks are run after the event has been added to the buffer of events. The buffer of events may be safely modified within the callback, such as getting (flushing) the type and severity of the triggering event.
|
||||
Using event callbacks in this manner means that periodically reading events is unnecessary.
|
||||
|
||||
.. _errors:
|
||||
|
||||
Errors
|
||||
~~~~~~~~~
|
||||
|
||||
The error system is threadsafe and separate from the events_ system.
|
||||
Each thread keeps track of the last error logged on it, and getting the last error will return the last error from the calling thread, removing it in the process.
|
||||
Trying to get the last error when there is none will return an event of type ``NoErrorFound`` and severity ``EventInfo``.
|
||||
|
||||
The API also contains some threads for internal use which may potentially log errors of their own and are inaccessible to the user.
|
||||
These threads have been marked to downgrade any errors that occur on them to severity ``EventWarning`` and will log the corresponding event in the events_ system described above.
|
||||
@@ -1,52 +0,0 @@
|
||||
============
|
||||
C++ Examples
|
||||
============
|
||||
|
||||
A variety of examples can be found within ``examples/cpp``, see below for an
|
||||
example that uses the polling API to receive CAN frames.
|
||||
|
||||
The C++ API is designed to be modern and easy to use. All library functions and
|
||||
classes are in the namespace ``icsneo``. Most applications will start by calling
|
||||
``icsneo::FindAllDevices()``. This will return an ``std::vector`` of
|
||||
``std::shared_ptr<icsneo::Device>`` objects. You will want to keep a copy of the
|
||||
``shared_ptr`` to any devices you want to use, as allowing it to go out of scope
|
||||
will automatically close the device and free all memory associated with it.
|
||||
|
||||
Any time you get bus traffic from the API, you will receive it as an
|
||||
``std::shared_ptr<icsneo::Message>``. The message will be valid as long as the
|
||||
``shared_ptr`` stays in scope. Checking the type of the message allows you to
|
||||
cast it accordingly and access extra data for certain protocols. For instance,
|
||||
casting an ``icsneo::Message`` to an ``icsneo::CANMessage`` allows you to access
|
||||
the arbitration ID.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
std::vector<std::shared_ptr<icsneo::Device>> devices = icsneo::FindAllDevices();
|
||||
std::cout << devices.size() << " found!" << std::endl;
|
||||
for(auto& device : devices)
|
||||
std::cout << "Found " << device->describe() << std::endl; // "Found neoVI FIRE 2 CY2345"
|
||||
std::shared_ptr<icsneo::Device> myDevice = devices[0];
|
||||
if(!myDevice->open()) // Device tried and failed to open, print the last error
|
||||
std::cout << icsneo::GetLastError() << std::endl;
|
||||
myDevice->goOnline(); // Start receiving messages
|
||||
myDevice->enableMessagePolling(); // Allow the use of myDevice->getMessages() later
|
||||
// Alternatively, assign a callback for new messages
|
||||
std::this_thread::wait_for(std::chrono::seconds(5));
|
||||
std::vector<std::shared_ptr<icsneo::Message>> messages = myDevice->getMessages();
|
||||
std::cout << "We got " << messages.size() << " messages!" << std::endl;
|
||||
for(auto& msg : messages) {
|
||||
switch(msg->network.getType()) {
|
||||
case icsneo::Network::Type::CAN:
|
||||
case icsneo::Network::Type::SWCAN:
|
||||
case icsneo::Network::Type::LSFTCAN: {
|
||||
// A message of type CAN is guaranteed to be a CANMessage, so we can static cast safely
|
||||
auto canmsg = std::static_pointer_cast<icsneo::CANMessage>(msg);
|
||||
// canmsg->arbid is valid here
|
||||
// canmsg->data is an std::vector<uint8_t>, you can check .size() for the DLC of the message
|
||||
// canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT)
|
||||
}
|
||||
default:
|
||||
// Handle others
|
||||
}
|
||||
}
|
||||
myDevice->close();
|
||||
@@ -1,11 +0,0 @@
|
||||
icsneocpp
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
installation
|
||||
deviceconcepts
|
||||
apiconcepts
|
||||
examples
|
||||
api
|
||||
@@ -1,39 +0,0 @@
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
The minimum requirements to build libicsneo are:
|
||||
- CMake version 3.12 or newer
|
||||
- A C++17 compiler
|
||||
- libusb and libpcap on Linux and macOS
|
||||
|
||||
|
||||
Building library & examples
|
||||
===========================
|
||||
|
||||
For a list of available configuration options, see the ``option()`` entries in
|
||||
``CMakeLists.txt``.
|
||||
|
||||
To build libicsneo with default options:
|
||||
#. ``cmake -B build``
|
||||
#. ``cmake --build build``
|
||||
|
||||
Adding to existing projects
|
||||
===========================
|
||||
|
||||
libicsneo supports being added as a sub-projects with CMake's
|
||||
``add_subdirectory()``.
|
||||
|
||||
#. Clone libicsneo into the desired location within the project
|
||||
#. Add ``add_subdirectory(path/to/libicsneo)`` to ``CMakeLists.txt``
|
||||
#. Link the project to libicsneo with ``target_link_libraries(app icsneocpp)``
|
||||
|
||||
Linux udev Rules
|
||||
================
|
||||
|
||||
Linux users may want to install the included udev rules to run libicsneo based
|
||||
applications without root, this can be done with:
|
||||
``cp 99-intrepidcs.rules /etc/udev/rules.d/``
|
||||
@@ -1,10 +0,0 @@
|
||||
==========
|
||||
Python API
|
||||
==========
|
||||
|
||||
.. automodule:: icsneopy
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
:imported-members:
|
||||
:special-members: __init__
|
||||
@@ -1,163 +0,0 @@
|
||||
===============
|
||||
Python Examples
|
||||
===============
|
||||
|
||||
Transmit CAN frames on DW CAN 01
|
||||
============================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import icsneopy
|
||||
|
||||
devices: list[icsneopy.Device] = icsneopy.find_all_devices()
|
||||
|
||||
# grab the first/only device found
|
||||
device: icsneopy.Device = devices[0]
|
||||
|
||||
message = icsneopy.CANMessage()
|
||||
message.network = icsneopy.Network(icsneopy.Network.NetID.DWCAN_01)
|
||||
message.arbid = 0x56
|
||||
message.data = (0x11, 0x22, 0x33)
|
||||
|
||||
device.open()
|
||||
|
||||
device.go_online()
|
||||
|
||||
device.transmit(message)
|
||||
|
||||
Receive CAN frames on DW CAN 01
|
||||
===========================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import icsneopy
|
||||
import time
|
||||
|
||||
devices: list[icsneopy.Device] = icsneopy.find_all_devices()
|
||||
|
||||
# grab the first/only device found
|
||||
device: icsneopy.Device = devices[0]
|
||||
|
||||
def on_message(message: icsneopy.CANMessage):
|
||||
print(message.arbid, message.data)
|
||||
message_filter = icsneopy.MessageFilter(icsneopy.Network.NetID.DWCAN_01)
|
||||
callback = icsneopy.MessageCallback(on_message, message_filter)
|
||||
|
||||
device.add_message_callback(callback)
|
||||
|
||||
device.open()
|
||||
device.go_online()
|
||||
|
||||
# rx for 10s
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
Monitor Ethernet Status
|
||||
=======================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import icsneopy
|
||||
import time
|
||||
|
||||
def main():
|
||||
devices = icsneopy.find_all_devices()
|
||||
if len(devices) == 0:
|
||||
print("error: no devices found")
|
||||
return False
|
||||
|
||||
device = devices[0]
|
||||
print(f"info: monitoring Ethernet status on {device}")
|
||||
|
||||
def on_message(message):
|
||||
print(f"info: network: {message.network}, state: {message.state}, speed: {message.speed}, duplex: {message.duplex}, mode: {message.mode}")
|
||||
|
||||
filter = icsneopy.MessageFilter(icsneopy.Message.Type.EthernetStatus)
|
||||
callback = icsneopy.MessageCallback(on_message, filter)
|
||||
device.add_message_callback(callback)
|
||||
|
||||
if not device.open():
|
||||
print("error: unable to open device")
|
||||
return False
|
||||
|
||||
if not device.go_online():
|
||||
print("error: unable to go online")
|
||||
return False
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
main()
|
||||
|
||||
TC10
|
||||
====
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import icsneopy
|
||||
import time
|
||||
|
||||
devices: list[icsneopy.Device] = icsneopy.find_all_devices()
|
||||
|
||||
device: icsneopy.Device = devices[0]
|
||||
|
||||
print(f"using {device} for TC10")
|
||||
|
||||
device.open()
|
||||
|
||||
netid = icsneopy.Network.NetID.AE_01
|
||||
|
||||
if device.supports_tc10():
|
||||
# initial
|
||||
status = device.get_tc10_status(netid)
|
||||
print(f"initial status: wake: {status.wakeStatus}, sleep: {status.sleepStatus}")
|
||||
time.sleep(1)
|
||||
|
||||
# sleep
|
||||
device.request_tc10_sleep(netid)
|
||||
print("waiting 1s for sleep to occur")
|
||||
time.sleep(1)
|
||||
status = device.get_tc10_status(netid)
|
||||
print(f"post sleep status: wake: {status.wakeStatus}, sleep: {status.sleepStatus}")
|
||||
|
||||
# wake
|
||||
device.request_tc10_wake(netid)
|
||||
print("waiting 1s for wake to occur")
|
||||
time.sleep(1)
|
||||
status = device.get_tc10_status(netid)
|
||||
print(f"post wake status: wake: {status.wakeStatus}, sleep: {status.sleepStatus}")
|
||||
else:
|
||||
print(f"{device} does not support TC10")
|
||||
|
||||
DoIP Ethernet Activation
|
||||
========================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import icsneopy
|
||||
import time
|
||||
|
||||
devs = icsneopy.find_all_devices()
|
||||
|
||||
dev = devs[0]
|
||||
|
||||
dev.open()
|
||||
|
||||
# the device must be online for digital I/O
|
||||
dev.go_online()
|
||||
|
||||
print(f"initial state: {dev.get_digital_io(icsneopy.IO.EthernetActivation, 1)}")
|
||||
|
||||
dev.set_digital_io(icsneopy.IO.EthernetActivation, 1, True)
|
||||
|
||||
print(f"after setting to true: {dev.get_digital_io(icsneopy.IO.EthernetActivation, 1)}")
|
||||
|
||||
# allow for observing the change
|
||||
time.sleep(2)
|
||||
|
||||
dev.set_digital_io(icsneopy.IO.EthernetActivation, 1, False)
|
||||
|
||||
print(f"after setting to false: {dev.get_digital_io(icsneopy.IO.EthernetActivation, 1)}")
|
||||
|
||||
# allow for observing the change
|
||||
time.sleep(2)
|
||||
@@ -1,10 +0,0 @@
|
||||
========
|
||||
icsneopy
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
examples
|
||||
api
|
||||
radepsilon
|
||||
@@ -1,137 +0,0 @@
|
||||
=======================================
|
||||
Python Examples for RAD-Epsilon Devices
|
||||
=======================================
|
||||
|
||||
|
||||
|
||||
Working with PHY Settings
|
||||
=========================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import sys
|
||||
import icsneopy
|
||||
|
||||
|
||||
class PhyStaticInfo:
|
||||
|
||||
def __init__(self, index, type, switch_port):
|
||||
self.index = index
|
||||
self.type = type
|
||||
self.switch_port = switch_port
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.switch_port}: Type {self.type} / Index {self.index}"
|
||||
|
||||
|
||||
# Switch Port name to PHY index and PHY type
|
||||
RAD_EPSILON_PHY_INFO = {
|
||||
"1": PhyStaticInfo(0, "88Q2112", "1"),
|
||||
"2": PhyStaticInfo(1, "88Q2112", "2"),
|
||||
"3": PhyStaticInfo(2, "88Q2112", "3"),
|
||||
"4": PhyStaticInfo(3, "88Q2112", "4"),
|
||||
"5": PhyStaticInfo(4, "88Q2112", "5"),
|
||||
"6": PhyStaticInfo(5, "88Q2112", "6"),
|
||||
"9": PhyStaticInfo(6, "88Q2112", "9"),
|
||||
"10": PhyStaticInfo(7, "88Q2112", "10")
|
||||
}
|
||||
|
||||
RAD_EPSILON_XL_PHY_INFO = {
|
||||
"A1": PhyStaticInfo(0, "88Q222x", "A1"),
|
||||
"A2": PhyStaticInfo(1, "88Q222x", "A2"),
|
||||
"A3": PhyStaticInfo(2, "88Q222x", "A3"),
|
||||
"A4": PhyStaticInfo(3, "88Q222x", "A4"),
|
||||
"A5": PhyStaticInfo(4, "88Q222x", "A5"),
|
||||
"A6": PhyStaticInfo(5, "88Q222x", "A6"),
|
||||
"A11": PhyStaticInfo(6, "88Q222x", "A11"),
|
||||
"A8": PhyStaticInfo(7, "88Q222x", "A8"),
|
||||
"B1": PhyStaticInfo(8, "88Q222x", "B1"),
|
||||
"B2": PhyStaticInfo(9, "88Q222x", "B2"),
|
||||
"B3": PhyStaticInfo(10, "88Q222x", "B3"),
|
||||
"B4": PhyStaticInfo(11, "88Q222x", "B4"),
|
||||
"B5": PhyStaticInfo(12, "88Q222x", "B5"),
|
||||
"B6": PhyStaticInfo(13, "88Q222x", "B6"),
|
||||
"B7": PhyStaticInfo(14, "88Q222x", "B7"),
|
||||
"B8": PhyStaticInfo(15, "88Q222x", "B8"),
|
||||
"A9": PhyStaticInfo(16, "88X3310", "A9"),
|
||||
"B9": PhyStaticInfo(17, "88X3310", "B9"),
|
||||
}
|
||||
|
||||
|
||||
def find_specific_device(type: icsneopy.DeviceType.Enum, serial: str | None = None) -> icsneopy.Device | None:
|
||||
devices = icsneopy.find_all_devices()
|
||||
for device in devices:
|
||||
device_type = device.get_type().get_device_type()
|
||||
if serial: # always find by serial if specified
|
||||
if device.get_serial() == serial:
|
||||
return device
|
||||
elif device_type == type:
|
||||
return device
|
||||
return None
|
||||
|
||||
|
||||
def find_rad_epsilonxl(serial: str | None = None) -> icsneopy.Device | None:
|
||||
return find_specific_device(icsneopy.DeviceType.Enum.RADEpsilonXL, serial)
|
||||
|
||||
|
||||
def find_rad_epsilon(serial: str | None = None) -> icsneopy.Device | None:
|
||||
return find_specific_device(icsneopy.DeviceType.Enum.RADEpsilon, serial)
|
||||
|
||||
|
||||
def report_phy_settings(device: icsneopy.Device, phy: PhyStaticInfo) -> bool:
|
||||
phy_enable = device.settings.get_phy_enable(phy.index)
|
||||
phy_mode = device.settings.get_phy_mode(phy.index)
|
||||
phy_speed = device.settings.get_phy_speed(phy.index)
|
||||
if phy_enable is None or phy_mode is None or phy_speed is None:
|
||||
print(f"failed to get settings for PHY{phy.index} on port {phy.switch_port}")
|
||||
print(f"PHY {phy.index} ({phy.type})")
|
||||
print(f"\tPort: {phy.switch_port}")
|
||||
print(f"\tEnabled: {'TRUE' if phy_enable else 'FALSE'}")
|
||||
print(f"\tMode: {phy_mode}")
|
||||
print(f"\tSpeed: {phy_speed}")
|
||||
return True
|
||||
|
||||
def configure_phy(device: icsneopy.Device, phy: PhyStaticInfo, enable: bool, mode: int, speed: int) -> bool:
|
||||
if not device.settings.set_phy_enable(phy.index, enable):
|
||||
print(f"failed to set enable for PHY{phy.index} at port {phy.switch_port}")
|
||||
return False
|
||||
if not device.settings.set_phy_mode(phy.index, mode):
|
||||
print(f"failed to set mode for PHY{phy.index} at port {phy.switch_port}")
|
||||
return False
|
||||
if not device.settings.set_phy_speed(phy.index, speed):
|
||||
print(f"failed to set speed for PHY{phy.index} at port {phy.switch_port}")
|
||||
return False
|
||||
if not device.settings.apply(True):
|
||||
print(f"failed to apply settings")
|
||||
print(icsneopy.get_last_error())
|
||||
return False
|
||||
print(f"Successfully set settings for PHY{phy.index} at port {phy.switch_port}")
|
||||
return True
|
||||
|
||||
|
||||
# find the first RAD-EpsilonXL
|
||||
device = find_rad_epsilonxl()
|
||||
if not device:
|
||||
print("failed to find a RAD-EpsilonXL to open")
|
||||
sys.exit(-1)
|
||||
if not device.open():
|
||||
print(f"Failed to open {device.describe()}")
|
||||
print(icsneopy.get_last_error())
|
||||
sys.exit(-1)
|
||||
print(f"Opened {device.describe()}")
|
||||
print("Applying default settings")
|
||||
if not device.settings.apply_defaults():
|
||||
print(icsneopy.get_last_error())
|
||||
sys.exit(-1)
|
||||
print("Reporting PHY settings")
|
||||
for phy in RAD_EPSILON_XL_PHY_INFO.values():
|
||||
report_phy_settings(device, phy)
|
||||
# Setting Port A1 to Master mode, enabled, 1G speed
|
||||
phy = RAD_EPSILON_XL_PHY_INFO["A1"]
|
||||
if configure_phy(device, phy, True, icsneopy.Settings.EthernetLinkMode.Master, icsneopy.Settings.EthernetLinkSpeed.Speed1G) and device.settings.refresh(True):
|
||||
report_phy_settings(device, phy) # report them back
|
||||
else:
|
||||
print(icsneopy.get_last_error())
|
||||
sys.exit(-1)
|
||||
device.close()
|
||||
|
||||
+6
-11
@@ -1,15 +1,10 @@
|
||||
=========
|
||||
libicsneo
|
||||
=========
|
||||
|
||||
libicsneo is the `Intrepid Control Systems <https://intrepidcs.com/>`_ device
|
||||
communication library. The source code for libicsneo can be found on GitHub:
|
||||
`https://github.com/intrepidcs/libicsneo <https://github.com/intrepidcs/libicsneo>`_
|
||||
Welcome to libicsneo's documentation!
|
||||
=======================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:maxdepth: 3
|
||||
:caption: Documentation
|
||||
|
||||
icsneocpp/index
|
||||
icsneopy/index
|
||||
icsneoc/index
|
||||
Usage
|
||||
icsneocpp
|
||||
icsneoc
|
||||
|
||||
@@ -1,4 +1 @@
|
||||
sphinx
|
||||
icsneopy
|
||||
breathe
|
||||
sphinx_rtd_theme
|
||||
breathe==4.12.0
|
||||
+11
-4
@@ -9,7 +9,10 @@ option(LIBICSNEO_BUILD_CPP_LIVEDATA_EXAMPLE "Build the Live Data example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_COREMINI_EXAMPLE "Build the Coremini example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_MDIO_EXAMPLE "Build the MDIO example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE "Build the VSA example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE "Build the app error example." ON)
|
||||
|
||||
# Disabled until we properly build these in-tree
|
||||
# option(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE "Build the command-line interactive C# example." OFF)
|
||||
# option(LIBICSNEO_BUILD_JAVA_INTERACTIVE_EXAMPLE "Build the command-line interactive Java example." OFF)
|
||||
|
||||
if(LIBICSNEO_BUILD_C_INTERACTIVE_EXAMPLE)
|
||||
add_subdirectory(c/interactive)
|
||||
@@ -55,6 +58,10 @@ if(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE)
|
||||
add_subdirectory(cpp/vsa)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE)
|
||||
add_subdirectory(cpp/apperror)
|
||||
endif()
|
||||
# if(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE)
|
||||
# add_subdirectory(csharp)
|
||||
# endif()
|
||||
|
||||
# if(LIBICSNEO_BUILD_JAVA_INTERACTIVE_EXAMPLE)
|
||||
# add_subdirectory(java)
|
||||
# endif()
|
||||
@@ -128,7 +128,7 @@ void printAPIEvents() {
|
||||
void printDeviceEvents(neodevice_t* device) {
|
||||
neoevent_t events[99];
|
||||
size_t eventCount = 99;
|
||||
if(icsneo_getDeviceEvents(device, events, &eventCount)) {
|
||||
if(icsneo_getDeviceEvents(selectedDevice, events, &eventCount)) {
|
||||
if(eventCount == 1) {
|
||||
printf("1 device event found!\n");
|
||||
printf("Event 0x%x: %s\n", events[0].eventNumber, events[0].description);
|
||||
@@ -160,7 +160,7 @@ char getCharInput(int numArgs, ...) {
|
||||
|
||||
char* list = (char*) calloc(numArgs, sizeof(char));
|
||||
for(int i = 0; i < numArgs; ++i) {
|
||||
*(list + i) = (char)va_arg(vaList, int);
|
||||
*(list + i) = va_arg(vaList, int);
|
||||
}
|
||||
|
||||
va_end(vaList);
|
||||
@@ -285,10 +285,10 @@ int main() {
|
||||
printf("Would you like to open or close %s?\n", productDescription);
|
||||
printf("[1] Open\n[2] Close\n[3] Cancel\n\n");
|
||||
|
||||
char userSelection = getCharInput(3, '1', '2', '3');
|
||||
char input = getCharInput(3, '1', '2', '3');
|
||||
printf("\n");
|
||||
|
||||
switch(userSelection) {
|
||||
switch(input) {
|
||||
case '1':
|
||||
// Attempt to open the selected device
|
||||
if(icsneo_openDevice(selectedDevice)) {
|
||||
@@ -346,10 +346,10 @@ int main() {
|
||||
printf("Would you like to have %s go online or offline?\n", productDescription);
|
||||
printf("[1] Online\n[2] Offline\n[3] Cancel\n\n");
|
||||
|
||||
char userSelection = getCharInput(3, '1', '2', '3');
|
||||
char input = getCharInput(3, '1', '2', '3');
|
||||
printf("\n");
|
||||
|
||||
switch(userSelection) {
|
||||
switch(input) {
|
||||
case '1':
|
||||
// Attempt to go online
|
||||
if(icsneo_goOnline(selectedDevice)) {
|
||||
@@ -394,10 +394,10 @@ int main() {
|
||||
printf("Would you like to enable or disable message polling for %s?\n", productDescription);
|
||||
printf("[1] Enable\n[2] Disable\n[3] Cancel\n\n");
|
||||
|
||||
char userSelection = getCharInput(3, '1', '2', '3');
|
||||
char input = getCharInput(3, '1', '2', '3');
|
||||
printf("\n");
|
||||
|
||||
switch(userSelection) {
|
||||
switch(input) {
|
||||
case '1':
|
||||
// Attempt to enable message polling
|
||||
if(icsneo_enableMessagePolling(selectedDevice)) {
|
||||
@@ -481,8 +481,8 @@ int main() {
|
||||
case ICSNEO_NETWORK_TYPE_CAN: {
|
||||
neomessage_can_t* canMsg = (neomessage_can_t*)frame;
|
||||
printf("\t0x%03x [%zu] ", canMsg->arbid, canMsg->length);
|
||||
for(size_t j = 0; j < canMsg->length; j++) {
|
||||
printf("%02x ", canMsg->data[j]);
|
||||
for(size_t i = 0; i < canMsg->length; i++) {
|
||||
printf("%02x ", canMsg->data[i]);
|
||||
}
|
||||
if(canMsg->status.transmitMessage)
|
||||
printf("TX%s %04x ", canMsg->status.globalError ? " ERR" : "", canMsg->description);
|
||||
@@ -495,18 +495,18 @@ int main() {
|
||||
size_t dataLen = (frameLen > 2) ? (frameLen - 2) : 0;
|
||||
size_t numberBytesHeader = (dataLen > 1) ? 3 : 1;
|
||||
size_t numberBytesData = frameLen - numberBytesHeader;
|
||||
if(linMsg->netid == ICSNEO_NETID_LIN_01) {
|
||||
if(linMsg->netid == ICSNEO_NETID_LIN) {
|
||||
printf("LIN 1 | ID: 0x%02x [%zu] ", linMsg->header[0], dataLen);
|
||||
}
|
||||
else if (linMsg->netid == ICSNEO_NETID_LIN_02) {
|
||||
else if (linMsg->netid == ICSNEO_NETID_LIN2) {
|
||||
printf("LIN 2 | ID: 0x%02x [%zu] ", linMsg->header[0], dataLen);
|
||||
}
|
||||
|
||||
for(size_t j = 0; j < dataLen; ++j) {
|
||||
if (j < 2) {
|
||||
printf("%02x ", linMsg->header[j+1]);
|
||||
for(size_t i = 0; i < dataLen; ++i) {
|
||||
if (i < 2) {
|
||||
printf("%02x ", linMsg->header[i+1]);
|
||||
} else {
|
||||
printf("%02x ", linMsg->data[j-2]);
|
||||
printf("%02x ", linMsg->data[i-2]);
|
||||
}
|
||||
}
|
||||
if(numberBytesData > 0)
|
||||
@@ -562,7 +562,7 @@ int main() {
|
||||
neomessage_can_t msg = {0};
|
||||
msg.arbid = 0x120;
|
||||
msg.length = 6;
|
||||
msg.netid = ICSNEO_NETID_DWCAN_01;
|
||||
msg.netid = ICSNEO_NETID_HSCAN;
|
||||
msg.data = sendMessageData;
|
||||
msg.description = 0x1c5; // Random description to match the receipt
|
||||
msg.status.canfdFDF = false;
|
||||
@@ -606,7 +606,7 @@ int main() {
|
||||
icsneo_describeDevice(selectedDevice, productDescription, &descriptionLength);
|
||||
|
||||
// Attempt to set baudrate and apply settings
|
||||
if(icsneo_setBaudrate(selectedDevice, ICSNEO_NETID_DWCAN_01, 250000) && icsneo_settingsApply(selectedDevice)) {
|
||||
if(icsneo_setBaudrate(selectedDevice, ICSNEO_NETID_HSCAN, 250000) && icsneo_settingsApply(selectedDevice)) {
|
||||
printf("Successfully set HS CAN baudrate for %s to 250k!\n\n", productDescription);
|
||||
} else {
|
||||
printf("Failed to set HS CAN for %s to 250k!\n\n", productDescription);
|
||||
@@ -632,7 +632,7 @@ int main() {
|
||||
icsneo_describeDevice(selectedDevice, productDescription, &descriptionLength);
|
||||
|
||||
// Attempt to set baudrate and apply settings
|
||||
if(icsneo_setBaudrate(selectedDevice, ICSNEO_NETID_DWCAN_01, 500000) && icsneo_settingsApply(selectedDevice)) {
|
||||
if(icsneo_setBaudrate(selectedDevice, ICSNEO_NETID_HSCAN, 500000) && icsneo_settingsApply(selectedDevice)) {
|
||||
printf("Successfully set HS CAN baudrate for %s to 500k!\n\n", productDescription);
|
||||
} else {
|
||||
printf("Failed to set HS CAN for %s to 500k!\n\n", productDescription);
|
||||
@@ -725,7 +725,7 @@ int main() {
|
||||
}
|
||||
|
||||
const bool set = selection2 == '1';
|
||||
neoio_t type = ICSNEO_IO_ETH_ACTIVATION;
|
||||
neoio_t type;
|
||||
switch (selection)
|
||||
{
|
||||
case '1': type = ICSNEO_IO_ETH_ACTIVATION; break;
|
||||
@@ -758,7 +758,7 @@ int main() {
|
||||
icsneo_describeDevice(selectedDevice, productDescription, &descriptionLength);
|
||||
|
||||
printf("Termination is ");
|
||||
const bool val = icsneo_isTerminationEnabledFor(selectedDevice, ICSNEO_NETID_DWCAN_01);
|
||||
const bool val = icsneo_isTerminationEnabledFor(selectedDevice, ICSNEO_NETID_HSCAN);
|
||||
neoevent_t err = { 0 };
|
||||
if(icsneo_getLastError(&err)) {
|
||||
printf("not available at this time: %s\n\n", err.description);
|
||||
@@ -776,7 +776,7 @@ int main() {
|
||||
}
|
||||
|
||||
// Attempt to set baudrate and apply settings
|
||||
if(icsneo_setTerminationFor(selectedDevice, ICSNEO_NETID_DWCAN_01, selection2 == '1') && icsneo_settingsApply(selectedDevice)) {
|
||||
if(icsneo_setTerminationFor(selectedDevice, ICSNEO_NETID_HSCAN, selection2 == '1') && icsneo_settingsApply(selectedDevice)) {
|
||||
printf("Successfully set HS CAN termination for %s!\n\n", productDescription);
|
||||
} else {
|
||||
printf("Failed to set HS CAN termination for %s!\n\n", productDescription);
|
||||
|
||||
@@ -11,7 +11,7 @@ e.g. pSettings.Settings.red2 -> pSettings.Settings.fire3
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined _WIN32
|
||||
#include <windows.h>
|
||||
#include "icsneo/platform/windows.h"
|
||||
#define SLEEP(msecs) Sleep(msecs)
|
||||
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
||||
#include <time.h>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined _WIN32
|
||||
#include <windows.h>
|
||||
#include "icsneo/platform/windows.h"
|
||||
#define SLEEP(msecs) Sleep(msecs)
|
||||
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
||||
#include <time.h>
|
||||
@@ -58,7 +58,7 @@ int main() {
|
||||
msg1.Protocol = SPY_PROTOCOL_LIN;
|
||||
msg1.StatusBitField = 0;
|
||||
msg1.StatusBitField2 = 0;
|
||||
lNetworkID = NETID_LIN_02;
|
||||
lNetworkID = NETID_LIN2;
|
||||
msg1.Header[0] = 0x11; //protected ID
|
||||
msg1.Header[1] = 0xaa;
|
||||
msg1.Header[2] = 0xbb;
|
||||
@@ -80,7 +80,7 @@ int main() {
|
||||
icsSpyMessageJ1850 msg2 = {0};
|
||||
msg2.Protocol = SPY_PROTOCOL_LIN;
|
||||
msg2.StatusBitField = SPY_STATUS_INIT_MESSAGE;
|
||||
lNetworkID = NETID_LIN_01;
|
||||
lNetworkID = NETID_LIN;
|
||||
msg2.Header[0] = 0x11; //protected ID
|
||||
msg2.NumberBytesData = 0;
|
||||
msg2.NumberBytesHeader = 1;
|
||||
@@ -96,7 +96,7 @@ int main() {
|
||||
msg3.Protocol = SPY_PROTOCOL_LIN;
|
||||
msg3.StatusBitField = SPY_STATUS_INIT_MESSAGE;
|
||||
msg3.StatusBitField2 = 0;
|
||||
lNetworkID = NETID_LIN_01;
|
||||
lNetworkID = NETID_LIN;
|
||||
msg3.Header[0] = 0xe2; //protected ID
|
||||
msg3.Header[1] = 0x44;
|
||||
msg3.Header[2] = 0x33;
|
||||
@@ -131,10 +131,10 @@ int main() {
|
||||
const icsSpyMessageJ1850* linMsg = (icsSpyMessageJ1850*)&rxMsg[idx];
|
||||
size_t frameLen = (linMsg->NumberBytesHeader + linMsg->NumberBytesData);
|
||||
size_t dataLen = (frameLen > 2) ? (frameLen - 2) : 0;
|
||||
if(linMsg->NetworkID == NETID_LIN_01) {
|
||||
if(linMsg->NetworkID == NETID_LIN) {
|
||||
printf("LIN 1 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
|
||||
}
|
||||
else if (linMsg->NetworkID == NETID_LIN_02) {
|
||||
else if (linMsg->NetworkID == NETID_LIN2) {
|
||||
printf("LIN 2 | ID: 0x%02x [%zu] ", linMsg->Header[0], dataLen);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ void printAPIEvents() {
|
||||
void printDeviceEvents(neodevice_t* device) {
|
||||
neoevent_t events[99];
|
||||
size_t eventCount = 99;
|
||||
if(icsneo_getDeviceEvents(device, events, &eventCount)) {
|
||||
if(icsneo_getDeviceEvents(selectedDevice, events, &eventCount)) {
|
||||
if(eventCount == 1) {
|
||||
printf("1 device event found!\n");
|
||||
printf("Event 0x%x: %s\n", events[0].eventNumber, events[0].description);
|
||||
@@ -155,7 +155,7 @@ char getCharInput(int numArgs, ...) {
|
||||
|
||||
char* list = (char*) calloc(numArgs, sizeof(char));
|
||||
for(int i = 0; i < numArgs; ++i) {
|
||||
*(list + i) = (char)va_arg(vaList, int);
|
||||
*(list + i) = va_arg(vaList, int);
|
||||
}
|
||||
|
||||
va_end(vaList);
|
||||
@@ -285,7 +285,7 @@ int main() {
|
||||
msg.header[1] = 0x11;
|
||||
msg.header[2] = 0x22;
|
||||
msg.length = 10;
|
||||
msg.netid = ICSNEO_NETID_LIN_01;
|
||||
msg.netid = ICSNEO_NETID_LIN;
|
||||
msg.data = sendMessageData;
|
||||
msg.linStatus.txCommander = 1;
|
||||
msg.linStatus.txChecksumEnhanced = 1;
|
||||
@@ -335,8 +335,8 @@ int main() {
|
||||
case ICSNEO_NETWORK_TYPE_CAN: {
|
||||
neomessage_can_t* canMsg = (neomessage_can_t*)frame;
|
||||
printf("\t0x%03x [%zu] ", canMsg->arbid, canMsg->length);
|
||||
for(size_t j = 0; i < canMsg->length; j++) {
|
||||
printf("%02x ", canMsg->data[j]);
|
||||
for(size_t i = 0; i < canMsg->length; i++) {
|
||||
printf("%02x ", canMsg->data[i]);
|
||||
}
|
||||
if(canMsg->status.transmitMessage)
|
||||
printf("TX%s %04x ", canMsg->status.globalError ? " ERR" : "", canMsg->description);
|
||||
@@ -347,18 +347,20 @@ int main() {
|
||||
neomessage_lin_t* linMsg = (neomessage_lin_t*)frame;
|
||||
size_t frameLen = linMsg->length;
|
||||
size_t dataLen = (frameLen > 2) ? (frameLen - 2) : 0;
|
||||
if(linMsg->netid == ICSNEO_NETID_LIN_01) {
|
||||
size_t numberBytesHeader = (dataLen > 1) ? 3 : 1;
|
||||
size_t numberBytesData = frameLen - numberBytesHeader;
|
||||
if(linMsg->netid == ICSNEO_NETID_LIN) {
|
||||
printf("LIN 1 | ID: 0x%02x [%zu] ", linMsg->header[0], dataLen);
|
||||
}
|
||||
else if (linMsg->netid == ICSNEO_NETID_LIN_02) {
|
||||
else if (linMsg->netid == ICSNEO_NETID_LIN2) {
|
||||
printf("LIN 2 | ID: 0x%02x [%zu] ", linMsg->header[0], dataLen);
|
||||
}
|
||||
|
||||
for(size_t j = 0; j < dataLen; ++j) {
|
||||
if (j < 2) {
|
||||
printf("%02x ", linMsg->header[j+1]);
|
||||
for(size_t i = 0; i < dataLen; ++i) {
|
||||
if (i < 2) {
|
||||
printf("%02x ", linMsg->header[i+1]);
|
||||
} else {
|
||||
printf("%02x ", linMsg->data[j-2]);
|
||||
printf("%02x ", linMsg->data[i-2]);
|
||||
}
|
||||
}
|
||||
printf("| Checksum: 0x%02x\n", linMsg->checksum);
|
||||
|
||||
@@ -79,7 +79,7 @@ void example0(const std::shared_ptr<icsneo::Device>& rada2b) {
|
||||
true /* true if we want 16 bit channels in the message, false for 32 bit. This should match the RAD-A2B device setting */
|
||||
);
|
||||
msg->txmsg = true;
|
||||
msg->network = icsneo::Network(icsneo::Network::NetID::A2B_02);
|
||||
msg->network = icsneo::Network(icsneo::Network::NetID::A2B2);
|
||||
|
||||
// Load the WAV audio data into the desired channel, break if we fail to load
|
||||
if(!msg->loadAudioBuffer(wavStream, channelMap)) {
|
||||
@@ -192,7 +192,7 @@ void example3(const std::shared_ptr<icsneo::Device>& rada2b) {
|
||||
std::shared_ptr<icsneo::A2BMessage> a2bmsgPtr = std::make_shared<icsneo::A2BMessage>(numFrames, icsneo::A2BMessage::TDMMode::TDM4, true);
|
||||
|
||||
icsneo::A2BMessage& a2bmsg = *a2bmsgPtr.get();
|
||||
a2bmsg.network = icsneo::Network(icsneo::Network::NetID::A2B_02);
|
||||
a2bmsg.network = icsneo::Network(icsneo::Network::NetID::A2B2);
|
||||
a2bmsg.txmsg = true;
|
||||
|
||||
for(size_t frame = 0; frame < a2bmsg.getNumFrames(); frame++) {
|
||||
@@ -241,13 +241,13 @@ void example3(const std::shared_ptr<icsneo::Device>& rada2b) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Example 4: Retrieving A2B bus status using I2C messages.
|
||||
* Example 4: Retrieving A2B bus status using I2C messaages.
|
||||
*/
|
||||
void example4(const std::shared_ptr<icsneo::Device>& rada2b) {
|
||||
std::shared_ptr<icsneo::I2CMessage> msg = std::make_shared<icsneo::I2CMessage>();
|
||||
std::shared_ptr<icsneo::MessageFilter> msgFilter = std::make_shared<icsneo::MessageFilter>(icsneo::Network::NetID::I2C_02);
|
||||
std::shared_ptr<icsneo::MessageFilter> msgFilter = std::make_shared<icsneo::MessageFilter>(icsneo::Network::NetID::I2C2);
|
||||
|
||||
msg->network = icsneo::Network(icsneo::Network::NetID::I2C_02);
|
||||
msg->network = icsneo::Network(icsneo::Network::NetID::I2C2);
|
||||
msg->controlBytes.resize(1);
|
||||
msg->controlBytes[0] = static_cast<uint8_t>(0x17u); // Register address for A2B INTTYPE
|
||||
msg->dataBytes.resize(1, 0);
|
||||
@@ -261,7 +261,7 @@ void example4(const std::shared_ptr<icsneo::Device>& rada2b) {
|
||||
|
||||
if(newMsg->type == icsneo::Message::Type::Frame) {
|
||||
const auto& frame = std::dynamic_pointer_cast<icsneo::Frame>(newMsg);
|
||||
if(frame && frame->network.getNetID() == icsneo::Network::NetID::I2C_02) {
|
||||
if(frame && frame->network.getNetID() == icsneo::Network::NetID::I2C2) {
|
||||
const auto& i2cMessage = std::dynamic_pointer_cast<icsneo::I2CMessage>(frame);
|
||||
|
||||
if(!i2cMessage) {
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
add_executable(libicsneocpp-app-error src/AppErrorExample.cpp)
|
||||
target_link_libraries(libicsneocpp-app-error icsneocpp)
|
||||
@@ -1,85 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#include "icsneo/icsneocpp.h"
|
||||
#include "icsneo/communication/message/apperrormessage.h"
|
||||
#include "icsneo/communication/message/message.h"
|
||||
/*
|
||||
* App errors are responses from the device indicating internal runtime errors
|
||||
* NOTE: To trigger the app error in this example, disable the DW CAN 01 network on the device
|
||||
* (e.g. with neoVI Explorer)
|
||||
*/
|
||||
int main() {
|
||||
std::cout << "Running libicsneo " << icsneo::GetVersion() << std::endl;
|
||||
std::cout << "\nFinding devices... " << std::flush;
|
||||
auto devices = icsneo::FindAllDevices();
|
||||
std::cout << "OK, " << devices.size() << " device" << (devices.size() == 1 ? "" : "s") << " found" << std::endl;
|
||||
|
||||
// List off the devices
|
||||
for(auto& device : devices)
|
||||
std::cout << '\t' << device->describe() << " @ Handle " << device->getNeoDevice().handle << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
for(auto device : devices) {
|
||||
std::cout << "Connecting to " << device->describe() << "... ";
|
||||
bool ret = device->open();
|
||||
if(!ret) { // Failed to open
|
||||
std::cout << "FAIL" << std::endl;
|
||||
std::cout << icsneo::GetLastError() << std::endl << std::endl;
|
||||
continue;
|
||||
}
|
||||
std::cout << "OK" << std::endl << std::endl;
|
||||
|
||||
// Create an app error message filter, including "internal" messages
|
||||
auto filter = std::make_shared<icsneo::MessageFilter>(icsneo::Message::Type::AppError);
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
// ...and register a callback with it.
|
||||
// Add your error handling here
|
||||
auto handler = device->addMessageCallback(std::make_shared<icsneo::MessageCallback>(filter, [](std::shared_ptr<icsneo::Message> message) {
|
||||
auto msg = std::static_pointer_cast<icsneo::AppErrorMessage>(message);
|
||||
if(icsneo::Network::NetID::RED_App_Error == msg->network.getNetID()) {
|
||||
std::cout << std::endl << "App error reported:" << std::endl;
|
||||
std::cout << msg->getAppErrorString() << std::endl << std::endl;
|
||||
}
|
||||
}));
|
||||
|
||||
std::cout << "Going online... ";
|
||||
ret = device->goOnline();
|
||||
if(!ret) {
|
||||
std::cout << "FAIL" << std::endl;
|
||||
device->close();
|
||||
continue;
|
||||
}
|
||||
std::cout << "OK" << std::endl;
|
||||
|
||||
// Prepare a CAN message
|
||||
std::cout << std::endl << "Transmitting a CAN frame... ";
|
||||
auto txMessage = std::make_shared<icsneo::CANMessage>();
|
||||
txMessage->network = icsneo::Network::NetID::DWCAN_01;
|
||||
txMessage->arbid = 0x22;
|
||||
txMessage->data.insert(txMessage->data.end(), {0xaa, 0xbb, 0xcc});
|
||||
// The DLC will come from the length of the data vector
|
||||
txMessage->isExtended = false;
|
||||
txMessage->isCANFD = false;
|
||||
|
||||
// Transmit a CAN message on DW CAN 01, even though DW CAN 01 is disabled on the device!
|
||||
// Expect to see an app error caught in the callback defined above
|
||||
ret = device->transmit(txMessage);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Go offline, stop sending and receiving traffic
|
||||
device->removeMessageCallback(handler);
|
||||
std::cout << "Going offline... ";
|
||||
ret = device->goOffline();
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
std::cout << "Disconnecting... ";
|
||||
ret = device->close();
|
||||
std::cout << (ret ? "OK\n" : "FAIL\n") << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ void printMessage(const std::shared_ptr<icsneo::Message>& message) {
|
||||
} // end of icsneo::Message::Type::Frame
|
||||
case icsneo::Message::Type::CANErrorCount: {
|
||||
// A message of type CANErrorCount is guaranteed to be a CANErrorCount, so we can static cast safely
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorMessage>(message);
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorCountMessage>(message);
|
||||
std::cout << "\t\t" << cec->network << " error counts changed, REC=" << cec->receiveErrorCount
|
||||
<< " TEC=" << cec->transmitErrorCount << " (" << (cec->busOff ? "" : "Not ") << "Bus Off)" << std::endl;
|
||||
break;
|
||||
@@ -508,7 +508,7 @@ int main() {
|
||||
|
||||
std::cout << "Transmitting a normal CAN frame..." << std::endl;
|
||||
auto msg = std::make_shared<icsneo::CANMessage>();
|
||||
msg->network = icsneo::Network::NetID::DWCAN_01;
|
||||
msg->network = icsneo::Network::NetID::HSCAN;
|
||||
msg->arbid = 0x120;
|
||||
msg->data.insert(msg->data.end(), {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff});
|
||||
msg->isExtended = false;
|
||||
@@ -525,7 +525,7 @@ int main() {
|
||||
/** Example of CAN FD
|
||||
std::cout << "Transmitting an extended CAN FD frame... " << std::endl;
|
||||
auto txMessage = std::make_shared<icsneo::CANMessage>();
|
||||
txMessage->network = icsneo::Network::NetID::DWCAN_01;
|
||||
txMessage->network = icsneo::Network::NetID::HSCAN;
|
||||
txMessage->arbid = 0x1C5001C5;
|
||||
txMessage->data.insert(txMessage->data.end(), {0xaa, 0xbb, 0xcc});
|
||||
// The DLC will come from the length of the data vector
|
||||
@@ -565,7 +565,7 @@ int main() {
|
||||
selectedDevice = selectDevice(devices);
|
||||
|
||||
// Attempt to set baudrate and apply settings
|
||||
if(selectedDevice->settings->setBaudrateFor(icsneo::Network::NetID::DWCAN_01, 250000) && selectedDevice->settings->apply()) {
|
||||
if(selectedDevice->settings->setBaudrateFor(icsneo::Network::NetID::HSCAN, 250000) && selectedDevice->settings->apply()) {
|
||||
std::cout << "Successfully set HS CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl;
|
||||
} else {
|
||||
std::cout << "Failed to set HS CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl << std::endl;
|
||||
@@ -586,7 +586,7 @@ int main() {
|
||||
selectedDevice = selectDevice(devices);
|
||||
|
||||
// Attempt to set baudrate and apply settings
|
||||
if(selectedDevice->settings->setBaudrateFor(icsneo::Network::NetID::LSFTCAN_01, 250000) && selectedDevice->settings->apply()) {
|
||||
if(selectedDevice->settings->setBaudrateFor(icsneo::Network::NetID::LSFTCAN, 250000) && selectedDevice->settings->apply()) {
|
||||
std::cout << "Successfully set LSFT CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl;
|
||||
} else {
|
||||
std::cout << "Failed to set LSFT CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl << std::endl;
|
||||
@@ -790,7 +790,7 @@ int main() {
|
||||
selectedDevice = selectDevice(devices);
|
||||
|
||||
std::cout << "Termination is ";
|
||||
const auto val = selectedDevice->settings->isTerminationEnabledFor(icsneo::Network::NetID::DWCAN_01);
|
||||
const auto val = selectedDevice->settings->isTerminationEnabledFor(icsneo::Network::NetID::HSCAN);
|
||||
if(!val.has_value()) {
|
||||
std::cout << "not available at this time: " << icsneo::GetLastError() << std::endl << std::endl;
|
||||
break;
|
||||
@@ -807,7 +807,7 @@ int main() {
|
||||
}
|
||||
|
||||
// Attempt to set termination and apply settings
|
||||
if(selectedDevice->settings->setTerminationFor(icsneo::Network::NetID::DWCAN_01, selection2 == '1') && selectedDevice->settings->apply()) {
|
||||
if(selectedDevice->settings->setTerminationFor(icsneo::Network::NetID::HSCAN, selection2 == '1') && selectedDevice->settings->apply()) {
|
||||
std::cout << "Successfully set HS CAN termination for " << selectedDevice->describe() << std::endl;
|
||||
} else {
|
||||
std::cout << "Failed to set HS CAN termination for " << selectedDevice->describe() << std::endl;
|
||||
|
||||
@@ -32,28 +32,28 @@ int main() {
|
||||
|
||||
int64_t baud = 19200;
|
||||
|
||||
std::cout << "Enable LIN 01 commander resistor... ";
|
||||
ret = device->settings->setCommanderResistorFor(icsneo::Network::NetID::LIN_01, true);
|
||||
std::cout << "Enable LIN commander resistor... ";
|
||||
ret = device->settings->setCommanderResistorFor(icsneo::Network::NetID::LIN, true);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Disable LIN 02 commander resistor... ";
|
||||
ret = device->settings->setCommanderResistorFor(icsneo::Network::NetID::LIN_02, false);
|
||||
std::cout << "Disable LIN2 commander resistor... ";
|
||||
ret = device->settings->setCommanderResistorFor(icsneo::Network::NetID::LIN2, false);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN 01 to operate at " << baud << "bit/s... ";
|
||||
ret = device->settings->setBaudrateFor(icsneo::Network::NetID::LIN_01, baud);
|
||||
std::cout << "Setting LIN to operate at " << baud << "bit/s... ";
|
||||
ret = device->settings->setBaudrateFor(icsneo::Network::NetID::LIN, baud);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN 02 to operate at " << baud << "bit/s... ";
|
||||
ret = device->settings->setBaudrateFor(icsneo::Network::NetID::LIN_02, baud);
|
||||
std::cout << "Setting LIN2 to operate at " << baud << "bit/s... ";
|
||||
ret = device->settings->setBaudrateFor(icsneo::Network::NetID::LIN2, baud);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN 01 mode to NORMAL... ";
|
||||
ret = device->settings->setLINModeFor(icsneo::Network::NetID::LIN_01, NORMAL_MODE);
|
||||
std::cout << "Setting LIN mode to NORMAL... ";
|
||||
ret = device->settings->setLINModeFor(icsneo::Network::NetID::LIN, NORMAL_MODE);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN 02 mode to NORMAL... ";
|
||||
ret = device->settings->setLINModeFor(icsneo::Network::NetID::LIN_02, NORMAL_MODE);
|
||||
std::cout << "Setting LIN2 mode to NORMAL... ";
|
||||
ret = device->settings->setLINModeFor(icsneo::Network::NetID::LIN2, NORMAL_MODE);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Applying settings... ";
|
||||
@@ -61,14 +61,14 @@ int main() {
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Getting LIN Baudrate... ";
|
||||
int64_t readBaud = device->settings->getBaudrateFor(icsneo::Network::NetID::LIN_01);
|
||||
int64_t readBaud = device->settings->getBaudrateFor(icsneo::Network::NetID::LIN);
|
||||
if(readBaud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
std::cout << "OK, " << (readBaud) << "bit/s" << std::endl;
|
||||
|
||||
std::cout << "Getting LIN 02 Baudrate... ";
|
||||
readBaud = device->settings->getBaudrateFor(icsneo::Network::NetID::LIN_02);
|
||||
std::cout << "Getting LIN2 Baudrate... ";
|
||||
readBaud = device->settings->getBaudrateFor(icsneo::Network::NetID::LIN2);
|
||||
if(readBaud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
@@ -113,18 +113,18 @@ int main() {
|
||||
}));
|
||||
|
||||
// We can transmit messages
|
||||
std::cout << "Transmitting a LIN 02 responder data frame... ";
|
||||
std::cout << "Transmitting a LIN responder data frame... ";
|
||||
auto lin_r = std::make_shared<icsneo::LINMessage>();
|
||||
lin_r->network = icsneo::Network::NetID::LIN_02;
|
||||
lin_r->network = icsneo::Network::NetID::LIN2;
|
||||
lin_r->ID = 0x11;
|
||||
lin_r->linMsgType = icsneo::LINMessage::Type::LIN_UPDATE_RESPONDER;
|
||||
lin_r->data = {0xaa, 0xbb, 0xcc, 0xdd, 0x11, 0x22, 0x33, 0x44};
|
||||
ret = device->transmit(lin_r); // This will return false if the device does not support LIN
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Transmitting a LIN 01 commander header... ";
|
||||
std::cout << "Transmitting a LIN commander header... ";
|
||||
auto lin_c = std::make_shared<icsneo::LINMessage>();
|
||||
lin_c->network = icsneo::Network::NetID::LIN_01;
|
||||
lin_c->network = icsneo::Network::NetID::LIN;
|
||||
lin_c->ID = 0x11;
|
||||
lin_c->linMsgType = icsneo::LINMessage::Type::LIN_HEADER_ONLY;
|
||||
ret = device->transmit(lin_c);
|
||||
@@ -132,9 +132,9 @@ int main() {
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
std::cout << "Transmitting a LIN 01 commander frame with responder data... ";
|
||||
std::cout << "Transmitting a LIN commander frame with responder data... ";
|
||||
auto lin_d = std::make_shared<icsneo::LINMessage>();
|
||||
lin_d->network = icsneo::Network::NetID::LIN_01;
|
||||
lin_d->network = icsneo::Network::NetID::LIN;
|
||||
lin_d->ID = 0x22;
|
||||
lin_d->isEnhancedChecksum = true;
|
||||
lin_d->linMsgType = icsneo::LINMessage::Type::LIN_COMMANDER_MSG;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user