mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-09-20 16:08:37 +02:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa77bbbc9e | ||
|
|
0b9491e5e3 | ||
|
|
ca630b4569 | ||
|
|
b2f67f7ce1 |
@@ -14,5 +14,3 @@ third-party/concurrentqueue/tests
|
||||
*.orig
|
||||
examples/csharp/bin
|
||||
examples/csharp/obj
|
||||
test/system
|
||||
.env
|
||||
|
||||
+67
-212
@@ -1,11 +1,9 @@
|
||||
variables:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
LIBICSNEO_ICSPB_REPO: https://gitlab-ci-token:${CI_JOB_TOKEN}@${LIBICSNEO_ICSPB_GIT}
|
||||
|
||||
stages:
|
||||
- build
|
||||
- unit_test
|
||||
- deploy
|
||||
- test
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Windows
|
||||
@@ -14,49 +12,49 @@ stages:
|
||||
build windows/x64:
|
||||
stage: build
|
||||
script:
|
||||
- cmd /C ci\build-windows64.bat
|
||||
- CMD.EXE /C ci\build-windows64.bat
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
|
||||
unit_test windows/x64:
|
||||
stage: unit_test
|
||||
test windows/x64:
|
||||
stage: test
|
||||
script:
|
||||
- build\libicsneo-unit-tests.exe
|
||||
- build\libicsneo-tests.exe
|
||||
dependencies:
|
||||
- build windows/x64
|
||||
needs:
|
||||
- build windows/x64
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
timeout: 5m
|
||||
|
||||
build windows/x86:
|
||||
stage: build
|
||||
script:
|
||||
- cmd /C ci\build-windows32.bat
|
||||
- CMD.EXE /C ci\build-windows32.bat
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
|
||||
unit_test windows/x86:
|
||||
stage: unit_test
|
||||
test windows/x86:
|
||||
stage: test
|
||||
script:
|
||||
- build\libicsneo-unit-tests.exe
|
||||
- build\libicsneo-tests.exe
|
||||
dependencies:
|
||||
- build windows/x86
|
||||
needs:
|
||||
- build windows/x86
|
||||
tags:
|
||||
- libicsneo-win-x64
|
||||
- icsneo-windows
|
||||
timeout: 5m
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -68,9 +66,7 @@ unit_test windows/x86:
|
||||
script:
|
||||
- apt update -y
|
||||
- apt upgrade -y
|
||||
- apt install -y g++ ninja-build cmake libpcap-dev git ca-certificates
|
||||
- echo "$ICS_IPA_CA_CRT" >/usr/local/share/ca-certificates/ica-ipa-ca.crt
|
||||
- update-ca-certificates --fresh
|
||||
- apt install -y g++ ninja-build cmake libusb-1.0-0-dev libpcap-dev
|
||||
- sh ci/build-posix.sh
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -81,12 +77,12 @@ unit_test windows/x86:
|
||||
- linux-build
|
||||
|
||||
.test_linux_ubuntu_gcc: &test_linux_ubuntu_gcc
|
||||
stage: unit_test
|
||||
stage: test
|
||||
script:
|
||||
- apt update -y
|
||||
- apt upgrade -y
|
||||
- apt install -y libpcap-dev
|
||||
- build/libicsneo-unit-tests
|
||||
- apt install -y libusb-1.0-0-dev libpcap-dev
|
||||
- build/libicsneo-tests
|
||||
tags:
|
||||
- linux-build
|
||||
timeout: 5m
|
||||
@@ -96,9 +92,7 @@ unit_test windows/x86:
|
||||
script:
|
||||
- apt update -y
|
||||
- apt upgrade -y
|
||||
- apt install -y clang lld ninja-build cmake libpcap-dev git ca-certificates
|
||||
- echo "$ICS_IPA_CA_CRT" >/usr/local/share/ca-certificates/ica-ipa-ca.crt
|
||||
- update-ca-certificates --fresh
|
||||
- apt install -y clang lld ninja-build cmake libusb-1.0-0-dev libpcap-dev
|
||||
- CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -109,21 +103,45 @@ unit_test windows/x86:
|
||||
- linux-build
|
||||
|
||||
.test_linux_ubuntu_clang: &test_linux_ubuntu_clang
|
||||
stage: unit_test
|
||||
stage: test
|
||||
script:
|
||||
- apt update -y
|
||||
- apt upgrade -y
|
||||
- apt install -y libpcap-dev
|
||||
- build/libicsneo-unit-tests
|
||||
- apt install -y libusb-1.0-0-dev libpcap-dev
|
||||
- build/libicsneo-tests
|
||||
tags:
|
||||
- linux-build
|
||||
timeout: 5m
|
||||
|
||||
build linux/ubuntu/2004/amd64/gcc:
|
||||
<<: *build_linux_ubuntu_gcc
|
||||
image: ubuntu:20.04
|
||||
|
||||
test linux/ubuntu/2004/amd64/gcc:
|
||||
<<: *test_linux_ubuntu_gcc
|
||||
image: ubuntu:20.04
|
||||
dependencies:
|
||||
- build linux/ubuntu/2004/amd64/gcc
|
||||
needs:
|
||||
- build linux/ubuntu/2004/amd64/gcc
|
||||
|
||||
build linux/ubuntu/2004/amd64/clang:
|
||||
<<: *build_linux_ubuntu_clang
|
||||
image: ubuntu:20.04
|
||||
|
||||
test linux/ubuntu/2004/amd64/clang:
|
||||
<<: *test_linux_ubuntu_clang
|
||||
image: ubuntu:20.04
|
||||
dependencies:
|
||||
- build linux/ubuntu/2004/amd64/clang
|
||||
needs:
|
||||
- build linux/ubuntu/2004/amd64/clang
|
||||
|
||||
build linux/ubuntu/2204/amd64/gcc:
|
||||
<<: *build_linux_ubuntu_gcc
|
||||
image: ubuntu:22.04
|
||||
|
||||
unit_test linux/ubuntu/2204/amd64/gcc:
|
||||
test linux/ubuntu/2204/amd64/gcc:
|
||||
<<: *test_linux_ubuntu_gcc
|
||||
image: ubuntu:22.04
|
||||
dependencies:
|
||||
@@ -135,7 +153,7 @@ build linux/ubuntu/2204/amd64/clang:
|
||||
<<: *build_linux_ubuntu_clang
|
||||
image: ubuntu:22.04
|
||||
|
||||
unit_test linux/ubuntu/2204/amd64/clang:
|
||||
test linux/ubuntu/2204/amd64/clang:
|
||||
<<: *test_linux_ubuntu_clang
|
||||
image: ubuntu:22.04
|
||||
dependencies:
|
||||
@@ -143,30 +161,6 @@ unit_test linux/ubuntu/2204/amd64/clang:
|
||||
needs:
|
||||
- build linux/ubuntu/2204/amd64/clang
|
||||
|
||||
build linux/ubuntu/2404/amd64/gcc:
|
||||
<<: *build_linux_ubuntu_gcc
|
||||
image: ubuntu:24.04
|
||||
|
||||
unit_test linux/ubuntu/2404/amd64/gcc:
|
||||
<<: *test_linux_ubuntu_gcc
|
||||
image: ubuntu:24.04
|
||||
dependencies:
|
||||
- build linux/ubuntu/2404/amd64/gcc
|
||||
needs:
|
||||
- build linux/ubuntu/2404/amd64/gcc
|
||||
|
||||
build linux/ubuntu/2404/amd64/clang:
|
||||
<<: *build_linux_ubuntu_clang
|
||||
image: ubuntu:24.04
|
||||
|
||||
unit_test linux/ubuntu/2404/amd64/clang:
|
||||
<<: *test_linux_ubuntu_clang
|
||||
image: ubuntu:24.04
|
||||
dependencies:
|
||||
- build linux/ubuntu/2404/amd64/clang
|
||||
needs:
|
||||
- build linux/ubuntu/2404/amd64/clang
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Fedora
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -177,12 +171,8 @@ unit_test linux/ubuntu/2404/amd64/clang:
|
||||
paths:
|
||||
- /var/cache/dnf
|
||||
script:
|
||||
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
|
||||
- echo fastestmirror=True >>/etc/dnf/dnf.conf
|
||||
- dnf upgrade -y
|
||||
- dnf install -y g++ libpcap-devel cmake ninja-build git ca-certificates
|
||||
- echo "$ICS_IPA_CA_CRT" >/etc/pki/ca-trust/source/anchors/ica-ipa-ca.crt
|
||||
- update-ca-trust
|
||||
- dnf install -y g++ libpcap-devel cmake ninja-build libusb1-devel
|
||||
- sh ci/build-posix.sh
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -193,16 +183,14 @@ unit_test linux/ubuntu/2404/amd64/clang:
|
||||
- linux-build
|
||||
|
||||
.test_linux_fedora_gcc: &test_linux_fedora_gcc
|
||||
stage: unit_test
|
||||
stage: test
|
||||
cache:
|
||||
paths:
|
||||
- /var/cache/dnf
|
||||
script:
|
||||
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
|
||||
- echo fastestmirror=True >>/etc/dnf/dnf.conf
|
||||
- dnf upgrade -y
|
||||
- dnf install -y libpcap-devel
|
||||
- build/libicsneo-unit-tests
|
||||
- dnf install -y libpcap-devel libusb1-devel
|
||||
- build/libicsneo-tests
|
||||
tags:
|
||||
- linux-build
|
||||
timeout: 5m
|
||||
@@ -213,12 +201,8 @@ unit_test linux/ubuntu/2404/amd64/clang:
|
||||
paths:
|
||||
- /var/cache/dnf
|
||||
script:
|
||||
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
|
||||
- echo fastestmirror=True >>/etc/dnf/dnf.conf
|
||||
- dnf upgrade -y
|
||||
- dnf install -y clang lld libpcap-devel cmake ninja-build git ca-certificates
|
||||
- echo "$ICS_IPA_CA_CRT" >/etc/pki/ca-trust/source/anchors/ica-ipa-ca.crt
|
||||
- update-ca-trust
|
||||
- dnf install -y clang lld libpcap-devel cmake ninja-build libusb1-devel
|
||||
- CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh
|
||||
artifacts:
|
||||
when: always
|
||||
@@ -229,167 +213,38 @@ unit_test linux/ubuntu/2404/amd64/clang:
|
||||
- linux-build
|
||||
|
||||
.test_linux_fedora_clang: &test_linux_fedora_clang
|
||||
stage: unit_test
|
||||
stage: test
|
||||
cache:
|
||||
paths:
|
||||
- /var/cache/dnf
|
||||
script:
|
||||
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
|
||||
- echo fastestmirror=True >>/etc/dnf/dnf.conf
|
||||
- dnf upgrade -y
|
||||
- dnf install -y libpcap-devel
|
||||
- build/libicsneo-unit-tests
|
||||
- dnf install -y libpcap-devel libusb1-devel
|
||||
- build/libicsneo-tests
|
||||
tags:
|
||||
- linux-build
|
||||
timeout: 5m
|
||||
|
||||
build linux/fedora/42/amd64/gcc:
|
||||
build linux/fedora/37/amd64/gcc:
|
||||
<<: *build_linux_fedora_gcc
|
||||
image: fedora:42
|
||||
image: fedora:37
|
||||
|
||||
unit_test linux/fedora/42/amd64/gcc:
|
||||
test linux/fedora/37/amd64/gcc:
|
||||
<<: *test_linux_fedora_gcc
|
||||
image: fedora:42
|
||||
image: fedora:37
|
||||
dependencies:
|
||||
- build linux/fedora/42/amd64/gcc
|
||||
- build linux/fedora/37/amd64/gcc
|
||||
needs:
|
||||
- build linux/fedora/42/amd64/gcc
|
||||
- build linux/fedora/37/amd64/gcc
|
||||
|
||||
build linux/fedora/42/amd64/clang:
|
||||
build linux/fedora/37/amd64/clang:
|
||||
<<: *build_linux_fedora_clang
|
||||
image: fedora:42
|
||||
image: fedora:37
|
||||
|
||||
unit_test linux/fedora/42/amd64/clang:
|
||||
test linux/fedora/37/amd64/clang:
|
||||
<<: *test_linux_fedora_clang
|
||||
image: fedora:42
|
||||
image: fedora:37
|
||||
dependencies:
|
||||
- build linux/fedora/42/amd64/clang
|
||||
- build linux/fedora/37/amd64/clang
|
||||
needs:
|
||||
- build linux/fedora/42/amd64/clang
|
||||
|
||||
build linux/fedora/43/amd64/gcc:
|
||||
<<: *build_linux_fedora_gcc
|
||||
image: fedora:43
|
||||
|
||||
unit_test linux/fedora/43/amd64/gcc:
|
||||
<<: *test_linux_fedora_gcc
|
||||
image: fedora:43
|
||||
dependencies:
|
||||
- build linux/fedora/43/amd64/gcc
|
||||
needs:
|
||||
- build linux/fedora/43/amd64/gcc
|
||||
|
||||
build linux/fedora/43/amd64/clang:
|
||||
<<: *build_linux_fedora_clang
|
||||
image: fedora:43
|
||||
|
||||
unit_test linux/fedora/43/amd64/clang:
|
||||
<<: *test_linux_fedora_clang
|
||||
image: fedora:43
|
||||
dependencies:
|
||||
- build linux/fedora/43/amd64/clang
|
||||
needs:
|
||||
- build linux/fedora/43/amd64/clang
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Python Module
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
build python/linux/amd64:
|
||||
stage: build
|
||||
tags:
|
||||
- linux-native-amd64
|
||||
variables:
|
||||
CIBW_BEFORE_ALL: sh ci/bootstrap-cibuildwheel.sh && sh ci/bootstrap-libpcap.sh
|
||||
CIBW_BUILD: "*manylinux*" # no musl
|
||||
CIBW_ARCHS: x86_64
|
||||
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install
|
||||
script:
|
||||
- sh ci/build-wheel-posix.sh
|
||||
artifacts:
|
||||
paths:
|
||||
- wheelhouse
|
||||
|
||||
build python/linux/arm64:
|
||||
stage: build
|
||||
tags:
|
||||
- arm64-linux-build
|
||||
variables:
|
||||
CIBW_BEFORE_ALL: sh ci/bootstrap-cibuildwheel.sh && sh ci/bootstrap-libpcap.sh
|
||||
CIBW_BUILD: "*manylinux*" # no musl
|
||||
CIBW_ARCHS: aarch64
|
||||
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/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
|
||||
CIBW_ARCHS: arm64
|
||||
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=$CI_PROJECT_DIR/libpcap/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.13
|
||||
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
|
||||
needs:
|
||||
- build python/linux/amd64
|
||||
- build python/linux/arm64
|
||||
- build python/macos
|
||||
- build python/windows
|
||||
|
||||
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
|
||||
needs:
|
||||
- deploy python/pypi
|
||||
script:
|
||||
- apk add git
|
||||
- git push https://$LIBICSNEO_GITHUB_USERNAME:$LIBICSNEO_GITHUB_TOKEN@github.com/intrepidcs/libicsneo.git HEAD:master
|
||||
- build linux/fedora/37/amd64/clang
|
||||
|
||||
@@ -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
|
||||
+21
-2
@@ -3,5 +3,24 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666"
|
||||
KERNEL=="ttyUSB?", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666"
|
||||
KERNEL=="ttyACM?", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666"
|
||||
|
||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="093c", KERNEL=="ttyUSB*", \
|
||||
RUN+="/bin/sh -c 'echo $id:1.0>/sys/bus/usb/drivers/ftdi_sio/unbind'"
|
||||
# neoVI ION/PLASMA PIDs are not in the latest ftdi_sio driver so lets make a
|
||||
# rule to add it when we see a new unclaimed device.
|
||||
# PLASMA = 0x0801, ION = 0x0901
|
||||
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \
|
||||
ATTRS{idVendor}=="093c", ATTRS{idProduct}=="0801", \
|
||||
DRIVER=="", \
|
||||
RUN+="/sbin/modprobe -b ftdi_sio"
|
||||
ACTION=="add", SUBSYSTEM=="drivers", \
|
||||
ENV{DEVPATH}=="/bus/usb-serial/drivers/ftdi_sio", \
|
||||
ATTR{new_id}="093c 0801"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \
|
||||
ATTRS{idVendor}=="093c", ATTRS{idProduct}=="0901", \
|
||||
DRIVER=="", \
|
||||
RUN+="/sbin/modprobe -b ftdi_sio"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \
|
||||
ATTRS{idVendor}=="093c", ATTRS{idProduct}=="1000", \
|
||||
DRIVER=="", \
|
||||
RUN+="/sbin/modprobe -b ftdi_sio"
|
||||
ACTION=="add", SUBSYSTEM=="drivers", \
|
||||
ENV{DEVPATH}=="/bus/usb-serial/drivers/ftdi_sio", \
|
||||
ATTR{new_id}="093c 0901"
|
||||
|
||||
+145
-145
@@ -1,18 +1,14 @@
|
||||
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)
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
|
||||
option(LIBICSNEO_BUILD_UNIT_TESTS "Build unit tests." OFF)
|
||||
option(LIBICSNEO_BUILD_TESTS "Build all 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")
|
||||
|
||||
# Device Drivers
|
||||
@@ -22,13 +18,14 @@ set(LIBICSNEO_NPCAP_INCLUDE_DIR "" CACHE STRING "Npcap include directory; set to
|
||||
option(LIBICSNEO_ENABLE_FIRMIO "Enable communication between Linux and CoreMini within the same device" OFF)
|
||||
option(LIBICSNEO_ENABLE_RAW_ETHERNET "Enable devices which communicate over raw ethernet" ON)
|
||||
option(LIBICSNEO_ENABLE_CDCACM "Enable devices which communicate over USB CDC ACM" ON)
|
||||
option(LIBICSNEO_ENABLE_ANDROIDUSB "Enable devices which communicate over USB CDC ACM on Android" ON)
|
||||
option(LIBICSNEO_ENABLE_FTDI "Enable devices which communicate over USB FTDI2XX" ON)
|
||||
option(LIBICSNEO_ENABLE_TCP "Enable devices which communicate over TCP" OFF)
|
||||
option(LIBICSNEO_ENABLE_DXX "Enable devices which communicate over D2XX/D3XX via libredxx" ON)
|
||||
option(LIBICSNEO_ENABLE_FTD3XX "Enable devices which communicate over USB FTD3XX" ON)
|
||||
|
||||
option(LIBICSNEO_ENABLE_BINDINGS_PYTHON "Enable Python library" OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
@@ -36,17 +33,19 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
# Enable Warnings
|
||||
if(MSVC)
|
||||
set(LIBICSNEO_COMPILER_WARNINGS /W4)
|
||||
# Force to always compile with W4
|
||||
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
endif()
|
||||
# http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html
|
||||
# Still supported until a suitable replacement is standardized
|
||||
add_definitions(-D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING)
|
||||
add_definitions(-D_ITERATOR_DEBUG_LEVEL=0)
|
||||
else() #if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(LIBICSNEO_COMPILER_WARNINGS -Wall -Wno-switch -Wno-unknown-pragmas)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-switch -Wno-unknown-pragmas")
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# doxygen
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
@@ -104,7 +103,6 @@ endif()
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SRC
|
||||
platform/windows/strings.cpp
|
||||
platform/windows/registry.cpp
|
||||
)
|
||||
|
||||
@@ -115,11 +113,17 @@ if(WIN32)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_CDCACM)
|
||||
if(LIBICSNEO_ENABLE_CDCACM OR LIBICSNEO_ENABLE_FTDI)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/windows/cdcacm.cpp
|
||||
platform/windows/vcp.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
elseif(LIBICSNEO_ENABLE_ANDROIDUSB)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/android/androidusb.cpp
|
||||
)
|
||||
|
||||
else() # Darwin or Linux
|
||||
set(PLATFORM_SRC)
|
||||
|
||||
@@ -135,6 +139,12 @@ else() # Darwin or Linux
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_FTDI)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/ftdi.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_CDCACM)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/cdcacm.cpp
|
||||
@@ -158,9 +168,52 @@ else() # Darwin or Linux
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_DXX)
|
||||
|
||||
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/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/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/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/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/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/23.28.0/libftd3xx-1.0.14-linux-armhf.zip")
|
||||
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=d813008117422cae958f7c71a065cdac0d31dca3b24809d3ab5e13604a9c3fb1")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT LIBICSNEO_FTD3XX_URL)
|
||||
message(FATAL_ERROR "Unsupported platform for FTD3XX driver")
|
||||
endif()
|
||||
FetchContent_Declare(
|
||||
ftdi3xx
|
||||
URL ${LIBICSNEO_FTD3XX_URL}
|
||||
URL_HASH ${LIBICSNEO_FTD3XX_URL_HASH}
|
||||
)
|
||||
FetchContent_GetProperties(ftdi3xx)
|
||||
if(NOT ftdi3xx_POPULATED)
|
||||
FetchContent_Populate(ftdi3xx)
|
||||
endif()
|
||||
set(FTD3XX_ROOT "${ftdi3xx_SOURCE_DIR}")
|
||||
endif()
|
||||
find_package(FTD3XX REQUIRED)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/dxx.cpp
|
||||
platform/ftd3xx.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -185,23 +238,14 @@ endforeach()
|
||||
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/callback/streamoutput/a2bdecoder.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/networkmutexmessage.cpp
|
||||
communication/message/clientidmessage.cpp
|
||||
communication/message/transmitmessage.cpp
|
||||
communication/packet/flexraypacket.cpp
|
||||
communication/packet/canpacket.cpp
|
||||
communication/packet/a2bpacket.cpp
|
||||
communication/packet/spipacket.cpp
|
||||
communication/packet/ethernetpacket.cpp
|
||||
communication/packet/versionpacket.cpp
|
||||
communication/packet/iso9141packet.cpp
|
||||
@@ -216,7 +260,6 @@ set(SRC_FILES
|
||||
communication/packet/componentversionpacket.cpp
|
||||
communication/packet/supportedfeaturespacket.cpp
|
||||
communication/packet/genericbinarystatuspacket.cpp
|
||||
communication/packet/hardwareinfopacket.cpp
|
||||
communication/decoder.cpp
|
||||
communication/encoder.cpp
|
||||
communication/ethernetpacketizer.cpp
|
||||
@@ -225,9 +268,6 @@ set(SRC_FILES
|
||||
communication/communication.cpp
|
||||
communication/driver.cpp
|
||||
communication/livedata.cpp
|
||||
core/ringbuffer.cpp
|
||||
core/crc32.cpp
|
||||
core/macseccfg.cpp
|
||||
device/extensions/flexray/extension.cpp
|
||||
device/extensions/flexray/controller.cpp
|
||||
device/idevicesettings.cpp
|
||||
@@ -241,24 +281,6 @@ set(SRC_FILES
|
||||
disk/plasiondiskreaddriver.cpp
|
||||
disk/extextractordiskreaddriver.cpp
|
||||
disk/fat.cpp
|
||||
disk/diskdetails.cpp
|
||||
disk/vsa/vsa.cpp
|
||||
disk/vsa/vsa02.cpp
|
||||
disk/vsa/vsa03.cpp
|
||||
disk/vsa/vsa04.cpp
|
||||
disk/vsa/vsa05.cpp
|
||||
disk/vsa/vsa06.cpp
|
||||
disk/vsa/vsa07.cpp
|
||||
disk/vsa/vsa08.cpp
|
||||
disk/vsa/vsa09.cpp
|
||||
disk/vsa/vsa0b.cpp
|
||||
disk/vsa/vsa0c.cpp
|
||||
disk/vsa/vsa0d.cpp
|
||||
disk/vsa/vsa0e.cpp
|
||||
disk/vsa/vsa0f.cpp
|
||||
disk/vsa/vsa6a.cpp
|
||||
disk/vsa/vsaparser.cpp
|
||||
platform/servd.cpp
|
||||
${PLATFORM_SRC}
|
||||
)
|
||||
|
||||
@@ -319,10 +341,8 @@ 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>)
|
||||
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)
|
||||
target_compile_options(icsneocpp PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
|
||||
message("Loaded extensions: " ${LIBICSNEO_EXTENSION_TARGETS})
|
||||
target_link_libraries(icsneocpp PUBLIC ${LIBICSNEO_EXTENSION_TARGETS})
|
||||
if(LIBICSNEO_ENABLE_FIRMIO)
|
||||
@@ -333,47 +353,64 @@ if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
endif()
|
||||
if(LIBICSNEO_ENABLE_CDCACM)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_CDCACM)
|
||||
if(APPLE)
|
||||
find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation REQUIRED)
|
||||
find_library(IO_KIT_FRAMEWORK IOKit REQUIRED)
|
||||
target_link_libraries(icsneocpp PRIVATE ${CORE_FOUNDATION_FRAMEWORK} ${IO_KIT_FRAMEWORK})
|
||||
endif()
|
||||
endif()
|
||||
if(LIBICSNEO_ENABLE_DXX)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_DXX)
|
||||
target_link_libraries(icsneocpp PRIVATE libredxx::libredxx)
|
||||
if(LIBICSNEO_ENABLE_FTDI)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_FTDI)
|
||||
endif()
|
||||
if(LIBICSNEO_ENABLE_FTD3XX)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_FTD3XX)
|
||||
target_link_libraries(icsneocpp PRIVATE FTD3XX::FTD3XX)
|
||||
endif()
|
||||
if(LIBICSNEO_ENABLE_TCP)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_TCP)
|
||||
if(WIN32)
|
||||
target_link_libraries(icsneocpp PRIVATE ws2_32 iphlpapi)
|
||||
target_link_libraries(icsneocpp PRIVATE ws2_32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_ANDROIDUSB)
|
||||
add_library(libusb SHARED IMPORTED)
|
||||
set_target_properties(libusb PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/third-party/libusb/android/libs/${ANDROID_ABI}/libusb1.0.so)
|
||||
target_include_directories(icsneocpp PRIVATE third-party/libusb/libusb)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_ANDROIDUSB)
|
||||
target_link_libraries(icsneocpp PRIVATE android log libusb)
|
||||
endif()
|
||||
|
||||
# fatfs
|
||||
add_subdirectory(third-party/fatfs)
|
||||
set_property(TARGET fatfs PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(icsneocpp PRIVATE fatfs)
|
||||
|
||||
# dxx
|
||||
if(LIBICSNEO_ENABLE_DXX)
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(libredxx
|
||||
GIT_REPOSITORY https://github.com/Zeranoe/libredxx.git
|
||||
GIT_TAG e1fe2bd6ba6079b17037379d78f3f18024b389d7
|
||||
)
|
||||
set(LIBREDXX_DISABLE_INSTALL ON)
|
||||
FetchContent_MakeAvailable(libredxx)
|
||||
endif()
|
||||
# libftdi
|
||||
if(LIBICSNEO_ENABLE_FTDI)
|
||||
if(NOT WIN32)
|
||||
target_include_directories(icsneocpp PUBLIC third-party/libftdi/src)
|
||||
set(LIBFTDI_DOCUMENTATION OFF CACHE INTERNAL "")
|
||||
set(LIBFTDI_BUILD_TESTS OFF CACHE INTERNAL "")
|
||||
set(LIBFTDI_INSTALL OFF CACHE INTERNAL "")
|
||||
set(LIBFTDI_PYTHON_BINDINGS OFF CACHE INTERNAL "")
|
||||
set(LIBFTDI_LINK_PYTHON_LIBRARY OFF CACHE INTERNAL "")
|
||||
set(FTDIPP OFF CACHE INTERNAL "")
|
||||
set(FTDI_EEPROM OFF CACHE INTERNAL "")
|
||||
add_subdirectory(third-party/libftdi)
|
||||
target_include_directories(icsneocpp PRIVATE ${LIBUSB_INCLUDE_DIR})
|
||||
|
||||
find_package(Threads)
|
||||
set_property(TARGET ftdi1-static PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(icsneocpp PUBLIC ftdi1-static)
|
||||
target_link_libraries(icsneocpp PUBLIC ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif(NOT WIN32)
|
||||
endif(LIBICSNEO_ENABLE_FTDI)
|
||||
|
||||
# pcap
|
||||
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)
|
||||
@@ -382,21 +419,6 @@ if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
endif(WIN32)
|
||||
endif(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
|
||||
# protobuf
|
||||
if(DEFINED ENV{LIBICSNEO_ICSPB_REPO})
|
||||
set(LIBICSNEO_ICSPB_REPO "$ENV{LIBICSNEO_ICSPB_REPO}")
|
||||
endif()
|
||||
if(NOT LIBICSNEO_ICSPB_REPO)
|
||||
set(LIBICSNEO_ICSPB_REPO https://github.com/intrepidcs/icspb.git)
|
||||
endif()
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(icspb
|
||||
GIT_REPOSITORY ${LIBICSNEO_ICSPB_REPO}
|
||||
GIT_TAG 48df5dd7fd0c38034f82a2f94e0eada404d5e2b9
|
||||
)
|
||||
FetchContent_MakeAvailable(icspb)
|
||||
target_link_libraries(icsneocpp PRIVATE icspb::icspb)
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOC)
|
||||
add_library(icsneoc SHARED api/icsneoc/icsneoc.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc)
|
||||
target_include_directories(icsneoc
|
||||
@@ -408,7 +430,11 @@ if(LIBICSNEO_BUILD_ICSNEOC)
|
||||
)
|
||||
target_link_libraries(icsneoc PRIVATE icsneocpp)
|
||||
target_compile_features(icsneoc PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||
target_compile_options(icsneoc PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
|
||||
if(LIBICSNEO_ENABLE_ANDROIDUSB)
|
||||
target_link_libraries(icsneoc PRIVATE android log)
|
||||
target_include_directories(icsneoc PRIVATE third-party/libusb/libusb)
|
||||
target_compile_definitions(icsneoc PRIVATE ICSNEO_ENABLE_ANDROIDUSB)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOC_STATIC)
|
||||
@@ -422,8 +448,6 @@ if(LIBICSNEO_BUILD_ICSNEOC_STATIC)
|
||||
)
|
||||
target_link_libraries(icsneoc-static PUBLIC icsneocpp)
|
||||
target_compile_features(icsneoc-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||
target_compile_definitions(icsneoc-static PUBLIC ICSNEOC_BUILD_STATIC)
|
||||
target_compile_options(icsneoc-static PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOLEGACY)
|
||||
@@ -442,67 +466,43 @@ if(LIBICSNEO_BUILD_ICSNEOLEGACY)
|
||||
)
|
||||
target_link_libraries(icsneolegacy PRIVATE icsneocpp)
|
||||
target_compile_features(icsneolegacy PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||
target_compile_options(icsneolegacy PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC)
|
||||
add_library(icsneolegacy-static STATIC
|
||||
api/icsneolegacy/icsneolegacy.cpp
|
||||
api/icsneolegacy/icsneolegacyextra.cpp
|
||||
api/icsneoc/icsneoc.cpp
|
||||
)
|
||||
|
||||
target_include_directories(icsneolegacy-static
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(icsneolegacy-static PUBLIC icsneocpp)
|
||||
target_compile_features(icsneolegacy-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||
target_compile_definitions(icsneolegacy-static PUBLIC ICSNEOC_BUILD_STATIC)
|
||||
target_compile_options(icsneolegacy-static PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
|
||||
endif()
|
||||
|
||||
add_subdirectory(bindings)
|
||||
|
||||
# googletest
|
||||
if(LIBICSNEO_BUILD_UNIT_TESTS)
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG 6986c2b575f77135401a4e1c65a7a42f20e18fef
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
if(LIBICSNEO_BUILD_TESTS)
|
||||
if(WIN32)
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
add_executable(libicsneo-unit-tests
|
||||
test/unit/main.cpp
|
||||
test/unit/diskdriverreadtest.cpp
|
||||
test/unit/diskdriverwritetest.cpp
|
||||
test/unit/eventmanagertest.cpp
|
||||
test/unit/ethernetpacketizertest.cpp
|
||||
test/unit/i2cencoderdecodertest.cpp
|
||||
test/unit/linencoderdecodertest.cpp
|
||||
test/unit/a2bencoderdecodertest.cpp
|
||||
test/unit/mdioencoderdecodertest.cpp
|
||||
test/unit/livedataencoderdecodertest.cpp
|
||||
test/unit/ringbuffertest.cpp
|
||||
test/unit/apperrordecodertest.cpp
|
||||
test/unit/windowsstrings.cpp
|
||||
test/unit/periodictest.cpp
|
||||
if (NOT TARGET gtest)
|
||||
add_subdirectory(third-party/googletest-master)
|
||||
endif()
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 2.8.11)
|
||||
include_directories("${gtest_SOURCE_DIR}/include")
|
||||
endif()
|
||||
|
||||
add_executable(libicsneo-tests
|
||||
test/main.cpp
|
||||
test/diskdriverreadtest.cpp
|
||||
test/diskdriverwritetest.cpp
|
||||
test/eventmanagertest.cpp
|
||||
test/ethernetpacketizertest.cpp
|
||||
test/i2cencoderdecodertest.cpp
|
||||
test/linencoderdecodertest.cpp
|
||||
test/a2bencoderdecodertest.cpp
|
||||
test/mdioencoderdecodertest.cpp
|
||||
test/livedataencoderdecodertest.cpp
|
||||
)
|
||||
|
||||
target_compile_options(libicsneo-unit-tests PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
|
||||
target_link_libraries(libicsneo-tests gtest gtest_main)
|
||||
target_link_libraries(libicsneo-tests icsneocpp)
|
||||
|
||||
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
||||
target_link_libraries(libicsneo-unit-tests icsneocpp)
|
||||
|
||||
target_include_directories(libicsneo-unit-tests PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
|
||||
target_include_directories(libicsneo-tests PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_test(NAME libicsneo-unit-test-suite COMMAND libicsneo-unit-tests)
|
||||
add_test(NAME libicsneo-test-suite COMMAND libicsneo-tests)
|
||||
endif()
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# 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
|
||||
|
||||
- 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
|
||||
@@ -1,29 +1,13 @@
|
||||
Copyright (c) 2018-2025 Intrepid Control Systems, Inc.
|
||||
Copyright 2018-2023 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,46 +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-Gemini
|
||||
- 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
|
||||
```
|
||||
|
||||
+14
-48
@@ -111,11 +111,15 @@ bool icsneo_isValidNeoDevice(const neodevice_t* device) {
|
||||
}
|
||||
|
||||
bool icsneo_openDevice(const neodevice_t* device) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
if(!icsneo_isValidNeoDevice(device)) {
|
||||
//todo error
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!device->device->open())
|
||||
return false;
|
||||
if(!device->device->open()) {
|
||||
//todo error
|
||||
return false;
|
||||
}
|
||||
|
||||
// We connected successfully, move the device to connected devices
|
||||
std::vector<std::vector<std::shared_ptr<Device>>::iterator> itemsToMove;
|
||||
@@ -144,17 +148,8 @@ bool icsneo_closeDevice(const neodevice_t* device) {
|
||||
if((*it).get() == device->device)
|
||||
itemsToDelete.push_back(it);
|
||||
}
|
||||
for(auto it : itemsToDelete) {
|
||||
// Move it back into connectable devices so we can open it again.
|
||||
// Without this we will be unable to use/reopen the device due to
|
||||
// icsneo_isValidNeoDevice / icsneo_openDevice checks against this
|
||||
// container. Since its closed we are in a connectable state again.
|
||||
// Notice: When we search again this will be cleaned up by
|
||||
// icsneo_freeUnconnectedDevices()
|
||||
connectableFoundDevices.push_back(*it);
|
||||
// Remove it from the connected devices as we are no longer connected.
|
||||
for(auto it : itemsToDelete)
|
||||
connectedDevices.erase(it);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -229,7 +224,6 @@ bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_
|
||||
return false;
|
||||
|
||||
*items = storage.size();
|
||||
|
||||
for(size_t i = 0; i < *items; i++) {
|
||||
// For each message, copy into neomessage_t buffer given
|
||||
messages[i] = CreateNeoMessage(storage[i]);
|
||||
@@ -750,40 +744,12 @@ int icsneo_getDeviceStatus(const neodevice_t* device, void* status, size_t* size
|
||||
|
||||
return true;
|
||||
}
|
||||
#ifdef ICSNEO_ENABLE_ANDROIDUSB
|
||||
bool icsneo_addSysFileDescriptor(int sysFd) {
|
||||
return icsneo::ANDROIDUSB::addSystemFD(sysFd);
|
||||
|
||||
bool icsneo_isOnlineSupported(const neodevice_t* device) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
return device->device->isOnlineSupported();
|
||||
}
|
||||
|
||||
bool icsneo_requestTC10Wake(const neodevice_t* device, neonetid_t netid) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
return device->device->requestTC10Wake((Network::NetID)netid);
|
||||
bool icsneo_removeSysFileDescriptor(int sysFd) {
|
||||
return icsneo::ANDROIDUSB::removeSystemFD(sysFd);
|
||||
}
|
||||
|
||||
bool icsneo_requestTC10Sleep(const neodevice_t* device, neonetid_t netid) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
return device->device->requestTC10Sleep((Network::NetID)netid);
|
||||
}
|
||||
|
||||
bool icsneo_getTC10Status(const neodevice_t* device, neonetid_t netid, neotc10status_t* status) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
const auto statusMsg = device->device->getTC10Status((Network::NetID)netid);
|
||||
|
||||
if(!statusMsg)
|
||||
return false;
|
||||
|
||||
status->wakeStatus = (neotc10wakestatus_t)statusMsg->wakeStatus;
|
||||
status->sleepStatus = (neotc10sleepstatus_t)statusMsg->sleepStatus;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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-2023"
|
||||
VALUE "OriginalFilename", "icsneoc.dll"
|
||||
VALUE "ProductName", "libicsneo"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
|
||||
+101
-144
@@ -72,11 +72,6 @@ static constexpr const char* MESSAGE_MAX_LENGTH_EXCEEDED = "The message was too
|
||||
static constexpr const char* VALUE_NOT_YET_PRESENT = "The value is not yet present.";
|
||||
static constexpr const char* TIMEOUT = "The timeout was reached.";
|
||||
static constexpr const char* WIVI_NOT_SUPPORTED = "Wireless neoVI functions are not supported on this device.";
|
||||
static constexpr const char* RESTRICTED_ENTRY_FLAG = "Attempted to set a restricted flag in a Root Directory entry.";
|
||||
static constexpr const char* NOT_SUPPORTED = "The requested feature is not supported.";
|
||||
static constexpr const char* FIXED_POINT_OVERFLOW = "Value is too large to convert to fixed point.";
|
||||
static constexpr const char* FIXED_POINT_PRECISION = "Value is too small for fixed point precision.";
|
||||
static constexpr const char* SYSCALL_ERROR = "Error returned from syscall, check errno/GetLastError().";
|
||||
|
||||
// Device Errors
|
||||
static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!";
|
||||
@@ -121,14 +116,6 @@ static constexpr const char* A2B_MESSAGE_INCOMPLETE_FRAME = "At least one of the
|
||||
static constexpr const char* COREMINI_UPLOAD_VERSION_MISMATCH = "The version of the coremini engine on the device and the script uploaded are not the same.";
|
||||
static constexpr const char* DISK_NOT_CONNECTED = "The program tried to access a disk that is not connected.";
|
||||
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";
|
||||
static constexpr const char* DISK_FORMAT_NOT_SUPPORTED = "Disk formatting is not supported on this device.";
|
||||
static constexpr const char* DISK_FORMAT_INVALID_COUNT = "Disk format config disk count is mismatched with device disk count.";
|
||||
|
||||
|
||||
|
||||
// Transport Errors
|
||||
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
||||
@@ -147,49 +134,44 @@ static constexpr const char* ERROR_SETTING_SOCKET_OPTION = "A call to setsockopt
|
||||
static constexpr const char* GETIFADDRS_ERROR = "A call to getifaddrs() failed.";
|
||||
static constexpr const char* SEND_TO_ERROR = "A call to sendto() failed.";
|
||||
|
||||
// VSA
|
||||
static constexpr const char* VSA_BUFFER_CORRUPTED = "VSA data in record buffer is corrupted.";
|
||||
static constexpr const char* VSA_TIMESTAMP_NOT_FOUND = "Unable to find a VSA record with a valid timestamp.";
|
||||
static constexpr const char* VSA_BUFFER_FORMAT_ERROR = "VSA record buffer is formatted incorrectly.";
|
||||
static constexpr const char* VSA_MAX_READ_ATTEMPTS_REACHED = "Reached max attempts to read VSA records before exit.";
|
||||
static constexpr const char* VSA_BYTE_PARSE_FAILURE = "Failure to parse record bytes from VSA buffer.";
|
||||
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.";
|
||||
|
||||
// MACSEC
|
||||
static constexpr const char* MACSEC_SECY_LIMIT = "Attempted to exceed the limit of SecY additions to this port";
|
||||
static constexpr const char* MACSEC_RULE_LIMIT = "Attempted to exceed the limit of rule additions to this port";
|
||||
static constexpr const char* MACSEC_SA_LIMIT = "Attempted to exceed the limit of SA additions to this port";
|
||||
static constexpr const char* MACSEC_INVALID_SECY_INDEX = "Attempted to access an invalid SecY index";
|
||||
static constexpr const char* MACSEC_INVALID_SA_INDEX = "Attempted to access an invalid SA index";
|
||||
static constexpr const char* MACSEC_INVALID_RULE_INDEX = "Attempted to access an invalid rule index";
|
||||
static constexpr const char* MACSEC_REKEY_NOT_ENABLED = "Attempted to set rekey SA when rekey was not enabled";
|
||||
static constexpr const char* MACSEC_NOT_SUPPORTED = "MACsec is not supported on this device";
|
||||
static constexpr const char* MACSEC_CONFIG_MISMATCH = "Attempted to configure device with a macsec configuration for a different device";
|
||||
// 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";
|
||||
|
||||
// DXX
|
||||
static constexpr const char* DXX_ERROR_SYS = "System error, check errno/GetLastError()";
|
||||
static constexpr const char* DXX_ERROR_INT = "DXX interrupt called";
|
||||
static constexpr const char* DXX_ERROR_OVERFLOW = "Overflow in DXX";
|
||||
static constexpr const char* DXX_ERROR_IO = "I/O failure in DXX";
|
||||
static constexpr const char* DXX_ERROR_ARG = "Invalid arg passed to DXX";
|
||||
// FTD3XX
|
||||
static constexpr const char* FT_OK = "FTD3XX success.";
|
||||
static constexpr const char* FT_INVALID_HANDLE = "Invalid FTD3XX handle.";
|
||||
static constexpr const char* FT_DEVICE_NOT_FOUND = "FTD3XX device not found.";
|
||||
static constexpr const char* FT_DEVICE_NOT_OPENED = "FTD3XX device not opened.";
|
||||
static constexpr const char* FT_IO_ERROR = "FTD3XX IO error.";
|
||||
static constexpr const char* FT_INSUFFICIENT_RESOURCES = "Insufficient resources for FTD3XX.";
|
||||
static constexpr const char* FT_INVALID_PARAMETER = "Invalid FTD3XX parameter.";
|
||||
static constexpr const char* FT_INVALID_BAUD_RATE = "Invalid FTD3XX baud rate.";
|
||||
static constexpr const char* FT_DEVICE_NOT_OPENED_FOR_ERASE = "FTD3XX device not opened for erase.";
|
||||
static constexpr const char* FT_DEVICE_NOT_OPENED_FOR_WRITE = "FTD3XX not opened for write.";
|
||||
static constexpr const char* FT_FAILED_TO_WRITE_DEVICE = "FTD3XX failed to write device.";
|
||||
static constexpr const char* FT_EEPROM_READ_FAILED = "FTD3XX EEPROM read failed.";
|
||||
static constexpr const char* FT_EEPROM_WRITE_FAILED = "FTD3XX EEPROM write failed.";
|
||||
static constexpr const char* FT_EEPROM_ERASE_FAILED = "FTD3XX EEPROM erase failed.";
|
||||
static constexpr const char* FT_EEPROM_NOT_PRESENT = "FTD3XX EEPROM not present.";
|
||||
static constexpr const char* FT_EEPROM_NOT_PROGRAMMED = "FTD3XX EEPROM not programmed.";
|
||||
static constexpr const char* FT_INVALID_ARGS = "Invalid FTD3XX arguments.";
|
||||
static constexpr const char* FT_NOT_SUPPORTED = "FTD3XX not supported.";
|
||||
static constexpr const char* FT_NO_MORE_ITEMS = "No more FTD3XX items.";
|
||||
static constexpr const char* FT_TIMEOUT = "FTD3XX timeout.";
|
||||
static constexpr const char* FT_OPERATION_ABORTED = "FTD3XX operation aborted.";
|
||||
static constexpr const char* FT_RESERVED_PIPE = "Reserved FTD3XX pipe.";
|
||||
static constexpr const char* FT_INVALID_CONTROL_REQUEST_DIRECTION = "Invalid FTD3XX control request direction.";
|
||||
static constexpr const char* FT_INVALID_CONTROL_REQUEST_TYPE = "Invalid FTD3XX control request type.";
|
||||
static constexpr const char* FT_IO_PENDING = "FTD3XX IO pending.";
|
||||
static constexpr const char* FT_IO_INCOMPLETE = "FTD3XX IO incomplete.";
|
||||
static constexpr const char* FT_HANDLE_EOF = "Handle FTD3XX EOF.";
|
||||
static constexpr const char* FT_BUSY = "FTD3XX busy.";
|
||||
static constexpr const char* FT_NO_SYSTEM_RESOURCES = "No FTD3XX system resources.";
|
||||
static constexpr const char* FT_DEVICE_LIST_NOT_READY = "FTD3XX device list not ready.";
|
||||
static constexpr const char* FT_DEVICE_NOT_CONNECTED = "FTD3XX device not connected.";
|
||||
static constexpr const char* FT_INCORRECT_DEVICE_PATH = "Incorrect FTD3XX device path.";
|
||||
static constexpr const char* FT_OTHER_ERROR = "Other FTD3XX error.";
|
||||
|
||||
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
|
||||
@@ -225,16 +207,6 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
return TIMEOUT;
|
||||
case Type::WiVINotSupported:
|
||||
return WIVI_NOT_SUPPORTED;
|
||||
case Type::RestrictedEntryFlag:
|
||||
return RESTRICTED_ENTRY_FLAG;
|
||||
case Type::NotSupported:
|
||||
return NOT_SUPPORTED;
|
||||
case Type::FixedPointOverflow:
|
||||
return FIXED_POINT_OVERFLOW;
|
||||
case Type::FixedPointPrecision:
|
||||
return FIXED_POINT_PRECISION;
|
||||
case Type::SyscallError:
|
||||
return SYSCALL_ERROR;
|
||||
|
||||
// Device Errors
|
||||
case Type::PollingMessageOverflow:
|
||||
@@ -321,12 +293,6 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
return DISK_NOT_CONNECTED;
|
||||
case Type::UnexpectedResponse:
|
||||
return UNEXPECTED_RESPONSE;
|
||||
case Type::LINSettingsNotAvailable:
|
||||
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;
|
||||
@@ -358,83 +324,74 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
return GETIFADDRS_ERROR;
|
||||
case Type::SendToError:
|
||||
return SEND_TO_ERROR;
|
||||
case Type::GPTPNotSupported:
|
||||
return GPTP_NOT_SUPPORTED;
|
||||
case Type::DiskFormatNotSupported:
|
||||
return DISK_FORMAT_NOT_SUPPORTED;
|
||||
case Type::DiskFormatInvalidCount:
|
||||
return DISK_FORMAT_INVALID_COUNT;
|
||||
|
||||
// VSA
|
||||
case Type::VSABufferCorrupted:
|
||||
return VSA_BUFFER_CORRUPTED;
|
||||
case Type::VSATimestampNotFound:
|
||||
return VSA_TIMESTAMP_NOT_FOUND;
|
||||
case Type::VSABufferFormatError:
|
||||
return VSA_BUFFER_FORMAT_ERROR;
|
||||
case Type::VSAMaxReadAttemptsReached:
|
||||
return VSA_MAX_READ_ATTEMPTS_REACHED;
|
||||
case Type::VSAByteParseFailure:
|
||||
return VSA_BYTE_PARSE_FAILURE;
|
||||
case Type::VSAExtendedMessageError:
|
||||
return VSA_EXTENDED_MESSAGE_ERROR;
|
||||
case Type::VSAOtherError:
|
||||
return VSA_OTHER_ERROR;
|
||||
|
||||
// MACSEC
|
||||
case Type::MACsecSecYLimit:
|
||||
return MACSEC_SECY_LIMIT;
|
||||
case Type::MACsecSaLimit:
|
||||
return MACSEC_SA_LIMIT;
|
||||
case Type::MACsecRuleLimit:
|
||||
return MACSEC_RULE_LIMIT;
|
||||
case Type::MACsecInvalidSecYIndex:
|
||||
return MACSEC_INVALID_SECY_INDEX;
|
||||
case Type::MACsecInvalidSaIndex:
|
||||
return MACSEC_INVALID_SA_INDEX;
|
||||
case Type::MACsecInvalidRuleIndex:
|
||||
return MACSEC_INVALID_RULE_INDEX;
|
||||
case Type::MACsecRekeyNotEnabled:
|
||||
return MACSEC_REKEY_NOT_ENABLED;
|
||||
case Type::MACsecNotSupported:
|
||||
return MACSEC_NOT_SUPPORTED;
|
||||
case Type::MACsecConfigMismatch:
|
||||
return MACSEC_CONFIG_MISMATCH;
|
||||
// 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;
|
||||
|
||||
// DXX
|
||||
case Type::DXXErrorSys:
|
||||
return DXX_ERROR_SYS;
|
||||
case Type::DXXErrorInt:
|
||||
return DXX_ERROR_INT;
|
||||
case Type::DXXErrorOverflow:
|
||||
return DXX_ERROR_OVERFLOW;
|
||||
case Type::DXXErrorIO:
|
||||
return DXX_ERROR_IO;
|
||||
case Type::DXXErrorArg:
|
||||
return DXX_ERROR_ARG;
|
||||
// FTD3XX
|
||||
case Type::FTOK:
|
||||
return FT_OK;
|
||||
case Type::FTInvalidHandle:
|
||||
return FT_INVALID_HANDLE;
|
||||
case Type::FTDeviceNotFound:
|
||||
return FT_DEVICE_NOT_FOUND;
|
||||
case Type::FTDeviceNotOpened:
|
||||
return FT_DEVICE_NOT_OPENED;
|
||||
case Type::FTIOError:
|
||||
return FT_IO_ERROR;
|
||||
case Type::FTInsufficientResources:
|
||||
return FT_INSUFFICIENT_RESOURCES;
|
||||
case Type::FTInvalidParameter:
|
||||
return FT_INVALID_PARAMETER;
|
||||
case Type::FTInvalidBaudRate:
|
||||
return FT_INVALID_BAUD_RATE;
|
||||
case Type::FTDeviceNotOpenedForErase:
|
||||
return FT_DEVICE_NOT_OPENED_FOR_ERASE;
|
||||
case Type::FTDeviceNotOpenedForWrite:
|
||||
return FT_DEVICE_NOT_OPENED_FOR_WRITE;
|
||||
case Type::FTFailedToWriteDevice:
|
||||
return FT_FAILED_TO_WRITE_DEVICE;
|
||||
case Type::FTEEPROMReadFailed:
|
||||
return FT_EEPROM_READ_FAILED;
|
||||
case Type::FTEEPROMWriteFailed:
|
||||
return FT_EEPROM_WRITE_FAILED;
|
||||
case Type::FTEEPROMEraseFailed:
|
||||
return FT_EEPROM_ERASE_FAILED;
|
||||
case Type::FTEEPROMNotPresent:
|
||||
return FT_EEPROM_NOT_PRESENT;
|
||||
case Type::FTEEPROMNotProgrammed:
|
||||
return FT_EEPROM_NOT_PROGRAMMED;
|
||||
case Type::FTInvalidArgs:
|
||||
return FT_INVALID_ARGS;
|
||||
case Type::FTNotSupported:
|
||||
return FT_NOT_SUPPORTED;
|
||||
case Type::FTNoMoreItems:
|
||||
return FT_NO_MORE_ITEMS;
|
||||
case Type::FTTimeout:
|
||||
return FT_TIMEOUT;
|
||||
case Type::FTOperationAborted:
|
||||
return FT_OPERATION_ABORTED;
|
||||
case Type::FTReservedPipe:
|
||||
return FT_RESERVED_PIPE;
|
||||
case Type::FTInvalidControlRequestDirection:
|
||||
return FT_INVALID_CONTROL_REQUEST_DIRECTION;
|
||||
case Type::FTInvalidControlRequestType:
|
||||
return FT_INVALID_CONTROL_REQUEST_TYPE;
|
||||
case Type::FTIOPending:
|
||||
return FT_IO_PENDING;
|
||||
case Type::FTIOIncomplete:
|
||||
return FT_IO_INCOMPLETE;
|
||||
case Type::FTHandleEOF:
|
||||
return FT_HANDLE_EOF;
|
||||
case Type::FTBusy:
|
||||
return FT_BUSY;
|
||||
case Type::FTNoSystemResources:
|
||||
return FT_NO_SYSTEM_RESOURCES;
|
||||
case Type::FTDeviceListNotReady:
|
||||
return FT_DEVICE_LIST_NOT_READY;
|
||||
case Type::FTDeviceNotConnected:
|
||||
return FT_DEVICE_NOT_CONNECTED;
|
||||
case Type::FTIncorrectDevicePath:
|
||||
return FT_INCORRECT_DEVICE_PATH;
|
||||
case Type::FTOtherError:
|
||||
return FT_OTHER_ERROR;
|
||||
|
||||
// Other Errors
|
||||
case Type::TooManyEvents:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "icsneo/icsneocpp.h"
|
||||
#include "icsneo/device/devicefinder.h"
|
||||
#include <jni.h>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <Tchar.h>
|
||||
|
||||
//Basic Functions
|
||||
FINDNEODEVICES icsneoFindNeoDevices;
|
||||
OPENNEODEVICE icsneoOpenNeoDevice;
|
||||
OPENDEVICE icsneoOpenDevice;
|
||||
CLOSEPORT icsneoClosePort;
|
||||
FREEOBJECT icsneoFreeObject;
|
||||
@@ -132,6 +134,10 @@ bool LoadDLLAPI(HINSTANCE &hAPIDLL)
|
||||
if((hAPIDLL = LoadLibrary(_T("icsneo40.dll"))) == NULL)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
icsneoFindNeoDevices = (FINDNEODEVICES) GetProcAddress(hAPIDLL, "icsneoFindNeoDevices");
|
||||
icsneoOpenNeoDevice = (OPENNEODEVICE) GetProcAddress(hAPIDLL, "icsneoOpenNeoDevice");
|
||||
icsneoOpenDevice = (OPENDEVICE) GetProcAddress(hAPIDLL, "icsneoOpenDevice");
|
||||
icsneoClosePort = (CLOSEPORT) GetProcAddress(hAPIDLL, "icsneoClosePort");
|
||||
icsneoFreeObject = (FREEOBJECT) GetProcAddress(hAPIDLL, "icsneoFreeObject");
|
||||
@@ -200,7 +206,7 @@ bool LoadDLLAPI(HINSTANCE &hAPIDLL)
|
||||
|
||||
icsneoEnableDOIPLine = (ENABLEDOIPACTIVATIONLINE)GetProcAddress(hAPIDLL, "icsneoEnableDOIPLine");
|
||||
|
||||
if(!icsneoOpenDevice || !icsneoClosePort || !icsneoFreeObject ||
|
||||
if(!icsneoFindNeoDevices || !icsneoOpenNeoDevice || !icsneoOpenDevice || !icsneoClosePort || !icsneoFreeObject ||
|
||||
!icsneoTxMessages || !icsneoGetMessages || !icsneoWaitForRxMessagesWithTimeOut ||
|
||||
!icsneoGetTimeStampForMsg || !icsneoEnableNetworkRXQueue || !icsneoGetISO15765Status || !icsneoTxMessagesEx ||
|
||||
!icsneoSetISO15765RxParameters || !icsneoGetConfiguration || !icsneoSendConfiguration ||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
//FILE: icsneo40DLLAPI.H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#include "icsneo/icsnVC40.h"
|
||||
|
||||
@@ -116,6 +114,8 @@ typedef int (__stdcall *SCRIPTWRITEISO15765TXMESSAGE)(void * hObject, unsigned
|
||||
|
||||
|
||||
//Basic Functions
|
||||
extern FINDNEODEVICES icsneoFindNeoDevices;
|
||||
extern OPENNEODEVICE icsneoOpenNeoDevice;
|
||||
extern OPENDEVICE icsneoOpenDevice;
|
||||
extern CLOSEPORT icsneoClosePort;
|
||||
extern FREEOBJECT icsneoFreeObject;
|
||||
|
||||
+155
-128
@@ -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"
|
||||
@@ -12,6 +14,7 @@
|
||||
#include "icsneo/communication/network.h"
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include <cstring>
|
||||
#include <climits>
|
||||
|
||||
@@ -24,32 +27,43 @@ using namespace icsneo;
|
||||
|
||||
typedef uint64_t legacymaphandle_t;
|
||||
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};
|
||||
|
||||
static NeoDevice OldNeoDeviceFromNew(const neodevice_t* newnd)
|
||||
{
|
||||
NeoDevice oldnd = {0};
|
||||
oldnd.DeviceType = newnd->type;
|
||||
oldnd.SerialNumber = icsneo_serialStringToNum(newnd->serial);
|
||||
oldnd.NumberOfClients = 0;
|
||||
oldnd.MaxAllowedClients = 1;
|
||||
static_assert(sizeof(neodevice_handle_t) == sizeof(oldnd.Handle),
|
||||
"neodevice_handle_t size must be sizeof(int) for compatibility reasons");
|
||||
oldnd.Handle = newnd->handle;
|
||||
return oldnd;
|
||||
}
|
||||
|
||||
static bool NeoMessageToSpyMessage(const neodevice_t* device, const neomessage_t& newmsg, icsSpyMessage& oldmsg)
|
||||
{
|
||||
@@ -90,7 +104,6 @@ static bool NeoMessageToSpyMessage(const neodevice_t* device, const neomessage_t
|
||||
copyFrameData();
|
||||
break;
|
||||
case Network::Type::Ethernet:
|
||||
case Network::Type::AutomotiveEthernet:
|
||||
oldmsg.Protocol = SPY_PROTOCOL_ETHERNET;
|
||||
oldmsg.NumberBytesData = static_cast<uint8_t>(frame.length & 0xFF);
|
||||
oldmsg.NumberBytesHeader = static_cast<uint8_t>(frame.length >> 8);
|
||||
@@ -305,81 +318,109 @@ static inline size_t GetVnetAgnosticNetid(size_t fullNetid)
|
||||
int LegacyDLLExport icsneoFindDevices(NeoDeviceEx* devs, int* devCount, unsigned int* devTypes, unsigned int devTypeCount,
|
||||
POptionsFindNeoEx* POptionsFindNeoEx, unsigned int* zero)
|
||||
{
|
||||
// Match the legacy API maximum, this derives from the maximum COM Port on old windows versions.
|
||||
constexpr int MAX_NEO_DEVICES = 255;
|
||||
|
||||
// Validate arguments
|
||||
if (!devCount && *devCount < 0) {
|
||||
if (!devs || !devCount)
|
||||
return 0;
|
||||
}
|
||||
// return the size only if devs is NULL.
|
||||
if (!devs)
|
||||
{
|
||||
icsneo_findAllDevices(nullptr, (size_t*)devCount);
|
||||
return 1;
|
||||
}
|
||||
// shrink the number of devices allowed to find
|
||||
if (*devCount > MAX_NEO_DEVICES) {
|
||||
*devCount = MAX_NEO_DEVICES;
|
||||
}
|
||||
// Find all the neodevice_t devices
|
||||
std::vector<neodevice_t> neoDevices(*devCount);
|
||||
auto neoDevicesSize = neoDevices.size();
|
||||
icsneo_findAllDevices(neoDevices.data(), &neoDevicesSize);
|
||||
neoDevices.resize(neoDevicesSize);
|
||||
// Filter out the devices if needed
|
||||
// No filtering needed
|
||||
if (devTypes && devTypeCount > 0) {
|
||||
neoDevices.erase(
|
||||
std::remove_if(
|
||||
neoDevices.begin(),
|
||||
neoDevices.end(),
|
||||
[&](const auto& iter) {
|
||||
for (unsigned int i=0; i < devTypeCount; ++i) {
|
||||
if (iter.type == devTypes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
),
|
||||
neoDevices.end()
|
||||
);
|
||||
}
|
||||
// Create a NeoDeviceEx From a neodevice_t
|
||||
auto _createNeoDeviceExFrom = [](const neodevice_t* neoDevice) -> NeoDeviceEx {
|
||||
NeoDeviceEx nde = {};
|
||||
nde.neoDevice.DeviceType = neoDevice->type;
|
||||
nde.neoDevice.SerialNumber = icsneo_serialStringToNum(neoDevice->serial);
|
||||
nde.neoDevice.NumberOfClients = 0;
|
||||
nde.neoDevice.MaxAllowedClients = 1;
|
||||
static_assert(sizeof(neodevice_handle_t) == sizeof(nde.neoDevice.Handle),
|
||||
"neodevice_handle_t size must be sizeof(int) for compatibility reasons");
|
||||
nde.neoDevice.Handle = neoDevice->handle;
|
||||
return nde;
|
||||
};
|
||||
|
||||
// Create the NeoDeviceEx from the neodevice_t
|
||||
auto i = 0;
|
||||
for (const auto& neoDevice : neoDevices) {
|
||||
// Fill the look up table
|
||||
neodevices[uint64_t(neoDevice.handle) << 32 | icsneo_serialStringToNum(neoDevice.serial)] = neoDevice;
|
||||
// Create the NeoDeviceEx
|
||||
devs[i] = _createNeoDeviceExFrom(&neoDevice);
|
||||
NeoDeviceEx* nde = &devs[i];
|
||||
++i;
|
||||
// Lookup the open NeoDeviceEx devices and match the NumberOfClients value if available.
|
||||
for (auto& [neo_device, open_nde]: openneodevices) {
|
||||
// SerialNumber should always be unique so lets compare against that.
|
||||
if (nde->neoDevice.SerialNumber == open_nde->neoDevice.SerialNumber) {
|
||||
nde->neoDevice.NumberOfClients = open_nde->neoDevice.NumberOfClients;
|
||||
if (*devCount < 0 || *devCount > 255)
|
||||
return 0;
|
||||
|
||||
// Find the devices without filtering by the device type
|
||||
// We allow this to find more than the requested number,
|
||||
// as we may filter out some devices.
|
||||
constexpr const size_t MAX_DEVICES = 255;
|
||||
NeoDevice foundDevices[MAX_DEVICES];
|
||||
int NumDevices = MAX_DEVICES;
|
||||
|
||||
int filteredDeviceCount = 0;
|
||||
|
||||
if (!icsneoFindNeoDevices(0, foundDevices, &NumDevices))
|
||||
return 0;
|
||||
|
||||
for (auto i = 0; i < NumDevices; i++)
|
||||
{
|
||||
// Check if the next device would overrun the user's buffer
|
||||
// We check this up here since the documentation allows zero
|
||||
// to be specified.
|
||||
if (filteredDeviceCount >= *devCount)
|
||||
break;
|
||||
|
||||
if (devTypes && devTypeCount)
|
||||
{
|
||||
for (unsigned int j = 0; j < devTypeCount; j++)
|
||||
{
|
||||
if (foundDevices[i].DeviceType == devTypes[j])
|
||||
{
|
||||
devs[filteredDeviceCount++].neoDevice = foundDevices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
devs[filteredDeviceCount++].neoDevice = foundDevices[i];
|
||||
}
|
||||
}
|
||||
*devCount = (int)neoDevices.size();
|
||||
|
||||
*devCount = filteredDeviceCount;
|
||||
return 1; // If the function succeeds but no devices are found 1 will still be returned and devCount will equal 0
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoFindNeoDevices(unsigned long DeviceTypes, NeoDevice* pNeoDevice, int* pNumDevices)
|
||||
{
|
||||
constexpr size_t MAX_DEVICES = 255;
|
||||
size_t count = MAX_DEVICES;
|
||||
|
||||
if (pNumDevices == nullptr)
|
||||
return 0;
|
||||
|
||||
if (pNeoDevice == nullptr)
|
||||
{
|
||||
icsneo_findAllDevices(nullptr, &count);
|
||||
*pNumDevices = (int)count;
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t bufferSize = (size_t)*pNumDevices;
|
||||
if (*pNumDevices < 0 || bufferSize > MAX_DEVICES)
|
||||
return 0;
|
||||
|
||||
neodevice_t devices[MAX_DEVICES];
|
||||
icsneo_findAllDevices(devices, &count);
|
||||
if (bufferSize < count)
|
||||
count = bufferSize;
|
||||
*pNumDevices = (int)count;
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
pNeoDevice[i] = OldNeoDeviceFromNew(&devices[i]); // Write out into user memory
|
||||
neodevices[uint64_t(devices[i].handle) << 32 | icsneo_serialStringToNum(devices[i].serial)] = devices[i]; // Fill the look up table
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoOpenNeoDevice(NeoDevice* pNeoDevice, void** hObject, unsigned char* bNetworkIDs, int bConfigRead, int bSyncToPC)
|
||||
{
|
||||
if (pNeoDevice == nullptr || hObject == nullptr)
|
||||
return false;
|
||||
|
||||
neodevice_t *device;
|
||||
try
|
||||
{
|
||||
device = &neodevices.at(uint64_t(pNeoDevice->Handle) << 32 | pNeoDevice->SerialNumber);
|
||||
}
|
||||
catch (const std::out_of_range&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*hObject = device;
|
||||
if (!icsneo_openDevice(device))
|
||||
return false;
|
||||
|
||||
return icsneo_setPollingMessageLimit(device, 20000) && icsneo_enableMessagePolling(device) && icsneo_goOnline(device);
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoOpenDevice(
|
||||
NeoDeviceEx* pNeoDeviceEx,
|
||||
void** hObject,
|
||||
@@ -402,50 +443,19 @@ int LegacyDLLExport icsneoOpenDevice(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pNeoDeviceEx->neoDevice.NumberOfClients >= pNeoDeviceEx->neoDevice.MaxAllowedClients) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*hObject = device;
|
||||
if(!icsneo_openDevice(device)) {
|
||||
if(!icsneo_openDevice(device))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (icsneo_isOnlineSupported(device)) {
|
||||
if (!icsneo_setPollingMessageLimit(device, 20000)) {
|
||||
icsneo_closeDevice(device);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!icsneo_enableMessagePolling(device)) {
|
||||
icsneo_closeDevice(device);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!icsneo_goOnline(device)) {
|
||||
icsneo_closeDevice(device);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pNeoDeviceEx->neoDevice.NumberOfClients = 1;
|
||||
// Add the open NeoDevice to the container so we can decrement NumberOfClients on close
|
||||
openneodevices[device] = pNeoDeviceEx;
|
||||
|
||||
return true;
|
||||
return icsneo_setPollingMessageLimit(device, 20000) && icsneo_enableMessagePolling(device) && icsneo_goOnline(device);
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoClosePort(void* hObject, int* pNumberOfErrors)
|
||||
{
|
||||
if (!icsneoValidateHObject(hObject))
|
||||
return false;
|
||||
if (pNumberOfErrors) {
|
||||
*pNumberOfErrors = 0;
|
||||
}
|
||||
neodevice_t* device = reinterpret_cast<neodevice_t*>(hObject);
|
||||
if (openneodevices.find(device) != openneodevices.end()) {
|
||||
openneodevices[device]->neoDevice.NumberOfClients -= 1;
|
||||
openneodevices.erase(device);
|
||||
}
|
||||
|
||||
return icsneo_closeDevice(device);
|
||||
}
|
||||
|
||||
@@ -981,7 +991,20 @@ int LegacyDLLExport icsneoScriptWriteAppSignal(void* hObject, unsigned int iInde
|
||||
return false;
|
||||
}
|
||||
|
||||
//Deprecated (but still suppored in the DLL)
|
||||
int LegacyDLLExport icsneoOpenPortEx(void* lPortNumber, int lPortType, int lDriverType, int lIPAddressMSB,
|
||||
int lIPAddressLSBOrBaudRate, int bConfigRead, unsigned char* bNetworkID, int* hObject)
|
||||
{
|
||||
// TODO Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoOpenPort(int lPortNumber, int lPortType, int lDriverType, unsigned char *bNetworkID,
|
||||
unsigned char* bSCPIDs, int* hObject)
|
||||
{
|
||||
// TODO Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoEnableNetworkCom(void* hObject, int Enable)
|
||||
{
|
||||
@@ -995,6 +1018,19 @@ int LegacyDLLExport icsneoEnableNetworkCom(void* hObject, int Enable)
|
||||
return icsneo_goOffline(device);
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoFindAllCOMDevices(int lDriverType, int lGetSerialNumbers, int lStopAtFirst, int lUSBCommOnly,
|
||||
int* p_lDeviceTypes, int* p_lComPorts, int* p_lSerialNumbers, int* lNumDevices)
|
||||
{
|
||||
// TODO Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoOpenNeoDeviceByChannels(NeoDevice* pNeoDevice, void** hObject, unsigned char* uChannels, int iSize,
|
||||
int bConfigRead, int iOptions)
|
||||
{
|
||||
// TODO Implement
|
||||
return false;
|
||||
}
|
||||
|
||||
int LegacyDLLExport icsneoGetVCAN4Settings(void* hObject, SVCAN4Settings* pSettings, int iNumBytes)
|
||||
{
|
||||
@@ -1076,18 +1112,9 @@ int LegacyDLLExport icsneoGetDeviceSettingsType(void* hObject, EPlasmaIonVnetCha
|
||||
case NEODEVICE_RADMOON3:
|
||||
*pDeviceSettingsType = DeviceRADMoon3SettingsType;
|
||||
break;
|
||||
case NEODEVICE_RADGEMINI:
|
||||
*pDeviceSettingsType = DeviceRADGeminiSettingsType;
|
||||
break;
|
||||
case NEODEVICE_RED2:
|
||||
*pDeviceSettingsType = DeviceRed2SettingsType;
|
||||
break;
|
||||
case NEODEVICE_FIRE3:
|
||||
*pDeviceSettingsType = DeviceFire3SettingsType;
|
||||
break;
|
||||
case NEODEVICE_FIRE3_FLEXRAY:
|
||||
*pDeviceSettingsType = DeviceFire3FlexraySettingsType;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
if(LIBICSNEO_ENABLE_BINDINGS_PYTHON)
|
||||
add_subdirectory(python)
|
||||
endif()
|
||||
@@ -1,59 +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 v3.0.1
|
||||
)
|
||||
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/spimessage.cpp
|
||||
icsneopy/communication/message/scriptstatusmessage.cpp
|
||||
icsneopy/communication/message/ethphymessage.cpp
|
||||
icsneopy/communication/message/callback/messagecallback.cpp
|
||||
icsneopy/communication/message/filter/messagefilter.cpp
|
||||
icsneopy/core/macseccfg.cpp
|
||||
icsneopy/flexray/flexray.cpp
|
||||
icsneopy/disk/diskdriver.cpp
|
||||
icsneopy/device/chipid.cpp
|
||||
icsneopy/device/versionreport.cpp
|
||||
icsneopy/device/device.cpp
|
||||
icsneopy/device/extensions/deviceextension.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,163 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/native_enum.h>
|
||||
|
||||
#include "icsneo/api/event.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_event(pybind11::module_& m) {
|
||||
pybind11::classh<APIEvent> apiEvent(m, "APIEvent");
|
||||
pybind11::native_enum<APIEvent::Type>(apiEvent, "Type", "enum.IntEnum")
|
||||
.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("FixedPointOverflow", APIEvent::Type::FixedPointOverflow)
|
||||
.value("FixedPointPrecision", APIEvent::Type::FixedPointPrecision)
|
||||
.value("SyscallError", APIEvent::Type::SyscallError)
|
||||
.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("GPTPNotSupported", APIEvent::Type::GPTPNotSupported)
|
||||
.value("SettingNotAvaiableDevice", APIEvent::Type::SettingNotAvaiableDevice)
|
||||
.value("DiskFormatNotSupported", APIEvent::Type::DiskFormatNotSupported)
|
||||
.value("DiskFormatInvalidCount", APIEvent::Type::DiskFormatInvalidCount)
|
||||
.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("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("ServdBindError", APIEvent::Type::ServdBindError)
|
||||
.value("ServdNonblockError", APIEvent::Type::ServdNonblockError)
|
||||
.value("ServdTransceiveError", APIEvent::Type::ServdTransceiveError)
|
||||
.value("ServdOutdatedError", APIEvent::Type::ServdOutdatedError)
|
||||
.value("ServdInvalidResponseError", APIEvent::Type::ServdInvalidResponseError)
|
||||
.value("ServdLockError", APIEvent::Type::ServdLockError)
|
||||
.value("ServdSendError", APIEvent::Type::ServdSendError)
|
||||
.value("ServdRecvError", APIEvent::Type::ServdRecvError)
|
||||
.value("ServdPollError", APIEvent::Type::ServdPollError)
|
||||
.value("ServdNoDataError", APIEvent::Type::ServdNoDataError)
|
||||
.value("ServdJoinMulticastError", APIEvent::Type::ServdJoinMulticastError)
|
||||
.value("DXXErrorSys", APIEvent::Type::DXXErrorSys)
|
||||
.value("DXXErrorInt", APIEvent::Type::DXXErrorInt)
|
||||
.value("DXXErrorOverflow", APIEvent::Type::DXXErrorOverflow)
|
||||
.value("DXXErrorIO", APIEvent::Type::DXXErrorIO)
|
||||
.value("DXXErrorArg", APIEvent::Type::DXXErrorArg)
|
||||
.value("NoErrorFound", APIEvent::Type::NoErrorFound)
|
||||
.value("TooManyEvents", APIEvent::Type::TooManyEvents)
|
||||
.value("Unknown", APIEvent::Type::Unknown)
|
||||
.finalize();
|
||||
|
||||
pybind11::native_enum<APIEvent::Severity>(apiEvent, "Severity", "enum.IntEnum")
|
||||
.value("Any", APIEvent::Severity::Any)
|
||||
.value("EventInfo", APIEvent::Severity::EventInfo)
|
||||
.value("EventWarning", APIEvent::Severity::EventWarning)
|
||||
.value("Error", APIEvent::Severity::Error)
|
||||
.finalize();
|
||||
|
||||
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::classh<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::classh<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::classh<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::classh<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::classh<MessageCallback>(m, "MessageCallback")
|
||||
.def(pybind11::init<MessageCallback::fn_messageCallback, std::shared_ptr<MessageFilter>>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/native_enum.h>
|
||||
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_errorcodes(pybind11::module_& m) {
|
||||
pybind11::native_enum<CANErrorCode>(m, "CANErrorCode", "enum.IntEnum")
|
||||
.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)
|
||||
.finalize();
|
||||
}
|
||||
|
||||
void init_canerrormessage(pybind11::module_& m) {
|
||||
init_errorcodes(m);
|
||||
pybind11::classh<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::classh<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::classh<MACAddress>(m, "MACAddress")
|
||||
.def("to_string", &MACAddress::toString)
|
||||
.def("__repr__", &MACAddress::toString);
|
||||
|
||||
pybind11::classh<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,36 +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::classh<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)
|
||||
.value("LinkModeNone", EthernetStatusMessage::LinkMode::LinkModeNone);
|
||||
|
||||
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,34 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/ethphymessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_ethphymessage(pybind11::module_& m) {
|
||||
pybind11::classh<Clause22Message>(m, "Clause22Message")
|
||||
.def_readwrite("phyAddr", &Clause22Message::phyAddr)
|
||||
.def_readwrite("page", &Clause22Message::page)
|
||||
.def_readwrite("regAddr", &Clause22Message::regAddr)
|
||||
.def_readwrite("regVal", &Clause22Message::regVal);
|
||||
pybind11::classh<Clause45Message>(m, "Clause45Message")
|
||||
.def_readwrite("port", &Clause45Message::port)
|
||||
.def_readwrite("device", &Clause45Message::device)
|
||||
.def_readwrite("regAddr", &Clause45Message::regAddr)
|
||||
.def_readwrite("regVal", &Clause45Message::regVal);
|
||||
pybind11::classh<PhyMessage>(m, "PhyMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("Enabled", &PhyMessage::Enabled)
|
||||
.def_readwrite("WriteEnable", &PhyMessage::WriteEnable)
|
||||
.def_readwrite("Clause45Enable", &PhyMessage::Clause45Enable)
|
||||
.def_readwrite("Version", &PhyMessage::Version)
|
||||
.def_readwrite("BusIndex", &PhyMessage::BusIndex)
|
||||
.def_readwrite("Clause22", &PhyMessage::Clause22)
|
||||
.def_readwrite("Clause45", &PhyMessage::Clause45);
|
||||
pybind11::classh<EthPhyMessage, Message>(m, "EthPhyMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("messages", &EthPhyMessage::messages);
|
||||
}
|
||||
|
||||
} // 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::classh<MessageFilter>(m, "MessageFilter")
|
||||
.def(pybind11::init())
|
||||
.def(pybind11::init<Message::Type>())
|
||||
.def(pybind11::init<Network::NetID>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,80 +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::classh<GPTPStatus, Message> gptpStatus(m, "GPTPStatus");
|
||||
|
||||
pybind11::classh<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::classh<GPTPStatus::ScaledNanoSeconds>(gptpStatus, "ScaledNanoSeconds")
|
||||
.def_readonly("nanoseconds_msb", &GPTPStatus::ScaledNanoSeconds::nanosecondsMSB)
|
||||
.def_readonly("nanoseconds_lsb", &GPTPStatus::ScaledNanoSeconds::nanosecondsLSB)
|
||||
.def_readonly("fractional_nanoseconds", &GPTPStatus::ScaledNanoSeconds::fractionalNanoseconds);
|
||||
|
||||
pybind11::classh<GPTPStatus::PortID>(gptpStatus, "PortID")
|
||||
.def_readonly("clock_identity", &GPTPStatus::PortID::clockIdentity)
|
||||
.def_readonly("port_number", &GPTPStatus::PortID::portNumber);
|
||||
|
||||
pybind11::classh<GPTPStatus::ClockQuality>(gptpStatus, "ClockQuality")
|
||||
.def_readonly("clock_class", &GPTPStatus::ClockQuality::clockClass)
|
||||
.def_readonly("clock_accuracy", &GPTPStatus::ClockQuality::clockAccuracy)
|
||||
.def_readonly("offset_scaled_log_variance", &GPTPStatus::ClockQuality::offsetScaledLogVariance);
|
||||
|
||||
pybind11::classh<GPTPStatus::SystemID>(gptpStatus, "SystemID")
|
||||
.def_readonly("priority1", &GPTPStatus::SystemID::priority1)
|
||||
.def_readonly("clock_quality", &GPTPStatus::SystemID::clockQuality)
|
||||
.def_readonly("priority2", &GPTPStatus::SystemID::priority2)
|
||||
.def_readonly("clock_id", &GPTPStatus::SystemID::clockID);
|
||||
|
||||
pybind11::classh<GPTPStatus::PriorityVector>(gptpStatus, "PriorityVector")
|
||||
.def_readonly("sys_id", &GPTPStatus::PriorityVector::sysID)
|
||||
.def_readonly("steps_removed", &GPTPStatus::PriorityVector::stepsRemoved)
|
||||
.def_readonly("port_id", &GPTPStatus::PriorityVector::portID)
|
||||
.def_readonly("port_number", &GPTPStatus::PriorityVector::portNumber);
|
||||
|
||||
pybind11::classh<GPTPStatus::ParentDS>(gptpStatus, "ParentDS")
|
||||
.def_readonly("parent_port_identity", &GPTPStatus::ParentDS::parentPortIdentity)
|
||||
.def_readonly("cumulative_rate_ratio", &GPTPStatus::ParentDS::cumulativeRateRatio)
|
||||
.def_readonly("grandmaster_identity", &GPTPStatus::ParentDS::grandmasterIdentity)
|
||||
.def_readonly("gm_clock_quality_clock_class", &GPTPStatus::ParentDS::gmClockQualityClockClass)
|
||||
.def_readonly("gm_clock_quality_clock_accuracy", &GPTPStatus::ParentDS::gmClockQualityClockAccuracy)
|
||||
.def_readonly("gm_clock_quality_offset_scaled_log_variance", &GPTPStatus::ParentDS::gmClockQualityOffsetScaledLogVariance)
|
||||
.def_readonly("gm_priority1", &GPTPStatus::ParentDS::gmPriority1)
|
||||
.def_readonly("gm_priority2", &GPTPStatus::ParentDS::gmPriority2);
|
||||
|
||||
pybind11::classh<GPTPStatus::CurrentDS>(gptpStatus, "CurrentDS")
|
||||
.def_readonly("steps_removed", &GPTPStatus::CurrentDS::stepsRemoved)
|
||||
.def_readonly("offset_from_master", &GPTPStatus::CurrentDS::offsetFromMaster)
|
||||
.def_readonly("lastgm_phase_change", &GPTPStatus::CurrentDS::lastgmPhaseChange)
|
||||
.def_readonly("lastgm_freq_change", &GPTPStatus::CurrentDS::lastgmFreqChange)
|
||||
.def_readonly("gm_time_base_indicator", &GPTPStatus::CurrentDS::gmTimeBaseIndicator)
|
||||
.def_readonly("gm_change_count", &GPTPStatus::CurrentDS::gmChangeCount)
|
||||
.def_readonly("time_of_lastgm_change_event", &GPTPStatus::CurrentDS::timeOfLastgmChangeEvent)
|
||||
.def_readonly("time_of_lastgm_phase_change_event", &GPTPStatus::CurrentDS::timeOfLastgmPhaseChangeEvent)
|
||||
.def_readonly("time_of_lastgm_freq_change_event", &GPTPStatus::CurrentDS::timeOfLastgmFreqChangeEvent);
|
||||
|
||||
gptpStatus.def_readonly("current_time", &GPTPStatus::currentTime)
|
||||
.def_readonly("gm_priority", &GPTPStatus::gmPriority)
|
||||
.def_readonly("ms_offset_ns", &GPTPStatus::msOffsetNs)
|
||||
.def_readonly("is_sync", &GPTPStatus::isSync)
|
||||
.def_readonly("link_status", &GPTPStatus::linkStatus)
|
||||
.def_readonly("link_delay_ns", &GPTPStatus::linkDelayNS)
|
||||
.def_readonly("selected_role", &GPTPStatus::selectedRole)
|
||||
.def_readonly("as_capable", &GPTPStatus::asCapable)
|
||||
.def_readonly("is_syntonized", &GPTPStatus::isSyntonized)
|
||||
.def_readonly("last_rx_sync_ts", &GPTPStatus::lastRXSyncTS)
|
||||
.def_readonly("current_ds", &GPTPStatus::currentDS)
|
||||
.def_readonly("parent_ds", &GPTPStatus::parentDS)
|
||||
.def_readonly("short_format", &GPTPStatus::shortFormat);
|
||||
|
||||
}
|
||||
|
||||
} // 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::classh<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::classh<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::classh<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,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::classh<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,57 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/native_enum.h>
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_message(pybind11::module_& m) {
|
||||
// Using py::smart_holder for safer lifetime management
|
||||
pybind11::classh<Message> message(m, "Message");
|
||||
pybind11::native_enum<Message::Type>(message, "Type", "enum.IntEnum")
|
||||
.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)
|
||||
.finalize();
|
||||
|
||||
message.def(pybind11::init<Message::Type>());
|
||||
message.def_readonly("type", &Message::type);
|
||||
message.def_readwrite("timestamp", &Message::timestamp);
|
||||
|
||||
pybind11::classh<RawMessage, Message>(m, "RawMessage")
|
||||
.def_readwrite("network", &RawMessage::network)
|
||||
.def_readwrite("data", &RawMessage::data);
|
||||
|
||||
pybind11::classh<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::classh<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,24 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/spimessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_spimessage(pybind11::module_& m) {
|
||||
pybind11::classh<SPIMessage, Frame> spiMessage(m, "SPIMessage");
|
||||
pybind11::enum_<SPIMessage::Direction>(spiMessage, "Direction")
|
||||
.value("Write", SPIMessage::Direction::Write)
|
||||
.value("Read", SPIMessage::Direction::Read);
|
||||
spiMessage
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("direction", &SPIMessage::direction)
|
||||
.def_readwrite("address", &SPIMessage::address)
|
||||
.def_readwrite("mms", &SPIMessage::mms)
|
||||
.def_readwrite("stats", &SPIMessage::stats)
|
||||
.def_readwrite("payload", &SPIMessage::payload);
|
||||
}
|
||||
|
||||
} // 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::classh<TC10StatusMessage, Message>(m, "TC10StatusMessage")
|
||||
.def_readonly("wakeStatus", &TC10StatusMessage::wakeStatus)
|
||||
.def_readonly("sleepStatus", &TC10StatusMessage::sleepStatus);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,202 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/native_enum.h>
|
||||
|
||||
#include "icsneo/communication/network.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_network(pybind11::module_& m) {
|
||||
pybind11::classh<Network> network(m, "Network");
|
||||
|
||||
pybind11::native_enum<Network::NetID>(network, "NetID", "enum.IntEnum")
|
||||
.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("ETHERNET_TX_WRAP", Network::NetID::ETHERNET_TX_WRAP)
|
||||
.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)
|
||||
.finalize();
|
||||
|
||||
pybind11::native_enum<Network::Type>(network, "Type", "enum.Enum")
|
||||
.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", Network::Type::I2C)
|
||||
.value("A2B", Network::Type::A2B)
|
||||
.value("SPI", Network::Type::SPI)
|
||||
.value("MDIO", Network::Type::MDIO)
|
||||
.value("AutomotiveEthernet", Network::Type::AutomotiveEthernet)
|
||||
.value("Any", Network::Type::Any)
|
||||
.value("Other", Network::Type::Other)
|
||||
.finalize();
|
||||
|
||||
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,166 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/core/macseccfg.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_macsecconfig(pybind11::module_ & m)
|
||||
{
|
||||
pybind11::enum_<MACsecPacketType>(m, "MACsecPacketType")
|
||||
.value("DEFAULT", MACsecPacketType::Default)
|
||||
.value("SINGLE_VLAN", MACsecPacketType::SingleVLAN)
|
||||
.value("DUAL_VLAN", MACsecPacketType::DualVLAN)
|
||||
.value("MPLS", MACsecPacketType::MPLS)
|
||||
.value("SINGLE_VLAN_FOLLOWED_BY_MPLS", MACsecPacketType::SingleVLANFollowedByMPLS)
|
||||
.value("DUAL_VLAN_FOLLOWED_BY_MPLS", MACsecPacketType::DualVLANFollowedByMPLS)
|
||||
.value("UNSUPPORTED", MACsecPacketType::Unsupported);
|
||||
|
||||
pybind11::enum_<MACsecValidation>(m, "MACsecValidation")
|
||||
.value("DISABLED", MACsecValidation::Disabled)
|
||||
.value("CHECK", MACsecValidation::Check)
|
||||
.value("STRICT", MACsecValidation::Strict)
|
||||
.value("NA", MACsecValidation::NA);
|
||||
|
||||
pybind11::enum_<MACsecStrip>(m, "MACsecStrip")
|
||||
.value("STRIP_SECTAG_AND_ICV", MACsecStrip::StripSecTagAndIcv)
|
||||
.value("STRIP_SECTAG_PRESERVE_ICV", MACsecStrip::StripSecTagPreserveICV)
|
||||
.value("PRESERVE_SECTAG_STRIP_ICV", MACsecStrip::PreserveSecTagStripICV)
|
||||
.value("NO_STRIP", MACsecStrip::NoStrip);
|
||||
|
||||
pybind11::enum_<MACsecCipherSuite>(m, "MACsecCipherSuite")
|
||||
.value("GCM_AES_128", MACsecCipherSuite::GcmAes128)
|
||||
.value("GCM_AES_256", MACsecCipherSuite::GcmAes256)
|
||||
.value("GCM_AES_128_XPN", MACsecCipherSuite::GcmAes128Xpn)
|
||||
.value("GCM_AES_256_XPN", MACsecCipherSuite::GcmAes256Xpn);
|
||||
|
||||
pybind11::classh<MACsecVLANTag>(m, "MACsecVLANTag")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("vid", &MACsecVLANTag::vid)
|
||||
.def_readwrite("pri_cfi", &MACsecVLANTag::priCfi);
|
||||
|
||||
pybind11::classh<MACsecMPLSOuter>(m, "MACsecMPLSOuter")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("mpls_label", &MACsecMPLSOuter::mplsLabel)
|
||||
.def_readwrite("exp", &MACsecMPLSOuter::exp);
|
||||
|
||||
pybind11::classh<MACsecTci>(m, "MACsecTci")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("es", &MACsecTci::es)
|
||||
.def_readwrite("sc", &MACsecTci::sc)
|
||||
.def_readwrite("scb", &MACsecTci::scb)
|
||||
.def_readwrite("e", &MACsecTci::e)
|
||||
.def_readwrite("c", &MACsecTci::c);
|
||||
|
||||
pybind11::classh<MACsecRxRule>(m, "MACsecRxRule")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("key_mac_da", &MACsecRxRule::keyMacDa)
|
||||
.def_readwrite("mask_mac_da", &MACsecRxRule::maskMacDa)
|
||||
.def_readwrite("key_mask_sa", &MACsecRxRule::keyMacSa)
|
||||
.def_readwrite("mask_mac_sa", &MACsecRxRule::maskMacSa)
|
||||
.def_readwrite("key_ether_type", &MACsecRxRule::keyEthertype)
|
||||
.def_readwrite("mask_ether_type", &MACsecRxRule::maskEthertype)
|
||||
.def_readwrite("key_vlan_tag_outer1", &MACsecRxRule::keyVlanTagOuter1)
|
||||
.def_readwrite("key_mpls_outer1", &MACsecRxRule::keyMplsOuter1)
|
||||
.def_readwrite("mask_vlan_tag_outer1", &MACsecRxRule::maskVlanTagOuter1)
|
||||
.def_readwrite("mask_mpls_outer1", &MACsecRxRule::maskMplsOuter1)
|
||||
.def_readwrite("key_vlan_tag_outer2", &MACsecRxRule::keyVlanTagOuter2)
|
||||
.def_readwrite("key_mpls_outer2", &MACsecRxRule::keyMplsOuter2)
|
||||
.def_readwrite("mask_vlan_tag_outer2", &MACsecRxRule::maskVlanTagOuter2)
|
||||
.def_readwrite("mask_mpls_outer2", &MACsecRxRule::maskMplsOuter2)
|
||||
.def_readwrite("key_bonus_data", &MACsecRxRule::keyBonusData)
|
||||
.def_readwrite("mask_bonus_data", &MACsecRxRule::maskBonusData)
|
||||
.def_readwrite("key_tag_match_bitmap", &MACsecRxRule::keyTagMatchBitmap)
|
||||
.def_readwrite("mask_tag_match_bitmap", &MACsecRxRule::maskTagMatchBitmap)
|
||||
.def_readwrite("key_packet_type", &MACsecRxRule::keyPacketType)
|
||||
.def_readwrite("mask_packet_type", &MACsecRxRule::maskPacketType)
|
||||
.def_readwrite("key_inner_vlan_type", &MACsecRxRule::keyInnerVlanType)
|
||||
.def_readwrite("mask_inner_vlan_type", &MACsecRxRule::maskInnerVlanType)
|
||||
.def_readwrite("key_outer_vlan_type", &MACsecRxRule::keyOuterVlanType)
|
||||
.def_readwrite("mask_outer_vlan_type", &MACsecRxRule::maskOuterVlanType)
|
||||
.def_readwrite("key_num_tags", &MACsecRxRule::keyNumTags)
|
||||
.def_readwrite("mask_num_tags", &MACsecRxRule::maskNumTags)
|
||||
.def_readwrite("key_express", &MACsecRxRule::keyExpress)
|
||||
.def_readwrite("mask_express", &MACsecRxRule::maskExpress)
|
||||
.def_readwrite("is_mpls", &MACsecRxRule::isMpls);
|
||||
|
||||
pybind11::classh<MACsecTxSecY>(m, "MACsecTxSecY")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("enable_control_port", &MACsecTxSecY::enableControlPort)
|
||||
.def_readwrite("cipher", &MACsecTxSecY::cipher)
|
||||
.def_readwrite("confidentiality_offset", &MACsecTxSecY::confidentialityOffset)
|
||||
.def_readwrite("icv_includes_da_sa", &MACsecTxSecY::icvIncludesDaSa)
|
||||
.def_readwrite("protect_frames", &MACsecTxSecY::protectFrames)
|
||||
.def_readwrite("sec_tag_offset", &MACsecTxSecY::secTagOffset)
|
||||
.def_readwrite("sec_tag_tci", &MACsecTxSecY::tci)
|
||||
.def_readwrite("mtu", &MACsecTxSecY::mtu)
|
||||
.def_readwrite("is_control_packet", &MACsecTxSecY::isControlPacket)
|
||||
.def_readwrite("auxiliary_policy", &MACsecTxSecY::auxiliaryPolicy)
|
||||
.def_readwrite("sci", &MACsecTxSecY::sci);
|
||||
|
||||
pybind11::classh<MACsecRxSecY>(m, "MACsecRxSecY")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("enable_control_port", &MACsecRxSecY::enableControlPort)
|
||||
.def_readwrite("frame_validation", &MACsecRxSecY::frameValidation)
|
||||
.def_readwrite("frame_strip", &MACsecRxSecY::frameStrip)
|
||||
.def_readwrite("cipher", &MACsecRxSecY::cipher)
|
||||
.def_readwrite("confidentiality_offset", &MACsecRxSecY::confidentialityOffset)
|
||||
.def_readwrite("icv_includes_da_sa", &MACsecRxSecY::icvIncludesDaSa)
|
||||
.def_readwrite("replay_protect", &MACsecRxSecY::replayProtect)
|
||||
.def_readwrite("replay_window", &MACsecRxSecY::replayWindow)
|
||||
.def_readwrite("is_control_packet", &MACsecRxSecY::isControlPacket)
|
||||
.def_readwrite("sci", &MACsecRxSecY::sci);
|
||||
|
||||
pybind11::classh<MACsecTxSa>(m, "MACsecTxSa")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("sak", &MACsecTxSa::sak)
|
||||
.def_readwrite("hash_key", &MACsecTxSa::hashKey)
|
||||
.def_readwrite("salt", &MACsecTxSa::salt)
|
||||
.def_readwrite("ssci", &MACsecTxSa::ssci)
|
||||
.def_readwrite("next_pn", &MACsecTxSa::nextPn)
|
||||
.def_readwrite("an", &MACsecTxSa::an);
|
||||
|
||||
pybind11::classh<MACsecRxSa>(m, "MACsecRxSa")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("sak", &MACsecRxSa::sak)
|
||||
.def_readwrite("hash_key", &MACsecRxSa::hashKey)
|
||||
.def_readwrite("salt", &MACsecRxSa::salt)
|
||||
.def_readwrite("ssci", &MACsecRxSa::ssci)
|
||||
.def_readwrite("next_pn", &MACsecRxSa::nextPn);
|
||||
|
||||
pybind11::classh<MACsecConfig>(m, "MACsecConfig")
|
||||
.def(pybind11::init<icsneo::DeviceType>())
|
||||
.def("add_rx_secy", &MACsecConfig::addRxSecY, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("add_tx_secY", &MACsecConfig::addTxSecY, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("add_rx_rule", &MACsecConfig::addRxRule, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("add_rx_sa", &MACsecConfig::addRxSa, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("add_tx_sa", &MACsecConfig::addTxSa, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_rx_secy", [](MACsecConfig& cfg, uint8_t index) -> MACsecRxSecY& { return cfg.getRxSecY(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_tx_secy", [](MACsecConfig& cfg, uint8_t index) -> MACsecTxSecY& { return cfg.getTxSecY(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_rx_sa", [](MACsecConfig& cfg, uint8_t index) -> MACsecRxSa& { return cfg.getRxSa(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_tx_sa", [](MACsecConfig& cfg, uint8_t index) -> MACsecTxSa& { return cfg.getTxSa(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_rx_rule", [](MACsecConfig& cfg, uint8_t index) -> MACsecRxRule& { return cfg.getRxRule(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_tx_sa_index", &MACsecConfig::setTxSaIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("enable_tx_rekey", &MACsecConfig::enableTxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_tx_sa_rekey_index", &MACsecConfig::setTxSaRekeyIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("disable_tx_rekey", &MACsecConfig::disableTxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_rx_sa_index", &MACsecConfig::setRxSaIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("enable_rx_rekey", &MACsecConfig::enableRxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_rx_sa_rekey_index", &MACsecConfig::setRxSaRekeyIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("disable_rx_rekey", &MACsecConfig::disableRxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_rx_enable", &MACsecConfig::setRxEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_tx_enable", &MACsecConfig::setTxEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_storage", &MACsecConfig::setStorage, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("clear", &MACsecConfig::clear, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("serialize", &MACsecConfig::serialize, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_bin_index", &MACsecConfig::getBinIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_type", &MACsecConfig::getType, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_max_num_rule", &MACsecConfig::getMaxNumRule, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_max_num_secy", &MACsecConfig::getMaxNumSecY, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_max_num_sa", &MACsecConfig::getMaxNumSa, pybind11::call_guard<pybind11::gil_scoped_release>());
|
||||
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/native_enum.h>
|
||||
|
||||
#include "icsneo/device/chipid.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_chipid(pybind11::module_& m) {
|
||||
pybind11::native_enum<ChipID>(m, "ChipID", "enum.IntEnum")
|
||||
.value("neoVIFIRE_MCHIP", ChipID::neoVIFIRE_MCHIP)
|
||||
.value("neoVIFIRE_LCHIP", ChipID::neoVIFIRE_LCHIP)
|
||||
.value("neoVIFIRE_UCHIP", ChipID::neoVIFIRE_UCHIP)
|
||||
.value("neoVIFIRE_JCHIP", ChipID::neoVIFIRE_JCHIP)
|
||||
.value("ValueCAN3_MCHIP", ChipID::ValueCAN3_MCHIP)
|
||||
.value("neoVIECU_MPIC", ChipID::neoVIECU_MPIC)
|
||||
.value("neoVIIEVB_MPIC", ChipID::neoVIIEVB_MPIC)
|
||||
.value("neoVIPENDANT_MPIC", ChipID::neoVIPENDANT_MPIC)
|
||||
.value("neoVIFIRE_VNET_MCHIP", ChipID::neoVIFIRE_VNET_MCHIP)
|
||||
.value("neoVIFIRE_VNET_LCHIP", ChipID::neoVIFIRE_VNET_LCHIP)
|
||||
.value("neoVIPLASMA_Core", ChipID::neoVIPLASMA_Core)
|
||||
.value("neoVIPLASMA_HID", ChipID::neoVIPLASMA_HID)
|
||||
.value("neoVIANALOG_MPIC", ChipID::neoVIANALOG_MPIC)
|
||||
.value("neoVIPLASMA_ANALOG_Core", ChipID::neoVIPLASMA_ANALOG_Core)
|
||||
.value("neoVIPLASMA_FlexRay_Core", ChipID::neoVIPLASMA_FlexRay_Core)
|
||||
.value("neoVIPLASMA_Core_1_12", ChipID::neoVIPLASMA_Core_1_12)
|
||||
.value("neoVIFIRE_Slave_VNET_MCHIP", ChipID::neoVIFIRE_Slave_VNET_MCHIP)
|
||||
.value("neoVIFIRE_Slave_VNET_LCHIP", ChipID::neoVIFIRE_Slave_VNET_LCHIP)
|
||||
.value("neoVIION_Core", ChipID::neoVIION_Core)
|
||||
.value("neoVIION_HID", ChipID::neoVIION_HID)
|
||||
.value("neoVIION_Core_Loader", ChipID::neoVIION_Core_Loader)
|
||||
.value("neoVIION_HID_Loader", ChipID::neoVIION_HID_Loader)
|
||||
.value("neoVIION_FPGA_BIT", ChipID::neoVIION_FPGA_BIT)
|
||||
.value("neoVIFIRE_VNET_EP_MCHIP", ChipID::neoVIFIRE_VNET_EP_MCHIP)
|
||||
.value("neoVIFIRE_VNET_EP_LCHIP", ChipID::neoVIFIRE_VNET_EP_LCHIP)
|
||||
.value("neoVIAnalogOut_MCHIP", ChipID::neoVIAnalogOut_MCHIP)
|
||||
.value("neoVIMOST25_MCHIP", ChipID::neoVIMOST25_MCHIP)
|
||||
.value("neoVIMOST50_MCHIP", ChipID::neoVIMOST50_MCHIP)
|
||||
.value("neoVIMOST150_MCHIP", ChipID::neoVIMOST150_MCHIP)
|
||||
.value("ValueCAN4_4_MCHIP", ChipID::ValueCAN4_4_MCHIP)
|
||||
.value("ValueCAN4_4_SCHIP", ChipID::ValueCAN4_4_SCHIP)
|
||||
.value("cmProbe_ZYNQ", ChipID::cmProbe_ZYNQ)
|
||||
.value("EEVB_STM32", ChipID::EEVB_STM32)
|
||||
.value("neoVIFIRE_Slave_VNET_EP_MCHIP", ChipID::neoVIFIRE_Slave_VNET_EP_MCHIP)
|
||||
.value("neoVIFIRE_Slave_VNET_EP_LCHIP", ChipID::neoVIFIRE_Slave_VNET_EP_LCHIP)
|
||||
.value("RADStar_MCHIP", ChipID::RADStar_MCHIP)
|
||||
.value("ValueCANrf_MCHIP", ChipID::ValueCANrf_MCHIP)
|
||||
.value("neoVIFIRE2_MCHIP", ChipID::neoVIFIRE2_MCHIP)
|
||||
.value("neoVIFIRE2_CCHIP", ChipID::neoVIFIRE2_CCHIP)
|
||||
.value("neoVIFIRE2_Core", ChipID::neoVIFIRE2_Core)
|
||||
.value("neoVIFIRE2_BLECHIP", ChipID::neoVIFIRE2_BLECHIP)
|
||||
.value("neoVIFIRE2_ZYNQ", ChipID::neoVIFIRE2_ZYNQ)
|
||||
.value("neoVIFIRE2_SECURITYCHIP", ChipID::neoVIFIRE2_SECURITYCHIP)
|
||||
.value("RADGalaxy_ZYNQ", ChipID::RADGalaxy_ZYNQ)
|
||||
.value("neoVIFIRE2_VNET_MCHIP", ChipID::neoVIFIRE2_VNET_MCHIP)
|
||||
.value("neoVIFIRE2_Slave_VNET_A_MCHIP", ChipID::neoVIFIRE2_Slave_VNET_A_MCHIP)
|
||||
.value("neoVIFIRE2_Slave_VNET_A_CCHIP", ChipID::neoVIFIRE2_Slave_VNET_A_CCHIP)
|
||||
.value("neoVIFIRE2_VNET_CCHIP", ChipID::neoVIFIRE2_VNET_CCHIP)
|
||||
.value("neoVIFIRE2_VNET_Core", ChipID::neoVIFIRE2_VNET_Core)
|
||||
.value("RADStar2_ZYNQ", ChipID::RADStar2_ZYNQ)
|
||||
.value("VividCAN_MCHIP", ChipID::VividCAN_MCHIP)
|
||||
.value("neoOBD2SIM_MCHIP", ChipID::neoOBD2SIM_MCHIP)
|
||||
.value("neoVIFIRE2_VNETZ_MCHIP", ChipID::neoVIFIRE2_VNETZ_MCHIP)
|
||||
.value("neoVIFIRE2_VNETZ_ZYNQ", ChipID::neoVIFIRE2_VNETZ_ZYNQ)
|
||||
.value("neoVIFIRE2_Slave_VNETZ_A_MCHIP", ChipID::neoVIFIRE2_Slave_VNETZ_A_MCHIP)
|
||||
.value("neoVIFIRE2_Slave_VNETZ_A_ZYNQ", ChipID::neoVIFIRE2_Slave_VNETZ_A_ZYNQ)
|
||||
.value("VividCAN_EXT_FLASH", ChipID::VividCAN_EXT_FLASH)
|
||||
.value("VividCAN_NRF52", ChipID::VividCAN_NRF52)
|
||||
.value("cmProbe_ZYNQ_Unused", ChipID::cmProbe_ZYNQ_Unused)
|
||||
.value("neoOBD2PRO_MCHIP", ChipID::neoOBD2PRO_MCHIP)
|
||||
.value("ValueCAN4_1_MCHIP", ChipID::ValueCAN4_1_MCHIP)
|
||||
.value("ValueCAN4_2_MCHIP", ChipID::ValueCAN4_2_MCHIP)
|
||||
.value("ValueCAN4_4_2EL_Core", ChipID::ValueCAN4_4_2EL_Core)
|
||||
.value("neoOBD2PRO_SCHIP", ChipID::neoOBD2PRO_SCHIP)
|
||||
.value("ValueCAN4_2EL_MCHIP", ChipID::ValueCAN4_2EL_MCHIP)
|
||||
.value("neoECUAVBTSN_MCHIP", ChipID::neoECUAVBTSN_MCHIP)
|
||||
.value("neoOBD2PRO_Core", ChipID::neoOBD2PRO_Core)
|
||||
.value("RADSupermoon_ZYNQ", ChipID::RADSupermoon_ZYNQ)
|
||||
.value("RADMoon2_ZYNQ", ChipID::RADMoon2_ZYNQ)
|
||||
.value("VividCANPRO_MCHIP", ChipID::VividCANPRO_MCHIP)
|
||||
.value("VividCANPRO_EXT_FLASH", ChipID::VividCANPRO_EXT_FLASH)
|
||||
.value("RADPluto_MCHIP", ChipID::RADPluto_MCHIP)
|
||||
.value("RADMars_ZYNQ", ChipID::RADMars_ZYNQ)
|
||||
.value("neoECU12_MCHIP", ChipID::neoECU12_MCHIP)
|
||||
.value("RADIOCANHUB_MCHIP", ChipID::RADIOCANHUB_MCHIP)
|
||||
.value("FlexRay_VNETZ_ZCHIP", ChipID::FlexRay_VNETZ_ZCHIP)
|
||||
.value("neoOBD2_LCBADGE_MCHIP", ChipID::neoOBD2_LCBADGE_MCHIP)
|
||||
.value("neoOBD2_LCBADGE_SCHIP", ChipID::neoOBD2_LCBADGE_SCHIP)
|
||||
.value("RADMoonDuo_MCHIP", ChipID::RADMoonDuo_MCHIP)
|
||||
.value("neoVIFIRE3_ZCHIP", ChipID::neoVIFIRE3_ZCHIP)
|
||||
.value("FlexRay_VNETZ_FCHIP", ChipID::FlexRay_VNETZ_FCHIP)
|
||||
.value("RADJupiter_MCHIP", ChipID::RADJupiter_MCHIP)
|
||||
.value("ValueCAN4Industrial_MCHIP", ChipID::ValueCAN4Industrial_MCHIP)
|
||||
.value("EtherBADGE_MCHIP", ChipID::EtherBADGE_MCHIP)
|
||||
.value("RADMars_3_ZYNQ", ChipID::RADMars_3_ZYNQ)
|
||||
.value("RADGigastar_USBZ_ZYNQ", ChipID::RADGigastar_USBZ_ZYNQ)
|
||||
.value("RADGigastar_ZYNQ", ChipID::RADGigastar_ZYNQ)
|
||||
.value("RAD4G_MCHIP", ChipID::RAD4G_MCHIP)
|
||||
.value("neoVIFIRE3_SCHIP", ChipID::neoVIFIRE3_SCHIP)
|
||||
.value("RADEpsilon_MCHIP", ChipID::RADEpsilon_MCHIP)
|
||||
.value("RADA2B_ZCHIP", ChipID::RADA2B_ZCHIP)
|
||||
.value("neoOBD2Dev_MCHIP", ChipID::neoOBD2Dev_MCHIP)
|
||||
.value("neoOBD2Dev_SCHIP", ChipID::neoOBD2Dev_SCHIP)
|
||||
.value("neoOBD2SIMDoIP_MCHIP", ChipID::neoOBD2SIMDoIP_MCHIP)
|
||||
.value("SFPModule_MCHIP", ChipID::SFPModule_MCHIP)
|
||||
.value("RADEpsilonT_MCHIP", ChipID::RADEpsilonT_MCHIP)
|
||||
.value("RADEpsilonExpress_MCHIP", ChipID::RADEpsilonExpress_MCHIP)
|
||||
.value("RADProxima_MCHIP", ChipID::RADProxima_MCHIP)
|
||||
.value("NewDevice57_ZCHIP", ChipID::NewDevice57_ZCHIP)
|
||||
.value("RAD_GALAXY_2_ZMPCHIP_ID", ChipID::RAD_GALAXY_2_ZMPCHIP_ID)
|
||||
.value("NewDevice59_MCHIP", ChipID::NewDevice59_MCHIP)
|
||||
.value("RADMoon2_Z7010_ZYNQ", ChipID::RADMoon2_Z7010_ZYNQ)
|
||||
.value("neoVIFIRE2_CORE_SG4", ChipID::neoVIFIRE2_CORE_SG4)
|
||||
.value("RADBMS_MCHIP", ChipID::RADBMS_MCHIP)
|
||||
.value("RADMoon2_ZL_MCHIP", ChipID::RADMoon2_ZL_MCHIP)
|
||||
.value("RADGigastar_USBZ_Z7010_ZYNQ", ChipID::RADGigastar_USBZ_Z7010_ZYNQ)
|
||||
.value("neoVIFIRE3_LINUX", ChipID::neoVIFIRE3_LINUX)
|
||||
.value("RADGigastar_USBZ_Z7007S_ZYNQ", ChipID::RADGigastar_USBZ_Z7007S_ZYNQ)
|
||||
.value("VEM_01_8DW_ZCHIP", ChipID::VEM_01_8DW_ZCHIP)
|
||||
.value("RADGalaxy_FFG_Zynq", ChipID::RADGalaxy_FFG_Zynq)
|
||||
.value("RADMoon3_MCHIP", ChipID::RADMoon3_MCHIP)
|
||||
.value("RADComet_ZYNQ", ChipID::RADComet_ZYNQ)
|
||||
.value("VEM_02_FR_ZCHIP", ChipID::VEM_02_FR_ZCHIP)
|
||||
.value("RADA2B_REVB_ZCHIP", ChipID::RADA2B_REVB_ZCHIP)
|
||||
.value("RADGigastar_FFG_ZYNQ", ChipID::RADGigastar_FFG_ZYNQ)
|
||||
.value("VEM_02_FR_FCHIP", ChipID::VEM_02_FR_FCHIP)
|
||||
.value("Connect_ZCHIP", ChipID::Connect_ZCHIP)
|
||||
.value("RADGALAXY2_SYSMON_CHIP", ChipID::RADGALAXY2_SYSMON_CHIP)
|
||||
.value("RADCOMET3_ZCHIP", ChipID::RADCOMET3_ZCHIP)
|
||||
.value("Connect_LINUX", ChipID::Connect_LINUX)
|
||||
.value("RADGigastar2_ZYNQ", ChipID::RADGigastar2_ZYNQ)
|
||||
.value("RADGemini_MCHIP", ChipID::RADGemini_MCHIP)
|
||||
.value("Invalid", ChipID::Invalid)
|
||||
.finalize();
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,64 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/chrono.h>
|
||||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/extensions/deviceextension.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_device(pybind11::module_& m) {
|
||||
pybind11::classh<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::arg("filter") = std::nullopt, 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_extension", static_cast<std::shared_ptr<DeviceExtension>(Device::*)(const std::string&) const>(&Device::getExtension)) // This has to be static_casted rather than overload_casted because DeviceExtension is forward declared in device.h
|
||||
.def("get_flexray_controllers", &Device::getFlexRayControllers)
|
||||
.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("send_eth_phy_msg", &Device::sendEthPhyMsg, pybind11::arg("message"), pybind11::arg("timeout") = std::chrono::milliseconds(50), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_chip_versions", &Device::getChipVersions, pybind11::arg("refreshComponents") = true, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def_readonly("settings", &Device::settings);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/native_enum.h>
|
||||
|
||||
#include "icsneo/device/devicetype.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_devicetype(pybind11::module_& m) {
|
||||
pybind11::classh<DeviceType> deviceType(m, "DeviceType");
|
||||
pybind11::native_enum<DeviceType::Enum>(deviceType, "Enum", "enum.IntEnum")
|
||||
.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("RADGemini", DeviceType::Enum::RADGemini)
|
||||
.value("RADComet", DeviceType::Enum::RADComet)
|
||||
.value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay)
|
||||
.value("FIRE3_T1S_LIN", DeviceType::Enum::FIRE3_T1S_LIN)
|
||||
.value("FIRE3_T1S_SENT", DeviceType::Enum::FIRE3_T1S_SENT)
|
||||
.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)
|
||||
.finalize();
|
||||
deviceType.def(pybind11::init<DeviceType::Enum>());
|
||||
deviceType.def("get_device_type", &DeviceType::getDeviceType);
|
||||
deviceType.def("get_generic_product_name", &DeviceType::getGenericProductName);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/device/extensions/deviceextension.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_deviceextension(pybind11::module_& m) {
|
||||
pybind11::classh<DeviceExtension>(m, "DeviceExtension")
|
||||
.def("get_name", &DeviceExtension::getName);
|
||||
}
|
||||
|
||||
} // 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::classh<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::classh<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::call_guard<pybind11::gil_scoped_release>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/device/versionreport.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_versionreport(pybind11::module_& m) {
|
||||
pybind11::classh<VersionReport>(m, "VersionReport")
|
||||
.def_readonly("id", &VersionReport::id)
|
||||
.def_readonly("name", &VersionReport::name)
|
||||
.def_readonly("major", &VersionReport::major)
|
||||
.def_readonly("minor", &VersionReport::minor)
|
||||
.def_readonly("maintenance", &VersionReport::maintenance)
|
||||
.def_readonly("build", &VersionReport::build);
|
||||
}
|
||||
|
||||
} // 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::classh<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,191 +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"
|
||||
#include "icsneo/device/extensions/flexray/controller.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct FlexRayNamespace {
|
||||
using Symbol = icsneo::FlexRay::Symbol;
|
||||
using CRCStatus = icsneo::FlexRay::CRCStatus;
|
||||
using Channel = icsneo::FlexRay::Channel;
|
||||
};
|
||||
|
||||
namespace FlexRay {
|
||||
|
||||
struct ClusterNamespace {
|
||||
using SpeedType = icsneo::FlexRay::Cluster::SpeedType;
|
||||
using SPPType = icsneo::FlexRay::Cluster::SPPType;
|
||||
};
|
||||
|
||||
void init_extension(pybind11::classh<FlexRayNamespace>& c) {
|
||||
pybind11::classh<MessageBuffer>(c, "MessageBuffer")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("is_dynamic", &MessageBuffer::isDynamic)
|
||||
.def_readwrite("is_sync", &MessageBuffer::isSync)
|
||||
.def_readwrite("is_startup", &MessageBuffer::isStartup)
|
||||
.def_readwrite("is_network_management_frame", &MessageBuffer::isNetworkManagementFrame)
|
||||
.def_readwrite("is_transmit", &MessageBuffer::isTransmit)
|
||||
.def_readwrite("frame_id", &MessageBuffer::frameID)
|
||||
.def_readwrite("channel_a", &MessageBuffer::channelA)
|
||||
.def_readwrite("channel_b", &MessageBuffer::channelB)
|
||||
.def_readwrite("frame_length_bytes", &MessageBuffer::frameLengthBytes)
|
||||
.def_readwrite("base_cycle", &MessageBuffer::baseCycle)
|
||||
.def_readwrite("cycle_repetition", &MessageBuffer::cycleRepetition)
|
||||
.def_readwrite("continuous_mode", &MessageBuffer::continuousMode);
|
||||
|
||||
auto controller = pybind11::classh<Controller>(c, "Controller")
|
||||
.def("get_network", &Controller::getNetwork)
|
||||
.def("get_configuration", &Controller::getConfiguration)
|
||||
.def("set_configuration", &Controller::setConfiguration)
|
||||
.def("get_start_when_going_online", &Controller::getStartWhenGoingOnline)
|
||||
.def("set_start_when_going_online", &Controller::setStartWhenGoingOnline)
|
||||
.def("get_allow_coldstart", &Controller::getAllowColdstart)
|
||||
.def("set_allow_coldstart", &Controller::setAllowColdstart)
|
||||
.def("get_wakeup_before_start", &Controller::getWakeupBeforeStart)
|
||||
.def("set_wakeup_before_start", &Controller::setWakeupBeforeStart)
|
||||
.def("add_message_buffer", &Controller::addMessageBuffer)
|
||||
.def("clear_message_buffers", &Controller::clearMessageBuffers)
|
||||
.def("wakeup", &Controller::wakeup)
|
||||
.def("configure", &Controller::getReady)
|
||||
.def("start", &Controller::start)
|
||||
.def("transmit", &Controller::transmit)
|
||||
.def("halt", &Controller::halt)
|
||||
.def("freeze", &Controller::freeze)
|
||||
.def("trigger_mts", &Controller::triggerMTS);
|
||||
|
||||
pybind11::classh<Controller::Configuration>(controller, "Configuration")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("accept_startup_range_microticks", &Controller::Configuration::AcceptStartupRangeMicroticks)
|
||||
.def_readwrite("allow_passive_to_active_cycle_pairs", &Controller::Configuration::AllowPassiveToActiveCyclePairs)
|
||||
.def_readwrite("cluster_drift_damping", &Controller::Configuration::ClusterDriftDamping)
|
||||
.def_readwrite("channel_a", &Controller::Configuration::ChannelA)
|
||||
.def_readwrite("channel_b", &Controller::Configuration::ChannelB)
|
||||
.def_readwrite("decoding_correction_microticks", &Controller::Configuration::DecodingCorrectionMicroticks)
|
||||
.def_readwrite("delay_compensation_a_microticks", &Controller::Configuration::DelayCompensationAMicroticks)
|
||||
.def_readwrite("delay_compensation_b_microticks", &Controller::Configuration::DelayCompensationBMicroticks)
|
||||
.def_readwrite("extern_offset_correction_control", &Controller::Configuration::ExternOffsetCorrectionControl)
|
||||
.def_readwrite("extern_rate_correction_control", &Controller::Configuration::ExternRateCorrectionControl)
|
||||
.def_readwrite("extern_offset_correction_microticks", &Controller::Configuration::ExternOffsetCorrectionMicroticks)
|
||||
.def_readwrite("extern_rate_correction_microticks", &Controller::Configuration::ExternRateCorrectionMicroticks)
|
||||
.def_readwrite("key_slot_id", &Controller::Configuration::KeySlotID)
|
||||
.def_readwrite("key_slot_used_for_startup", &Controller::Configuration::KeySlotUsedForStartup)
|
||||
.def_readwrite("key_slot_used_for_sync", &Controller::Configuration::KeySlotUsedForSync)
|
||||
.def_readwrite("latest_tx_minislot", &Controller::Configuration::LatestTxMinislot)
|
||||
.def_readwrite("listen_timeout", &Controller::Configuration::ListenTimeout)
|
||||
.def_readwrite("macro_initial_offset_a", &Controller::Configuration::MacroInitialOffsetA)
|
||||
.def_readwrite("macro_initial_offset_b", &Controller::Configuration::MacroInitialOffsetB)
|
||||
.def_readwrite("micro_initial_offset_a", &Controller::Configuration::MicroInitialOffsetA)
|
||||
.def_readwrite("micro_initial_offset_b", &Controller::Configuration::MicroInitialOffsetB)
|
||||
.def_readwrite("micro_per_cycle", &Controller::Configuration::MicroPerCycle)
|
||||
.def_readwrite("mts_on_a", &Controller::Configuration::MTSOnA)
|
||||
.def_readwrite("mts_on_b", &Controller::Configuration::MTSOnB)
|
||||
.def_readwrite("offset_correction_out_microticks", &Controller::Configuration::OffsetCorrectionOutMicroticks)
|
||||
.def_readwrite("rate_correction_out_microticks", &Controller::Configuration::RateCorrectionOutMicroticks)
|
||||
.def_readwrite("second_key_slot_id", &Controller::Configuration::SecondKeySlotID)
|
||||
.def_readwrite("two_key_slot_mode", &Controller::Configuration::TwoKeySlotMode)
|
||||
.def_readwrite("wakeup_pattern", &Controller::Configuration::WakeupPattern)
|
||||
.def_readwrite("wakeup_on_channel_b", &Controller::Configuration::WakeupOnChannelB);
|
||||
|
||||
// Dummy class for cluster namespace
|
||||
pybind11::classh<ClusterNamespace> cluster(c, "Cluster");
|
||||
|
||||
pybind11::enum_<Cluster::SpeedType>(cluster, "SpeedType")
|
||||
.value("FLEXRAY_BAUDRATE_10M", Cluster::SpeedType::FLEXRAY_BAUDRATE_10M)
|
||||
.value("FLEXRAY_BAUDRATE_5M", Cluster::SpeedType::FLEXRAY_BAUDRATE_5M)
|
||||
.value("FLEXRAY_BAUDRATE_2M5", Cluster::SpeedType::FLEXRAY_BAUDRATE_2M5)
|
||||
.value("FLEXRAY_BAUDRATE_2M5_ALT", Cluster::SpeedType::FLEXRAY_BAUDRATE_2M5_ALT);
|
||||
|
||||
pybind11::enum_<Cluster::SPPType>(cluster, "SPPType")
|
||||
.value("FLEXRAY_SPP_5", Cluster::SPPType::FLEXRAY_SPP_5)
|
||||
.value("FLEXRAY_SPP_4", Cluster::SPPType::FLEXRAY_SPP_4)
|
||||
.value("FLEXRAY_SPP_6", Cluster::SPPType::FLEXRAY_SPP_6)
|
||||
.value("FLEXRAY_SPP_5_ALT", Cluster::SPPType::FLEXRAY_SPP_5_ALT);
|
||||
|
||||
pybind11::classh<Cluster::Configuration>(cluster, "Configuration")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("speed", &Cluster::Configuration::Speed)
|
||||
.def_readwrite("strobe_point_position", &Cluster::Configuration::StrobePointPosition)
|
||||
.def_readwrite("action_point_offset", &Cluster::Configuration::ActionPointOffset)
|
||||
.def_readwrite("casr_x_low_max", &Cluster::Configuration::CASRxLowMax)
|
||||
.def_readwrite("cold_start_attempts", &Cluster::Configuration::ColdStartAttempts)
|
||||
.def_readwrite("dynamic_slot_idle_phase_minislots", &Cluster::Configuration::DynamicSlotIdlePhaseMinislots)
|
||||
.def_readwrite("listen_noise_macroticks", &Cluster::Configuration::ListenNoiseMacroticks)
|
||||
.def_readwrite("macroticks_per_cycle", &Cluster::Configuration::MacroticksPerCycle)
|
||||
.def_readwrite("macrotick_duration_micro_sec", &Cluster::Configuration::MacrotickDurationMicroSec)
|
||||
.def_readwrite("max_without_clock_correction_fatal", &Cluster::Configuration::MaxWithoutClockCorrectionFatal)
|
||||
.def_readwrite("max_without_clock_correction_passive", &Cluster::Configuration::MaxWithoutClockCorrectionPassive)
|
||||
.def_readwrite("minislot_action_point_offset_macroticks", &Cluster::Configuration::MinislotActionPointOffsetMacroticks)
|
||||
.def_readwrite("minislot_duration_macroticks", &Cluster::Configuration::MinislotDurationMacroticks)
|
||||
.def_readwrite("network_idle_time_macroticks", &Cluster::Configuration::NetworkIdleTimeMacroticks)
|
||||
.def_readwrite("network_management_vector_length_bytes", &Cluster::Configuration::NetworkManagementVectorLengthBytes)
|
||||
.def_readwrite("number_of_minislots", &Cluster::Configuration::NumberOfMinislots)
|
||||
.def_readwrite("number_of_static_slots", &Cluster::Configuration::NumberOfStaticSlots)
|
||||
.def_readwrite("offset_correction_start_macroticks", &Cluster::Configuration::OffsetCorrectionStartMacroticks)
|
||||
.def_readwrite("payload_length_of_static_slot_in_words", &Cluster::Configuration::PayloadLengthOfStaticSlotInWords)
|
||||
.def_readwrite("static_slot_macroticks", &Cluster::Configuration::StaticSlotMacroticks)
|
||||
.def_readwrite("symbol_window_macroticks", &Cluster::Configuration::SymbolWindowMacroticks)
|
||||
.def_readwrite("symbol_window_action_point_offset_macroticks", &Cluster::Configuration::SymbolWindowActionPointOffsetMacroticks)
|
||||
.def_readwrite("sync_frame_id_count_max", &Cluster::Configuration::SyncFrameIDCountMax)
|
||||
.def_readwrite("transmission_start_sequence_duration_bits", &Cluster::Configuration::TransmissionStartSequenceDurationBits)
|
||||
.def_readwrite("wakeup_rx_idle_bits", &Cluster::Configuration::WakeupRxIdleBits)
|
||||
.def_readwrite("wakeup_rx_low_bits", &Cluster::Configuration::WakeupRxLowBits)
|
||||
.def_readwrite("wakeup_rx_window_bits", &Cluster::Configuration::WakeupRxWindowBits)
|
||||
.def_readwrite("wakeup_tx_active_bits", &Cluster::Configuration::WakeupTxActiveBits)
|
||||
.def_readwrite("wakeup_tx_idle_bits", &Cluster::Configuration::WakeupTxIdleBits);
|
||||
}
|
||||
|
||||
} // namespace FlexRay
|
||||
|
||||
void init_flexraymessage(pybind11::module_& m) {
|
||||
pybind11::classh<FlexRayMessage, Frame>(m, "FlexRayMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("slotid", &FlexRayMessage::slotid)
|
||||
.def_readwrite("tsslen", &FlexRayMessage::tsslen)
|
||||
.def_readwrite("framelen", &FlexRayMessage::framelen)
|
||||
.def_readwrite("symbol", &FlexRayMessage::symbol)
|
||||
.def_readwrite("header_crc_status", &FlexRayMessage::headerCRCStatus)
|
||||
.def_readwrite("header_crc", &FlexRayMessage::headerCRC)
|
||||
.def_readwrite("frame_crc_status", &FlexRayMessage::crcStatus)
|
||||
.def_readwrite("frame_crc", &FlexRayMessage::frameCRC)
|
||||
.def_readwrite("channel", &FlexRayMessage::channel)
|
||||
.def_readwrite("null_frame", &FlexRayMessage::nullFrame)
|
||||
.def_readwrite("payload_preamble", &FlexRayMessage::payloadPreamble)
|
||||
.def_readwrite("sync_frame", &FlexRayMessage::sync)
|
||||
.def_readwrite("startup_frame", &FlexRayMessage::startup)
|
||||
.def_readwrite("dynamic_frame", &FlexRayMessage::dynamic)
|
||||
.def_readwrite("cycle", &FlexRayMessage::cycle);
|
||||
|
||||
//// TODO: Eliminate FlexRayControlMessage class references in controller class and eliminate getStatus function in bindings
|
||||
}
|
||||
|
||||
void init_flexray(pybind11::module_& m) {
|
||||
// Dummy class to act as FlexRay namespace
|
||||
pybind11::classh<FlexRayNamespace> flexray(m, "FlexRay");
|
||||
|
||||
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);
|
||||
|
||||
init_flexraymessage(m);
|
||||
FlexRay::init_extension(flexray);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,79 +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_spimessage(pybind11::module_&);
|
||||
void init_ethernetstatusmessage(pybind11::module_&);
|
||||
void init_macsecconfig(pybind11::module_&);
|
||||
void init_scriptstatusmessage(pybind11::module_&);
|
||||
void init_diskdriver(pybind11::module_&);
|
||||
void init_deviceextension(pybind11::module_&);
|
||||
void init_chipid(pybind11::module_&);
|
||||
void init_versionreport(pybind11::module_&);
|
||||
void init_device(pybind11::module_&);
|
||||
void init_messagefilter(pybind11::module_&);
|
||||
void init_messagecallback(pybind11::module_&);
|
||||
void init_version(pybind11::module_&);
|
||||
void init_flexray(pybind11::module_& m);
|
||||
void init_idevicesettings(pybind11::module_&);
|
||||
void init_ethphymessage(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_macsecconfig(m);
|
||||
init_scriptstatusmessage(m);
|
||||
init_spimessage(m);
|
||||
init_messagefilter(m);
|
||||
init_messagecallback(m);
|
||||
init_diskdriver(m);
|
||||
init_flexray(m);
|
||||
init_ethphymessage(m);
|
||||
init_chipid(m);
|
||||
init_versionreport(m);
|
||||
init_device(m);
|
||||
init_deviceextension(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,7 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
yum install -y flex ca-certificates || exit 1
|
||||
|
||||
echo "$ICS_IPA_CA_CRT" >/etc/pki/ca-trust/source/anchors/ica-ipa-ca.crt
|
||||
|
||||
update-ca-trust || exit 1
|
||||
@@ -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
-1
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_EXAMPLES=ON \
|
||||
-DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_ENABLE_TCP=OFF || exit 1
|
||||
-DLIBICSNEO_BUILD_TESTS=ON -DLIBICSNEO_ENABLE_TCP=ON || 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
|
||||
+11
-8
@@ -1,9 +1,12 @@
|
||||
@setlocal
|
||||
@echo off
|
||||
REM clean intermediate directories
|
||||
rmdir /s /q build
|
||||
mkdir build
|
||||
|
||||
mkdir build >nul 2>&1
|
||||
|
||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_UNIT_TESTS=ON ^
|
||||
-DLIBICSNEO_ENABLE_TCP=ON || exit /b 1
|
||||
|
||||
cmake --build build || exit /b 1
|
||||
REM build
|
||||
cd build
|
||||
set CFLAGS=/WX
|
||||
set CXXFLAGS=/WX
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLIBICSNEO_BUILD_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"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
find_path(FTD3XX_INCLUDE_DIR
|
||||
NAMES ftd3xx.h FTD3XX.h
|
||||
)
|
||||
|
||||
find_library(FTD3XX_LIBRARY
|
||||
NAMES libftd3xx.a libftd3xx-static.a FTD3XX.lib
|
||||
PATH_SUFFIXES x64/Static
|
||||
)
|
||||
|
||||
mark_as_advanced(FTD3XX_FOUND FTD3XX_INCLUDE_DIR FTD3XX_LIBRARY)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(FTD3XX
|
||||
REQUIRED_VARS FTD3XX_INCLUDE_DIR FTD3XX_LIBRARY
|
||||
)
|
||||
if(FTD3XX_FOUND AND NOT TARGET D3XX::D3XX)
|
||||
add_library(FTD3XX::FTD3XX INTERFACE IMPORTED)
|
||||
set_target_properties(FTD3XX::FTD3XX PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${FTD3XX_INCLUDE_DIR}"
|
||||
INTERFACE_LINK_LIBRARIES "${FTD3XX_LIBRARY}"
|
||||
)
|
||||
endif()
|
||||
@@ -14,18 +14,14 @@
|
||||
#include "icsneo/communication/message/readsettingsmessage.h"
|
||||
#include "icsneo/communication/message/versionmessage.h"
|
||||
#include "icsneo/communication/message/componentversionsmessage.h"
|
||||
#include "icsneo/communication/message/filter/extendedresponsefilter.h"
|
||||
#include "icsneo/communication/message/clientidmessage.h"
|
||||
#include "icsneo/communication/icspb.h"
|
||||
|
||||
#include <commands/generic/v1/client_id.pb.h>
|
||||
#include <commands/network/v1/mutex.pb.h>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
int Communication::messageCallbackIDCounter = 1;
|
||||
|
||||
Communication::~Communication() {
|
||||
if(redirectingRead)
|
||||
clearRedirectRead();
|
||||
if(isOpen())
|
||||
close();
|
||||
}
|
||||
@@ -43,28 +39,24 @@ bool Communication::open() {
|
||||
}
|
||||
|
||||
void Communication::spawnThreads() {
|
||||
closing = false;
|
||||
readTaskThread = std::thread(&Communication::readTask, this);
|
||||
}
|
||||
|
||||
void Communication::joinThreads() {
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -104,6 +96,23 @@ bool Communication::sendCommand(ExtendedCommand cmd, std::vector<uint8_t> argume
|
||||
return sendCommand(Command::Extended, arguments);
|
||||
}
|
||||
|
||||
bool Communication::redirectRead(std::function<void(std::vector<uint8_t>&&)> redirectTo) {
|
||||
if(redirectingRead)
|
||||
return false;
|
||||
redirectionFn = redirectTo;
|
||||
redirectingRead = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Communication::clearRedirectRead() {
|
||||
if(!redirectingRead)
|
||||
return;
|
||||
// The mutex is required to clear the redirection, but not to set it
|
||||
std::lock_guard<std::mutex> lk(redirectingReadMutex);
|
||||
redirectingRead = false;
|
||||
redirectionFn = std::function<void(std::vector<uint8_t>&&)>();
|
||||
}
|
||||
|
||||
bool Communication::getSettingsSync(std::vector<uint8_t>& data, std::chrono::milliseconds timeout) {
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::ReadSettings);
|
||||
std::shared_ptr<Message> msg = waitForMessageSync([this]() {
|
||||
@@ -252,55 +261,44 @@ void Communication::dispatchMessage(const std::shared_ptr<Message>& msg) {
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
}
|
||||
|
||||
void Communication::pauseReads() {
|
||||
std::unique_lock<std::mutex> lk(pauseReadTaskMutex);
|
||||
pauseReadTask = true;
|
||||
}
|
||||
|
||||
void Communication::resumeReads() {
|
||||
std::unique_lock<std::mutex> lk(pauseReadTaskMutex);
|
||||
if(!pauseReadTask) {
|
||||
return;
|
||||
}
|
||||
pauseReadTask = false;
|
||||
lk.unlock();
|
||||
|
||||
pauseReadTaskCv.notify_one();
|
||||
}
|
||||
|
||||
bool Communication::readsArePaused() {
|
||||
std::unique_lock<std::mutex> lk(pauseReadTaskMutex);
|
||||
return pauseReadTask;
|
||||
}
|
||||
|
||||
void Communication::readTask() {
|
||||
std::vector<uint8_t> readBytes;
|
||||
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
|
||||
while(!closing) {
|
||||
if(pauseReadTask) {
|
||||
std::unique_lock<std::mutex> lk(pauseReadTaskMutex);
|
||||
pauseReadTaskCv.wait(lk, [this]() { return !pauseReadTask; });
|
||||
}
|
||||
if(driver->waitForRx(readTaskWakeLimit, readTaskWakeTimeout)) {
|
||||
if(pauseReadTask) {
|
||||
/**
|
||||
* Reads could have paused while the driver was not available
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
handleInput(*packetizer);
|
||||
readBytes.clear();
|
||||
if(driver->readWait(readBytes)) {
|
||||
handleInput(*packetizer, readBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Communication::handleInput(Packetizer& p) {
|
||||
if(p.input(driver->getReadBuffer())) {
|
||||
for(const auto& packet : p.output()) {
|
||||
std::shared_ptr<Message> msg;
|
||||
if(!decoder->decode(msg, packet))
|
||||
continue;
|
||||
void Communication::handleInput(Packetizer& p, std::vector<uint8_t>& readBytes) {
|
||||
if(redirectingRead) {
|
||||
// redirectingRead is an atomic so it can be set without acquiring a mutex
|
||||
// However, we do not clear it without the mutex. The idea is that if another
|
||||
// thread calls clearRedirectRead(), it will block until the redirectionFn
|
||||
// finishes, and after that the redirectionFn will not be called again.
|
||||
std::unique_lock<std::mutex> lk(redirectingReadMutex);
|
||||
// So after we acquire the mutex, we need to check the atomic again, and
|
||||
// if it has become cleared, we *can not* run the redirectionFn.
|
||||
if(redirectingRead) {
|
||||
redirectionFn(std::move(readBytes));
|
||||
} else {
|
||||
// The redirectionFn got cleared while we were acquiring the lock
|
||||
lk.unlock(); // We don't need the lock anymore
|
||||
handleInput(p, readBytes); // and we might as well process this input ourselves
|
||||
}
|
||||
} else {
|
||||
if(p.input(readBytes)) {
|
||||
for(const auto& packet : p.output()) {
|
||||
std::shared_ptr<Message> msg;
|
||||
if(!decoder->decode(msg, packet))
|
||||
continue;
|
||||
|
||||
dispatchMessage(msg);
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,32 +317,3 @@ std::optional< std::vector<ComponentVersion> > Communication::getComponentVersio
|
||||
|
||||
return std::make_optional< std::vector<ComponentVersion> >(std::move(ver->versions));
|
||||
}
|
||||
|
||||
std::optional<uint32_t> Communication::getClientIDSync() {
|
||||
constexpr auto timeout = std::chrono::milliseconds(250);
|
||||
commands::generic::v1::ClientId msg;
|
||||
msg.Clear();
|
||||
|
||||
std::vector<uint8_t> payload = protoapi::getPayload(protoapi::Command::GET, msg);
|
||||
|
||||
std::shared_ptr<Message> response = waitForMessageSync(
|
||||
[this, payload](){
|
||||
return sendCommand(ExtendedCommand::ProtobufAPI, payload);
|
||||
},
|
||||
std::make_shared<MessageFilter>(Message::Type::ClientId),
|
||||
timeout
|
||||
);
|
||||
|
||||
if(!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto clientIdMessage = std::dynamic_pointer_cast<ClientIdMessage>(response);
|
||||
if(!clientIdMessage) {
|
||||
report(APIEvent::Type::UnexpectedResponse, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return clientIdMessage->clientId;
|
||||
}
|
||||
|
||||
+21
-137
@@ -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,15 +15,7 @@
|
||||
#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/message/networkmutexmessage.h"
|
||||
#include "icsneo/communication/message/clientidmessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
@@ -44,11 +35,6 @@
|
||||
#include "icsneo/communication/packet/mdiopacket.h"
|
||||
#include "icsneo/communication/packet/genericbinarystatuspacket.h"
|
||||
#include "icsneo/communication/packet/livedatapacket.h"
|
||||
#include "icsneo/communication/packet/hardwareinfopacket.h"
|
||||
#include "icsneo/communication/packet/spipacket.h"
|
||||
#include "icsneo/communication/icspb.h"
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace icsneo;
|
||||
@@ -62,9 +48,8 @@ uint64_t Decoder::GetUInt64FromLEBytes(const uint8_t* bytes) {
|
||||
|
||||
bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet) {
|
||||
switch(packet->network.getType()) {
|
||||
case Network::Type::Ethernet:
|
||||
case Network::Type::AutomotiveEthernet: {
|
||||
result = HardwareEthernetPacket::DecodeToMessage(packet->data);
|
||||
case Network::Type::Ethernet: {
|
||||
result = HardwareEthernetPacket::DecodeToMessage(packet->data, report);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was not long enough to decode
|
||||
@@ -102,7 +87,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;
|
||||
}
|
||||
@@ -174,7 +159,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
|
||||
A2BMessage& msg = *static_cast<A2BMessage*>(result.get());
|
||||
msg.network = packet->network;
|
||||
msg.timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case Network::Type::LIN: {
|
||||
@@ -187,20 +171,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::SPI: {
|
||||
result = HardwareSPIPacket::DecodeToMessage(packet->data);
|
||||
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was not long enough to decode
|
||||
}
|
||||
|
||||
SPIMessage& msg = *static_cast<SPIMessage*>(result.get());
|
||||
msg.network = packet->network;
|
||||
msg.timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case Network::Type::MDIO: {
|
||||
@@ -259,26 +229,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) {
|
||||
result = HardwareCANPacket::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
return false; // A nullptr was returned, the packet was malformed
|
||||
}
|
||||
|
||||
if(can->arbid == 0x162) {
|
||||
result = EthernetStatusMessage::DecodeToMessage(can->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;
|
||||
// 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
|
||||
}
|
||||
|
||||
result->timestamp = can->timestamp * timestampResolution;
|
||||
raw->timestamp *= timestampResolution;
|
||||
raw->network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::DeviceStatus: {
|
||||
@@ -286,18 +251,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);
|
||||
@@ -312,11 +265,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;
|
||||
@@ -326,53 +279,12 @@ 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;
|
||||
}
|
||||
case ExtendedCommand::ProtobufAPI: {
|
||||
// get the proto id
|
||||
std::vector<uint8_t> responseBody(
|
||||
packet->data.begin() + sizeof(ExtendedResponseMessage::ResponseHeader),
|
||||
packet->data.end()
|
||||
);
|
||||
protoapi::Id protoId = protoapi::getProtoId(responseBody.data(), responseBody.size());
|
||||
switch(protoId) {
|
||||
case protoapi::Id::NetworkMutex:
|
||||
result = NetworkMutexMessage::DecodeToMessage(responseBody);
|
||||
return true;
|
||||
case protoapi::Id::ClientId:
|
||||
result = ClientIdMessage::DecodeToMessage(responseBody);
|
||||
return true;
|
||||
default:
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case ExtendedCommand::GetDiskDetails:
|
||||
case ExtendedCommand::DiskFormatProgress: {
|
||||
std::vector<uint8_t> responseBody(
|
||||
packet->data.begin() + sizeof(ExtendedResponseMessage::ResponseHeader),
|
||||
packet->data.end()
|
||||
);
|
||||
auto response = std::make_shared<ExtendedResponseMessage>(resp.command);
|
||||
response->data = std::move(responseBody);
|
||||
result = response;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// No defined handler, treat this as a RawMessage
|
||||
break;
|
||||
@@ -382,6 +294,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
case Network::NetID::ExtendedData: {
|
||||
if(packet->data.size() < sizeof(ExtendedDataMessage::ExtendedDataHeader))
|
||||
break;
|
||||
|
||||
const auto& header = *reinterpret_cast<ExtendedDataMessage::ExtendedDataHeader*>(packet->data.data());
|
||||
|
||||
switch(header.subCommand) {
|
||||
@@ -393,8 +306,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
extDataMsg->data.resize(numRead);
|
||||
|
||||
std::copy(packet->data.begin() + sizeof(header), packet->data.begin() + sizeof(header) + numRead, extDataMsg->data.begin());
|
||||
|
||||
extDataMsg->network = Network(static_cast<uint16_t>(Network::NetID::ExtendedData), false);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
@@ -445,16 +356,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
|
||||
return true;
|
||||
}
|
||||
case Command::GetHardwareInfo: {
|
||||
result = HardwareInfoPacket::DecodeToMessage(packet->data);
|
||||
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
auto msg = std::make_shared<Main51Message>();
|
||||
msg->command = Command(packet->data[0]);
|
||||
@@ -478,14 +379,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]);
|
||||
@@ -541,16 +434,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;
|
||||
|
||||
+22
-33
@@ -8,44 +8,37 @@
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
bool Driver::pushRx(const uint8_t* buf, size_t numReceived) {
|
||||
bool ret = readBuffer.write(buf, numReceived);
|
||||
bool Driver::read(std::vector<uint8_t>& bytes, size_t limit) {
|
||||
// A limit of zero indicates no limit
|
||||
if(limit == 0)
|
||||
limit = (size_t)-1;
|
||||
|
||||
rxWaitCv.notify_all();
|
||||
if(limit > (readQueue.size_approx() + 4))
|
||||
limit = (readQueue.size_approx() + 4);
|
||||
|
||||
return ret;
|
||||
}
|
||||
if(bytes.capacity() < limit)
|
||||
bytes.resize(limit);
|
||||
|
||||
void Driver::clearBuffers()
|
||||
{
|
||||
WriteOperation flushop;
|
||||
size_t actuallyRead = readQueue.try_dequeue_bulk(bytes.data(), limit);
|
||||
|
||||
readBuffer.clear();
|
||||
rxWaitCv.notify_all();
|
||||
if(bytes.size() > actuallyRead)
|
||||
bytes.resize(actuallyRead);
|
||||
|
||||
while (writeQueue.try_dequeue(flushop)) {}
|
||||
}
|
||||
|
||||
bool Driver::waitForRx(size_t limit, std::chrono::milliseconds timeout) {
|
||||
return waitForRx([limit, this]() {
|
||||
return readBuffer.size() >= limit;
|
||||
}, 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);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Driver::readWait(std::vector<uint8_t>& bytes, std::chrono::milliseconds timeout, size_t limit) {
|
||||
// wait until we have enough data, or the timeout occurs
|
||||
waitForRx(limit, timeout);
|
||||
// A limit of zero indicates no limit
|
||||
if(limit == 0)
|
||||
limit = (size_t)-1;
|
||||
|
||||
size_t actuallyRead = readBuffer.size();
|
||||
bytes.resize(actuallyRead);
|
||||
if(limit > (readQueue.size_approx() + 4))
|
||||
limit = (readQueue.size_approx() + 4);
|
||||
|
||||
bytes.resize(limit);
|
||||
|
||||
size_t actuallyRead = readQueue.wait_dequeue_bulk_timed(bytes.data(), limit, timeout);
|
||||
|
||||
readBuffer.read(bytes.data(), 0, actuallyRead);
|
||||
readBuffer.pop(actuallyRead);
|
||||
bytes.resize(actuallyRead);
|
||||
|
||||
#ifdef ICSNEO_DRIVER_DEBUG_PRINTS
|
||||
@@ -71,12 +64,8 @@ bool Driver::write(const std::vector<uint8_t>& bytes) {
|
||||
|
||||
if(writeBlocks) {
|
||||
if(writeQueueFull()) {
|
||||
while(writeQueueAlmostFull() && !isDisconnected() && !isClosing()) // Wait until we have some decent amount of space
|
||||
while(writeQueueAlmostFull()) // Wait until we have some decent amount of space
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
|
||||
if(isDisconnected() || isClosing()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(writeQueueFull()) {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "icsneo/communication/packet/a2bpacket.h"
|
||||
#include "icsneo/communication/packet/linpacket.h"
|
||||
#include "icsneo/communication/packet/mdiopacket.h"
|
||||
#include "icsneo/communication/packet/spipacket.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
@@ -32,31 +31,19 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
netid = uint16_t(frame->network.getNetID());
|
||||
|
||||
switch(frame->network.getType()) {
|
||||
case Network::Type::Ethernet:
|
||||
case Network::Type::AutomotiveEthernet: {
|
||||
case Network::Type::Ethernet: {
|
||||
auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(message);
|
||||
if(!ethmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
return false; // The message was not a properly formed EthernetMessage
|
||||
}
|
||||
|
||||
shortFormat = false; // Ensure long-format RED header is added
|
||||
netid = static_cast<uint16_t>(Network::NetID::ETHERNET_TX_WRAP);
|
||||
buffer = &result;
|
||||
|
||||
if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result, report)) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result, report))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(result.empty()) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Network::Type::Internal:
|
||||
} // End of Network::Type::Ethernet
|
||||
case Network::Type::CAN:
|
||||
case Network::Type::SWCAN:
|
||||
case Network::Type::LSFTCAN: {
|
||||
@@ -136,17 +123,6 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
}
|
||||
break;
|
||||
} // End of Network::Type::MDIO
|
||||
case Network::Type::SPI: {
|
||||
auto msg = std::dynamic_pointer_cast<SPIMessage>(message);
|
||||
if(!msg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false; // The message was not a properly formed LiveDataMessage
|
||||
}
|
||||
if(!HardwareSPIPacket::EncodeFromMessage(*msg, result, report))
|
||||
return false;
|
||||
result = packetizer.packetWrap(result, false);
|
||||
return true;
|
||||
} // End of Network::Type::SPI
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
@@ -254,6 +230,7 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
(uint8_t)(netid >> 8)
|
||||
});
|
||||
}
|
||||
|
||||
result = packetizer.packetWrap(*buffer, shortFormat);
|
||||
return true;
|
||||
}
|
||||
@@ -285,12 +262,9 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
case Command::RequestSerialNumber:
|
||||
case Command::EnableNetworkCommunication:
|
||||
case Command::EnableNetworkCommunicationEx:
|
||||
case Command::KeepAlive:
|
||||
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;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "icsneo/communication/livedata.h"
|
||||
#include <cmath>
|
||||
namespace icsneo {
|
||||
|
||||
namespace LiveDataUtil {
|
||||
@@ -19,61 +18,5 @@ double liveDataValueToDouble(const LiveDataValue& val) {
|
||||
return val.value * liveDataFixedPointToDouble;
|
||||
}
|
||||
|
||||
bool liveDataDoubleToValue(const double& dFloat, LiveDataValue& value) {
|
||||
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)std::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)std::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 true;
|
||||
|
||||
//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 || dFloat < INT32_MIN_DOUBLE) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::FixedPointOverflow, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use absolute value for minimum fixed point check
|
||||
double absFloat = (dFloat < 0.0) ? -dFloat : dFloat;
|
||||
if(absFloat < MIN_FIXED_POINT_DOUBLE) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::FixedPointPrecision, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace LiveDataUtil
|
||||
} // namespace icsneo
|
||||
@@ -1,257 +0,0 @@
|
||||
#include "icsneo/communication/message/a2bmessage.h"
|
||||
#include "icsneo/communication/message/callback/streamoutput/streamoutput.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
// Read a 16 bit sample from the audio buffer, which is stored as little endian
|
||||
#define SAMPLE_FROM_BYTES_16(audioData) (((audioData)[0]) | ((audioData)[1] << 8))
|
||||
|
||||
// Read a 32 bit sample from the audio buffer
|
||||
#define SAMPLE_FROM_BYTES_32(audioData) (((audioData)[0]) | ((audioData)[1] << 8) | ((audioData)[2] << 16) | ((audioData)[3] << 24))
|
||||
|
||||
// Read the most significant bytes of a sample stored in a 32 bit unsigned integer into audioData
|
||||
#define SAMPLE_TO_BYTES_16(audioData, offset, sample) {\
|
||||
(audioData)[(offset)++] = static_cast<uint8_t>(((sample) & 0x00FF0000u) >> 16);\
|
||||
(audioData)[(offset)++] = static_cast<uint8_t>(((sample) & 0xFF000000u) >> 24);\
|
||||
}
|
||||
|
||||
// Read little endian a 32 bit unsigned integer into audioData
|
||||
#define SAMPLE_TO_BYTES_32(audioData, offset, sample) {\
|
||||
(audioData)[(offset)++] = static_cast<uint8_t>(((sample) & 0x000000FFu));\
|
||||
(audioData)[(offset)++] = static_cast<uint8_t>(((sample) & 0x0000FF00u) >> 8);\
|
||||
(audioData)[(offset)++] = static_cast<uint8_t>(((sample) & 0x00FF0000u) >> 16);\
|
||||
(audioData)[(offset)++] = static_cast<uint8_t>(((sample) & 0xFF000000u) >> 24);\
|
||||
}
|
||||
|
||||
uint8_t A2BMessage::tdmToChannelNum(TDMMode tdm) {
|
||||
switch(tdm) {
|
||||
case TDMMode::TDM2:
|
||||
return 4;
|
||||
case TDMMode::TDM4:
|
||||
return 8;
|
||||
case TDMMode::TDM8:
|
||||
return 16;
|
||||
case TDMMode::TDM12:
|
||||
return 24;
|
||||
case TDMMode::TDM16:
|
||||
return 32;
|
||||
case TDMMode::TDM20:
|
||||
return 40;
|
||||
case TDMMode::TDM24:
|
||||
return 48;
|
||||
case TDMMode::TDM32:
|
||||
return 64;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t A2BMessage::getBytesPerChannel() const {
|
||||
return channelSize16 ? 2u : 4u;
|
||||
}
|
||||
size_t A2BMessage::getFrameSize() const {
|
||||
return static_cast<size_t>(2 * numChannels * getBytesPerChannel());
|
||||
}
|
||||
|
||||
size_t A2BMessage::getSampleOffset(Direction dir, uint8_t channel, size_t frame) const {
|
||||
size_t frameSize = getFrameSize();
|
||||
size_t sampleOffset = static_cast<size_t>(frameSize * frame + 2 * channel * getBytesPerChannel());
|
||||
|
||||
if(dir == Direction::Upstream) {
|
||||
sampleOffset += getBytesPerChannel();
|
||||
}
|
||||
|
||||
return sampleOffset;
|
||||
}
|
||||
|
||||
size_t A2BMessage::getNumFrames() const {
|
||||
size_t frameSize = getFrameSize();
|
||||
if(frameSize == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return data.size() / frameSize;
|
||||
}
|
||||
|
||||
A2BMessage::A2BMessage(size_t numFrames, TDMMode tdm, bool chSize16) : channelSize16(chSize16) {
|
||||
numChannels = static_cast<uint8_t>(tdmToChannelNum(tdm) / 2);
|
||||
|
||||
size_t frameSize = static_cast<size_t>(2 * numChannels * (chSize16 ? 2u : 4u));
|
||||
size_t audioBufferSize = frameSize * numFrames;
|
||||
if(audioBufferSize > maxAudioBufferSize) {
|
||||
size_t maxNumFrames = maxAudioBufferSize / frameSize;
|
||||
audioBufferSize = maxNumFrames * frameSize;
|
||||
}
|
||||
|
||||
data.resize(std::min<size_t>(maxAudioBufferSize, audioBufferSize), 0);
|
||||
}
|
||||
|
||||
A2BMessage::A2BMessage(TDMMode tdm, bool chSize16) : channelSize16(chSize16) {
|
||||
numChannels = static_cast<uint8_t>(tdmToChannelNum(tdm) / 2);
|
||||
size_t frameSize = static_cast<size_t>(2 * numChannels * (chSize16 ? 2u : 4u));
|
||||
|
||||
size_t maxNumFrames = maxAudioBufferSize / frameSize;
|
||||
size_t audioBufferSize = maxNumFrames * frameSize;
|
||||
|
||||
data.resize(audioBufferSize, 0);
|
||||
}
|
||||
|
||||
PCMSample A2BMessage::getChannelSample(Direction dir, uint8_t channel, size_t frame, PCMType pcmType) const {
|
||||
size_t sampleOffset = getSampleOffset(dir, channel, frame);
|
||||
const uint8_t* audioData = &data[sampleOffset];
|
||||
PCMSample result = 0;
|
||||
|
||||
// Samples coming from the device will either come from a 16 bit channel or 32 bit channel
|
||||
if(channelSize16) {
|
||||
int16_t sample16 = 0;
|
||||
uint16_t& uSample16 = *reinterpret_cast<uint16_t*>(&sample16);
|
||||
|
||||
// Read little endian from the audio buffer
|
||||
uSample16 = SAMPLE_FROM_BYTES_16(audioData);
|
||||
|
||||
// Scale the sample up according to the desired PCM size by
|
||||
// multiplying using logical shifting
|
||||
switch(pcmType) {
|
||||
case PCMType::L16:
|
||||
result = static_cast<PCMSample>(sample16);
|
||||
break;
|
||||
case PCMType::L24:
|
||||
result = static_cast<PCMSample>(sample16) << 8;
|
||||
break;
|
||||
case PCMType::L32:
|
||||
result = static_cast<PCMSample>(sample16) << 16;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
PCMSample sample32 = 0;
|
||||
uint32_t& uSample32 = *reinterpret_cast<uint32_t*>(&sample32);
|
||||
|
||||
// Read little endian
|
||||
uSample32 = SAMPLE_FROM_BYTES_32(audioData);
|
||||
|
||||
// Scale the sample down according to the desired PCM size by dividing using
|
||||
// logical shifting, if the A2B network was set up with the desired pcmType
|
||||
// there should be a clean division and no loss in PCM resolution.
|
||||
switch(pcmType) {
|
||||
case PCMType::L16:
|
||||
result = sample32 >> 16;
|
||||
break;
|
||||
case PCMType::L24:
|
||||
result = sample32 >> 8;
|
||||
break;
|
||||
case PCMType::L32:
|
||||
result = sample32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void A2BMessage::setChannelSample(Direction dir, uint8_t channel, size_t frame, PCMSample sampleToSet, PCMType pcmType) {
|
||||
|
||||
size_t sampleOffset = getSampleOffset(dir, channel, frame);
|
||||
uint32_t& uSample = *reinterpret_cast<uint32_t*>(&sampleToSet);
|
||||
|
||||
// Align the bytes towards the most significant bit by multiplying using
|
||||
// left shifts
|
||||
switch(pcmType) {
|
||||
case PCMType::L16:
|
||||
sampleToSet = sampleToSet << 16;
|
||||
break;
|
||||
case PCMType::L24:
|
||||
sampleToSet = sampleToSet << 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if(channelSize16) {
|
||||
// Read the 2 most significant bytes of the sample
|
||||
SAMPLE_TO_BYTES_16(data, sampleOffset, uSample)
|
||||
} else {
|
||||
// Read the entire sample
|
||||
SAMPLE_TO_BYTES_32(data, sampleOffset, uSample);
|
||||
}
|
||||
}
|
||||
|
||||
bool A2BMessage::loadAudioBuffer(IWAVStream& wavStream, const ChannelMap& channelMap) {
|
||||
if(!wavStream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t totalMessageChannels = numChannels * 2; // Multiply by two inorder to include both down and upstream channels
|
||||
size_t bytesPerChannel = static_cast<size_t>(getBytesPerChannel()); // Number of bytes per message channel
|
||||
size_t frameSize = getFrameSize();
|
||||
size_t numFrames = getNumFrames();
|
||||
|
||||
size_t bytesPerSampleWAV = static_cast<size_t>(wavStream.header.bitsPerSample / 8); // Number of bytes per sample in the WAV data-stream
|
||||
size_t numWAVChannels = static_cast<size_t>(wavStream.header.numChannels);
|
||||
size_t wavFrameSize = numWAVChannels * bytesPerSampleWAV;
|
||||
|
||||
if(bytesPerSampleWAV != 2 && bytesPerSampleWAV != 3 && bytesPerSampleWAV != 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(numFrames == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* audioBuffer = data.data();
|
||||
|
||||
std::vector<uint8_t> wavFrame(wavFrameSize, 0);
|
||||
for(size_t frame = 0; frame < numFrames; frame++) {
|
||||
|
||||
// Read one frame of data from the input stream
|
||||
if(!wavStream.read(reinterpret_cast<char*>(wavFrame.data()), wavFrame.size())) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Iterate through each mapping and set a message channel to a channel in the WAV frame above
|
||||
for(const auto& [messageChannel, wavChannel] : channelMap) {
|
||||
if(messageChannel >= totalMessageChannels || wavChannel >= numWAVChannels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t frameOffset = wavChannel * bytesPerSampleWAV; // Offset in the read WAV frame
|
||||
size_t audioBufferOffset = frame * frameSize + messageChannel * bytesPerChannel; // Offset in the message audio buffer
|
||||
|
||||
if(bytesPerChannel < bytesPerSampleWAV) {
|
||||
// In this case, the message channels are smaller than the samples in the input WAV
|
||||
// samples in both the message channel and WAV are little endian, so we write only the
|
||||
// most significant bytes of the WAV
|
||||
|
||||
// Align to most significant bytes of wav frame
|
||||
size_t align = bytesPerSampleWAV - bytesPerChannel;
|
||||
|
||||
for(
|
||||
size_t frameByte = frameOffset + align;
|
||||
frameByte < frameOffset + bytesPerSampleWAV;
|
||||
frameByte++,
|
||||
audioBufferOffset++
|
||||
) {
|
||||
audioBuffer[audioBufferOffset] = wavFrame[frameByte];
|
||||
}
|
||||
} else {
|
||||
// The message channel is greater than or equal to the sample in the WAV
|
||||
// I2S specifies that the sample in this case is right aligned to the most significant
|
||||
// byte of the message channel
|
||||
|
||||
// Align to most significant byte of audio buffer channel
|
||||
size_t align = bytesPerChannel - bytesPerSampleWAV;
|
||||
|
||||
for(
|
||||
size_t audioByte = audioBufferOffset + align;
|
||||
audioByte < audioBufferOffset + bytesPerChannel;
|
||||
audioByte++,
|
||||
frameOffset++
|
||||
) {
|
||||
audioBuffer[audioByte] = wavFrame[frameOffset];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,156 @@
|
||||
#include "icsneo/communication/message/callback/streamoutput/a2bdecoder.h"
|
||||
#include <chrono>
|
||||
#include "icsneo/icsneocpp.h"
|
||||
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
static constexpr uint8_t maxChannel = 255;
|
||||
|
||||
|
||||
size_t A2BAudioChannelMap::getChannelIndex(Channel channel, A2BMessage::A2BDirection dir) const {
|
||||
size_t output = (size_t)channel;
|
||||
|
||||
if(dir == A2BMessage::A2BDirection::Upstream) {
|
||||
output++;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
A2BAudioChannelMap::A2BAudioChannelMap(uint8_t tdm) {
|
||||
rawMap.resize(2*tdm, maxChannel);
|
||||
}
|
||||
|
||||
void A2BAudioChannelMap::set(Channel outChannel, A2BMessage::A2BDirection dir, Channel inChannel) {
|
||||
auto index = getChannelIndex(outChannel, dir);
|
||||
rawMap[index] = inChannel;
|
||||
}
|
||||
|
||||
void A2BAudioChannelMap::setAll(Channel inChannel) {
|
||||
std::fill(rawMap.begin(), rawMap.end(), inChannel);
|
||||
}
|
||||
|
||||
Channel A2BAudioChannelMap::get(Channel outChannel, A2BMessage::A2BDirection dir) const {
|
||||
auto index = getChannelIndex(outChannel, dir);
|
||||
|
||||
return rawMap[index];
|
||||
}
|
||||
|
||||
size_t A2BAudioChannelMap::A2BAudioChannelMap::size() const {
|
||||
return rawMap.size();
|
||||
}
|
||||
|
||||
uint8_t A2BAudioChannelMap::getTDM() const {
|
||||
return (uint8_t)(rawMap.size() / 2);
|
||||
}
|
||||
|
||||
Channel& A2BAudioChannelMap::operator[](size_t idx) {
|
||||
return rawMap[idx];
|
||||
}
|
||||
|
||||
A2BAudioChannelMap::operator const std::vector<Channel>&() const {
|
||||
return rawMap;
|
||||
}
|
||||
|
||||
A2BDecoder::A2BDecoder(
|
||||
std::unique_ptr<std::istream>&& streamOut,
|
||||
bool chSize16,
|
||||
const A2BAudioChannelMap& chMap
|
||||
) : channelSize16(chSize16), channelMap(chMap) {
|
||||
stream = std::move(streamOut);
|
||||
tdm = chMap.getTDM();
|
||||
initializeFromHeader();
|
||||
}
|
||||
|
||||
A2BDecoder::A2BDecoder(
|
||||
const char* filename,
|
||||
bool chSize16,
|
||||
const A2BAudioChannelMap& chMap
|
||||
) : A2BDecoder(std::make_unique<std::ifstream>(filename, std::ios::binary), chSize16, chMap) { }
|
||||
|
||||
A2BDecoder::operator bool() const {
|
||||
return initialized && stream->good() && !stream->eof();
|
||||
}
|
||||
|
||||
void A2BDecoder::initializeFromHeader() {
|
||||
WaveFileHeader header;
|
||||
if(!stream->read((char*)&header, sizeof(header))) {
|
||||
initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Only allow 16 or 24 bit samples
|
||||
if(header.bitsPerSample != 16 && header.bitsPerSample != 24) {
|
||||
initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
audioBytesPerSample = header.bitsPerSample == 16 ? 2 : 3;
|
||||
channelsInWave = (uint8_t)header.numChannels;
|
||||
|
||||
size_t bytesPerSample = channelSize16 ? 2 : 4;
|
||||
size_t frameSize = 2*tdm*bytesPerSample;
|
||||
size_t frameSizeWave = (size_t)(channelsInWave) * (size_t)(audioBytesPerSample);
|
||||
|
||||
frame.resize(frameSize, 0);
|
||||
frameWave.resize(frameSizeWave, 0);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
std::shared_ptr<A2BMessage> A2BDecoder::decode() {
|
||||
if(!*(this)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto a2bMessagePtr = std::make_shared<icsneo::A2BMessage>(
|
||||
tdm,
|
||||
channelSize16,
|
||||
2048
|
||||
);
|
||||
|
||||
A2BMessage& a2bMessage = *a2bMessagePtr.get();
|
||||
|
||||
a2bMessage.setMonitorBit(false); // Probably not necessary
|
||||
a2bMessage.setTxMsgBit(true);
|
||||
|
||||
a2bMessage.network = Network(Network::NetID::A2B2);
|
||||
|
||||
for(uint32_t frameIndex = 0; frameIndex < a2bMessage.getNumFrames(); frameIndex++) {
|
||||
if(!stream->read((char*)frameWave.data(), frameWave.size())) {
|
||||
break;
|
||||
}
|
||||
|
||||
for(size_t icsChannel = 0; icsChannel < channelMap.size(); icsChannel++) {
|
||||
|
||||
if(channelMap[icsChannel] >= maxChannel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t wBegin = audioBytesPerSample * channelMap[icsChannel];
|
||||
A2BPCMSample sample = 0;
|
||||
uint8_t* sampBytes = (uint8_t*)&sample;
|
||||
|
||||
std::copy(frameWave.begin() + wBegin, frameWave.begin() + wBegin + audioBytesPerSample, sampBytes);
|
||||
a2bMessage[frameIndex][icsChannel] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
return a2bMessagePtr;
|
||||
}
|
||||
|
||||
bool A2BDecoder::outputAll(std::shared_ptr<Device>& device) {
|
||||
const auto& networks = device->getSupportedTXNetworks();
|
||||
|
||||
if(std::none_of(networks.begin(), networks.end(), [](const Network& net) { return net.getNetID() == Network::NetID::A2B2; })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while(*this) {
|
||||
device->transmit(decode());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,99 +4,15 @@
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
A2BWAVOutput::A2BWAVOutput(
|
||||
const char* filename,
|
||||
const ChannelMap& channelMap,
|
||||
PCMType bitDepth,
|
||||
size_t numWAVChannels,
|
||||
uint32_t sampleRate
|
||||
)
|
||||
: StreamOutput(filename), wavSampleRate(sampleRate), numChannelsWAV(numWAVChannels), chMap(channelMap) {
|
||||
switch(bitDepth) {
|
||||
case PCMType::L16:
|
||||
bytesPerSampleWAV = 2;
|
||||
break;
|
||||
case PCMType::L24:
|
||||
bytesPerSampleWAV = 3;
|
||||
break;
|
||||
case PCMType::L32:
|
||||
bytesPerSampleWAV = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if(initialize()) {
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
A2BWAVOutput::A2BWAVOutput(
|
||||
std::ostream& os,
|
||||
const ChannelMap& channelMap,
|
||||
PCMType bitDepth,
|
||||
size_t numWAVChannels,
|
||||
uint32_t sampleRate
|
||||
)
|
||||
: StreamOutput(os), wavSampleRate(sampleRate), numChannelsWAV(numWAVChannels), chMap(channelMap) {
|
||||
switch(bitDepth) {
|
||||
case PCMType::L16:
|
||||
bytesPerSampleWAV = 2;
|
||||
break;
|
||||
case PCMType::L24:
|
||||
bytesPerSampleWAV = 3;
|
||||
break;
|
||||
case PCMType::L32:
|
||||
bytesPerSampleWAV = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if(initialize()) {
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
A2BWAVOutput::~A2BWAVOutput() {
|
||||
if(!closed) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
bool A2BWAVOutput::initialize() {
|
||||
static constexpr size_t maxWAVChannels = 256;
|
||||
|
||||
if(numChannelsWAV > maxWAVChannels) {
|
||||
return false;
|
||||
}
|
||||
|
||||
maxMessageChannel = 0;
|
||||
|
||||
// Check if the inputted channel map has invalid mappings and compute maxMessageChannel
|
||||
for(auto [wavChannel, messageChannel] : chMap) {
|
||||
maxMessageChannel = std::max<size_t>(maxMessageChannel, messageChannel);
|
||||
if(wavChannel >= numChannelsWAV) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
WAVHeader header = WAVHeader(
|
||||
static_cast<uint16_t>(chMap.size()),
|
||||
wavSampleRate,
|
||||
static_cast<uint16_t>(bytesPerSampleWAV * 8)
|
||||
);
|
||||
|
||||
if(!stream->write(reinterpret_cast<const char*>(&header), sizeof(WAVHeader))) {
|
||||
return false;
|
||||
}
|
||||
void A2BWAVOutput::writeHeader(const std::shared_ptr<A2BMessage>& firstMsg) const {
|
||||
|
||||
WaveFileHeader header = WaveFileHeader(2 * firstMsg->getNumChannels(), wavSampleRate, firstMsg->getBitDepth());
|
||||
header.write(stream);
|
||||
streamStartPos = static_cast<uint32_t>(stream->tellp());
|
||||
wavBuffer = std::vector<uint8_t>(wavBufferSize, 0);
|
||||
wavBufferOffset = 0;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool A2BWAVOutput::callIfMatch(const std::shared_ptr<Message>& message) const {
|
||||
if(!initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(closed) {
|
||||
return false;
|
||||
@@ -106,87 +22,28 @@ bool A2BWAVOutput::callIfMatch(const std::shared_ptr<Message>& message) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& frameMsg = std::dynamic_pointer_cast<Frame>(message);
|
||||
const auto& frame = std::static_pointer_cast<Frame>(message);
|
||||
|
||||
if(!frameMsg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(frameMsg->network.getType() != Network::Type::A2B)
|
||||
if(frame->network.getType() != Network::Type::A2B)
|
||||
return false;
|
||||
|
||||
const auto& a2bMsg = std::dynamic_pointer_cast<A2BMessage>(frameMsg);
|
||||
const auto& a2bmsg = std::static_pointer_cast<A2BMessage>(frame);
|
||||
|
||||
if(!a2bMsg) {
|
||||
return false;
|
||||
if(firstMessageFlag) {
|
||||
writeHeader(a2bmsg);
|
||||
firstMessageFlag = false;
|
||||
}
|
||||
|
||||
size_t frameSize = a2bMsg->getFrameSize();
|
||||
size_t wavFrameSize = numChannelsWAV * bytesPerSampleWAV;
|
||||
size_t bytesPerChannel = static_cast<size_t>(a2bMsg->getBytesPerChannel());
|
||||
size_t numMessageChannels = 2 * a2bMsg->numChannels;
|
||||
size_t numFrames = a2bMsg->getNumFrames();
|
||||
|
||||
const uint8_t* audioBuffer = a2bMsg->data.data();
|
||||
|
||||
if(maxMessageChannel >= numMessageChannels) {
|
||||
// The max message channel in our channel map is larger than the number of channels in this message
|
||||
// this is likely due to the user inputting incorrect settings
|
||||
return false;
|
||||
// Might need to readd this block of code later if sample alignment fix is necessary
|
||||
/*
|
||||
std::streamsize bps = (std::streamsize)a2bmsg->getBytesPerSample();
|
||||
for(size_t i=0; i<a2bmsg->getNumSamples(); i++) {
|
||||
A2BPCMSample samp = *(a2bmsg->getSample(i));
|
||||
write((void*)&samp, bps);
|
||||
}
|
||||
*/
|
||||
|
||||
for(size_t frame = 0; frame < numFrames; frame++) {
|
||||
// Check to see if we can read another frame in wavBuffer, otherwise write and clear the buffer
|
||||
if(wavBufferOffset + wavFrameSize >= wavBufferSize) {
|
||||
if(!writeCurrentBuffer()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t wavChannel = 0; wavChannel < numChannelsWAV; wavChannel++) {
|
||||
if(auto iter = chMap.find(static_cast<uint8_t>(wavChannel)); iter != chMap.end()) {
|
||||
auto messageChannel = iter->second;
|
||||
size_t messageChannelOffset = messageChannel * bytesPerChannel + frameSize* frame;
|
||||
|
||||
// Samples in the WAV are little endian signed integers
|
||||
// Samples in the message channels are little endian signed integers that are
|
||||
// most significant bit aligned
|
||||
if(a2bMsg->channelSize16) {
|
||||
// In this case, the channel size will be less than or equal to the sample we are writing
|
||||
// so we zero out any of the least significant bytes which won't be occupied by a sample byte
|
||||
|
||||
for(size_t zeroByte = 0; zeroByte < bytesPerSampleWAV - bytesPerChannel; zeroByte++) {
|
||||
wavBuffer[wavBufferOffset++] = 0;
|
||||
}
|
||||
|
||||
// Write the channel data in the most signifant bytes of the wav sample, this effectively
|
||||
// writes a sample which is scaled up.
|
||||
for(size_t channelByte = 0; channelByte < bytesPerChannel; channelByte++) {
|
||||
wavBuffer[wavBufferOffset++] = audioBuffer[messageChannelOffset + channelByte];
|
||||
}
|
||||
} else {
|
||||
// In this case, the channel size will be greater than or equal to the sample we are reading
|
||||
|
||||
// Align the wav sample with the most significant bytes of the channel
|
||||
size_t channelByte = messageChannelOffset + (bytesPerChannel - bytesPerSampleWAV);
|
||||
|
||||
// Read the most significant bytes of the channel into the wavBuffer
|
||||
for(size_t sampleByte = 0; sampleByte < bytesPerSampleWAV; sampleByte++, channelByte++) {
|
||||
wavBuffer[wavBufferOffset++] = audioBuffer[channelByte];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If this channel wasn't specified in the channel map, set a zero sample
|
||||
for(
|
||||
size_t sampleByte = 0;
|
||||
sampleByte < bytesPerSampleWAV;
|
||||
sampleByte++
|
||||
) {
|
||||
wavBuffer[wavBufferOffset++] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
write((void*)a2bmsg->getAudioBuffer(), a2bmsg->getAudioBufferSize());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -196,39 +53,17 @@ void A2BWAVOutput::close() const {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Write any left over data in the buffer
|
||||
if(wavBufferOffset > 0) {
|
||||
writeCurrentBuffer();
|
||||
}
|
||||
|
||||
// Seek back in the output stream and write the WAV chunk sizes
|
||||
uint32_t streamEndPos = static_cast<uint32_t>(stream->tellp());
|
||||
|
||||
uint32_t subChunk2Size = streamEndPos - streamStartPos;
|
||||
uint32_t chunkSize = streamEndPos - 8;
|
||||
|
||||
stream->seekp(streamStartPos - 4);
|
||||
stream->write(reinterpret_cast<const char*>(&subChunk2Size), 4);
|
||||
write((void*)&subChunk2Size, 4);
|
||||
stream->seekp(4, std::ios::beg);
|
||||
stream->write(reinterpret_cast<const char*>(&chunkSize), 4);
|
||||
write((void*)&chunkSize, 4);
|
||||
|
||||
closed = true;
|
||||
}
|
||||
|
||||
bool A2BWAVOutput::writeCurrentBuffer() const {
|
||||
|
||||
if(!stream->write(reinterpret_cast<const char*>(wavBuffer.data()), wavBufferOffset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wavBufferOffset = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "icsneo/communication/message/clientidmessage.h"
|
||||
#include "icsneo/communication/icspb.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::shared_ptr<ClientIdMessage> ClientIdMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
ClientIdMessage decoded;
|
||||
commands::generic::v1::ClientId msg;
|
||||
|
||||
if(!protoapi::processResponse(bytestream.data(), bytestream.size(), msg)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(msg.has_client_id()) {
|
||||
decoded.clientId.emplace(msg.client_id());
|
||||
}
|
||||
|
||||
return std::make_shared<ClientIdMessage>(decoded);
|
||||
}
|
||||
@@ -1,80 +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 TLinkMode {
|
||||
T_LINK_NONE,
|
||||
T_LINK_MASTER,
|
||||
T_LINK_SLAVE,
|
||||
T_LINK_AUTO,
|
||||
T_LINK_INVALID = 255,
|
||||
};
|
||||
|
||||
enum AELinkMode {
|
||||
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(Network::GetTypeOfNetID((Network::NetID)packet->network, false)) {
|
||||
case Network::Type::Ethernet:
|
||||
switch(packet->mode) {
|
||||
case T_LINK_NONE: mode = EthernetStatusMessage::LinkMode::LinkModeNone; break;
|
||||
case T_LINK_MASTER: mode = EthernetStatusMessage::LinkMode::LinkModeMaster; break;
|
||||
case T_LINK_SLAVE: mode = EthernetStatusMessage::LinkMode::LinkModeSlave; break;
|
||||
case T_LINK_AUTO: mode = EthernetStatusMessage::LinkMode::LinkModeAuto; break;
|
||||
case T_LINK_INVALID: mode = EthernetStatusMessage::LinkMode::LinkModeInvalid; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
break;
|
||||
case Network::Type::AutomotiveEthernet:
|
||||
switch(packet->mode) {
|
||||
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;
|
||||
case AE_LINK_INVALID: mode = EthernetStatusMessage::LinkMode::LinkModeInvalid; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
break;
|
||||
default: return nullptr;
|
||||
}
|
||||
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state, speed, packet->duplex, mode);
|
||||
}
|
||||
@@ -8,7 +8,7 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph
|
||||
msg->Clause45Enable = clause45;
|
||||
msg->Enabled = enabled;
|
||||
msg->WriteEnable = writeEnable;
|
||||
msg->Version = 1u;
|
||||
msg->version = 1u;
|
||||
if( (FiveBits < phyAddrOrPort) ||
|
||||
(clause45 && (FiveBits < pageOrDevice)) ||
|
||||
(!clause45 && (FiveBits < regAddr)) )
|
||||
@@ -18,17 +18,17 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph
|
||||
|
||||
if(clause45)
|
||||
{
|
||||
msg->Clause45.port = phyAddrOrPort;
|
||||
msg->Clause45.device = pageOrDevice;
|
||||
msg->Clause45.regAddr = regAddr;
|
||||
msg->Clause45.regVal = regVal;
|
||||
msg->clause45.port = phyAddrOrPort;
|
||||
msg->clause45.device = pageOrDevice;
|
||||
msg->clause45.regAddr = regAddr;
|
||||
msg->clause45.regVal = regVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->Clause22.phyAddr = phyAddrOrPort;
|
||||
msg->Clause22.page = pageOrDevice;
|
||||
msg->Clause22.regAddr = regAddr;
|
||||
msg->Clause22.regVal = regVal;
|
||||
msg->clause22.phyAddr = phyAddrOrPort;
|
||||
msg->clause22.page = pageOrDevice;
|
||||
msg->clause22.regAddr = regAddr;
|
||||
msg->clause22.regVal = regVal;
|
||||
}
|
||||
return appendPhyMessage(msg);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,9 @@ 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;
|
||||
ret.reserve(args.size() + 4);
|
||||
ret.push_back(controller);
|
||||
const uint16_t size = static_cast<uint16_t>(std::min(args.size() + 1, size_t(std::numeric_limits<uint16_t>::max()))); // Add 1 for the opcode
|
||||
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));
|
||||
ret.push_back(uint8_t(size >> 8));
|
||||
ret.push_back(uint8_t(op));
|
||||
|
||||
@@ -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,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;
|
||||
@@ -44,15 +44,14 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
||||
can.status.canfdESI = canmsg->errorStateIndicator;
|
||||
break;
|
||||
}
|
||||
case Network::Type::Ethernet:
|
||||
case Network::Type::AutomotiveEthernet: {
|
||||
case Network::Type::Ethernet: {
|
||||
neomessage_eth_t& eth = *(neomessage_eth_t*)&neomsg;
|
||||
auto ethmsg = std::static_pointer_cast<EthernetMessage>(message);
|
||||
eth.preemptionFlags = ethmsg->preemptionFlags;
|
||||
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;
|
||||
}
|
||||
@@ -76,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;
|
||||
@@ -107,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;
|
||||
@@ -143,8 +140,7 @@ std::shared_ptr<Message> icsneo::CreateMessageFromNeoMessage(const neomessage_t*
|
||||
canmsg->errorStateIndicator = can.status.canfdESI;
|
||||
return canmsg;
|
||||
}
|
||||
case Network::Type::Ethernet:
|
||||
case Network::Type::AutomotiveEthernet: {
|
||||
case Network::Type::Ethernet: {
|
||||
neomessage_eth_t& eth = *(neomessage_eth_t*)neomessage;
|
||||
auto ethmsg = std::make_shared<EthernetMessage>();
|
||||
ethmsg->network = network;
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
#include "icsneo/communication/message/networkmutexmessage.h"
|
||||
#include "icsneo/communication/icspb.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::shared_ptr<NetworkMutexMessage> NetworkMutexMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
NetworkMutexMessage decoded;
|
||||
commands::network::v1::NetworkMutex msg;
|
||||
|
||||
if(!protoapi::processResponse(bytestream.data(), bytestream.size(), msg)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(msg.has_client_id()) {
|
||||
decoded.owner_id.emplace(msg.client_id());
|
||||
}
|
||||
if(msg.has_type()) {
|
||||
decoded.type.emplace(static_cast<NetworkMutexType>(msg.type()));
|
||||
}
|
||||
if(msg.has_priority()) {
|
||||
decoded.priority.emplace(msg.priority());
|
||||
}
|
||||
if(msg.has_ttl()){
|
||||
decoded.ttlMs.emplace(msg.ttl());
|
||||
}
|
||||
if(msg.has_event()){
|
||||
decoded.event.emplace(static_cast<NetworkMutexEvent>(msg.event()));
|
||||
}
|
||||
for(int i = 0 ; i < msg.network_ids_size(); ++i){
|
||||
decoded.networks.emplace(static_cast<Network::NetID>(msg.network_ids(i)));
|
||||
}
|
||||
return std::make_shared<NetworkMutexMessage>(decoded);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForLock(uint32_t client_id, NetworkMutexType type, uint32_t priority, uint32_t ttlMs, const std::set<Network::NetID>& networks, const device_eventhandler_t& /* report */) {
|
||||
commands::network::v1::NetworkMutex msg;
|
||||
for(auto&& network_id : networks) {
|
||||
msg.add_network_ids(static_cast<commands::network::v1::NetworkId>(network_id));
|
||||
}
|
||||
msg.set_client_id(client_id);
|
||||
msg.set_priority(priority);
|
||||
msg.set_ttl(ttlMs);
|
||||
msg.set_type(static_cast<commands::network::v1::MutexType>(type));
|
||||
|
||||
return protoapi::getPayload(protoapi::Command::PUT, msg);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForLockAll(uint32_t client_id, NetworkMutexType type, uint32_t priority, uint32_t ttlMs, const device_eventhandler_t& /* report */) {
|
||||
commands::network::v1::NetworkMutex msg;
|
||||
msg.set_client_id(client_id);
|
||||
msg.set_priority(priority);
|
||||
msg.set_ttl(ttlMs);
|
||||
msg.set_type(static_cast<commands::network::v1::MutexType>(type));
|
||||
msg.set_global(true);
|
||||
|
||||
return protoapi::getPayload(protoapi::Command::PUT, msg);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForUnlock(uint32_t client_id, const std::set<Network::NetID>& networks, const device_eventhandler_t& /* report */) {
|
||||
commands::network::v1::NetworkMutex msg;
|
||||
msg.Clear();
|
||||
for(auto&& network_id : networks)
|
||||
{
|
||||
msg.add_network_ids(static_cast<commands::network::v1::NetworkId>(network_id));
|
||||
}
|
||||
msg.set_client_id(client_id);
|
||||
msg.set_release(true);
|
||||
|
||||
return protoapi::getPayload(protoapi::Command::PUT, msg);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForUnlockAll(uint32_t client_id, const device_eventhandler_t& /* report */) {
|
||||
commands::network::v1::NetworkMutex msg;
|
||||
msg.Clear();
|
||||
msg.set_client_id(client_id);
|
||||
msg.set_release(true);
|
||||
msg.set_global(true);
|
||||
|
||||
return protoapi::getPayload(protoapi::Command::PUT, msg);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForStatus(Network::NetID network, const device_eventhandler_t& /* report */) {
|
||||
commands::network::v1::NetworkMutex msg;
|
||||
msg.add_network_ids(static_cast<commands::network::v1::NetworkId>(network));
|
||||
return protoapi::getPayload(protoapi::Command::GET, msg);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
#pragma pack(push, 2)
|
||||
struct Header {
|
||||
ExtendedCommand command;
|
||||
uint16_t length;
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
Header header;
|
||||
TC10WakeStatus wakeStatus;
|
||||
TC10SleepStatus sleepStatus;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
std::shared_ptr<TC10StatusMessage> TC10StatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(Packet)) {
|
||||
return nullptr;
|
||||
}
|
||||
const Packet* packet = (Packet*)bytestream.data();
|
||||
if (packet->header.command != ExtendedCommand::GetTC10Status) {
|
||||
return nullptr;
|
||||
}
|
||||
if (packet->header.length < sizeof(Packet) - sizeof(Header)) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::make_shared<TC10StatusMessage>(packet->wakeStatus, packet->sleepStatus);
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
#include "icsneo/communication/message/transmitmessage.h"
|
||||
|
||||
// packet defs
|
||||
#include "icsneo/communication/packet/ethernetpacket.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
#include "icsneo/communication/packet/linpacket.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
// copied.. TODO
|
||||
static std::optional<uint8_t> CAN_LengthToDLC(size_t dataLength, bool fd) {
|
||||
if(dataLength <= 8)
|
||||
return uint8_t(dataLength);
|
||||
|
||||
if(fd) {
|
||||
if(dataLength <= 12)
|
||||
return uint8_t(0x9);
|
||||
if(dataLength <= 16)
|
||||
return uint8_t(0xA);
|
||||
if(dataLength <= 20)
|
||||
return uint8_t(0xB);
|
||||
if(dataLength <= 24)
|
||||
return uint8_t(0xC);
|
||||
if(dataLength <= 32)
|
||||
return uint8_t(0xD);
|
||||
if(dataLength <= 48)
|
||||
return uint8_t(0xE);
|
||||
if(dataLength <= 64)
|
||||
return uint8_t(0xF);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> EncodeFromMessageEthernet(std::shared_ptr<Frame> frame, const device_eventhandler_t& report) {
|
||||
auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(frame);
|
||||
if(!ethmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return {};
|
||||
}
|
||||
std::vector<uint8_t> encoded;
|
||||
size_t messageLen = ethmsg->data.size();
|
||||
encoded.resize(sizeof(TransmitMessage) + messageLen);
|
||||
|
||||
TransmitMessage* const msg = (TransmitMessage*)encoded.data();
|
||||
HardwareEthernetPacket* const ethpacket = (HardwareEthernetPacket*)(msg->commonHeader);
|
||||
uint8_t* const payload = encoded.data() + sizeof(TransmitMessage);
|
||||
|
||||
ethpacket->header.ENABLE_PADDING = ethmsg->noPadding ? 0 : 1;
|
||||
ethpacket->header.FCS_OVERRIDE = ethmsg->fcs ? 1 : 0;
|
||||
ethpacket->eid.txlen = static_cast<uint16_t>(messageLen);
|
||||
ethpacket->Length = static_cast<uint16_t>(messageLen);
|
||||
ethpacket->stats = ethmsg->description;
|
||||
ethpacket->NetworkID = static_cast<uint16_t>(ethmsg->network.getNetID());
|
||||
std::copy(ethmsg->data.begin(), ethmsg->data.end(), payload);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> EncodeFromMessageCAN(std::shared_ptr<Frame> frame, const device_eventhandler_t& report) {
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(frame);
|
||||
if(!canmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return {};
|
||||
}
|
||||
if(canmsg->isCANFD && canmsg->isRemote) {
|
||||
report(APIEvent::Type::RTRNotSupported, APIEvent::Severity::Error);
|
||||
return {}; // RTR frames can not be used with CAN FD
|
||||
}
|
||||
std::vector<uint8_t> encoded;
|
||||
size_t messageLen = canmsg->data.size();
|
||||
size_t extraLen = 0;
|
||||
if(messageLen > 8) {
|
||||
extraLen = messageLen - 8;
|
||||
}
|
||||
encoded.resize(sizeof(TransmitMessage) + extraLen);
|
||||
|
||||
TransmitMessage* const msg = (TransmitMessage*)encoded.data();
|
||||
HardwareCANPacket* const canpacket = (HardwareCANPacket*)(msg->commonHeader);
|
||||
uint8_t* const extra_payload = encoded.data() + sizeof(TransmitMessage);
|
||||
|
||||
const size_t dataSize = canmsg->data.size();
|
||||
std::optional<uint8_t> dlc = CAN_LengthToDLC(dataSize, canmsg->isCANFD);
|
||||
if(!dlc.has_value()) {
|
||||
report(APIEvent::Type::MessageMaxLengthExceeded, APIEvent::Severity::Error);
|
||||
return {}; // Too much data for the protocol
|
||||
}
|
||||
// arb id
|
||||
if(canmsg->isExtended) {
|
||||
canpacket->header.IDE = 1;
|
||||
canpacket->header.SID = (canmsg->arbid >> 18) & 0x7FF;
|
||||
canpacket->eid.EID = (canmsg->arbid >> 6) & 0xfff;
|
||||
canpacket->dlc.EID2 = canmsg->arbid & 0x3f;
|
||||
} else {
|
||||
canpacket->header.IDE = 0;
|
||||
canpacket->header.SID = canmsg->arbid & 0x7FF;
|
||||
}
|
||||
|
||||
// DLC
|
||||
canpacket->dlc.DLC = dlc.value();
|
||||
|
||||
// FDF/BRS or remote frames
|
||||
if(canmsg->isCANFD) {
|
||||
canpacket->header.EDL = 1;
|
||||
canpacket->header.BRS = canmsg->baudrateSwitch ? 1 : 0;
|
||||
canpacket->header.ESI = canmsg->errorStateIndicator ? 1 : 0;
|
||||
canpacket->dlc.RTR = 0;
|
||||
canpacket->timestamp.IsExtended = 1;
|
||||
|
||||
} else {
|
||||
canpacket->header.EDL = 0;
|
||||
canpacket->header.BRS = 0;
|
||||
canpacket->header.ESI = 0;
|
||||
canpacket->dlc.RTR = canmsg->isRemote ? 1 : 0;
|
||||
}
|
||||
// network
|
||||
canpacket->NetworkID = static_cast<uint16_t>(canmsg->network.getNetID());
|
||||
canpacket->Length = static_cast<uint16_t>(extraLen);
|
||||
// description id
|
||||
canpacket->stats = canmsg->description;
|
||||
// first 8 bytes
|
||||
std::copy(canmsg->data.begin(), canmsg->data.begin() + (messageLen > 8 ? 8 : messageLen), canpacket->data);
|
||||
// extra bytes
|
||||
if(extraLen > 0) {
|
||||
// copy extra data after the can packet
|
||||
std::copy(canmsg->data.begin() + 8, canmsg->data.end(), extra_payload);
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> EncodeFromMessageLIN(std::shared_ptr<Frame> /* frame */, const device_eventhandler_t& report) {
|
||||
// TODO
|
||||
report(APIEvent::Type::UnsupportedTXNetwork, APIEvent::Severity::Error);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<uint8_t> TransmitMessage::EncodeFromMessage(std::shared_ptr<Frame> frame, uint32_t client_id, const device_eventhandler_t& report) {
|
||||
std::vector<uint8_t> result;
|
||||
switch(frame->network.getType()) {
|
||||
case Network::Type::Ethernet:
|
||||
case Network::Type::AutomotiveEthernet:
|
||||
result = EncodeFromMessageEthernet(frame, report);
|
||||
break;
|
||||
case Network::Type::Internal:
|
||||
case Network::Type::CAN:
|
||||
result = EncodeFromMessageCAN(frame, report);
|
||||
break;
|
||||
case Network::Type::LIN:
|
||||
result = EncodeFromMessageLIN(frame, report);
|
||||
break;
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return result;
|
||||
}
|
||||
// common fields
|
||||
TransmitMessage* const msg = (TransmitMessage*)result.data();
|
||||
msg->options.clientId = client_id;
|
||||
msg->options.networkId = static_cast<uint32_t>(frame->network.getNetID());
|
||||
msg->options.reserved[0] = 0;
|
||||
msg->options.reserved[1] = 0;
|
||||
msg->options.reserved[2] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ using namespace icsneo;
|
||||
MultiChannelCommunication::MultiChannelCommunication(device_eventhandler_t err, std::unique_ptr<Driver> com,
|
||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer, std::unique_ptr<Encoder> e,
|
||||
std::unique_ptr<Decoder> md, size_t vnetCount) :
|
||||
Communication(err, std::move(com), makeConfiguredPacketizer, std::move(e), std::move(md)), numVnets(vnetCount), packetRB(2048) {
|
||||
Communication(err, std::move(com), makeConfiguredPacketizer, std::move(e), std::move(md)), numVnets(vnetCount) {
|
||||
vnetThreads.resize(numVnets);
|
||||
vnetQueues.resize(numVnets);
|
||||
}
|
||||
@@ -24,7 +24,6 @@ void MultiChannelCommunication::spawnThreads() {
|
||||
|
||||
void MultiChannelCommunication::joinThreads() {
|
||||
closing = true;
|
||||
ringBufCV.notify_all();
|
||||
if(hidReadThread.joinable())
|
||||
hidReadThread.join();
|
||||
for(auto& thread : vnetThreads) {
|
||||
@@ -149,13 +148,9 @@ void MultiChannelCommunication::hidReadTask() {
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock lk(ringBufMutex);
|
||||
if(!packetRB.write(std::move(payloadBytes)) && gotPacket)
|
||||
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToRead, APIEvent::Severity::Error));
|
||||
payloadBytes.clear();
|
||||
}
|
||||
ringBufCV.notify_all();
|
||||
if(!currentQueue->enqueue(std::move(payloadBytes)) && gotPacket)
|
||||
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToRead, APIEvent::Severity::Error));
|
||||
payloadBytes.clear();
|
||||
gotPacket = true;
|
||||
state = PreprocessState::SearchForCommand;
|
||||
break;
|
||||
@@ -165,6 +160,7 @@ void MultiChannelCommunication::hidReadTask() {
|
||||
}
|
||||
|
||||
void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) {
|
||||
moodycamel::BlockingReaderWriterQueue< std::vector<uint8_t> >& queue = vnetQueues[vnetIndex];
|
||||
std::vector<uint8_t> payloadBytes;
|
||||
std::unique_ptr<Packetizer> packetizerLifetime;
|
||||
Packetizer* vnetPacketizer;
|
||||
@@ -178,19 +174,11 @@ void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) {
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
|
||||
while(!closing) {
|
||||
std::unique_lock lk(ringBufMutex);
|
||||
ringBufCV.wait(lk);
|
||||
if(closing) {
|
||||
break;
|
||||
}
|
||||
if(vnetPacketizer->input(packetRB)) {
|
||||
for(const auto& packet : vnetPacketizer->output()) {
|
||||
std::shared_ptr<Message> msg;
|
||||
if(!decoder->decode(msg, packet))
|
||||
continue;
|
||||
if(queue.wait_dequeue_timed(payloadBytes, std::chrono::milliseconds(250))) {
|
||||
if(closing)
|
||||
break;
|
||||
|
||||
dispatchMessage(msg);
|
||||
}
|
||||
}
|
||||
handleInput(*vnetPacketizer, payloadBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,51 +4,55 @@
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
const size_t HardwareA2BPacket::a2bMessageMaxLength = sizeof(HardwareA2BPacket) + 1024;
|
||||
const size_t HardwareA2BPacket::coreMiniMessageHeaderSize = 28;
|
||||
const size_t HardwareA2BPacket::a2bMessageMaxLength = (size_t)HardwareA2BPacket::coreMiniMessageHeaderSize + 1024;
|
||||
const size_t HardwareA2BPacket::a2bHeaderSize = 6;
|
||||
|
||||
std::shared_ptr<Message> HardwareA2BPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
|
||||
if(bytestream.size() < sizeof(HardwareA2BPacket))
|
||||
if(bytestream.size() < coreMiniMessageHeaderSize)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const HardwareA2BPacket* data = (const HardwareA2BPacket*)bytestream.data();
|
||||
const HardwareA2BPacket *data = (const HardwareA2BPacket*)bytestream.data();
|
||||
|
||||
size_t totalPackedLength = static_cast<size_t>(bytestream.size()) - sizeof(HardwareA2BPacket); // First 28 bytes are message header.
|
||||
size_t totalPackedLength = static_cast<size_t>(bytestream.size()) - static_cast<size_t>(coreMiniMessageHeaderSize); // First 28 bytes are message header.
|
||||
|
||||
if(totalPackedLength == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
std::shared_ptr<A2BMessage> msg = std::make_shared<A2BMessage>(
|
||||
(uint8_t)data->header.channelNum,
|
||||
data->header.channelSize16,
|
||||
totalPackedLength
|
||||
);
|
||||
|
||||
std::shared_ptr<A2BMessage> msg = std::make_shared<A2BMessage>();
|
||||
msg->setMonitorBit(data->header.monitor);
|
||||
msg->setTxMsgBit(data->header.txmsg);
|
||||
msg->setErrIndicatorBit(data->header.errIndicator);
|
||||
msg->setSyncFrameBit(data->header.syncFrame);
|
||||
msg->setRFU2(data->header.rfu2);
|
||||
msg->setAudioBuffer(bytestream.begin() + coreMiniMessageHeaderSize, bytestream.end());
|
||||
|
||||
msg->numChannels = data->header.channelNum;
|
||||
msg->channelSize16 = data->header.channelSize16;
|
||||
msg->monitor = data->header.monitor;
|
||||
msg->txmsg = data->header.txmsg;
|
||||
msg->errIndicator = data->header.errIndicator;
|
||||
msg->syncFrame = data->header.syncFrame;
|
||||
msg->rfu2 = data->header.rfu2;
|
||||
msg->timestamp = data->timestamp.TS;
|
||||
|
||||
msg->data = std::vector(bytestream.begin() + sizeof(HardwareA2BPacket), bytestream.end());
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool HardwareA2BPacket::EncodeFromMessage(const A2BMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& /*report*/) {
|
||||
bool HardwareA2BPacket::EncodeFromMessage(const A2BMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) {
|
||||
constexpr size_t a2btxMessageHeaderSize = 6;
|
||||
|
||||
size_t audioBufferSize = message.data.size();
|
||||
size_t totalSize = a2btxMessageHeaderSize + audioBufferSize;
|
||||
if(message.getBytesPerSample() != 2 && message.getBytesPerSample() != 4) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t sampleBytes = message.getAudioBufferSize();
|
||||
size_t totalSize = a2btxMessageHeaderSize + sampleBytes;
|
||||
|
||||
bytestream.resize(totalSize, 0);
|
||||
uint32_t offset = 0;
|
||||
|
||||
bytestream[offset++] = 0;
|
||||
bytestream[offset++] = 0;
|
||||
bytestream[offset++] = (uint8_t)(audioBufferSize & 0xFF);
|
||||
bytestream[offset++] = (uint8_t)((audioBufferSize >> 8) & 0xFF);
|
||||
bytestream[offset++] = (uint8_t)(sampleBytes & 0xFF);
|
||||
bytestream[offset++] = (uint8_t)((sampleBytes >> 8) & 0xFF);
|
||||
bytestream[offset++] = (uint8_t)((message.description >> 8) & 0xFF);
|
||||
bytestream[offset++] = (uint8_t)(message.description & 0xFF);
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -114,7 +112,7 @@ std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<ui
|
||||
msg->data.insert(msg->data.end(), data->data, data->data + (length > 8 ? 8 : length));
|
||||
if(length > 8) { // If there are more than 8 bytes, they come at the end of the message
|
||||
// Messages with extra data are formatted as message, then uint16_t netid, then uint16_t length, then extra data
|
||||
const auto extraDataStart = bytestream.begin() + sizeof(HardwareCANPacket);
|
||||
const auto extraDataStart = bytestream.begin() + sizeof(HardwareCANPacket) + 2 + 2;
|
||||
msg->data.insert(msg->data.end(), extraDataStart, extraDataStart + (length - 8));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,129 +1,98 @@
|
||||
#include "icsneo/communication/packet/ethernetpacket.h"
|
||||
#include <algorithm> // for std::copy
|
||||
#include <cstring> // memcpy
|
||||
#include <iostream>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) {
|
||||
const HardwareEthernetPacket* packet = (const HardwareEthernetPacket*)((const void*)bytestream.data());
|
||||
const uint16_t* rawWords = (const uint16_t*)bytestream.data();
|
||||
|
||||
// Make sure we have enough to read the packet length first
|
||||
if(bytestream.size() < sizeof(HardwareEthernetPacket))
|
||||
return nullptr;
|
||||
|
||||
// packet->Length will also encompass the two uint16_t's at the end of the struct, make sure that at least they are here
|
||||
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;
|
||||
|
||||
// Check for oversized packets, noting that some devices will send an extra byte to have an even number of bytes
|
||||
if(bytestreamActualSize > bytestreamExpectedSize + 1)
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
|
||||
auto messagePtr = std::make_shared<EthernetMessage>();
|
||||
EthernetMessage& message = *messagePtr;
|
||||
|
||||
message.transmitted = packet->eid.TXMSG;
|
||||
if(message.transmitted)
|
||||
message.description = packet->stats;
|
||||
|
||||
message.preemptionEnabled = packet->header.PREEMPTION_ENABLED;
|
||||
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;
|
||||
|
||||
// This timestamp is raw off the device (in timestampResolution increments)
|
||||
// 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;
|
||||
}
|
||||
|
||||
bool HardwareEthernetPacket::EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t&) {
|
||||
const size_t unpaddedSize = message.data.size();
|
||||
if(unpaddedSize == 0)
|
||||
return false;
|
||||
size_t paddedSize = unpaddedSize;
|
||||
uint16_t description = message.description;
|
||||
|
||||
if(!message.noPadding && unpaddedSize < 60)
|
||||
paddedSize = 60; // Pad out short messages
|
||||
|
||||
size_t sizeWithHeader = paddedSize + 4; // DescriptionID and Padded Count
|
||||
|
||||
// Description ID Most Significant bit is used to identify preemption frames
|
||||
uint16_t description = message.description;
|
||||
if(description & 0x8000)
|
||||
return false;
|
||||
|
||||
const bool preempt = message.preemptionEnabled;
|
||||
// full header including parent
|
||||
const size_t headerByteCount = preempt ? 15 : 14;
|
||||
// local header for netID, description, and flags
|
||||
const size_t localHeader = preempt ? 10 : 9;
|
||||
// allocate space for fcs override
|
||||
const size_t fcsSize = message.fcs ? 4 : 0;
|
||||
|
||||
if(preempt)
|
||||
if(message.preemptionEnabled) {
|
||||
sizeWithHeader++; // Make space for the preemption flags
|
||||
description |= 0x8000;
|
||||
|
||||
size_t paddedSize = unpaddedSize;
|
||||
if(!message.noPadding && unpaddedSize < 60)
|
||||
paddedSize = 60;
|
||||
|
||||
// size of full payload including optional fcs
|
||||
size_t payloadSize = paddedSize + fcsSize;
|
||||
|
||||
|
||||
// totalBufferSize is local header + ethernet payload and option fcs
|
||||
const size_t totalBufferSize = localHeader + paddedSize + fcsSize;
|
||||
|
||||
bytestream.clear();
|
||||
bytestream.reserve(totalBufferSize);
|
||||
|
||||
// Header size field (little endian)
|
||||
bytestream.push_back(static_cast<uint8_t>(payloadSize & 0xFF));
|
||||
bytestream.push_back(static_cast<uint8_t>((payloadSize >> 8) & 0xFF));
|
||||
|
||||
// Description (big endian)
|
||||
bytestream.push_back(static_cast<uint8_t>(description >> 8));
|
||||
bytestream.push_back(static_cast<uint8_t>(description));
|
||||
|
||||
bytestream.push_back(0x00);
|
||||
bytestream.push_back(static_cast<uint8_t>(headerByteCount));
|
||||
|
||||
// Network ID (little endian)
|
||||
uint16_t realID = static_cast<uint16_t>(message.network.getNetID());
|
||||
bytestream.push_back(static_cast<uint8_t>(realID & 0xFF));
|
||||
bytestream.push_back(static_cast<uint8_t>((realID >> 8) & 0xFF));
|
||||
|
||||
// Flags
|
||||
constexpr uint8_t FLAG_PADDING = 0x01;
|
||||
constexpr uint8_t FLAG_FCS = 0x04;
|
||||
constexpr uint8_t FLAG_PREEMPTION = 0x08;
|
||||
|
||||
uint8_t flags = 0x00;
|
||||
if(!message.noPadding) flags |= FLAG_PADDING;
|
||||
if(message.fcs) flags |= FLAG_FCS;
|
||||
if(message.preemptionEnabled) flags |= FLAG_PREEMPTION;
|
||||
|
||||
bytestream.push_back(flags);
|
||||
|
||||
if(preempt)
|
||||
bytestream.push_back(static_cast<uint8_t>(message.preemptionFlags));
|
||||
|
||||
bytestream.insert(bytestream.end(), message.data.begin(), message.data.end());
|
||||
|
||||
// Only zero-fill when we want padding
|
||||
if(!message.noPadding && unpaddedSize < 60) {
|
||||
size_t paddingNeeded = 60 - unpaddedSize;
|
||||
bytestream.insert(bytestream.end(), paddingNeeded, 0); // Zero-fill for padding
|
||||
}
|
||||
|
||||
if(message.fcs) {
|
||||
uint32_t fcs = message.fcs.value();
|
||||
const uint8_t* fcsBytes = reinterpret_cast<const uint8_t*>(&fcs);
|
||||
bytestream.insert(bytestream.end(), fcsBytes, fcsBytes + sizeof(fcs));
|
||||
}
|
||||
bytestream.reserve(sizeWithHeader + 8); // Also reserve space for the bytes we'll use later on
|
||||
bytestream.resize(sizeWithHeader);
|
||||
size_t index = 0;
|
||||
|
||||
// Padded size, little endian
|
||||
bytestream[index++] = uint8_t(paddedSize);
|
||||
bytestream[index++] = uint8_t(paddedSize >> 8);
|
||||
|
||||
// Description ID, big endian
|
||||
bytestream[index++] = uint8_t(description >> 8);
|
||||
bytestream[index++] = uint8_t(description);
|
||||
|
||||
// The header is one byte larger if preemption is enabled, shifting the data
|
||||
if(message.preemptionEnabled)
|
||||
bytestream[index++] = message.preemptionFlags;
|
||||
|
||||
// We only copy in the unpadded size, the rest will be 0
|
||||
memcpy(bytestream.data() + index, message.data.data(), unpaddedSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -34,12 +34,11 @@ std::shared_ptr<EthPhyMessage> HardwareEthernetPhyRegisterPacket::DecodeToMessag
|
||||
phyMessage->Enabled = (pEntry->Enabled != 0u);
|
||||
phyMessage->WriteEnable = (pEntry->WriteEnable != 0u);
|
||||
phyMessage->Clause45Enable = (pEntry->Clause45Enable != 0u);
|
||||
phyMessage->BusIndex = static_cast<uint8_t>(pEntry->BusIndex);
|
||||
phyMessage->Version = static_cast<uint8_t>(pEntry->version);
|
||||
phyMessage->version = static_cast<uint8_t>(pEntry->version);
|
||||
if(phyMessage->Clause45Enable)
|
||||
phyMessage->Clause45 = pEntry->clause45;
|
||||
phyMessage->clause45 = pEntry->clause45;
|
||||
else
|
||||
phyMessage->Clause22 = pEntry->clause22;
|
||||
phyMessage->clause22 = pEntry->clause22;
|
||||
msg->messages.push_back(phyMessage);
|
||||
}
|
||||
}
|
||||
@@ -70,35 +69,34 @@ bool HardwareEthernetPhyRegisterPacket::EncodeFromMessage(const EthPhyMessage& m
|
||||
PhyRegisterPacket_t tempPacket;
|
||||
tempPacket.Enabled = phyMessage->Enabled ? 0x1u : 0x0u;
|
||||
tempPacket.WriteEnable = phyMessage->WriteEnable ? 0x1u : 0x0u;
|
||||
tempPacket.BusIndex = (phyMessage->BusIndex & 0xF);
|
||||
tempPacket.version = (phyMessage->Version & 0xF);
|
||||
tempPacket.version = (phyMessage->version & 0xF);
|
||||
if(phyMessage->Clause45Enable)
|
||||
{
|
||||
if( (FiveBits < phyMessage->Clause45.port) ||
|
||||
(FiveBits < phyMessage->Clause45.device) )
|
||||
if( (FiveBits < phyMessage->clause45.port) ||
|
||||
(FiveBits < phyMessage->clause45.device) )
|
||||
{
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
tempPacket.Clause45Enable = 0x1u;
|
||||
tempPacket.clause45.port = phyMessage->Clause45.port;
|
||||
tempPacket.clause45.device = phyMessage->Clause45.device;
|
||||
tempPacket.clause45.regAddr = phyMessage->Clause45.regAddr;
|
||||
tempPacket.clause45.regVal = phyMessage->Clause45.regVal;
|
||||
tempPacket.clause45.port = phyMessage->clause45.port;
|
||||
tempPacket.clause45.device = phyMessage->clause45.device;
|
||||
tempPacket.clause45.regAddr = phyMessage->clause45.regAddr;
|
||||
tempPacket.clause45.regVal = phyMessage->clause45.regVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (FiveBits < phyMessage->Clause22.phyAddr) ||
|
||||
(FiveBits < phyMessage->Clause22.regAddr) )
|
||||
if( (FiveBits < phyMessage->clause22.phyAddr) ||
|
||||
(FiveBits < phyMessage->clause22.regAddr) )
|
||||
{
|
||||
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
tempPacket.Clause45Enable = 0x0u;
|
||||
tempPacket.clause22.phyAddr = phyMessage->Clause22.phyAddr;
|
||||
tempPacket.clause22.page = phyMessage->Clause22.page;
|
||||
tempPacket.clause22.regAddr = phyMessage->Clause22.regAddr;
|
||||
tempPacket.clause22.regVal = phyMessage->Clause22.regVal;
|
||||
tempPacket.clause22.phyAddr = phyMessage->clause22.phyAddr;
|
||||
tempPacket.clause22.page = phyMessage->clause22.page;
|
||||
tempPacket.clause22.regAddr = phyMessage->clause22.regAddr;
|
||||
tempPacket.clause22.regVal = phyMessage->clause22.regVal;
|
||||
}
|
||||
uint8_t* pktPtr = reinterpret_cast<uint8_t*>(&tempPacket);
|
||||
bytestream.insert(bytestream.end(), pktPtr, pktPtr + sizeof(PhyRegisterPacket_t));
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "icsneo/communication/packet/hardwareinfopacket.h"
|
||||
#include "icsneo/communication/message/hardwareinfo.h"
|
||||
#include <iostream>
|
||||
using namespace icsneo;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t valid;
|
||||
struct
|
||||
{
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint16_t year;
|
||||
} manufactureDate;
|
||||
struct
|
||||
{
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
} hwRev;
|
||||
uint8_t deviceId;
|
||||
struct
|
||||
{
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
} blVersion;
|
||||
} HardwareInfoFrame;
|
||||
#pragma pack(pop)
|
||||
|
||||
std::shared_ptr<HardwareInfo> HardwareInfoPacket::DecodeToMessage(const std::vector<uint8_t>& bytes) {
|
||||
if(bytes.size() < (sizeof(HardwareInfoFrame) + 1)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto* frame = reinterpret_cast<const HardwareInfoFrame*>(&bytes[1]);
|
||||
|
||||
auto msg = std::make_shared<HardwareInfo>();
|
||||
|
||||
msg->manufactureDate.day = frame->manufactureDate.day;
|
||||
msg->manufactureDate.year = frame->manufactureDate.year;
|
||||
msg->manufactureDate.month = frame->manufactureDate.month;
|
||||
|
||||
msg->hardwareRevision.major = frame->hwRev.major;
|
||||
msg->hardwareRevision.minor = frame->hwRev.minor;
|
||||
|
||||
msg->bootloaderVersion.major = frame->blVersion.major;
|
||||
msg->bootloaderVersion.minor = frame->blVersion.minor;
|
||||
|
||||
return msg;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace icsneo
|
||||
report(APIEvent::Type::I2CMessageExceedsMaxLength, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(message.controlBytes.empty() && message.dataBytes.empty())
|
||||
if(message.controlBytes.empty() || message.dataBytes.empty())
|
||||
{
|
||||
//You'll need to provide a target R/W register in controlBytes
|
||||
//alternatively, you're expecting to read without providing a dataBytes payload
|
||||
|
||||
@@ -9,7 +9,7 @@ std::shared_ptr<Message> HardwareLINPacket::DecodeToMessage(const std::vector<ui
|
||||
size_t numDataBytes = packet->CoreMiniBitsLIN.len;
|
||||
size_t numHeaderBytes = sizeof(HardwareLINPacket::CoreMiniBitsLIN);
|
||||
|
||||
if( (sizeof(HardwareLINPacket) > bytestream.size()) ||
|
||||
if( (sizeof(HardwareLINPacket) != bytestream.size()) ||
|
||||
((numDataBytes + numHeaderBytes) > bytestream.size()) )
|
||||
return nullptr;
|
||||
|
||||
@@ -17,6 +17,7 @@ std::shared_ptr<Message> HardwareLINPacket::DecodeToMessage(const std::vector<ui
|
||||
--numDataBytes; //If data is present, there will be a checksum included
|
||||
|
||||
auto msg = std::make_shared<LINMessage>(static_cast<uint8_t>(packet->CoreMiniBitsLIN.ID));
|
||||
msg->network = Network::GetNetIDFromCoreMiniNetwork(static_cast<Network::CoreMini>(packet->networkID));
|
||||
msg->isEnhancedChecksum = static_cast<bool>(packet->CoreMiniBitsLIN.TxChkSumEnhanced);
|
||||
|
||||
/* Minimum one responder byte and one checksum byte. */
|
||||
@@ -30,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->numSetValues = (uint32_t)numArgs;
|
||||
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(LiveDataValue::value);
|
||||
}
|
||||
} else {
|
||||
report(APIEvent::Type::LiveDataInvalidArgument, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
report(APIEvent::Type::LiveDataInvalidCommand, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#include "icsneo/communication/packet/spipacket.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
static size_t SPISubHeaderLength = 5u;
|
||||
|
||||
std::shared_ptr<Message> HardwareSPIPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(HardwareSPIPacket)) {
|
||||
return nullptr;
|
||||
}
|
||||
const HardwareSPIPacket* packet = (const HardwareSPIPacket*)bytestream.data();
|
||||
size_t totalPackedLength = static_cast<size_t>(bytestream.size()) - sizeof(HardwareSPIPacket); // First 28 bytes are message header.
|
||||
if(totalPackedLength < SPISubHeaderLength) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const uint8_t* bytes = bytestream.data() + sizeof(HardwareSPIPacket);
|
||||
std::shared_ptr<SPIMessage> msg = std::make_shared<SPIMessage>();
|
||||
msg->direction = static_cast<SPIMessage::Direction>(bytes[0]);
|
||||
msg->address = *reinterpret_cast<const uint16_t*>(&bytes[1]);
|
||||
msg->mms = bytes[3];
|
||||
msg->stats = packet->stats;
|
||||
msg->timestamp = packet->timestamp.TS;
|
||||
|
||||
size_t numWords = (totalPackedLength - SPISubHeaderLength) / 4;
|
||||
msg->payload.reserve(numWords);
|
||||
for(size_t offset = SPISubHeaderLength; offset < totalPackedLength; offset += 4) {
|
||||
msg->payload.push_back(*reinterpret_cast<const uint32_t*>(bytes + offset));
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool HardwareSPIPacket::EncodeFromMessage(const SPIMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& /*report*/) {
|
||||
// Payload length is everything excluding cmdHeader (note at the beginning there is an offset of 2)
|
||||
uint16_t payloadLength = static_cast<uint16_t>(
|
||||
2 +
|
||||
sizeof(HardwareSPIPacket) +
|
||||
SPISubHeaderLength +
|
||||
message.payload.size() * sizeof(uint32_t)
|
||||
);
|
||||
if(payloadLength % 2) {
|
||||
// Pad payload to even number
|
||||
payloadLength++;
|
||||
}
|
||||
// +1 for AA, another +1 for firmware nuance
|
||||
uint16_t fullSize = 1 + sizeof(ExtendedCommandHeader) + payloadLength + 1;
|
||||
uint16_t unwrappedSize = sizeof(ExtendedCommandHeader) + payloadLength; // fullSize without AA and firmware nuance
|
||||
|
||||
bytestream.resize(unwrappedSize, 0);
|
||||
uint32_t offset = 0;
|
||||
auto* cmdHeader = reinterpret_cast<ExtendedCommandHeader*>(bytestream.data() + offset);
|
||||
cmdHeader->netid = static_cast<uint8_t>(Network::NetID::Main51);
|
||||
cmdHeader->fullLength = fullSize;
|
||||
cmdHeader->command = static_cast<uint8_t>(Command::Extended);
|
||||
cmdHeader->extendedCommand = static_cast<uint16_t>(ExtendedCommand::TransmitCoreminiMessage);
|
||||
cmdHeader->payloadLength = payloadLength;
|
||||
|
||||
offset += sizeof(ExtendedCommandHeader) + 2; // Offset of 2 between header and packet
|
||||
auto* packet = reinterpret_cast<HardwareSPIPacket*>(bytestream.data() + offset);
|
||||
packet->header.frameLength = static_cast<uint16_t>(SPISubHeaderLength + message.payload.size() * sizeof(uint32_t));
|
||||
packet->networkID = static_cast<uint16_t>(message.network.getNetID());
|
||||
packet->length = packet->header.frameLength;
|
||||
packet->timestamp.IsExtended = 1;
|
||||
|
||||
offset += sizeof(HardwareSPIPacket);
|
||||
// Write the sub header details
|
||||
bytestream[offset++] = static_cast<uint8_t>(message.direction);
|
||||
bytestream[offset++] = static_cast<uint8_t>(message.address & 0xFF);
|
||||
bytestream[offset++] = static_cast<uint8_t>((message.address >> 8) & 0xFF);
|
||||
bytestream[offset++] = static_cast<uint8_t>(message.mms);
|
||||
bytestream[offset++] = static_cast<uint8_t>(message.payload.size());
|
||||
|
||||
// Write the words
|
||||
for(uint32_t word : message.payload) {
|
||||
*reinterpret_cast<uint32_t*>(bytestream.data() + offset) = word;
|
||||
offset += sizeof(uint32_t);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -23,9 +23,6 @@ std::shared_ptr<SupportedFeaturesMessage> SupportedFeaturesPacket::DecodeToMessa
|
||||
}
|
||||
// Get a reference to the payload to fully validate the length
|
||||
const auto& response = *reinterpret_cast<const SupportedFeaturesResponse*>(bytes.data());
|
||||
if(response.cmdVersion != SupportedFeaturesCommandVersion) {
|
||||
return msg;
|
||||
}
|
||||
// Expected size is the header, cmdVersion and numValidBits fields, plus the number of 32-bit bitfields in the response based on numValidBits
|
||||
auto expectedSize = sizeof(ExtendedResponseMessage::ResponseHeader) + 4 + ((response.numValidBits + 31) / 32) * 4;
|
||||
// If the response is malformed (too small), return an empty message
|
||||
|
||||
@@ -31,46 +31,24 @@ std::shared_ptr<WiVI::ResponseMessage> WiVI::CommandPacket::DecodeToMessage(cons
|
||||
break;
|
||||
}
|
||||
case WiVI::Command::GetAll: {
|
||||
if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAllHeader))
|
||||
if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAll))
|
||||
return {};
|
||||
|
||||
const auto& getAll = *reinterpret_cast<const WiVI::CommandPacket::GetAllHeader*>(bytestream.data());
|
||||
const auto& getAll = *reinterpret_cast<const WiVI::CommandPacket::GetAll*>(bytestream.data());
|
||||
msg->responseTo = WiVI::Command::GetAll;
|
||||
msg->info.emplace();
|
||||
msg->info->sleepRequest = getAll.sleepRequest;
|
||||
msg->info->connectionTimeoutMinutes = getAll.connectionTimeoutMinutes;
|
||||
|
||||
// Check that we have enough data for the capture infos
|
||||
size_t captureInfosSize = sizeof(WiVI::CaptureInfo) * getAll.numCaptureInfos;
|
||||
if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAllHeader) + captureInfosSize)
|
||||
if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAll) + (sizeof(WiVI::CaptureInfo) * getAll.numCaptureInfos))
|
||||
return {};
|
||||
|
||||
const WiVI::CaptureInfo* const captureInfos = (const WiVI::CaptureInfo*)(bytestream.data() + sizeof(WiVI::CommandPacket::GetAllHeader));
|
||||
msg->info->captures.resize(getAll.numCaptureInfos);
|
||||
for(uint16_t i = 0; i < getAll.numCaptureInfos; i++)
|
||||
msg->info->captures[i] = captureInfos[i];
|
||||
|
||||
|
||||
// New field vinAvail was added - check if it is present:
|
||||
if(bytestream.size() >= sizeof(WiVI::CommandPacket::GetAllHeader) + captureInfosSize + 2) {
|
||||
msg->info->vinAvailable = *(bytestream.data() + sizeof(WiVI::CommandPacket::GetAllHeader) + captureInfosSize);
|
||||
} else {
|
||||
msg->info->vinAvailable = 0;
|
||||
}
|
||||
|
||||
msg->info->captures[i] = getAll.captureInfos[i];
|
||||
break;
|
||||
}
|
||||
case WiVI::Command::GetVIN: {
|
||||
if (bytestream.size() < sizeof(WiVI::CommandPacket::GetVIN))
|
||||
return {};
|
||||
|
||||
const auto& getVIN = *reinterpret_cast<const WiVI::CommandPacket::GetVIN*>(bytestream.data());
|
||||
msg->responseTo = WiVI::Command::GetVIN;
|
||||
msg->vin = getVIN.VIN;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: // Unknown command response
|
||||
return {};
|
||||
}
|
||||
@@ -100,9 +78,9 @@ std::vector<uint8_t> WiVI::CommandPacket::SetSignal::Encode(WiVI::SignalType typ
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> WiVI::CommandPacket::GetAllHeader::Encode() {
|
||||
std::vector<uint8_t> ret(sizeof(WiVI::CommandPacket::GetAllHeader));
|
||||
auto& frame = *reinterpret_cast<WiVI::CommandPacket::GetAllHeader*>(ret.data());
|
||||
std::vector<uint8_t> WiVI::CommandPacket::GetAll::Encode() {
|
||||
std::vector<uint8_t> ret(sizeof(WiVI::CommandPacket::GetAll));
|
||||
auto& frame = *reinterpret_cast<WiVI::CommandPacket::GetAll*>(ret.data());
|
||||
|
||||
frame.header.cmd = WiVI::Command::GetAll;
|
||||
frame.header.length = sizeof(frame) - sizeof(frame.header);
|
||||
@@ -120,15 +98,3 @@ std::vector<uint8_t> WiVI::CommandPacket::ClearUploads::Encode(const std::vector
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> WiVI::CommandPacket::GetVIN::Encode()
|
||||
{
|
||||
std::vector<uint8_t> ret(sizeof(WiVI::CommandPacket::GetVIN));
|
||||
auto& frame = *reinterpret_cast<WiVI::CommandPacket::GetVIN*>(ret.data());
|
||||
|
||||
frame.header.cmd = WiVI::Command::GetVIN;
|
||||
frame.header.length = sizeof(frame) - sizeof(frame.header);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,9 +24,11 @@ std::vector<uint8_t>& Packetizer::packetWrap(std::vector<uint8_t>& data, bool sh
|
||||
return data;
|
||||
}
|
||||
|
||||
bool Packetizer::input(RingBuffer& bytes) {
|
||||
bool Packetizer::input(const std::vector<uint8_t>& inputBytes) {
|
||||
bool haveEnoughData = true;
|
||||
|
||||
bytes.Copy(inputBytes);
|
||||
|
||||
while(haveEnoughData) {
|
||||
switch(state) {
|
||||
case ReadState::SearchForHeader:
|
||||
@@ -150,14 +152,14 @@ bool Packetizer::input(RingBuffer& bytes) {
|
||||
if(packetLength > 0)
|
||||
packet.data.resize(packetLength - headerSize);
|
||||
|
||||
bytes.read(packet.data.data(), currentIndex, (packetLength - currentIndex));
|
||||
bytes.CopyTo(packet.data.data(), currentIndex, (packetLength - currentIndex));
|
||||
currentIndex = packetLength;
|
||||
|
||||
if(disableChecksum || !checksum || bytes[currentIndex] == ICSChecksum(packet.data)) {
|
||||
// Got a good packet
|
||||
gotGoodPackets = true;
|
||||
processedPackets.push_back(std::make_shared<Packet>(packet));
|
||||
bytes.pop(packetLength);
|
||||
bytes.Erase_front(packetLength);
|
||||
|
||||
if(packet.network == Network::NetID::DiskData && (packetLength - headerSize) % 2 == 0) {
|
||||
bytes.pop_front();
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* crc32.c
|
||||
*
|
||||
* Created on: Jun 22, 2020
|
||||
* Author: BJones
|
||||
*/
|
||||
#include "icsneo/core/crc32.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 icsneo::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)
|
||||
{
|
||||
uint16_t k;
|
||||
|
||||
for (k = 0; k < 256; k++)
|
||||
rev_crc32_table[crc32_table[k] >> 24] = (unsigned char)k;
|
||||
}
|
||||
|
||||
uint32_t icsneo::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;
|
||||
}
|
||||
@@ -1,776 +0,0 @@
|
||||
#include "icsneo/core/macseccfg.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "icsneo/core/crc32.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201) // nameless struct/union
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t VID; /*!< 12 bits */
|
||||
uint8_t PRI_CFI; /*!< PRI - 3 bits, CFI - 1bit */
|
||||
} MACSEC_VLANTAG_t;
|
||||
/**
|
||||
* @brief Structure of MPLS
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t MPLS_label; /*!< 20 bits */
|
||||
uint8_t exp; /*!< 3 bits */
|
||||
} MACSEC_MPLS_OUTER_t;
|
||||
|
||||
#define MACSEC_SETTINGS_RULE_SIZE (88)
|
||||
typedef union _MACSecRule
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index;
|
||||
uint8_t key_MAC_DA[6]; /*!< MAC DA field extracted from the packet */
|
||||
uint8_t mask_MAC_DA[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t key_MAC_SA[6]; /*!< MAC SA field extracted from the packet */
|
||||
uint8_t mask_MAC_SA[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t key_Ethertype; /*!< First E-Type found in the packet that doesn't match one of the preconfigured custom tag. */
|
||||
uint16_t mask_Ethertype; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_VLANTAG_t key_vlantag_outer1; /*!< outermost/1st VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACSEC_MPLS_OUTER_t key_MPLS_outer1;
|
||||
MACSEC_VLANTAG_t mask_vlantag_outer1; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_MPLS_OUTER_t mask_MPLS_outer1;
|
||||
MACSEC_VLANTAG_t key_vlantag_outer2; /*!< 2nd outermost VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACSEC_MPLS_OUTER_t key_MPLS_outer2;
|
||||
MACSEC_VLANTAG_t mask_vlantag_outer2; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_MPLS_OUTER_t mask_MPLS_outer2;
|
||||
uint16_t key_bonus_data; /*!< 2 bytes of additional bonus data extracted from one of the custom tags. */
|
||||
uint16_t mask_bonus_data; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t
|
||||
key_tag_match_bitmap; /*!< 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 mask_tag_match_bitmap; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACsecPacketType key_packet_type; /*!< Encoded Packet Type, see MACSEC_PACKET_TYPE */
|
||||
uint8_t mask_packet_type; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t
|
||||
key_inner_vlan_type; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the second outermost VLAN Tag. */
|
||||
uint16_t mask_inner_vlan_type; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t key_outer_vlan_type; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the outermost VLAN Tag. */
|
||||
uint16_t mask_outer_vlan_type; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t
|
||||
key_num_tags; /*!< 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 mask_num_tags; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t key_express; /*!< 1 bits. Express packet. */
|
||||
uint8_t mask_express; /*!< 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 */
|
||||
#define MACSEC_SETTINGS_MAP_SIZE (20)
|
||||
typedef union _MACSecMap
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index;
|
||||
uint64_t sectag_sci; /*!< 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 auxiliary_plcy; /*!< 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 */
|
||||
|
||||
#define MACSEC_SETTINGS_SECY_SIZE (24)
|
||||
typedef union _MACSecSecY
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index; /*!< Identifies the SecY for this Flow. */
|
||||
uint8_t controlled_port_enabled; /*!< Enable (or disable) operation of the Controlled port associated with this SecY */
|
||||
MACsecValidation validate_frames; /*!< see MACSEC_VALIDATEFRAME */
|
||||
MACsecStrip strip_sectag_icv; /*!< see MACSEC_STRIP_SECTAG_ICV */
|
||||
MACsecCipherSuite cipher; /*!< Define the cipher suite to use for this SecY */
|
||||
uint8_t confidential_offset; /*!< Define the number of bytes that are unencrypted following the SecTag. */
|
||||
uint8_t icv_includes_da_sa; /*!< When set, the outer DA/SA bytes are included in the authentication GHASH calculation */
|
||||
uint8_t replay_protect; /*!< Enables Anti-Replay protection */
|
||||
uint32_t replay_window; /*!< Unsigned value indicating the size of the anti-replay window. */
|
||||
uint8_t
|
||||
protect_frames; /*!< 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
|
||||
sectag_offset; /*!< Define the offset in bytes from either the start of the packet or a matching Etype depending on SecTag_Insertion_Mode. */
|
||||
uint8_t sectag_tci; /*!< 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 */
|
||||
#define 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 sa_index0; /*!< Define the 1st SA to use */
|
||||
uint8_t sa_index1; /*!< Define the 2nd SA to use */
|
||||
uint8_t sa_index0_in_use; /*!< Specifies whether 1st SA is in use or not. */
|
||||
uint8_t sa_index1_in_use; /*!< Specifies whether 2nd SA is in use or not. */
|
||||
uint8_t enable_auto_rekey; /*!< 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 */
|
||||
#define 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 */
|
||||
#define MACSEC_SETTINGS_FLAGS_SIZE (4)
|
||||
typedef union _MACSecFlags
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t en : 1; // '1' = enable; '0' = disable
|
||||
uint32_t reserved : 31;
|
||||
};
|
||||
uint32_t flags_32b;
|
||||
} MACSecFlags_t;
|
||||
/* MACSec Settings for 1 port/phy */
|
||||
#define MACSEC_NUM_FLAGS_PER_CONFIG (1)
|
||||
#define MACSEC_NUM_RULES_PER_CONFIG (2)
|
||||
#define MACSEC_NUM_MAPS_PER_CONFIG (2)
|
||||
#define MACSEC_NUM_SECY_PER_CONFIG (2)
|
||||
#define MACSEC_NUM_SC_PER_CONFIG (2)
|
||||
#define MACSEC_NUM_SA_PER_CONFIG (4)
|
||||
typedef struct MACSEC_CONFIG_t
|
||||
{
|
||||
MACSecFlags_t flags;
|
||||
MACSecRule_t rule[MACSEC_NUM_RULES_PER_CONFIG];
|
||||
MACSecMap_t map[MACSEC_NUM_MAPS_PER_CONFIG];
|
||||
MACSecSecY_t secy[MACSEC_NUM_SECY_PER_CONFIG];
|
||||
MACSecSc_t sc[MACSEC_NUM_SC_PER_CONFIG];
|
||||
MACSecSa_t sa[MACSEC_NUM_SA_PER_CONFIG];
|
||||
} 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
|
||||
typedef struct MACSEC_SETTINGS_W_HDR
|
||||
{
|
||||
uint16_t version;
|
||||
uint16_t len;
|
||||
uint32_t crc32;
|
||||
MACSEC_SETTINGS macsec;
|
||||
} MACSEC_SETTINGS_W_HDR;
|
||||
#define MACSEC_SETTINGS_W_HDR_SIZE (2048)
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
static void ReportEvent(APIEvent::Type event, APIEvent::Severity severity) {
|
||||
auto& em = EventManager::GetInstance();
|
||||
em.add(APIEvent(event, severity));
|
||||
}
|
||||
|
||||
MACsecConfig::MACsecConfig(const DeviceType& deviceType) : type(deviceType) {
|
||||
switch(deviceType.getDeviceType()) {
|
||||
case icsneo::DeviceType::Enum::RADMoon2:
|
||||
case icsneo::DeviceType::Enum::RADMoon3:
|
||||
case icsneo::DeviceType::Enum::RADEpsilon:
|
||||
maxSecY = 2;
|
||||
maxRule = 2;
|
||||
maxSa = 4;
|
||||
binIndex = 0;
|
||||
break;
|
||||
default:
|
||||
maxSecY = 0;
|
||||
maxSa = 0;
|
||||
maxRule = 0;
|
||||
binIndex = 0;
|
||||
ReportEvent(APIEvent::Type::MACsecNotSupported, APIEvent::Severity::Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int MACsecConfig::addRxSecY(const MACsecRxSecY& secY, uint8_t saIndex) {
|
||||
if(rxSecY.size() >= maxSecY) {
|
||||
ReportEvent(APIEvent::Type::MACsecSecYLimit, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(saIndex >= rxSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = static_cast<int>(rxSecY.size());
|
||||
rxSecY.emplace_back(secY);
|
||||
rxSecYSaIndices.emplace_back(saIndex, saIndex + 1);
|
||||
rxSecYRekey.emplace_back(false);
|
||||
rxRuleIndices.emplace_back(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MACsecConfig::addTxSecY(const MACsecTxSecY& secY, uint8_t saIndex) {
|
||||
if(txSecY.size() >= maxSecY) {
|
||||
ReportEvent(APIEvent::Type::MACsecSecYLimit, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(saIndex >= txSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = static_cast<int>(txSecY.size());
|
||||
txSecY.emplace_back(secY);
|
||||
txSecYSaIndices.emplace_back(saIndex, saIndex + 1);
|
||||
txSecYRekey.emplace_back(false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MACsecConfig::addRxSa(const MACsecRxSa& sa) {
|
||||
if(rxSa.size() >= maxSa) {
|
||||
ReportEvent(APIEvent::Type::MACsecSaLimit, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = static_cast<int>(rxSa.size());
|
||||
rxSa.emplace_back(sa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MACsecConfig::addTxSa(const MACsecTxSa& sa) {
|
||||
if(txSa.size() >= maxSa) {
|
||||
ReportEvent(APIEvent::Type::MACsecSaLimit, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = static_cast<int>(txSa.size());
|
||||
txSa.emplace_back(sa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MACsecConfig::addRxRule(const MACsecRxRule& rule, uint8_t secYIndex) {
|
||||
if(rxRule.size() >= maxRule) {
|
||||
ReportEvent(APIEvent::Type::MACsecSaLimit, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(maxSecY >= rxRule.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecSecYLimit, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = static_cast<int>(rxRule.size());
|
||||
rxRuleIndices[secYIndex] = static_cast<uint8_t>(rxRule.size());
|
||||
rxRule.emplace_back(rule);
|
||||
return ret;
|
||||
}
|
||||
|
||||
MACsecRxRule& MACsecConfig::getRxRule(uint8_t ruleIndex) {
|
||||
return rxRule[ruleIndex];
|
||||
}
|
||||
|
||||
const MACsecRxRule& MACsecConfig::getRxRule(uint8_t ruleIndex) const {
|
||||
return rxRule[ruleIndex];
|
||||
}
|
||||
|
||||
MACsecRxSecY& MACsecConfig::getRxSecY(uint8_t secYIndex) {
|
||||
return rxSecY[secYIndex];
|
||||
}
|
||||
|
||||
const MACsecRxSecY& MACsecConfig::getRxSecY(uint8_t secYIndex) const {
|
||||
return rxSecY[secYIndex];
|
||||
}
|
||||
|
||||
MACsecTxSecY& MACsecConfig::getTxSecY(uint8_t secYIndex) {
|
||||
return txSecY[secYIndex];
|
||||
}
|
||||
|
||||
const MACsecTxSecY& MACsecConfig::getTxSecY(uint8_t secYIndex) const {
|
||||
return txSecY[secYIndex];
|
||||
}
|
||||
|
||||
MACsecRxSa& MACsecConfig::getRxSa(uint8_t saIndex) {
|
||||
return rxSa[saIndex];
|
||||
}
|
||||
|
||||
const MACsecRxSa& MACsecConfig::getRxSa(uint8_t saIndex) const {
|
||||
return rxSa[saIndex];
|
||||
}
|
||||
|
||||
MACsecTxSa& MACsecConfig::getTxSa(uint8_t saIndex) {
|
||||
return txSa[saIndex];
|
||||
}
|
||||
|
||||
const MACsecTxSa& MACsecConfig::getTxSa(uint8_t saIndex) const {
|
||||
return txSa[saIndex];
|
||||
}
|
||||
|
||||
bool MACsecConfig::setTxSaIndex(uint8_t secYIndex, uint8_t saIndex) {
|
||||
if(secYIndex >= txSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(saIndex >= txSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
txSecYSaIndices[secYIndex].first = saIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MACsecConfig::enableTxRekey(uint8_t secYIndex, uint8_t rekeySaIndex) {
|
||||
if(secYIndex >= txSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(rekeySaIndex >= txSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
txSecYSaIndices[secYIndex].second = rekeySaIndex;
|
||||
txSecYRekey[secYIndex] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MACsecConfig::setTxSaRekeyIndex(uint8_t secYIndex, uint8_t saIndex) {
|
||||
if(secYIndex >= txSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(saIndex >= txSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
txSecYSaIndices[secYIndex].second = saIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MACsecConfig::disableTxRekey(uint8_t secYIndex) {
|
||||
if(secYIndex >= txSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::EventWarning);
|
||||
return;
|
||||
}
|
||||
txSecYRekey[secYIndex] = false;
|
||||
}
|
||||
|
||||
bool MACsecConfig::setRxSaIndex(uint8_t secYIndex, uint8_t saIndex) {
|
||||
if(secYIndex >= rxSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(saIndex >= rxSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
rxSecYSaIndices[secYIndex].first = saIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MACsecConfig::enableRxRekey(uint8_t secYIndex, uint8_t rekeySaIndex) {
|
||||
if(secYIndex >= rxSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(rekeySaIndex >= rxSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
rxSecYSaIndices[secYIndex].second = rekeySaIndex;
|
||||
rxSecYRekey[secYIndex] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MACsecConfig::setRxSaRekeyIndex(uint8_t secYIndex, uint8_t saIndex) {
|
||||
if(secYIndex >= rxSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
if(saIndex >= rxSa.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
rxSecYSaIndices[secYIndex].second = saIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MACsecConfig::disableRxRekey(uint8_t secYIndex) {
|
||||
if(secYIndex >= rxSecY.size()) {
|
||||
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::EventWarning);
|
||||
return;
|
||||
}
|
||||
rxSecYRekey[secYIndex] = false;
|
||||
}
|
||||
|
||||
void MACsecConfig::setRxEnable(bool newRxEnable) {
|
||||
enableRx = newRxEnable;
|
||||
}
|
||||
|
||||
void MACsecConfig::setTxEnable(bool newTxEnable) {
|
||||
enableTx = newTxEnable;
|
||||
}
|
||||
|
||||
void MACsecConfig::setStorage(bool temporary) {
|
||||
nvm = !temporary;
|
||||
}
|
||||
|
||||
|
||||
void MACsecConfig::clear() {
|
||||
// Set everything back to default, except device maximums
|
||||
rxSecY.clear();
|
||||
txSecY.clear();
|
||||
rxSa.clear();
|
||||
txSa.clear();
|
||||
rxRule.clear();
|
||||
rxSecYRekey.clear();
|
||||
txSecYRekey.clear();
|
||||
rxSecYSaIndices.clear();
|
||||
txSecYSaIndices.clear();
|
||||
rxRuleIndices.clear();
|
||||
enableRx = false;
|
||||
enableTx = false;
|
||||
nvm = false;
|
||||
}
|
||||
|
||||
MACsecConfig::operator bool() const {
|
||||
return (maxSa != 0) || (maxSecY != 0) || (maxRule != 0);
|
||||
}
|
||||
|
||||
uint16_t MACsecConfig::getBinIndex() const {
|
||||
return binIndex;
|
||||
}
|
||||
|
||||
DeviceType MACsecConfig::getType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
uint8_t MACsecConfig::getMaxNumRule() const {
|
||||
return maxRule;
|
||||
}
|
||||
|
||||
uint8_t MACsecConfig::getMaxNumSecY() const {
|
||||
return maxSecY;
|
||||
}
|
||||
|
||||
uint8_t MACsecConfig::getMaxNumSa() const {
|
||||
return maxSa;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t TCItoInt(const MACsecTci& tci) {
|
||||
uint8_t res = 0;
|
||||
res |= tci.c ? 0x01u : 0;
|
||||
res |= tci.e ? 0x02u : 0;
|
||||
res |= tci.scb ? 0x04u : 0;
|
||||
res |= tci.sc ? 0x08u : 0;
|
||||
res |= tci.es ? 0x10u : 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void SetHardwareTxSecY(
|
||||
MACSEC_SETTINGS_W_HDR* hwSettings,
|
||||
const MACsecTxSecY& secY,
|
||||
bool rekeyEnabled,
|
||||
const std::pair<uint8_t, uint8_t>& saIndices,
|
||||
uint8_t index
|
||||
) {
|
||||
|
||||
MACSecSecY_t* hwSecY = &hwSettings->macsec.tx.secy[index];
|
||||
MACSecSc_t* hwSc = &hwSettings->macsec.tx.sc[index];
|
||||
MACSecMap_t* hwMap = &hwSettings->macsec.tx.map[index];
|
||||
|
||||
hwSecY->index = index;
|
||||
hwSecY->enable = true;
|
||||
hwSecY->controlled_port_enabled = secY.enableControlPort ? 0x1u : 0x0u;
|
||||
hwSecY->cipher = secY.cipher;
|
||||
hwSecY->confidential_offset = secY.confidentialityOffset;
|
||||
hwSecY->icv_includes_da_sa = secY.icvIncludesDaSa ? 0x1u : 0x0u;
|
||||
hwSecY->mtu = secY.mtu;
|
||||
hwSecY->sectag_tci = TCItoInt(secY.tci);
|
||||
hwSecY->sectag_offset = secY.secTagOffset;
|
||||
hwSecY->protect_frames = secY.protectFrames;
|
||||
|
||||
hwSc->index = index;
|
||||
hwSc->enable = true;
|
||||
hwSc->secYIndex = index;
|
||||
hwSc->enable_auto_rekey = rekeyEnabled ? 0x1u : 0x0u;
|
||||
hwSc->sa_index0 = saIndices.first;
|
||||
hwSc->sa_index1 = saIndices.second;
|
||||
hwSc->sa_index0_in_use = true;
|
||||
hwSc->sa_index1_in_use = rekeyEnabled ? true : false;
|
||||
hwSc->isActiveSA1 = rekeyEnabled ? true : false;
|
||||
hwSc->sci = secY.sci;
|
||||
|
||||
hwMap->index = index;
|
||||
hwMap->enable = true;
|
||||
hwMap->auxiliary_plcy = secY.auxiliaryPolicy;
|
||||
hwMap->secYIndex = index;
|
||||
hwMap->isControlPacket = secY.isControlPacket ? 0x1u : 0x0u;
|
||||
hwMap->scIndex = index;
|
||||
hwMap->sectag_sci = secY.sci;
|
||||
|
||||
}
|
||||
|
||||
static void SetHardwareRxSecY(
|
||||
MACSEC_SETTINGS_W_HDR* hwSettings,
|
||||
const MACsecRxSecY& secY,
|
||||
bool rekeyEnabled,
|
||||
uint8_t ruleIndex,
|
||||
const std::pair<uint8_t, uint8_t>& saIndices,
|
||||
uint8_t index
|
||||
) {
|
||||
|
||||
MACSecSecY_t* hwSecY = &hwSettings->macsec.rx.secy[index];
|
||||
MACSecSc_t* hwSc = &hwSettings->macsec.rx.sc[index];
|
||||
MACSecMap_t* hwMap = &hwSettings->macsec.rx.map[index];
|
||||
|
||||
hwSecY->index = index;
|
||||
hwSecY->enable = 0x1u;
|
||||
hwSecY->controlled_port_enabled = secY.enableControlPort ? 0x1u : 0x0u;
|
||||
hwSecY->cipher = secY.cipher;
|
||||
hwSecY->confidential_offset = secY.confidentialityOffset;
|
||||
hwSecY->icv_includes_da_sa = secY.icvIncludesDaSa ? 0x1u : 0x0u;
|
||||
hwSecY->replay_protect = secY.replayProtect ? 0x1u : 0x0u;
|
||||
hwSecY->replay_window = secY.replayWindow;
|
||||
hwSecY->validate_frames = secY.frameValidation;
|
||||
hwSecY->strip_sectag_icv = secY.frameStrip;
|
||||
hwSecY->sectag_offset = 12;
|
||||
|
||||
hwSc->index = index;
|
||||
hwSc->enable = 0x1u;
|
||||
hwSc->secYIndex = index;
|
||||
hwSc->enable_auto_rekey = rekeyEnabled ? 0x1u : 0x0u;
|
||||
hwSc->sa_index0 = saIndices.first;
|
||||
hwSc->sa_index1 = saIndices.second;
|
||||
hwSc->sa_index0_in_use = 0x1u;
|
||||
hwSc->sa_index1_in_use = rekeyEnabled ? 0x1u : 0x0u;
|
||||
hwSc->isActiveSA1 = rekeyEnabled ? 0x1u : 0x0u;
|
||||
hwSc->sci = secY.sci;
|
||||
|
||||
hwMap->index = index;
|
||||
hwMap->enable = 0x1u;
|
||||
hwMap->secYIndex = index;
|
||||
hwMap->ruleId = ruleIndex;
|
||||
hwMap->isControlPacket = secY.isControlPacket ? 0x1u : 0x0u;
|
||||
hwMap->scIndex = index;
|
||||
hwMap->sectag_sci = secY.sci;
|
||||
|
||||
}
|
||||
|
||||
static void SetHardwareTxSa(MACSEC_SETTINGS_W_HDR* hwSettings, const MACsecTxSa& sa, uint8_t index) {
|
||||
MACSecSa_t* hwSa = &hwSettings->macsec.tx.sa[index];
|
||||
|
||||
hwSa->index = index;
|
||||
hwSa->enable = 0x1u;
|
||||
memcpy(hwSa->sak, sa.sak.data(), 32);
|
||||
memcpy(hwSa->hashKey, sa.hashKey.data(), 16);
|
||||
memcpy(hwSa->salt, sa.salt.data(), 12);
|
||||
hwSa->ssci = sa.ssci;
|
||||
hwSa->AN = sa.an;
|
||||
hwSa->nextPN = sa.nextPn;
|
||||
|
||||
}
|
||||
|
||||
static void SetHardwareRxSa(MACSEC_SETTINGS_W_HDR* hwSettings, const MACsecRxSa& sa, uint8_t index) {
|
||||
MACSecSa_t* hwSa = &hwSettings->macsec.rx.sa[index];
|
||||
|
||||
hwSa->index = index;
|
||||
hwSa->enable = 0x1u;
|
||||
memcpy(hwSa->sak, sa.sak.data(), 32);
|
||||
memcpy(hwSa->hashKey, sa.hashKey.data(), 16);
|
||||
memcpy(hwSa->salt, sa.salt.data(), 12);
|
||||
hwSa->ssci = sa.ssci;
|
||||
hwSa->nextPN = sa.nextPn;
|
||||
|
||||
}
|
||||
|
||||
static void SetHardwareRxRule(MACSecRule_t* hwRule, const MACsecRxRule& rule, uint8_t index) {
|
||||
|
||||
hwRule->enable = 0x1u;
|
||||
hwRule->index = index;
|
||||
memcpy(hwRule->key_MAC_DA, rule.keyMacDa.data(), 6);
|
||||
memcpy(hwRule->mask_MAC_DA, rule.maskMacDa.data(), 6);
|
||||
memcpy(hwRule->key_MAC_SA, rule.keyMacSa.data(), 6);
|
||||
memcpy(hwRule->mask_MAC_SA, rule.maskMacSa.data(), 6);
|
||||
hwRule->key_Ethertype = rule.keyEthertype;
|
||||
hwRule->mask_Ethertype = rule.maskEthertype;
|
||||
hwRule->key_vlantag_outer1.PRI_CFI = rule.keyVlanTagOuter1.priCfi;
|
||||
hwRule->key_vlantag_outer1.VID = rule.keyVlanTagOuter1.vid;
|
||||
hwRule->key_MPLS_outer1.exp = rule.keyMplsOuter1.exp;
|
||||
hwRule->key_MPLS_outer1.MPLS_label = rule.keyMplsOuter1.mplsLabel;
|
||||
hwRule->mask_vlantag_outer1.PRI_CFI = rule.maskVlanTagOuter1.priCfi;
|
||||
hwRule->mask_vlantag_outer1.VID = rule.maskVlanTagOuter1.vid;
|
||||
hwRule->mask_MPLS_outer1.exp = rule.maskMplsOuter1.exp;
|
||||
hwRule->mask_MPLS_outer1.MPLS_label = rule.maskMplsOuter1.mplsLabel;
|
||||
hwRule->key_vlantag_outer2.PRI_CFI = rule.keyVlanTagOuter2.priCfi;
|
||||
hwRule->key_vlantag_outer2.VID = rule.keyVlanTagOuter2.vid;
|
||||
hwRule->key_MPLS_outer2.exp = rule.keyMplsOuter2.exp;
|
||||
hwRule->key_MPLS_outer2.MPLS_label = rule.keyMplsOuter2.mplsLabel;
|
||||
hwRule->mask_vlantag_outer2.PRI_CFI = rule.maskVlanTagOuter2.priCfi;
|
||||
hwRule->mask_vlantag_outer2.VID = rule.maskVlanTagOuter2.vid;
|
||||
hwRule->mask_MPLS_outer2.exp = rule.maskMplsOuter2.exp;
|
||||
hwRule->mask_MPLS_outer2.MPLS_label = rule.maskMplsOuter2.mplsLabel;
|
||||
hwRule->key_bonus_data = rule.keyBonusData;
|
||||
hwRule->mask_bonus_data = rule.maskBonusData;
|
||||
hwRule->key_tag_match_bitmap = rule.keyTagMatchBitmap;
|
||||
hwRule->mask_tag_match_bitmap = rule.maskTagMatchBitmap;
|
||||
hwRule->key_packet_type = rule.keyPacketType;
|
||||
hwRule->mask_packet_type = rule.maskPacketType;
|
||||
hwRule->key_inner_vlan_type = rule.keyInnerVlanType;
|
||||
hwRule->mask_inner_vlan_type = rule.maskInnerVlanType;
|
||||
hwRule->key_outer_vlan_type = rule.keyOuterVlanType;
|
||||
hwRule->mask_outer_vlan_type = rule.maskOuterVlanType;
|
||||
hwRule->key_num_tags = rule.keyNumTags;
|
||||
hwRule->mask_num_tags = rule.maskNumTags;
|
||||
hwRule->key_express = rule.keyExpress ? 0x1u : 0x0u;
|
||||
hwRule->mask_express = rule.maskExpress ? 0x1u : 0x0u;
|
||||
hwRule->isMPLS = rule.isMpls ? 0x1u : 0x0u;
|
||||
|
||||
}
|
||||
|
||||
std::vector<uint8_t> MACsecConfig::serialize() const {
|
||||
std::vector<uint8_t> res(sizeof(MACSEC_SETTINGS_W_HDR), 0);
|
||||
MACSEC_SETTINGS_W_HDR* hwSettings = (MACSEC_SETTINGS_W_HDR*)(res.data());
|
||||
|
||||
for(uint8_t i = 0; i < maxSecY; i++) {
|
||||
if(i < rxSecY.size()) {
|
||||
SetHardwareRxSecY(
|
||||
hwSettings,
|
||||
rxSecY[i],
|
||||
rxSecYRekey[i],
|
||||
rxRuleIndices[i],
|
||||
rxSecYSaIndices[i],
|
||||
i
|
||||
);
|
||||
} else {
|
||||
hwSettings->macsec.rx.secy[i].enable = false;
|
||||
hwSettings->macsec.rx.map[i].enable = false;
|
||||
hwSettings->macsec.rx.sc[i].enable = false;
|
||||
}
|
||||
|
||||
if(i < txSecY.size()) {
|
||||
SetHardwareTxSecY(
|
||||
hwSettings,
|
||||
txSecY[i],
|
||||
txSecYRekey[i],
|
||||
txSecYSaIndices[i],
|
||||
i
|
||||
);
|
||||
} else {
|
||||
hwSettings->macsec.tx.secy[i].enable = false;
|
||||
hwSettings->macsec.tx.map[i].enable = false;
|
||||
hwSettings->macsec.tx.sc[i].enable = false;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < maxSa; i++) {
|
||||
if(i < rxSa.size()) {
|
||||
SetHardwareRxSa(hwSettings, rxSa[i], i);
|
||||
} else {
|
||||
hwSettings->macsec.rx.sa[i].enable = false;
|
||||
}
|
||||
|
||||
if(i < txSa.size()) {
|
||||
SetHardwareTxSa(hwSettings, txSa[i], i);
|
||||
} else {
|
||||
hwSettings->macsec.tx.sa[i].enable = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(rxRule.size() == 0) {
|
||||
MACsecRxRule defaultRule;
|
||||
MACSecRule_t* hwRxRule = &hwSettings->macsec.rx.rule[0];
|
||||
MACSecRule_t* hwTxRule = &hwSettings->macsec.tx.rule[0];
|
||||
SetHardwareRxRule(hwRxRule, defaultRule, 0);
|
||||
SetHardwareRxRule(hwTxRule, defaultRule, 0);
|
||||
//hwSettings->macsec.tx.rule[0].enable = false;
|
||||
for(uint8_t i = 1; i < maxRule; i++) {
|
||||
hwSettings->macsec.rx.rule[i].enable = false;
|
||||
hwSettings->macsec.tx.rule[i].enable = false;
|
||||
}
|
||||
} else {
|
||||
for(uint8_t i = 0; i < maxRule; i++) {
|
||||
if(i < rxRule.size()) {
|
||||
auto* hwRxRule = &hwSettings->macsec.rx.rule[i];
|
||||
SetHardwareRxRule(hwRxRule, rxRule[i], i);
|
||||
} else {
|
||||
hwSettings->macsec.rx.rule[i].enable = false;
|
||||
hwSettings->macsec.tx.rule[i].enable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hwSettings->len = sizeof(MACSEC_SETTINGS_W_HDR);
|
||||
hwSettings->version = MACSEC_SETTINGS_VERSION;
|
||||
hwSettings->macsec.flags.en = (enableRx || enableTx) ? 1u : 0u;
|
||||
hwSettings->macsec.flags.nvm = nvm ? 1u : 0u;
|
||||
hwSettings->macsec.rx.flags.en = enableRx ? 1u : 0u;
|
||||
hwSettings->macsec.tx.flags.en = enableTx ? 1u : 0u;
|
||||
hwSettings->crc32 = crc32(0, (uint8_t*)&hwSettings->macsec, sizeof(MACSEC_SETTINGS));
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
#include "icsneo/core/ringbuffer.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
RingBuffer::RingBuffer(size_t bufferSize) : readCursor(0), writeCursor(0) {
|
||||
// round the buffer size to the nearest power of 2
|
||||
bufferSize = RoundUp(bufferSize);
|
||||
mask = bufferSize - 1;
|
||||
buf = new uint8_t[bufferSize];
|
||||
}
|
||||
|
||||
RingBuffer::~RingBuffer() {
|
||||
delete[] buf;
|
||||
buf = nullptr;
|
||||
}
|
||||
|
||||
const uint8_t& RingBuffer::operator[](size_t offset) const {
|
||||
return get(offset);
|
||||
}
|
||||
|
||||
size_t RingBuffer::size() const {
|
||||
// The values in the cursors are monotonic, i.e. they only ever increment. They can be considered to be the total number of elements ever written or read
|
||||
auto currentWriteCursor = writeCursor.load(std::memory_order_relaxed);
|
||||
auto currentReadCursor = readCursor.load(std::memory_order_relaxed);
|
||||
// Using unmasked values, writeCursor is guaranteed to be >= readCursor. If they are equal that means the buffer is empty
|
||||
return currentWriteCursor - currentReadCursor;
|
||||
}
|
||||
|
||||
void RingBuffer::pop_front() {
|
||||
pop(1);
|
||||
}
|
||||
|
||||
void RingBuffer::pop(size_t count) {
|
||||
if (size() < count) {
|
||||
throw std::runtime_error("RingBuffer: Underflow");
|
||||
}
|
||||
readCursor.fetch_add(count, std::memory_order_release);
|
||||
}
|
||||
|
||||
const uint8_t& RingBuffer::get(size_t offset) const {
|
||||
if (offset >= size()) {
|
||||
throw std::runtime_error("RingBuffer: Index out of range");
|
||||
}
|
||||
auto currentReadCursor = readCursor.load(std::memory_order_acquire);
|
||||
return *resolve(currentReadCursor, offset);
|
||||
}
|
||||
|
||||
bool RingBuffer::write(const uint8_t* addr, size_t length) {
|
||||
const auto freeSpace = (capacity() - size());
|
||||
if (length > freeSpace) {
|
||||
return false;
|
||||
}
|
||||
auto currentWriteCursor = writeCursor.load(std::memory_order_relaxed);
|
||||
auto spaceAtEnd = std::min(freeSpace, capacity() - (currentWriteCursor & mask)); // number of bytes from (masked) writeCursor to the end of the writable space (i.e. we reach the masked read cursor or the end of the buffer)
|
||||
auto firstCopySize = std::min(spaceAtEnd, length);
|
||||
(void)memcpy(resolve(currentWriteCursor, 0), addr, firstCopySize);
|
||||
if (firstCopySize < length)
|
||||
{
|
||||
(void)memcpy(buf, &addr[firstCopySize], length - firstCopySize);
|
||||
}
|
||||
|
||||
writeCursor.store(currentWriteCursor + length, std::memory_order_release);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RingBuffer::write(const std::vector<uint8_t>& source) {
|
||||
return write(source.data(), source.size());
|
||||
}
|
||||
|
||||
bool RingBuffer::read(uint8_t* dest, size_t startIndex, size_t length) const {
|
||||
auto currentSize = size();
|
||||
if ((startIndex >= currentSize) || ((startIndex + length) > size())) {
|
||||
return false;
|
||||
}
|
||||
auto currentReadCursor = readCursor.load(std::memory_order_relaxed);
|
||||
auto bytesAtEnd = std::min<size_t>(capacity() - ((currentReadCursor + startIndex) & mask), length);
|
||||
const auto bytesAtStart = (length - bytesAtEnd);
|
||||
|
||||
(void)memcpy(dest, resolve(currentReadCursor, startIndex), bytesAtEnd);
|
||||
if (bytesAtStart > 0) {
|
||||
(void)memcpy(&dest[bytesAtEnd], buf, bytesAtStart);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RingBuffer::clear() {
|
||||
pop(size());
|
||||
}
|
||||
|
||||
}
|
||||
+105
-2211
File diff suppressed because it is too large
Load Diff
+43
-103
@@ -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"
|
||||
@@ -16,8 +15,16 @@
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_DXX
|
||||
#include "icsneo/platform/dxx.h"
|
||||
#ifdef ICSNEO_ENABLE_ANDROIDUSB
|
||||
#include "icsneo/platform/android/androidusb.h"
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_FTDI
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_FTD3XX
|
||||
#include "icsneo/platform/ftd3xx.h"
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_TCP
|
||||
@@ -36,14 +43,11 @@ static void makeIfSerialMatches(const FoundDevice& dev, std::vector<std::shared_
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void makeIfSerialRangeMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
|
||||
// Relies on the subclass to have
|
||||
// `static constexpr uint32_t SERIAL_RANGE_LOW = 0x12345678`
|
||||
// `static constexpr uint32_t SERIAL_RANGE_HIGH = 0x12345678`
|
||||
static void makeIfPIDMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
|
||||
// Relies on the subclass to have a `static constexpr uint16_t PRODUCT_ID = 0x1111`
|
||||
// and also a public constructor `T(const FoundDevice& dev)`
|
||||
// Use macro ICSNEO_FINDABLE_DEVICE_BY_SERIAL_RANGE() to create these
|
||||
uint32_t serialNum = Device::SerialStringToNum(dev.serial);
|
||||
if(serialNum >= Device::SerialStringToNum(T::SERIAL_RANGE_LOW) && serialNum <= Device::SerialStringToNum(T::SERIAL_RANGE_HIGH))
|
||||
// Use macro ICSNEO_FINDABLE_DEVICE_BY_PID() to create these
|
||||
if(dev.productId == T::PRODUCT_ID)
|
||||
into.push_back(std::make_shared<T>(dev));
|
||||
}
|
||||
|
||||
@@ -51,29 +55,33 @@ 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
|
||||
#ifdef ICSNEO_ENABLE_FIRMIO
|
||||
FirmIO::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_TCP
|
||||
TCP::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
#ifdef ICSNEO_ENABLE_TCP
|
||||
TCP::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
||||
PCAP::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
||||
PCAP::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_CDCACM
|
||||
CDCACM::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
#ifdef ICSNEO_ENABLE_CDCACM
|
||||
CDCACM::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_DXX
|
||||
DXX::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
}
|
||||
#ifdef ICSNEO_ENABLE_ANDROIDUSB
|
||||
ANDROIDUSB::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_FTDI
|
||||
FTDI::Find(newDriverFoundDevices);
|
||||
#endif
|
||||
|
||||
#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;
|
||||
@@ -125,12 +133,8 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
makeIfSerialMatches<NeoOBD2SIM>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVICONNECT_H_
|
||||
makeIfSerialMatches<NeoVIConnect>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
makeIfSerialRangeMatches<NeoVIFIRE>(dev, newFoundDevices);
|
||||
makeIfPIDMatches<NeoVIFIRE>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2_H_
|
||||
@@ -145,20 +149,16 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
makeIfSerialMatches<NeoVIFIRE3FlexRay>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE3T1SLIN_H_
|
||||
makeIfSerialMatches<NeoVIFIRE3T1SLIN>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIRED2_H_
|
||||
makeIfSerialMatches<NeoVIRED2>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
makeIfSerialMatches<NeoVIION>(dev, newFoundDevices);
|
||||
makeIfPIDMatches<NeoVIION>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIPLASMA_H_
|
||||
makeIfSerialMatches<NeoVIPLASMA>(dev, newFoundDevices);
|
||||
makeIfPIDMatches<NeoVIPLASMA>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADA2B_H_
|
||||
@@ -166,37 +166,17 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
#endif
|
||||
|
||||
#ifdef __RADCOMET_H_
|
||||
makeIfSerialRangeMatches<RADComet>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADCOMET2_H_
|
||||
makeIfSerialRangeMatches<RADComet2>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADCOMET3_H_
|
||||
makeIfSerialMatches<RADComet3>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONT1S_H_
|
||||
makeIfSerialMatches<RADMoonT1S>(dev, newFoundDevices);
|
||||
makeIfSerialMatches<RADCOMET>(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
|
||||
@@ -205,10 +185,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
|
||||
@@ -225,10 +201,6 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
makeIfSerialMatches<RADMoon3>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGEMINI_H_
|
||||
makeIfSerialMatches<RADGemini>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONDUO_H_
|
||||
makeIfSerialMatches<RADMoonDuo>(dev, newFoundDevices);
|
||||
#endif
|
||||
@@ -246,7 +218,7 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
makeIfSerialRangeMatches<ValueCAN3>(dev, newFoundDevices);
|
||||
makeIfPIDMatches<ValueCAN3>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_1_H_
|
||||
@@ -304,10 +276,6 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
NeoVIRED2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVICONNECT_H_
|
||||
NeoVIConnect::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
NeoVIFIRE::DEVICE_TYPE,
|
||||
#endif
|
||||
@@ -324,10 +292,6 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
NeoVIFIRE3FlexRay::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE3T1SLIN_H_
|
||||
NeoVIFIRE3T1SLIN::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
NeoVIION::DEVICE_TYPE,
|
||||
#endif
|
||||
@@ -341,33 +305,17 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
#endif
|
||||
|
||||
#ifdef __RADCOMET_H_
|
||||
RADComet::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADCOMET3_H_
|
||||
RADComet3::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONT1S_H_
|
||||
RADMoonT1S::DEVICE_TYPE,
|
||||
RADCOMET::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
|
||||
@@ -376,10 +324,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
|
||||
@@ -388,10 +332,6 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
RADMoon3::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGEMINI_H_
|
||||
RADGemini::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONDUO_H_
|
||||
RADMoonDuo::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
void FlexRay::Controller::_setStatus(std::shared_ptr<FlexRayControlMessage> msg) {
|
||||
std::lock_guard<std::mutex> lk(statusLock);
|
||||
status = msg;
|
||||
}
|
||||
|
||||
std::shared_ptr<FlexRayControlMessage> FlexRay::Controller::getStatus() const {
|
||||
std::lock_guard<std::mutex> lk(statusLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
std::pair<const FlexRay::Cluster::Configuration&, const FlexRay::Controller::Configuration&> FlexRay::Controller::getConfiguration() const {
|
||||
return { clusterConfig, controllerConfig };
|
||||
}
|
||||
@@ -64,7 +74,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
||||
((controllerConfig.KeySlotUsedForStartup & 0x1) << 8) | // TXST
|
||||
((controllerConfig.KeySlotUsedForSync & 0x1) << 9) | // TXSY
|
||||
((clusterConfig.ColdStartAttempts & 0x1f) << 11) | // CSA
|
||||
((controllerConfig.AllowPassiveToActiveCyclePairs & 0x1F) << 16) | // PTA
|
||||
((controllerConfig.AllowPassiveToActiveCyclePairs & 0x1f) << 16) | // PTA
|
||||
((controllerConfig.WakeupOnChannelB & 0x1) << 21) | // WUCS
|
||||
((controllerConfig.KeySlotOnlyEnabled & 0x1) << 22) | // TSM
|
||||
((controllerConfig.AllowHaltDueToClock & 0x1) << 23) | // HCSE
|
||||
@@ -75,100 +85,99 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::SUCC2,
|
||||
((controllerConfig.ListenTimeout & 0x1FFFFF)) |
|
||||
(((clusterConfig.ListenNoiseMacroticks - 1) & 0xF) << 24)
|
||||
((controllerConfig.ListenTimeout & 0x1fffff)) |
|
||||
((clusterConfig.ListenNoiseMacroticks - 1) << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::SUCC3,
|
||||
(clusterConfig.MaxWithoutClockCorrectionPassive & 0xF) |
|
||||
((clusterConfig.MaxWithoutClockCorrectionFatal & 0xF) << 4)
|
||||
((clusterConfig.MaxWithoutClockCorrectionFatal) << 4)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::NEMC,
|
||||
clusterConfig.NetworkManagementVectorLengthBytes & 0xF
|
||||
clusterConfig.NetworkManagementVectorLengthBytes
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::PRTC1,
|
||||
(clusterConfig.TransmissionStartSequenceDurationBits & 0xF) |
|
||||
((clusterConfig.CASRxLowMax & 0x1F) << 4) |
|
||||
(0x1 << 10) | // Most significant bit of CASRxLowMax. Hardwired to 1 and cannot be modified
|
||||
((clusterConfig.CASRxLowMax & 0x3F) << 4) |
|
||||
((clusterConfig.StrobePointPosition & 0x3) << 12) |
|
||||
((clusterConfig.Speed & 0x3) << 14) |
|
||||
((clusterConfig.WakeupRxWindowBits & 0x1FF) << 16) |
|
||||
((controllerConfig.WakeupPattern & 0x3F) << 26)
|
||||
((clusterConfig.WakeupRxWindowBits & 0x1ff) << 16) |
|
||||
((controllerConfig.WakeupPattern) << 26)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::PRTC2,
|
||||
(clusterConfig.WakeupRxIdleBits & 0x3F) |
|
||||
((clusterConfig.WakeupRxLowBits & 0x3F) << 8) |
|
||||
(clusterConfig.WakeupRxIdleBits) |
|
||||
((clusterConfig.WakeupRxLowBits) << 8) |
|
||||
((clusterConfig.WakeupTxIdleBits) << 16) |
|
||||
((clusterConfig.WakeupTxActiveBits & 0x3F) << 24)
|
||||
((clusterConfig.WakeupTxActiveBits) << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::MHDC,
|
||||
(clusterConfig.PayloadLengthOfStaticSlotInWords & 0x7F) |
|
||||
((controllerConfig.LatestTxMinislot & 0x1FFF) << 16)
|
||||
(clusterConfig.PayloadLengthOfStaticSlotInWords) |
|
||||
((controllerConfig.LatestTxMinislot) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC1,
|
||||
controllerConfig.MicroPerCycle & 0xFFFFF
|
||||
controllerConfig.MicroPerCycle
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC2,
|
||||
(clusterConfig.SyncFrameIDCountMax << 16) |
|
||||
(clusterConfig.MacroticksPerCycle & 0x3FFF)
|
||||
clusterConfig.MacroticksPerCycle
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC3,
|
||||
(controllerConfig.MicroInitialOffsetA) |
|
||||
((controllerConfig.MicroInitialOffsetB) << 8) |
|
||||
((controllerConfig.MacroInitialOffsetA & 0x7F) << 16) |
|
||||
((controllerConfig.MacroInitialOffsetB & 0x7F) << 24)
|
||||
((controllerConfig.MacroInitialOffsetA) << 16) |
|
||||
((controllerConfig.MacroInitialOffsetB) << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC4,
|
||||
((clusterConfig.MacroticksPerCycle - clusterConfig.NetworkIdleTimeMacroticks - 1) & 0x3FFF) |
|
||||
(((clusterConfig.OffsetCorrectionStartMacroticks - 1) & 0x3FFF) << 16)
|
||||
((clusterConfig.MacroticksPerCycle - clusterConfig.NetworkIdleTimeMacroticks - 1) & 0xFFFF) |
|
||||
((clusterConfig.OffsetCorrectionStartMacroticks - 1) << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC5,
|
||||
controllerConfig.DelayCompensationAMicroticks |
|
||||
(controllerConfig.DelayCompensationBMicroticks << 8) |
|
||||
((controllerConfig.ClusterDriftDamping & 0x1F) << 16) |
|
||||
(controllerConfig.ClusterDriftDamping << 16) |
|
||||
(controllerConfig.DecodingCorrectionMicroticks << 24)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC6,
|
||||
(controllerConfig.AcceptStartupRangeMicroticks & 0x7FF) |
|
||||
((controllerConfig.RateCorrectionOutMicroticks & 0x7FF) << 16)
|
||||
controllerConfig.AcceptStartupRangeMicroticks |
|
||||
(controllerConfig.RateCorrectionOutMicroticks << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC7,
|
||||
(clusterConfig.StaticSlotMacroticks & 0x3FF) |
|
||||
((clusterConfig.NumberOfStaticSlots & 0x3FF) << 16)
|
||||
(clusterConfig.StaticSlotMacroticks) |
|
||||
(clusterConfig.NumberOfStaticSlots << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC8,
|
||||
(clusterConfig.MinislotDurationMacroticks & 0x3F) |
|
||||
((clusterConfig.NumberOfMinislots & 0x1FFF) << 16)
|
||||
clusterConfig.MinislotDurationMacroticks |
|
||||
(clusterConfig.NumberOfMinislots << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC9,
|
||||
(clusterConfig.ActionPointOffset & 0x3F) |
|
||||
((clusterConfig.MinislotActionPointOffsetMacroticks & 0x1F) << 8) |
|
||||
((clusterConfig.DynamicSlotIdlePhaseMinislots & 0x03) << 16)
|
||||
clusterConfig.ActionPointOffset |
|
||||
(clusterConfig.MinislotActionPointOffsetMacroticks << 8) |
|
||||
(clusterConfig.DynamicSlotIdlePhaseMinislots << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC10,
|
||||
(controllerConfig.OffsetCorrectionOutMicroticks & 0x3FFF) |
|
||||
((controllerConfig.RateCorrectionOutMicroticks & 0x7FF) << 16)
|
||||
controllerConfig.OffsetCorrectionOutMicroticks |
|
||||
(controllerConfig.RateCorrectionOutMicroticks << 16)
|
||||
});
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::GTUC11,
|
||||
(controllerConfig.ExternOffsetCorrectionControl & 0x3) |
|
||||
((controllerConfig.ExternRateCorrectionControl & 0x3) << 8) |
|
||||
((controllerConfig.ExternOffsetCorrectionMicroticks & 0x7) << 16) |
|
||||
((controllerConfig.ExternRateCorrectionMicroticks & 0x7) << 24)
|
||||
controllerConfig.ExternOffsetCorrectionControl |
|
||||
(controllerConfig.ExternRateCorrectionControl << 8) |
|
||||
(controllerConfig.ExternOffsetCorrectionMicroticks << 16) |
|
||||
(controllerConfig.ExternRateCorrectionMicroticks << 24)
|
||||
});
|
||||
|
||||
std::vector<std::shared_ptr<MessageBuffer>> staticTx;
|
||||
@@ -201,7 +210,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
||||
second->isStartup = controllerConfig.KeySlotUsedForStartup;
|
||||
second->isSync = controllerConfig.KeySlotUsedForSync;
|
||||
second->isTransmit = true;
|
||||
second->channelB = true;
|
||||
second->channelB =true;
|
||||
second->frameID = controllerConfig.SecondKeySlotID;
|
||||
second->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
|
||||
second->baseCycle = 0;
|
||||
@@ -257,7 +266,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
||||
totalBuffers = 128;
|
||||
|
||||
registerWrites.push_back({ ERAYRegister::MRC,
|
||||
(static_cast<uint8_t>(staticTx.size())) | // FDB[7:0] message buffers exclusively for the static segment
|
||||
(uint8_t(staticTx.size())) | // FDB[7:0] message buffers exclusively for the static segment
|
||||
// FFB[7:0] set to 0x80, No message buffer assigned to the FIFO
|
||||
(0x80 << 8) |
|
||||
(uint8_t(totalBuffers - 1) << 16) |
|
||||
@@ -278,12 +287,12 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
|
||||
buf.frameID = static_cast<uint16_t>(i | (1 << 10));
|
||||
|
||||
uint32_t hs1 = (
|
||||
(buf.frameID) | // FID
|
||||
(CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition) << 16) | // CYA
|
||||
((buf.channelA & 0x1) << 24) | // CHA
|
||||
((buf.channelB & 0x1) << 25) | // CHB
|
||||
(buf.frameID) |
|
||||
(CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition) << 16) |
|
||||
((buf.channelA & 0x1) << 24) |
|
||||
((buf.channelB & 0x1) << 25) |
|
||||
((buf.isTransmit & 0x1) << 26) | // CFG
|
||||
((buf.isNetworkManagementFrame & 0x1) << 27) | // PPIT
|
||||
((buf.isNMFrame & 0x1) << 27) | // PPIT
|
||||
((!buf.continuousMode & 0x1) << 28) | // TXM
|
||||
((0 & 0x1) << 29) // MBI, disabled for now but we might want confirmations in the future
|
||||
);
|
||||
@@ -601,8 +610,7 @@ uint16_t FlexRay::Controller::CalculateCycleFilter(uint8_t baseCycle, uint8_t cy
|
||||
}
|
||||
|
||||
std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const {
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>();
|
||||
filter->includeInternalInAny = true;
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(icsneo::Network::NetID::FlexRayControl);
|
||||
if(timeout.count() <= 20)
|
||||
return {false, 0}; // Out of time!
|
||||
|
||||
|
||||
@@ -25,6 +25,26 @@ void FlexRay::Extension::onGoOffline() {
|
||||
controller->halt();
|
||||
}
|
||||
|
||||
void FlexRay::Extension::handleMessage(const std::shared_ptr<Message>& message) {
|
||||
switch(message->type) {
|
||||
case Message::Type::FlexRayControl: {
|
||||
auto msg = std::dynamic_pointer_cast<FlexRayControlMessage>(message);
|
||||
if(!msg || !msg->decoded)
|
||||
return;
|
||||
switch(msg->opcode) {
|
||||
case FlexRay::Opcode::ReadCCStatus:
|
||||
if(msg->controller >= controllers.size())
|
||||
return; // TODO error
|
||||
controllers[msg->controller]->_setStatus(msg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool FlexRay::Extension::transmitHook(const std::shared_ptr<Frame>& frame, bool& success) {
|
||||
if(!frame || frame->network.getType() != Network::Type::FlexRay)
|
||||
return true; // Don't hook non-FlexRay messages
|
||||
|
||||
+35
-244
@@ -4,9 +4,9 @@
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
std::optional<uint16_t> IDeviceSettings::CalculateGSChecksum(const std::vector<uint8_t>& settings) {
|
||||
std::optional<uint16_t> IDeviceSettings::CalculateGSChecksum(const std::vector<uint8_t>& settings, std::optional<size_t> knownSize) {
|
||||
const uint16_t* p = reinterpret_cast<const uint16_t*>(settings.data());
|
||||
size_t words = settings.size();
|
||||
size_t words = std::min(knownSize.value_or(0), settings.size());
|
||||
if(words % 2 == 1)
|
||||
return std::nullopt; // Somehow settings is not word aligned
|
||||
words /= 2;
|
||||
@@ -128,43 +128,15 @@ int64_t IDeviceSettings::GetBaudrateValueForEnum(CANBaudrate enumValue) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IDeviceSettings::ValidateLINBaudrate(int64_t baudrate) {
|
||||
switch(baudrate) {
|
||||
case 4800:
|
||||
// fallthrough
|
||||
case 9600:
|
||||
// fallthrough
|
||||
case 10400:
|
||||
// fallthrough
|
||||
case 10417:
|
||||
// fallthrough
|
||||
case 10504:
|
||||
// fallthrough
|
||||
case 10593:
|
||||
// fallthrough
|
||||
case 10684:
|
||||
// fallthrough
|
||||
case 10776:
|
||||
// fallthrough
|
||||
case 10870:
|
||||
// fallthrough
|
||||
case 10965:
|
||||
// fallthrough
|
||||
case 11062:
|
||||
// fallthrough
|
||||
case 19200:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDeviceSettings::refresh() {
|
||||
bool IDeviceSettings::refresh(bool ignoreChecksum) {
|
||||
if(disabled) {
|
||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(disableGSChecksumming)
|
||||
ignoreChecksum = true;
|
||||
|
||||
std::vector<uint8_t> rxSettings;
|
||||
bool ret = com->getSettingsSync(rxSettings);
|
||||
if(!ret) {
|
||||
@@ -172,14 +144,24 @@ bool IDeviceSettings::refresh() {
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr size_t GsSize = 3 * sizeof(uint16_t); // <version> <length> <checksum>
|
||||
constexpr size_t GsSize = 3 * sizeof(uint16_t);
|
||||
if(rxSettings.size() < GsSize) { // We need to at least have the header of GLOBAL_SETTINGS
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The length of the settings structure sent to us
|
||||
// This is the length the firmware thinks the current version of the structure is
|
||||
const size_t rxLen = rxSettings.size() - GsSize;
|
||||
|
||||
const uint16_t gsVersion = rxSettings[0] | (rxSettings[1] << 8);
|
||||
|
||||
// The length of the settings last saved
|
||||
// If the firmware is updated, it will have either extended (with zeros) or truncated
|
||||
// the structure, but this value will continue to be set to the last saved value
|
||||
const uint16_t gsLen = rxSettings[2] | (rxSettings[3] << 8);
|
||||
|
||||
const uint16_t gsChecksum = rxSettings[4] | (rxSettings[5] << 8);
|
||||
rxSettings.erase(rxSettings.begin(), rxSettings.begin() + GsSize);
|
||||
|
||||
if(gsVersion != GS_VERSION) {
|
||||
@@ -187,6 +169,19 @@ bool IDeviceSettings::refresh() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(rxLen < gsLen) {
|
||||
// We got less data, i.e. the firmware thinks the strucure is smaller than what
|
||||
// was last saved. Usually this is due to a firmware downgrade. We'll ignore the
|
||||
// checksum for now, because it will definitely be wrong.
|
||||
ignoreChecksum = true;
|
||||
}
|
||||
|
||||
// We check the checksum against the data last saved
|
||||
if(!ignoreChecksum && gsChecksum != CalculateGSChecksum(rxSettings, gsLen)) {
|
||||
report(APIEvent::Type::SettingsChecksumError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
settings = std::move(rxSettings);
|
||||
settingsInDeviceRAM = settings;
|
||||
settingsLoaded = true;
|
||||
@@ -235,7 +230,7 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
|
||||
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
|
||||
return com->sendCommand(Command::SetSettings, bytestream);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(2000)));
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000)));
|
||||
|
||||
if(!msg || msg->data[0] != 1) { // We did not receive a response
|
||||
// Attempt to get the settings from the device so we're up to date if possible
|
||||
@@ -246,7 +241,7 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
return false;
|
||||
}
|
||||
|
||||
refresh();
|
||||
refresh(true); // Refresh ignoring checksum
|
||||
// The device might modify the settings once they are applied, however in this case it does not update the checksum
|
||||
// We refresh to get these updates, update the checksum, and send it back so it's all in sync
|
||||
gsChecksum = CalculateGSChecksum(settings);
|
||||
@@ -261,7 +256,7 @@ bool IDeviceSettings::apply(bool temporary) {
|
||||
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
|
||||
return com->sendCommand(Command::SetSettings, bytestream);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(2000)));
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000)));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
// Attempt to get the settings from the device so we're up to date if possible
|
||||
if(refresh()) {
|
||||
@@ -316,7 +311,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
// This short wait helps on FIRE devices, otherwise the checksum might be wrong!
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(3));
|
||||
|
||||
refresh();
|
||||
refresh(true); // Refresh ignoring checksum
|
||||
// The device might modify the settings once they are applied, however in this case it does not update the checksum
|
||||
// We refresh to get these updates, update the checksum, and send it back so it's all in sync
|
||||
std::vector<uint8_t> bytestream;
|
||||
@@ -338,7 +333,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
|
||||
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
|
||||
return com->sendCommand(Command::SetSettings, bytestream);
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(2000)));
|
||||
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000)));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
// Attempt to get the settings from the device so we're up to date if possible
|
||||
if(refresh()) {
|
||||
@@ -419,15 +414,6 @@ int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
||||
}
|
||||
return baudrate;
|
||||
}
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return cfg->Baudrate;
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return -1;
|
||||
@@ -507,21 +493,6 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
||||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||
return true;
|
||||
}
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid = ValidateLINBaudrate(baudrate);
|
||||
if(!valid) {
|
||||
report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
cfg->Baudrate = (uint32_t)baudrate;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
@@ -733,186 +704,6 @@ bool IDeviceSettings::setTerminationFor(Network net, bool enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<bool> IDeviceSettings::isCommanderResistorEnabledFor(Network net) const {
|
||||
if(!settingsLoaded) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(disabled) {
|
||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return (cfg->CommanderResistor != RESISTOR_OFF);
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDeviceSettings::setCommanderResistorFor(Network net, bool resistor_on) {
|
||||
if(disabled) {
|
||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!settingsLoaded) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readonly) {
|
||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg->CommanderResistor = resistor_on ? RESISTOR_ON : RESISTOR_OFF;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<LINMode> IDeviceSettings::getLINModeFor(Network net) const {
|
||||
if(!settingsLoaded) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(disabled) {
|
||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return static_cast<LINMode>(cfg->Mode);
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDeviceSettings::setLINModeFor(Network net, LINMode mode) {
|
||||
if(disabled) {
|
||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!settingsLoaded) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readonly) {
|
||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg->Mode = static_cast<uint8_t>(mode);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<uint8_t> IDeviceSettings::getLINCommanderResponseTimeFor(Network net) const {
|
||||
if(!settingsLoaded) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(disabled) {
|
||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return cfg->numBitsDelay;
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDeviceSettings::setLINCommanderResponseTimeFor(Network net, uint8_t bits) {
|
||||
if(disabled) {
|
||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!settingsLoaded) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readonly) {
|
||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
cfg->numBitsDelay = bits;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> bool IDeviceSettings::applyStructure(const T& newStructure) {
|
||||
if(!settingsLoaded) {
|
||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#include <icsneo/disk/diskdetails.h>
|
||||
#include <icsneo/device/idevicesettings.h>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
#pragma pack(push, 2)
|
||||
|
||||
struct DISK_STATUS {
|
||||
uint16_t status;
|
||||
uint64_t sectors;
|
||||
uint32_t bytesPerSector;
|
||||
};
|
||||
|
||||
struct DISK_DETAILS {
|
||||
DISK_SETTINGS settings;
|
||||
uint16_t options;
|
||||
DISK_STATUS status[12];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
static constexpr uint8_t DISK_FORMAT_FAT32 = 0x01u;
|
||||
static constexpr uint8_t DISK_STATUS_PRESENT = 0x01u;
|
||||
static constexpr uint8_t DISK_STATUS_INITIALIZED = 0x02u;
|
||||
static constexpr uint16_t DISK_DETAILS_FULL_FORMAT = 0x01u;
|
||||
|
||||
std::vector<uint8_t> DiskDetails::Encode(const DiskDetails& config) {
|
||||
std::vector<uint8_t> result(sizeof(DISK_DETAILS), 0);
|
||||
DISK_DETAILS* details = reinterpret_cast<DISK_DETAILS*>(result.data());
|
||||
details->settings.disk_layout = static_cast<uint8_t>(config.layout);
|
||||
details->settings.disk_format = DISK_FORMAT_FAT32; // Always FAT32
|
||||
details->options = config.fullFormat ? DISK_DETAILS_FULL_FORMAT : 0;
|
||||
uint32_t& enables = details->settings.disk_enables;
|
||||
enables = 0u;
|
||||
for(size_t i = 0; i < config.disks.size(); i++) {
|
||||
auto& disk = config.disks[i];
|
||||
details->status[i].sectors = disk.sectors;
|
||||
details->status[i].bytesPerSector = disk.bytesPerSector;
|
||||
|
||||
uint16_t& status = details->status[i].status;
|
||||
status = 0u;
|
||||
if(disk.initialized) {
|
||||
status |= DISK_STATUS_INITIALIZED;
|
||||
}
|
||||
if(disk.present) {
|
||||
status |= DISK_STATUS_PRESENT;
|
||||
}
|
||||
if(disk.formatted) {
|
||||
enables |= (1u << i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<DiskDetails> DiskDetails::Decode(const std::vector<uint8_t>& bytes, size_t diskCount, device_eventhandler_t report) {
|
||||
if(bytes.size() < sizeof(DISK_DETAILS)) {
|
||||
report(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto result = std::make_shared<DiskDetails>();
|
||||
const DISK_DETAILS* details = reinterpret_cast<const DISK_DETAILS*>(bytes.data());
|
||||
result->layout = static_cast<DiskLayout>(details->settings.disk_layout);
|
||||
result->fullFormat = details->options & DISK_DETAILS_FULL_FORMAT;
|
||||
|
||||
result->disks.reserve(diskCount);
|
||||
|
||||
for(size_t i = 0; i < diskCount; i++) {
|
||||
auto& disk = details->status[i];
|
||||
result->disks.emplace_back();
|
||||
auto& info = result->disks.back();
|
||||
info.present = static_cast<bool>(disk.status & DISK_STATUS_PRESENT);
|
||||
info.initialized = static_cast<bool>(disk.status & DISK_STATUS_INITIALIZED);
|
||||
info.formatted = static_cast<bool>(details->settings.disk_enables & (1u << i));
|
||||
info.sectors = disk.sectors;
|
||||
info.bytesPerSector = disk.bytesPerSector;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user