mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-09-22 17:08:38 +02:00
Compare commits
43
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
771d82826f | ||
|
|
b7330a2cea | ||
|
|
fb3778f91b | ||
|
|
a0c8cc62df | ||
|
|
77b3564677 | ||
|
|
051063e684 | ||
|
|
7c1cfde6a0 | ||
|
|
d4995fa2a9 | ||
|
|
fb5c4babce | ||
|
|
4ba1a1e1dd | ||
|
|
6b9a687ff9 | ||
|
|
02b5dafca9 | ||
|
|
f04cd16bee | ||
|
|
c5ba2d8d32 | ||
|
|
a22791c9e0 | ||
|
|
dc2a364afb | ||
|
|
114b664d78 | ||
|
|
2acf248583 | ||
|
|
f18aa00322 | ||
|
|
87baa97c3f | ||
|
|
8dcbbe0d72 | ||
|
|
b624d06ca0 | ||
|
|
c249df8756 | ||
|
|
b2161211c5 | ||
|
|
0ee8a990a7 | ||
|
|
dc0f16b1d2 | ||
|
|
c4ce803d62 | ||
|
|
34cacf4cf2 | ||
|
|
4157558e84 | ||
|
|
40b85488dc | ||
|
|
7584563002 | ||
|
|
4f83614037 | ||
|
|
38a4af8062 | ||
|
|
3b95b41be4 | ||
|
|
3da31a29b4 | ||
|
|
d0f3e593df | ||
|
|
90268a4f04 | ||
|
|
dbe19a5616 | ||
|
|
e5d7a38160 | ||
|
|
d714b620c4 | ||
|
|
10d2625cb6 | ||
|
|
b9cfa85009 | ||
|
|
776d14bb3e |
+22
-119
@@ -4,7 +4,6 @@ variables:
|
||||
stages:
|
||||
- build
|
||||
- unit_test
|
||||
- hardware_test
|
||||
- deploy
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -21,7 +20,7 @@ build windows/x64:
|
||||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
|
||||
unit_test windows/x64:
|
||||
stage: unit_test
|
||||
@@ -32,7 +31,7 @@ unit_test windows/x64:
|
||||
needs:
|
||||
- build windows/x64
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
timeout: 5m
|
||||
|
||||
build windows/x86:
|
||||
@@ -45,7 +44,7 @@ build windows/x86:
|
||||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
|
||||
unit_test windows/x86:
|
||||
stage: unit_test
|
||||
@@ -56,7 +55,7 @@ unit_test windows/x86:
|
||||
needs:
|
||||
- build windows/x86
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
timeout: 5m
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -307,119 +306,6 @@ unit_test linux/fedora/39/amd64/clang:
|
||||
needs:
|
||||
- build linux/fedora/39/amd64/clang
|
||||
|
||||
.hw_test: &hw_test
|
||||
stage: hardware_test
|
||||
tags:
|
||||
- libicsneo_hil
|
||||
timeout: 5m
|
||||
script:
|
||||
- echo $GUEST_OS_TAG
|
||||
- echo $DEVICE_PORT
|
||||
- /opt/libvirt-driver/prepare.sh
|
||||
- /opt/libvirt-driver/run.sh
|
||||
after_script:
|
||||
- /opt/libvirt-driver/cleanup.sh
|
||||
allow_failure: true
|
||||
|
||||
.fedora38_needs: &fedora38_needs
|
||||
needs:
|
||||
- job: build linux/fedora/38/amd64/clang
|
||||
artifacts: true
|
||||
|
||||
hardware_test fedora38-red2:
|
||||
<<: *hw_test
|
||||
<<: *fedora38_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: fedora38
|
||||
DEVICE_PORT: ETH_A
|
||||
|
||||
hardware_test fedora38-vcan42:
|
||||
<<: *hw_test
|
||||
<<: *fedora38_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: fedora38
|
||||
DEVICE_PORT: USB_D
|
||||
|
||||
hardware_test fedora38-fire3:
|
||||
<<: *hw_test
|
||||
<<: *fedora38_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: fedora38
|
||||
DEVICE_PORT: ETH_B
|
||||
|
||||
hardware_test fedora38-vcan42-EL:
|
||||
<<: *hw_test
|
||||
<<: *fedora38_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: fedora38
|
||||
DEVICE_PORT: USB_C
|
||||
|
||||
.ubuntu2204_needs: &ubuntu2204_needs
|
||||
needs:
|
||||
- job: build linux/ubuntu/2204/amd64/clang
|
||||
artifacts: true
|
||||
|
||||
hardware_test ubuntu2204-red2:
|
||||
<<: *hw_test
|
||||
<<: *ubuntu2204_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: ubuntu22.04
|
||||
DEVICE_PORT: ETH_A
|
||||
|
||||
hardware_test ubuntu2204-vcan42:
|
||||
<<: *hw_test
|
||||
<<: *ubuntu2204_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: ubuntu22.04
|
||||
DEVICE_PORT: USB_D
|
||||
|
||||
hardware_test ubuntu2204-fire3:
|
||||
<<: *hw_test
|
||||
<<: *ubuntu2204_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: ubuntu22.04
|
||||
DEVICE_PORT: ETH_B
|
||||
|
||||
hardware_test ubuntu2204-vcan42-EL:
|
||||
<<: *hw_test
|
||||
<<: *ubuntu2204_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: ubuntu22.04
|
||||
DEVICE_PORT: USB_C
|
||||
|
||||
.win10_needs: &win10_needs
|
||||
needs:
|
||||
- job: build windows/x64
|
||||
artifacts: true
|
||||
|
||||
hardware_test win10-red2:
|
||||
<<: *hw_test
|
||||
<<: *win10_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: win10
|
||||
DEVICE_PORT: ETH_A
|
||||
|
||||
hardware_test win10-vcan42:
|
||||
<<: *hw_test
|
||||
<<: *win10_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: win10
|
||||
DEVICE_PORT: USB_D
|
||||
|
||||
hardware_test win10-fire3:
|
||||
<<: *hw_test
|
||||
<<: *win10_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: win10
|
||||
DEVICE_PORT: ETH_B
|
||||
|
||||
hardware_test win10-vcan42-EL:
|
||||
<<: *hw_test
|
||||
<<: *win10_needs
|
||||
variables:
|
||||
GUEST_OS_TAG: win10
|
||||
DEVICE_PORT: USB_C
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Python Module
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -437,7 +323,7 @@ build python/linux/amd64:
|
||||
CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh
|
||||
CIBW_BUILD: "*manylinux*" # no musl
|
||||
CIBW_ARCHS: x86_64
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_HOST: unix:///var/run/docker.sock
|
||||
DOCKER_DRIVER: overlay2
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install
|
||||
@@ -514,3 +400,20 @@ deploy python/pypi:
|
||||
- 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
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ build:
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/icsneopy/requirements.txt
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
+7
-18
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(libicsneo VERSION 0.3.0)
|
||||
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
@@ -7,7 +7,6 @@ if(POLICY CMP0135)
|
||||
endif()
|
||||
|
||||
option(LIBICSNEO_BUILD_UNIT_TESTS "Build unit tests." OFF)
|
||||
option(LIBICSNEO_BUILD_SYSTEM_TESTS "Build system tests." OFF)
|
||||
option(LIBICSNEO_BUILD_DOCS "Build documentation. Don't use in Visual Studio." OFF)
|
||||
option(LIBICSNEO_BUILD_EXAMPLES "Build examples." ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON)
|
||||
@@ -111,6 +110,7 @@ endif()
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SRC
|
||||
platform/windows/strings.cpp
|
||||
platform/windows/registry.cpp
|
||||
)
|
||||
|
||||
@@ -246,6 +246,9 @@ set(SRC_FILES
|
||||
communication/message/linmessage.cpp
|
||||
communication/message/livedatamessage.cpp
|
||||
communication/message/tc10statusmessage.cpp
|
||||
communication/message/gptpstatusmessage.cpp
|
||||
communication/message/ethernetstatusmessage.cpp
|
||||
communication/message/macsecmessage.cpp
|
||||
communication/packet/flexraypacket.cpp
|
||||
communication/packet/canpacket.cpp
|
||||
communication/packet/a2bpacket.cpp
|
||||
@@ -273,6 +276,7 @@ set(SRC_FILES
|
||||
communication/driver.cpp
|
||||
communication/livedata.cpp
|
||||
communication/ringbuffer.cpp
|
||||
communication/crc32.cpp
|
||||
device/extensions/flexray/extension.cpp
|
||||
device/extensions/flexray/controller.cpp
|
||||
device/idevicesettings.cpp
|
||||
@@ -525,6 +529,7 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
||||
test/unit/livedataencoderdecodertest.cpp
|
||||
test/unit/ringbuffertest.cpp
|
||||
test/unit/apperrordecodertest.cpp
|
||||
test/unit/windowsstrings.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
||||
@@ -537,22 +542,6 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
||||
add_test(NAME libicsneo-unit-test-suite COMMAND libicsneo-unit-tests)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_SYSTEM_TESTS)
|
||||
if(DEFINED ENV{LIBICSNEO_SYSTEM_TESTS})
|
||||
include(FetchContent)
|
||||
file(MAKE_DIRECTORY test/system)
|
||||
FetchContent_Declare(
|
||||
SystemTests
|
||||
GIT_REPOSITORY $ENV{LIBICSNEO_SYSTEM_TESTS}
|
||||
GIT_TAG main
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test/system
|
||||
)
|
||||
FetchContent_MakeAvailable(SystemTests)
|
||||
else()
|
||||
message("System test repo not defined!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||
include(CPack)
|
||||
@@ -1,13 +1,29 @@
|
||||
Copyright 2018-2024 Intrepid Control Systems, Inc.
|
||||
Copyright (c) 2018-2025 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.
|
||||
|
||||
@@ -24,6 +24,7 @@ each of the respective APIs.
|
||||
- RAD-Comet 2
|
||||
- RAD-Comet 3
|
||||
- RAD-Galaxy
|
||||
- RAD-Galaxy 2
|
||||
- RAD-Gigastar
|
||||
- RAD-Gigastar 2
|
||||
- RAD-Moon 2
|
||||
|
||||
@@ -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-2024"
|
||||
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2025"
|
||||
VALUE "OriginalFilename", "icsneoc.dll"
|
||||
VALUE "ProductName", "libicsneo"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
|
||||
@@ -120,6 +120,7 @@ static constexpr const char* DISK_NOT_CONNECTED = "The program tried to access a
|
||||
static constexpr const char* UNEXPECTED_RESPONSE = "Received an unexpected or invalid response from the device.";
|
||||
static constexpr const char* LIN_SETTINGS_NOT_AVAILABLE = "LIN settings are not available for this device.";
|
||||
static constexpr const char* MODE_NOT_FOUND = "The mode was not found.";
|
||||
static constexpr const char* GPTP_NOT_SUPPORTED = "GPTP clock synchronization is not supported on this device.";
|
||||
|
||||
// Transport Errors
|
||||
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
||||
@@ -185,6 +186,7 @@ static constexpr const char* VSA_OTHER_ERROR = "Unknown error in VSA read API.";
|
||||
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
|
||||
@@ -345,6 +347,8 @@ const char* APIEvent::DescriptionForType(Type type) {
|
||||
return GETIFADDRS_ERROR;
|
||||
case Type::SendToError:
|
||||
return SEND_TO_ERROR;
|
||||
case Type::GPTPNotSupported:
|
||||
return GPTP_NOT_SUPPORTED;
|
||||
|
||||
// FTD3XX
|
||||
case Type::FTOK:
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
set(PYBIND11_FINDPYTHON ON)
|
||||
find_package(pybind11 CONFIG REQUIRED)
|
||||
|
||||
if(PYBIND11_ROOT)
|
||||
find_package(pybind11 CONFIG REQUIRED)
|
||||
else()
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
GIT_REPOSITORY https://github.com/pybind/pybind11.git
|
||||
GIT_TAG v2.13.6
|
||||
)
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
endif()
|
||||
|
||||
pybind11_add_module(icsneopy
|
||||
icsneopy/api/event.cpp
|
||||
@@ -12,13 +23,29 @@ pybind11_add_module(icsneopy
|
||||
icsneopy/communication/network.cpp
|
||||
icsneopy/communication/message/message.cpp
|
||||
icsneopy/communication/message/canmessage.cpp
|
||||
icsneopy/communication/message/canerrormessage.cpp
|
||||
icsneopy/communication/message/ethernetmessage.cpp
|
||||
icsneopy/communication/message/linmessage.cpp
|
||||
icsneopy/communication/message/tc10statusmessage.cpp
|
||||
icsneopy/communication/message/mdiomessage.cpp
|
||||
icsneopy/communication/message/gptpstatusmessage.cpp
|
||||
icsneopy/communication/message/ethernetstatusmessage.cpp
|
||||
icsneopy/communication/message/macsecmessage.cpp
|
||||
icsneopy/communication/message/scriptstatusmessage.cpp
|
||||
icsneopy/communication/message/callback/messagecallback.cpp
|
||||
icsneopy/communication/message/filter/messagefilter.cpp
|
||||
icsneopy/disk/diskdriver.cpp
|
||||
icsneopy/device/device.cpp
|
||||
icsneopy/icsneocpp.cpp
|
||||
)
|
||||
target_link_libraries(icsneopy PRIVATE icsneocpp)
|
||||
|
||||
install(TARGETS icsneopy LIBRARY DESTINATION .)
|
||||
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)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from .icsneopy import *
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_errorcodes(pybind11::module_& m) {
|
||||
pybind11::enum_<CANErrorCode>(m, "CANErrorCode")
|
||||
.value("NoError", CANErrorCode::NoError)
|
||||
.value("StuffError", CANErrorCode::StuffError)
|
||||
.value("FormError", CANErrorCode::FormError)
|
||||
.value("AckError", CANErrorCode::AckError)
|
||||
.value("Bit1Error", CANErrorCode::Bit1Error)
|
||||
.value("Bit0Error", CANErrorCode::Bit0Error)
|
||||
.value("CRCError", CANErrorCode::CRCError)
|
||||
.value("NoChange", CANErrorCode::NoChange);
|
||||
}
|
||||
|
||||
void init_canerrormessage(pybind11::module_& m) {
|
||||
init_errorcodes(m);
|
||||
pybind11::class_<CANErrorMessage, std::shared_ptr<CANErrorMessage>, Message>(m, "CANErrorMessage")
|
||||
.def_readonly("network", &CANErrorMessage::network)
|
||||
.def_readonly("transmitErrorCount", &CANErrorMessage::transmitErrorCount)
|
||||
.def_readonly("receiveErrorCount", &CANErrorMessage::receiveErrorCount)
|
||||
.def_readonly("busOff", &CANErrorMessage::busOff)
|
||||
.def_readonly("errorPassive", &CANErrorMessage::errorPassive)
|
||||
.def_readonly("errorWarn", &CANErrorMessage::errorWarn)
|
||||
.def_readonly("dataErrorCode", &CANErrorMessage::dataErrorCode)
|
||||
.def_readonly("errorCode", &CANErrorMessage::errorCode);
|
||||
|
||||
|
||||
m.attr("CANErrorCountMessage") = m.attr("CANErrorMessage");
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -15,7 +15,7 @@ void init_ethernetmessage(pybind11::module_& m) {
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("preemptionEnabled", &EthernetMessage::preemptionEnabled)
|
||||
.def_readwrite("preemptionFlags", &EthernetMessage::preemptionFlags)
|
||||
.def_readwrite("fcsAvailable", &EthernetMessage::fcsAvailable)
|
||||
.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)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_ethernetstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<EthernetStatusMessage, std::shared_ptr<EthernetStatusMessage>, Message> ethernetStatusMessage(m, "EthernetStatusMessage");
|
||||
|
||||
pybind11::enum_<EthernetStatusMessage::LinkSpeed>(ethernetStatusMessage, "LinkSpeed")
|
||||
.value("LinkSpeedAuto", EthernetStatusMessage::LinkSpeed::LinkSpeedAuto)
|
||||
.value("LinkSpeed10", EthernetStatusMessage::LinkSpeed::LinkSpeed10)
|
||||
.value("LinkSpeed100", EthernetStatusMessage::LinkSpeed::LinkSpeed100)
|
||||
.value("LinkSpeed1000", EthernetStatusMessage::LinkSpeed::LinkSpeed1000)
|
||||
.value("LinkSpeed2500", EthernetStatusMessage::LinkSpeed::LinkSpeed2500)
|
||||
.value("LinkSpeed5000", EthernetStatusMessage::LinkSpeed::LinkSpeed5000)
|
||||
.value("LinkSpeed10000", EthernetStatusMessage::LinkSpeed::LinkSpeed10000);
|
||||
|
||||
pybind11::enum_<EthernetStatusMessage::LinkMode>(ethernetStatusMessage, "LinkMode")
|
||||
.value("LinkModeAuto", EthernetStatusMessage::LinkMode::LinkModeAuto)
|
||||
.value("LinkModeMaster", EthernetStatusMessage::LinkMode::LinkModeMaster)
|
||||
.value("LinkModeSlave", EthernetStatusMessage::LinkMode::LinkModeSlave)
|
||||
.value("LinkModeInvalid", EthernetStatusMessage::LinkMode::LinkModeInvalid);
|
||||
|
||||
ethernetStatusMessage
|
||||
.def_readonly("network", &EthernetStatusMessage::network)
|
||||
.def_readonly("state", &EthernetStatusMessage::state)
|
||||
.def_readonly("speed", &EthernetStatusMessage::speed)
|
||||
.def_readonly("duplex", &EthernetStatusMessage::duplex)
|
||||
.def_readonly("mode", &EthernetStatusMessage::mode);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -8,6 +8,8 @@ namespace icsneo {
|
||||
|
||||
void init_messagefilter(pybind11::module_& m) {
|
||||
pybind11::class_<MessageFilter, std::shared_ptr<MessageFilter>>(m, "MessageFilter")
|
||||
.def(pybind11::init())
|
||||
.def(pybind11::init<Message::Type>())
|
||||
.def(pybind11::init<Network::NetID>());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/gptpstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_gptpstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<GPTPStatus, std::shared_ptr<GPTPStatus>, Message> gptpStatus(m, "GPTPStatus");
|
||||
|
||||
pybind11::class_<GPTPStatus::Timestamp>(gptpStatus, "Timestamp")
|
||||
.def_readonly("seconds", &GPTPStatus::Timestamp::seconds)
|
||||
.def_readonly("nanoseconds", &GPTPStatus::Timestamp::nanoseconds)
|
||||
.def("to_seconds", &GPTPStatus::Timestamp::toSeconds, pybind11::call_guard<pybind11::gil_scoped_release>());
|
||||
|
||||
pybind11::class_<GPTPStatus::ScaledNanoSeconds>(gptpStatus, "ScaledNanoSeconds")
|
||||
.def_readonly("nanosecondsMSB", &GPTPStatus::ScaledNanoSeconds::nanosecondsMSB)
|
||||
.def_readonly("nanosecondsLSB", &GPTPStatus::ScaledNanoSeconds::nanosecondsLSB)
|
||||
.def_readonly("fractionalNanoseconds", &GPTPStatus::ScaledNanoSeconds::fractionalNanoseconds);
|
||||
|
||||
pybind11::class_<GPTPStatus::PortID>(gptpStatus, "PortID")
|
||||
.def_readonly("clockIdentity", &GPTPStatus::PortID::clockIdentity)
|
||||
.def_readonly("portNumber", &GPTPStatus::PortID::portNumber);
|
||||
|
||||
pybind11::class_<GPTPStatus::ClockQuality>(gptpStatus, "ClockQuality")
|
||||
.def_readonly("clockClass", &GPTPStatus::ClockQuality::clockClass)
|
||||
.def_readonly("clockAccuracy", &GPTPStatus::ClockQuality::clockAccuracy)
|
||||
.def_readonly("offsetScaledLogVariance", &GPTPStatus::ClockQuality::offsetScaledLogVariance);
|
||||
|
||||
pybind11::class_<GPTPStatus::SystemID>(gptpStatus, "SystemID")
|
||||
.def_readonly("priority1", &GPTPStatus::SystemID::priority1)
|
||||
.def_readonly("clockQuality", &GPTPStatus::SystemID::clockQuality)
|
||||
.def_readonly("priority2", &GPTPStatus::SystemID::priority2)
|
||||
.def_readonly("clockID", &GPTPStatus::SystemID::clockID);
|
||||
|
||||
pybind11::class_<GPTPStatus::PriorityVector>(gptpStatus, "PriorityVector")
|
||||
.def_readonly("sysID", &GPTPStatus::PriorityVector::sysID)
|
||||
.def_readonly("stepsRemoved", &GPTPStatus::PriorityVector::stepsRemoved)
|
||||
.def_readonly("portID", &GPTPStatus::PriorityVector::portID)
|
||||
.def_readonly("portNumber", &GPTPStatus::PriorityVector::portNumber);
|
||||
|
||||
pybind11::class_<GPTPStatus::ParentDS>(gptpStatus, "ParentDS")
|
||||
.def_readonly("parentPortIdentity", &GPTPStatus::ParentDS::parentPortIdentity)
|
||||
.def_readonly("cumulativeRateRatio", &GPTPStatus::ParentDS::cumulativeRateRatio)
|
||||
.def_readonly("grandmasterIdentity", &GPTPStatus::ParentDS::grandmasterIdentity)
|
||||
.def_readonly("gmClockQualityClockClass", &GPTPStatus::ParentDS::gmClockQualityClockClass)
|
||||
.def_readonly("gmClockQualityClockAccuracy", &GPTPStatus::ParentDS::gmClockQualityClockAccuracy)
|
||||
.def_readonly("gmClockQualityOffsetScaledLogVariance", &GPTPStatus::ParentDS::gmClockQualityOffsetScaledLogVariance)
|
||||
.def_readonly("gmPriority1", &GPTPStatus::ParentDS::gmPriority1)
|
||||
.def_readonly("gmPriority2", &GPTPStatus::ParentDS::gmPriority2);
|
||||
|
||||
pybind11::class_<GPTPStatus::CurrentDS>(gptpStatus, "CurrentDS")
|
||||
.def_readonly("stepsRemoved", &GPTPStatus::CurrentDS::stepsRemoved)
|
||||
.def_readonly("offsetFromMaster", &GPTPStatus::CurrentDS::offsetFromMaster)
|
||||
.def_readonly("lastgmPhaseChange", &GPTPStatus::CurrentDS::lastgmPhaseChange)
|
||||
.def_readonly("lastgmFreqChange", &GPTPStatus::CurrentDS::lastgmFreqChange)
|
||||
.def_readonly("gmTimeBaseIndicator", &GPTPStatus::CurrentDS::gmTimeBaseIndicator)
|
||||
.def_readonly("gmChangeCount", &GPTPStatus::CurrentDS::gmChangeCount)
|
||||
.def_readonly("timeOfLastgmChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmChangeEvent)
|
||||
.def_readonly("timeOfLastgmPhaseChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmPhaseChangeEvent)
|
||||
.def_readonly("timeOfLastgmFreqChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmFreqChangeEvent);
|
||||
|
||||
gptpStatus.def_readonly("currentTime", &GPTPStatus::currentTime)
|
||||
.def_readonly("gmPriority", &GPTPStatus::gmPriority)
|
||||
.def_readonly("msOffsetNs", &GPTPStatus::msOffsetNs)
|
||||
.def_readonly("isSync", &GPTPStatus::isSync)
|
||||
.def_readonly("linkStatus", &GPTPStatus::linkStatus)
|
||||
.def_readonly("linkDelayNS", &GPTPStatus::linkDelayNS)
|
||||
.def_readonly("selectedRole", &GPTPStatus::selectedRole)
|
||||
.def_readonly("asCapable", &GPTPStatus::asCapable)
|
||||
.def_readonly("isSyntonized", &GPTPStatus::isSyntonized)
|
||||
.def_readonly("lastRXSyncTS", &GPTPStatus::lastRXSyncTS)
|
||||
.def_readonly("currentDS", &GPTPStatus::currentDS)
|
||||
.def_readonly("parentDS", &GPTPStatus::parentDS);
|
||||
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/linmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_linmessage(pybind11::module_& m) {
|
||||
pybind11::class_<LINErrorFlags>(m, "LINErrorFlags")
|
||||
.def_readwrite("ErrRxBreakOnly", &LINErrorFlags::ErrRxBreakOnly)
|
||||
.def_readwrite("ErrRxBreakSyncOnly", &LINErrorFlags::ErrRxBreakSyncOnly)
|
||||
.def_readwrite("ErrTxRxMismatch", &LINErrorFlags::ErrTxRxMismatch)
|
||||
.def_readwrite("ErrRxBreakNotZero", &LINErrorFlags::ErrRxBreakNotZero)
|
||||
.def_readwrite("ErrRxBreakTooShort", &LINErrorFlags::ErrRxBreakTooShort)
|
||||
.def_readwrite("ErrRxSyncNot55", &LINErrorFlags::ErrRxSyncNot55)
|
||||
.def_readwrite("ErrRxDataLenOver8", &LINErrorFlags::ErrRxDataLenOver8)
|
||||
.def_readwrite("ErrFrameSync", &LINErrorFlags::ErrFrameSync)
|
||||
.def_readwrite("ErrFrameMessageID", &LINErrorFlags::ErrFrameMessageID)
|
||||
.def_readwrite("ErrFrameResponderData", &LINErrorFlags::ErrFrameResponderData)
|
||||
.def_readwrite("ErrChecksumMatch", &LINErrorFlags::ErrChecksumMatch);
|
||||
|
||||
pybind11::class_<LINStatusFlags>(m, "LINStatusFlags")
|
||||
.def_readwrite("TxChecksumEnhanced", &LINStatusFlags::TxChecksumEnhanced)
|
||||
.def_readwrite("TxCommander", &LINStatusFlags::TxCommander)
|
||||
.def_readwrite("TxResponder", &LINStatusFlags::TxResponder)
|
||||
.def_readwrite("TxAborted", &LINStatusFlags::TxAborted)
|
||||
.def_readwrite("UpdateResponderOnce", &LINStatusFlags::UpdateResponderOnce)
|
||||
.def_readwrite("HasUpdatedResponderOnce", &LINStatusFlags::HasUpdatedResponderOnce)
|
||||
.def_readwrite("BusRecovered", &LINStatusFlags::BusRecovered)
|
||||
.def_readwrite("BreakOnly", &LINStatusFlags::BreakOnly);
|
||||
|
||||
pybind11::class_<LINMessage, std::shared_ptr<LINMessage>, Frame> linMessage(m, "LINMessage");
|
||||
|
||||
pybind11::enum_<LINMessage::Type>(linMessage, "Type")
|
||||
.value("NOT_SET", LINMessage::Type::NOT_SET)
|
||||
.value("LIN_COMMANDER_MSG", LINMessage::Type::LIN_COMMANDER_MSG)
|
||||
.value("LIN_HEADER_ONLY", LINMessage::Type::LIN_HEADER_ONLY)
|
||||
.value("LIN_BREAK_ONLY", LINMessage::Type::LIN_BREAK_ONLY)
|
||||
.value("LIN_SYNC_ONLY", LINMessage::Type::LIN_SYNC_ONLY)
|
||||
.value("LIN_UPDATE_RESPONDER", LINMessage::Type::LIN_UPDATE_RESPONDER)
|
||||
.value("LIN_ERROR", LINMessage::Type::LIN_ERROR);
|
||||
|
||||
linMessage
|
||||
.def(pybind11::init<>())
|
||||
.def(pybind11::init<uint8_t>())
|
||||
.def_static("calc_checksum", &LINMessage::calcChecksum)
|
||||
.def("calc_protected_id", &LINMessage::calcProtectedID)
|
||||
.def_readwrite("ID", &LINMessage::ID)
|
||||
.def_readwrite("protectedID", &LINMessage::protectedID)
|
||||
.def_readwrite("checksum", &LINMessage::checksum)
|
||||
.def_readwrite("linMsgType", &LINMessage::linMsgType)
|
||||
.def_readwrite("isEnhancedChecksum", &LINMessage::isEnhancedChecksum)
|
||||
.def_readwrite("errFlags", &LINMessage::errFlags)
|
||||
.def_readwrite("statusFlags", &LINMessage::statusFlags);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/macsecmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_macsecmessage(pybind11::module_ & m)
|
||||
{
|
||||
pybind11::enum_<MACsecPacketType>(m, "MACsecPacketType")
|
||||
.value("NoVLAN_OrMPLS", MACsecPacketType::NoVLANOrMPLS)
|
||||
.value("SingleVLAN", MACsecPacketType::SingleVLAN)
|
||||
.value("DualVLAN", MACsecPacketType::DualVLAN)
|
||||
.value("MPLS", MACsecPacketType::MPLS)
|
||||
.value("SingleVLAN_FollowByMPLS", MACsecPacketType::SingleVLANFollowedByMPLS)
|
||||
.value("DualVLAN_FollowByMPLS", MACsecPacketType::DualVLANFollowedByMPLS)
|
||||
.value("Unsupported", MACsecPacketType::Unsupported);
|
||||
|
||||
pybind11::enum_<MACsecValidateFrameType>(m, "MACsecValidateFrameType")
|
||||
.value("Disabled", MACsecValidateFrameType::Disabled)
|
||||
.value("Check", MACsecValidateFrameType::Check)
|
||||
.value("Strict", MACsecValidateFrameType::Strict)
|
||||
.value("NA", MACsecValidateFrameType::NA);
|
||||
|
||||
pybind11::enum_<MACsecSecTagIcvStripType>(m, "MACsecSecTagIcvStripType")
|
||||
.value("StripBoth", MACsecSecTagIcvStripType::StripBoth)
|
||||
.value("StripSecTagPreserveICV", MACsecSecTagIcvStripType::StripSecTagPreserveICV)
|
||||
.value("PreserveSecTagStripICV", MACsecSecTagIcvStripType::PreserveSecTagStripICV)
|
||||
.value("PreserveBoth", MACsecSecTagIcvStripType::PreserveBoth);
|
||||
|
||||
pybind11::enum_<MACsecCipherSuiteType>(m, "MACsecCipherSuiteType")
|
||||
.value("AES_128", MACsecCipherSuiteType::GcmAes128)
|
||||
.value("AES_256", MACsecCipherSuiteType::GcmAes256)
|
||||
.value("AES_128_XPN", MACsecCipherSuiteType::GcmAes128Xpn)
|
||||
.value("AES_256_XPN", MACsecCipherSuiteType::GcmAes256Xpn);
|
||||
|
||||
pybind11::class_<MACsecVLANTag, std::shared_ptr<MACsecVLANTag>>(m, "MACsecVLANTag")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("vid", &MACsecVLANTag::vid)
|
||||
.def_readwrite("pri_cfi", &MACsecVLANTag::priCfi);
|
||||
|
||||
pybind11::class_<MACsecMPLSOuter, std::shared_ptr<MACsecMPLSOuter>>(m, "MACsecMPLSOuter")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("mpls_label", &MACsecMPLSOuter::mplsLabel)
|
||||
.def_readwrite("exp", &MACsecMPLSOuter::exp);
|
||||
|
||||
pybind11::class_<MACsecRule, std::shared_ptr<MACsecRule>>(m, "MACsecRule")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecRule::index)
|
||||
.def_readwrite("keyMacDa", &MACsecRule::keyMacDa)
|
||||
.def_readwrite("maskMacDa", &MACsecRule::maskMacDa)
|
||||
.def_readwrite("keyMacSa", &MACsecRule::keyMacSa)
|
||||
.def_readwrite("maskMacSa", &MACsecRule::maskMacSa)
|
||||
.def_readwrite("keyEthertype", &MACsecRule::keyEthertype)
|
||||
.def_readwrite("maskEthertype", &MACsecRule::maskEthertype)
|
||||
.def_readwrite("keyVlanTagOuter1", &MACsecRule::keyVlanTagOuter1)
|
||||
.def_readwrite("keyMplsOuter1", &MACsecRule::keyMplsOuter1)
|
||||
.def_readwrite("maskVlanTagOuter1", &MACsecRule::maskVlanTagOuter1)
|
||||
.def_readwrite("maskMplsOuter1", &MACsecRule::maskMplsOuter1)
|
||||
.def_readwrite("keyVlanTagOuter2", &MACsecRule::keyVlanTagOuter2)
|
||||
.def_readwrite("keyMplsOuter2", &MACsecRule::keyMplsOuter2)
|
||||
.def_readwrite("maskVlanTagOuter2", &MACsecRule::maskVlanTagOuter2)
|
||||
.def_readwrite("maskMplsOuter2", &MACsecRule::maskMplsOuter2)
|
||||
.def_readwrite("keyBonusData", &MACsecRule::keyBonusData)
|
||||
.def_readwrite("maskBonusData", &MACsecRule::maskBonusData)
|
||||
.def_readwrite("keyTagMatchBitmap", &MACsecRule::keyTagMatchBitmap)
|
||||
.def_readwrite("maskTagMatchBitmap", &MACsecRule::maskTagMatchBitmap)
|
||||
.def_readwrite("keyPacketType", &MACsecRule::keyPacketType)
|
||||
.def_readwrite("maskPacketType", &MACsecRule::maskPacketType)
|
||||
.def_readwrite("keyInnerVlanType", &MACsecRule::keyInnerVlanType)
|
||||
.def_readwrite("maskInnerVlanType", &MACsecRule::maskInnerVlanType)
|
||||
.def_readwrite("keyOuterVlanType", &MACsecRule::keyOuterVlanType)
|
||||
.def_readwrite("maskOuterVlanType", &MACsecRule::maskOuterVlanType)
|
||||
.def_readwrite("keyNumTags", &MACsecRule::keyNumTags)
|
||||
.def_readwrite("maskNumTags", &MACsecRule::maskNumTags)
|
||||
.def_readwrite("keyExpress", &MACsecRule::keyExpress)
|
||||
.def_readwrite("maskExpress", &MACsecRule::maskExpress)
|
||||
.def_readwrite("isMpls", &MACsecRule::isMpls)
|
||||
.def_readwrite("enable", &MACsecRule::enable);
|
||||
|
||||
pybind11::class_<MACsecMap, std::shared_ptr<MACsecMap>>(m, "MACsecMap")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecMap::index)
|
||||
.def_readwrite("secTagSci", &MACsecMap::secTagSci)
|
||||
.def_readwrite("secYIndex", &MACsecMap::secYIndex)
|
||||
.def_readwrite("isControlPacket", &MACsecMap::isControlPacket)
|
||||
.def_readwrite("scIndex", &MACsecMap::scIndex)
|
||||
.def_readwrite("auxiliaryPlcy", &MACsecMap::auxiliaryPlcy)
|
||||
.def_readwrite("ruleId", &MACsecMap::ruleId)
|
||||
.def_readwrite("enable", &MACsecMap::enable);
|
||||
|
||||
pybind11::class_<MACsecSecY, std::shared_ptr<MACsecSecY>>(m, "MACsecSecY")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecSecY::index)
|
||||
.def_readwrite("controlledPortEnabled", &MACsecSecY::controlledPortEnabled)
|
||||
.def_readwrite("frameValidationType", &MACsecSecY::frameValidationType)
|
||||
.def_readwrite("secTagIcvStripType", &MACsecSecY::secTagIcvStripType)
|
||||
.def_readwrite("cipher", &MACsecSecY::cipher)
|
||||
.def_readwrite("confidentialOffset", &MACsecSecY::confidentialOffset)
|
||||
.def_readwrite("icvIncludesDaSa", &MACsecSecY::icvIncludesDaSa)
|
||||
.def_readwrite("replayProtect", &MACsecSecY::replayProtect)
|
||||
.def_readwrite("replayWindow", &MACsecSecY::replayWindow)
|
||||
.def_readwrite("protectFrames", &MACsecSecY::protectFrames)
|
||||
.def_readwrite("secTagOffset", &MACsecSecY::secTagOffset)
|
||||
.def_readwrite("secTagTci", &MACsecSecY::secTagTci)
|
||||
.def_readwrite("mtu", &MACsecSecY::mtu)
|
||||
.def_readwrite("enable", &MACsecSecY::enable);
|
||||
|
||||
pybind11::class_<MACsecSc, std::shared_ptr<MACsecSc>>(m, "MACsecSc")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecSc::index)
|
||||
.def_readwrite("secYIndex", &MACsecSc::secYIndex)
|
||||
.def_readwrite("sci", &MACsecSc::sci)
|
||||
.def_readwrite("saIndex0", &MACsecSc::saIndex0)
|
||||
.def_readwrite("saIndex1", &MACsecSc::saIndex1)
|
||||
.def_readwrite("saIndex0InUse", &MACsecSc::saIndex0InUse)
|
||||
.def_readwrite("saIndex1InUse", &MACsecSc::saIndex1InUse)
|
||||
.def_readwrite("enableAutoRekey", &MACsecSc::enableAutoRekey)
|
||||
.def_readwrite("isActiveSa1", &MACsecSc::isActiveSa1)
|
||||
.def_readwrite("enable", &MACsecSc::enable);
|
||||
|
||||
pybind11::class_<MACsecSa, std::shared_ptr<MACsecSa>>(m, "MACsecSa")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("index", &MACsecSa::index)
|
||||
.def_readwrite("sak", &MACsecSa::sak)
|
||||
.def_readwrite("hashKey", &MACsecSa::hashKey)
|
||||
.def_readwrite("salt", &MACsecSa::salt)
|
||||
.def_readwrite("ssci", &MACsecSa::ssci)
|
||||
.def_readwrite("an", &MACsecSa::an)
|
||||
.def_readwrite("nextPn", &MACsecSa::nextPn)
|
||||
.def_readwrite("enable", &MACsecSa::enable);
|
||||
|
||||
pybind11::class_<MACSecFlags, std::shared_ptr<MACSecFlags>>(m, "MACSecFlags")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("en", &MACSecFlags::en);
|
||||
|
||||
pybind11::class_<MACsecConfig, std::shared_ptr<MACsecConfig>>(m, "MACsecConfig")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("flags", &MACsecConfig::flags)
|
||||
.def_readwrite("rule", &MACsecConfig::rule)
|
||||
.def_readwrite("map", &MACsecConfig::map)
|
||||
.def_readwrite("secy", &MACsecConfig::secy)
|
||||
.def_readwrite("sc", &MACsecConfig::sc)
|
||||
.def_readwrite("sa", &MACsecConfig::sa);
|
||||
|
||||
pybind11::class_<MACSecGlobalFlags, std::shared_ptr<MACSecGlobalFlags>>(m, "MACSecGlobalFlags")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("en", &MACSecGlobalFlags::en)
|
||||
.def_readwrite("nvm", &MACSecGlobalFlags::nvm);
|
||||
|
||||
pybind11::class_<MACsecMessage, std::shared_ptr<MACsecMessage>>(m, "MACsecMessage")
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("flags", &MACsecMessage::flags)
|
||||
.def_readwrite("rx", &MACsecMessage::rx)
|
||||
.def_readwrite("tx", &MACsecMessage::tx);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/mdiomessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_mdiomessage(pybind11::module_& m) {
|
||||
pybind11::class_<MDIOMessage, std::shared_ptr<MDIOMessage>, Frame> mdioMessage(m, "MDIOMessage");
|
||||
pybind11::enum_<MDIOMessage::Clause>(mdioMessage, "Clause")
|
||||
.value("Clause45", MDIOMessage::Clause::Clause45)
|
||||
.value("Clause22", MDIOMessage::Clause::Clause22);
|
||||
pybind11::enum_<MDIOMessage::Direction>(mdioMessage, "Direction")
|
||||
.value("Write", MDIOMessage::Direction::Write)
|
||||
.value("Read", MDIOMessage::Direction::Read);
|
||||
mdioMessage
|
||||
.def(pybind11::init())
|
||||
.def_readwrite("isTXMsg", &MDIOMessage::isTXMsg)
|
||||
.def_readwrite("txTimeout", &MDIOMessage::txTimeout)
|
||||
.def_readwrite("txAborted", &MDIOMessage::txAborted)
|
||||
.def_readwrite("txInvalidBus", &MDIOMessage::txInvalidBus)
|
||||
.def_readwrite("txInvalidPhyAddr", &MDIOMessage::txInvalidPhyAddr)
|
||||
.def_readwrite("txInvalidRegAddr", &MDIOMessage::txInvalidRegAddr)
|
||||
.def_readwrite("txInvalidClause", &MDIOMessage::txInvalidClause)
|
||||
.def_readwrite("txInvalidOpcode", &MDIOMessage::txInvalidOpcode)
|
||||
.def_readwrite("phyAddress", &MDIOMessage::phyAddress)
|
||||
.def_readwrite("devAddress", &MDIOMessage::devAddress)
|
||||
.def_readwrite("regAddress", &MDIOMessage::regAddress)
|
||||
.def_readwrite("direction", &MDIOMessage::direction)
|
||||
.def_readwrite("clause", &MDIOMessage::clause);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -11,6 +11,7 @@ void init_message(pybind11::module_& m) {
|
||||
pybind11::enum_<Message::Type>(message, "Type")
|
||||
.value("Frame", Message::Type::Frame)
|
||||
.value("CANErrorCount", Message::Type::CANErrorCount)
|
||||
.value("CANError", Message::Type::CANError)
|
||||
.value("LINHeaderOnly", Message::Type::LINHeaderOnly)
|
||||
.value("LINBreak", Message::Type::LINBreak)
|
||||
.value("Invalid", Message::Type::Invalid)
|
||||
@@ -31,7 +32,9 @@ void init_message(pybind11::module_& m) {
|
||||
.value("LiveData", Message::Type::LiveData)
|
||||
.value("HardwareInfo", Message::Type::HardwareInfo)
|
||||
.value("TC10Status", Message::Type::TC10Status)
|
||||
.value("AppError", Message::Type::AppError);
|
||||
.value("AppError", Message::Type::AppError)
|
||||
.value("GPTPStatus", Message::Type::GPTPStatus)
|
||||
.value("EthernetStatus", Message::Type::EthernetStatus);
|
||||
|
||||
message.def(pybind11::init<Message::Type>());
|
||||
message.def_readonly("type", &Message::type);
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_scriptstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<ScriptStatusMessage, std::shared_ptr<ScriptStatusMessage>, Message>(m, "ScriptStatusMessage")
|
||||
.def_readonly("isEncrypted", &ScriptStatusMessage::isEncrypted)
|
||||
.def_readonly("isCoreminiRunning", &ScriptStatusMessage::isCoreminiRunning)
|
||||
.def_readonly("sectorOverflows", &ScriptStatusMessage::sectorOverflows)
|
||||
.def_readonly("numRemainingSectorBuffers", &ScriptStatusMessage::numRemainingSectorBuffers)
|
||||
.def_readonly("lastSector", &ScriptStatusMessage::lastSector)
|
||||
.def_readonly("readBinSize", &ScriptStatusMessage::readBinSize)
|
||||
.def_readonly("minSector", &ScriptStatusMessage::minSector)
|
||||
.def_readonly("maxSector", &ScriptStatusMessage::maxSector)
|
||||
.def_readonly("currentSector", &ScriptStatusMessage::currentSector)
|
||||
.def_readonly("coreminiCreateTime", &ScriptStatusMessage::coreminiCreateTime)
|
||||
.def_readonly("fileChecksum", &ScriptStatusMessage::fileChecksum)
|
||||
.def_readonly("coreminiVersion", &ScriptStatusMessage::coreminiVersion)
|
||||
.def_readonly("coreminiHeaderSize", &ScriptStatusMessage::coreminiHeaderSize)
|
||||
.def_readonly("diagnosticErrorCode", &ScriptStatusMessage::diagnosticErrorCode)
|
||||
.def_readonly("diagnosticErrorCodeCount", &ScriptStatusMessage::diagnosticErrorCodeCount)
|
||||
.def_readonly("maxCoreminiSizeKB", &ScriptStatusMessage::maxCoreminiSizeKB);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -167,7 +167,30 @@ void init_network(pybind11::module_& m) {
|
||||
.value("Any", Network::NetID::Any)
|
||||
.value("Invalid", Network::NetID::Invalid);
|
||||
|
||||
network.def(pybind11::init<Network::NetID>());
|
||||
pybind11::enum_<Network::Type>(network, "Type")
|
||||
.value("Invalid", Network::Type::Invalid)
|
||||
.value("Internal", Network::Type::Internal)
|
||||
.value("CAN", Network::Type::CAN)
|
||||
.value("LIN", Network::Type::LIN)
|
||||
.value("FlexRay", Network::Type::FlexRay)
|
||||
.value("MOST", Network::Type::MOST)
|
||||
.value("Ethernet", Network::Type::Ethernet)
|
||||
.value("LSFTCAN", Network::Type::LSFTCAN)
|
||||
.value("SWCAN", Network::Type::SWCAN)
|
||||
.value("ISO9141", Network::Type::ISO9141)
|
||||
.value("I2C", Network::Type::I2C)
|
||||
.value("A2B", Network::Type::A2B)
|
||||
.value("SPI", Network::Type::SPI)
|
||||
.value("MDIO", Network::Type::MDIO)
|
||||
.value("Any", Network::Type::Any)
|
||||
.value("Other", Network::Type::Other);
|
||||
|
||||
network
|
||||
.def(pybind11::init<Network::NetID>())
|
||||
.def("__repr__", [](Network& self) { return Network::GetNetIDString(self.getNetID()); })
|
||||
.def_static("get_net_id_string", &Network::GetNetIDString, pybind11::arg("netid"), pybind11::arg("expand") = true)
|
||||
.def("get_net_id", &Network::getNetID)
|
||||
.def("get_type", &Network::getType);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -1,42 +1,55 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <pybind11/chrono.h>
|
||||
|
||||
#include "icsneo/device/device.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_device(pybind11::module_& m) {
|
||||
pybind11::class_<Device, std::shared_ptr<Device>>(m, "Device")
|
||||
.def("get_type", &Device::getType)
|
||||
.def("get_serial", &Device::getSerial)
|
||||
.def("get_serial_number", &Device::getSerialNumber)
|
||||
.def("get_product_name", &Device::getProductName)
|
||||
.def("open", [](Device& device) { return device.open(); })
|
||||
.def("close", &Device::close)
|
||||
.def("is_open", &Device::isOpen)
|
||||
.def("go_online", &Device::goOnline)
|
||||
.def("go_offline", &Device::goOffline)
|
||||
.def("is_online", &Device::isOnline).def("enable_message_polling", &Device::enableMessagePolling)
|
||||
.def("disable_message_polling", &Device::disableMessagePolling)
|
||||
.def("is_message_polling_enabled", &Device::isMessagePollingEnabled)
|
||||
.def("get_messages", [](Device& device) { return device.getMessages(); })
|
||||
.def("__repr__", &Device::describe)
|
||||
.def("add_message_callback", &Device::addMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("clear_script", &Device::clearScript, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("close", &Device::close, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("describe", &Device::describe)
|
||||
.def("disable_message_polling", &Device::disableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("enable_message_polling", &Device::enableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_current_message_count", &Device::getCurrentMessageCount)
|
||||
.def("get_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("set_polling_message_limit", &Device::setPollingMessageLimit)
|
||||
.def("add_message_callback", &Device::addMessageCallback)
|
||||
.def("remove_message_callback", &Device::removeMessageCallback)
|
||||
.def("transmit", pybind11::overload_cast<std::shared_ptr<Frame>>(&Device::transmit))
|
||||
.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_rtc", &Device::getRTC)
|
||||
.def("set_rtc", &Device::setRTC)
|
||||
.def("describe", &Device::describe)
|
||||
.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_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("request_tc10_wake", &Device::requestTC10Wake)
|
||||
.def("request_tc10_sleep", &Device::requestTC10Sleep)
|
||||
.def("__repr__", &Device::describe);
|
||||
.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>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
@@ -33,6 +33,7 @@ void init_devicetype(pybind11::module_& m) {
|
||||
.value("EtherBADGE", DeviceType::Enum::EtherBADGE)
|
||||
.value("RAD_A2B", DeviceType::Enum::RAD_A2B)
|
||||
.value("RADEpsilon", DeviceType::Enum::RADEpsilon)
|
||||
.value("RADGalaxy2", DeviceType::Enum::RADGalaxy2)
|
||||
.value("RADMoon3", DeviceType::Enum::RADMoon3)
|
||||
.value("RADComet", DeviceType::Enum::RADComet)
|
||||
.value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/disk/diskdriver.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
// binding namespace workaround to avoid submodules
|
||||
struct DiskNamespace {
|
||||
using Access = icsneo::Disk::Access;
|
||||
using MemoryType = icsneo::Disk::MemoryType;
|
||||
};
|
||||
|
||||
void init_diskdriver(pybind11::module_& m) {
|
||||
pybind11::class_<DiskNamespace> disk(m, "Disk");
|
||||
pybind11::enum_<Disk::Access>(disk, "Access")
|
||||
.value("None", Disk::Access::None)
|
||||
.value("EntireCard", Disk::Access::EntireCard)
|
||||
.value("VSA", Disk::Access::VSA);
|
||||
pybind11::enum_<Disk::MemoryType>(disk, "MemoryType")
|
||||
.value("Flash", Disk::MemoryType::Flash)
|
||||
.value("SD", Disk::MemoryType::SD);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -13,14 +13,24 @@ void init_network(pybind11::module_&);
|
||||
void init_devicetype(pybind11::module_&);
|
||||
void init_message(pybind11::module_&);
|
||||
void init_canmessage(pybind11::module_&);
|
||||
void init_canerrormessage(pybind11::module_&);
|
||||
void init_ethernetmessage(pybind11::module_&);
|
||||
void init_linmessage(pybind11::module_&);
|
||||
void init_tc10statusmessage(pybind11::module_&);
|
||||
void init_gptpstatusmessage(pybind11::module_&);
|
||||
void init_mdiomessage(pybind11::module_&);
|
||||
void init_ethernetstatusmessage(pybind11::module_&);
|
||||
void init_macsecmessage(pybind11::module_&);
|
||||
void init_scriptstatusmessage(pybind11::module_&);
|
||||
void init_diskdriver(pybind11::module_&);
|
||||
void init_device(pybind11::module_&);
|
||||
void init_messagefilter(pybind11::module_&);
|
||||
void init_messagecallback(pybind11::module_&);
|
||||
void init_version(pybind11::module_&);
|
||||
|
||||
PYBIND11_MODULE(icsneopy, m) {
|
||||
pybind11::options options;
|
||||
options.disable_enum_members_docstring();
|
||||
m.doc() = "libicsneo Python module";
|
||||
|
||||
init_event(m);
|
||||
@@ -31,10 +41,18 @@ PYBIND11_MODULE(icsneopy, m) {
|
||||
init_network(m);
|
||||
init_message(m);
|
||||
init_canmessage(m);
|
||||
init_canerrormessage(m);
|
||||
init_ethernetmessage(m);
|
||||
init_linmessage(m);
|
||||
init_tc10statusmessage(m);
|
||||
init_gptpstatusmessage(m);
|
||||
init_mdiomessage(m);
|
||||
init_ethernetstatusmessage(m);
|
||||
init_macsecmessage(m);
|
||||
init_scriptstatusmessage(m);
|
||||
init_messagefilter(m);
|
||||
init_messagecallback(m);
|
||||
init_diskdriver(m);
|
||||
init_device(m);
|
||||
|
||||
m.def("find_all_devices", &FindAllDevices);
|
||||
|
||||
+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_BUILD_SYSTEM_TESTS=ON -DLIBICSNEO_ENABLE_TCP=OFF || exit 1
|
||||
-DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_ENABLE_TCP=OFF || exit 1
|
||||
|
||||
cmake --build build || exit 1
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ REM build
|
||||
cd build
|
||||
set CFLAGS=/WX
|
||||
set CXXFLAGS=/WX
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_BUILD_SYSTEM_TESTS=ON -DLIBICSNEO_ENABLE_TCP=ON ..
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLIBICSNEO_BUILD_UNIT_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%"
|
||||
call "%VCVARS32_2022%"
|
||||
call "ci\build-windows.bat"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
call "%VCVARS64%"
|
||||
call "%VCVARS64_2022%"
|
||||
call "ci\build-windows.bat"
|
||||
|
||||
@@ -37,29 +37,28 @@ bool Communication::open() {
|
||||
}
|
||||
|
||||
void Communication::spawnThreads() {
|
||||
closing = false;
|
||||
readTaskThread = std::thread(&Communication::readTask, this);
|
||||
}
|
||||
|
||||
void Communication::joinThreads() {
|
||||
closing = true;
|
||||
|
||||
if(pauseReadTask) {
|
||||
resumeReads();
|
||||
}
|
||||
|
||||
closing = true;
|
||||
if(readTaskThread.joinable())
|
||||
readTaskThread.join();
|
||||
closing = false;
|
||||
}
|
||||
|
||||
bool Communication::close() {
|
||||
joinThreads();
|
||||
|
||||
if(!isOpen() && !isDisconnected()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
joinThreads();
|
||||
|
||||
return driver->close();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* crc32.c
|
||||
*
|
||||
* Created on: Jun 22, 2020
|
||||
* Author: BJones
|
||||
*/
|
||||
#include "icsneo/communication/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 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)
|
||||
{
|
||||
unsigned char k;
|
||||
|
||||
for (k = 0; k < 256; k++)
|
||||
rev_crc32_table[crc32_table[k] >> 24] = k;
|
||||
}
|
||||
|
||||
uint32_t revcrc32(uint32_t crc, const unsigned char* buf, uint32_t len)
|
||||
{
|
||||
unsigned char k;
|
||||
revgen();
|
||||
crc = ~crc;
|
||||
while (len--)
|
||||
{
|
||||
k = rev_crc32_table[crc >> 24];
|
||||
crc = ((crc ^ crc32_table[k]) << 8) | (k ^ buf[len]);
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
+35
-19
@@ -3,7 +3,7 @@
|
||||
#include "icsneo/communication/message/serialnumbermessage.h"
|
||||
#include "icsneo/communication/message/resetstatusmessage.h"
|
||||
#include "icsneo/communication/message/readsettingsmessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
||||
#include "icsneo/communication/message/flashmemorymessage.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
@@ -19,7 +19,9 @@
|
||||
#include "icsneo/communication/message/diskdatamessage.h"
|
||||
#include "icsneo/communication/message/hardwareinfo.h"
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
#include "icsneo/communication/message/gptpstatusmessage.h"
|
||||
#include "icsneo/communication/message/apperrormessage.h"
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
@@ -93,7 +95,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
break;
|
||||
}
|
||||
case Message::Type::CANErrorCount: {
|
||||
CANErrorCountMessage& can = *static_cast<CANErrorCountMessage*>(result.get());
|
||||
CANErrorMessage& can = *static_cast<CANErrorMessage*>(result.get());
|
||||
can.network = packet->network;
|
||||
break;
|
||||
}
|
||||
@@ -178,6 +180,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
|
||||
LINMessage& msg = *static_cast<LINMessage*>(result.get());
|
||||
msg.network = packet->network;
|
||||
msg.timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case Network::Type::MDIO: {
|
||||
@@ -236,21 +239,26 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
return true;
|
||||
}
|
||||
|
||||
result = HardwareCANPacket::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
const auto can = std::dynamic_pointer_cast<CANMessage>(HardwareCANPacket::DecodeToMessage(packet->data));
|
||||
if(!can) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was malformed
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
raw->timestamp *= timestampResolution;
|
||||
raw->network = packet->network;
|
||||
result->timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::DeviceStatus: {
|
||||
@@ -284,11 +292,11 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||
}
|
||||
case Network::NetID::ExtendedCommand: {
|
||||
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::PackedGenericResponse))
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::ResponseHeader))
|
||||
break; // Handle as a raw message, might not be a generic response
|
||||
|
||||
const auto& resp = *reinterpret_cast<ExtendedResponseMessage::PackedGenericResponse*>(packet->data.data());
|
||||
switch(resp.header.command) {
|
||||
const auto& resp = *reinterpret_cast<ExtendedResponseMessage::ResponseHeader*>(packet->data.data());
|
||||
switch(resp.command) {
|
||||
case ExtendedCommand::GetComponentVersions:
|
||||
result = ComponentVersionPacket::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
@@ -298,15 +306,23 @@ 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:
|
||||
result = std::make_shared<ExtendedResponseMessage>(resp.command, resp.returnCode);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
case ExtendedCommand::LiveData:
|
||||
result = HardwareLiveDataPacket::DecodeToMessage(packet->data, report);
|
||||
return true;
|
||||
case ExtendedCommand::GetTC10Status:
|
||||
result = TC10StatusMessage::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::GetGPTPStatus: {
|
||||
result = GPTPStatus::DecodeToMessage(packet->data, report);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// No defined handler, treat this as a RawMessage
|
||||
break;
|
||||
|
||||
@@ -265,6 +265,8 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
||||
case Command::GetMainVersion:
|
||||
case Command::GetSecondaryVersions:
|
||||
case Command::NeoReadMemory:
|
||||
case Command::ClearCoreMini:
|
||||
case Command::LoadCoreMini:
|
||||
// There is a firmware handling idiosyncrasy with these commands
|
||||
// They must be encoded in the short format
|
||||
m51msg->forceShortFormat = true;
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
enum LinkSpeed {
|
||||
ethSpeed10,
|
||||
ethSpeed100,
|
||||
ethSpeed1000,
|
||||
ethSpeedAutoNeg,
|
||||
ethSpeed2500,
|
||||
ethSpeed5000,
|
||||
ethSpeed10000,
|
||||
};
|
||||
|
||||
enum LinkMode {
|
||||
OPETH_LINK_AUTO,
|
||||
OPETH_LINK_MASTER,
|
||||
OPETH_LINK_SLAVE,
|
||||
OPETH_LINK_INVALID = 255,
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
uint8_t state;
|
||||
uint8_t speed;
|
||||
uint8_t duplex;
|
||||
uint16_t network;
|
||||
uint8_t mode;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(Packet)) {
|
||||
return nullptr;
|
||||
}
|
||||
Packet* packet = (Packet*)bytestream.data();
|
||||
LinkSpeed speed;
|
||||
switch(packet->speed) {
|
||||
case ethSpeed10: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10; break;
|
||||
case ethSpeed100: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed100; break;
|
||||
case ethSpeed1000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed1000; break;
|
||||
case ethSpeedAutoNeg: speed = EthernetStatusMessage::LinkSpeed::LinkSpeedAuto; break;
|
||||
case ethSpeed2500: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed2500; break;
|
||||
case ethSpeed5000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed5000; break;
|
||||
case ethSpeed10000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10000; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
LinkMode mode;
|
||||
switch(packet->mode) {
|
||||
case OPETH_LINK_INVALID: mode = EthernetStatusMessage::LinkMode::LinkModeInvalid; break;
|
||||
case OPETH_LINK_AUTO: mode = EthernetStatusMessage::LinkMode::LinkModeAuto; break;
|
||||
case OPETH_LINK_MASTER: mode = EthernetStatusMessage::LinkMode::LinkModeMaster; break;
|
||||
case OPETH_LINK_SLAVE: mode = EthernetStatusMessage::LinkMode::LinkModeSlave; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state, speed, packet->duplex, mode);
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,531 @@
|
||||
#include "icsneo/communication/message/macsecmessage.h"
|
||||
|
||||
#include "icsneo/communication/crc32.h"
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
namespace icsneo
|
||||
{
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4201) // nameless struct/union
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
/* MACsec Rule */
|
||||
/**
|
||||
* @brief Structure of Vlan tag
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t vid; /*!< 12 bits */
|
||||
uint8_t priCfi; /*!< PRI - 3 bits, CFI - 1bit */
|
||||
} MACSEC_VLANTAG_t;
|
||||
/**
|
||||
* @brief Structure of MPLS
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mplsLabel; /*!< 20 bits */
|
||||
uint8_t exp; /*!< 3 bits */
|
||||
} MACSEC_MPLS_OUTER_t;
|
||||
/**
|
||||
* @brief Define Encoded Packet Type from the parser
|
||||
*
|
||||
*/
|
||||
static constexpr int MACSEC_SETTINGS_RULE_SIZE = 88;
|
||||
typedef union _MACSecRule
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index;
|
||||
uint8_t keyMacDa[6]; /*!< MAC DA field extracted from the packet */
|
||||
uint8_t maskMacDa[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyMacSa[6]; /*!< MAC SA field extracted from the packet */
|
||||
uint8_t maskMacSa[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t keyEthertype; /*!< First E-Type found in the packet that doesn't match one of the preconfigured custom tag. */
|
||||
uint16_t maskEthertype; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_VLANTAG_t keyVlanTagOuter1; /*!< outermost/1st VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACSEC_MPLS_OUTER_t keyMplsOuter1;
|
||||
MACSEC_VLANTAG_t maskVlanTagOuter1; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_MPLS_OUTER_t maskMplsOuter1;
|
||||
MACSEC_VLANTAG_t keyVlanTagOuter2; /*!< 2nd outermost VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACSEC_MPLS_OUTER_t keyMplsOuter2;
|
||||
MACSEC_VLANTAG_t maskVlanTagOuter2; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACSEC_MPLS_OUTER_t maskMplsOuter2;
|
||||
uint16_t keyBonusData; /*!< 2 bytes of additional bonus data extracted from one of the custom tags. */
|
||||
uint16_t maskBonusData; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t
|
||||
keyTagMatchBitmap; /*!< 8 bits total. Maps 1 to 1 bitwise with the set of custom tags. (set bit[N]=1 if check Nth custom tag) */
|
||||
uint8_t maskTagMatchBitmap; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyPacketType; /*!< Encoded Packet Type, see MACSEC_PACKET_TYPE */
|
||||
uint8_t maskPacketType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t
|
||||
keyInnerVlanType; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the second outermost VLAN Tag. */
|
||||
uint16_t maskInnerVlanType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t keyOuterVlanType; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the outermost VLAN Tag. */
|
||||
uint16_t maskOuterVlanType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t
|
||||
keyNumTags; /*!< 7 bits total. Number of VLAN/custom tags or MPLS lables detected. Ingress: before SecTag; Egress: total detected. Exclude MCS header tags. i.e. Bit 2: 2 tags/labels before SecTAG...Bit 6: 6 or more tags/labels before SecTAG. */
|
||||
uint8_t maskNumTags; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyExpress; /*!< 1 bits. Express packet. */
|
||||
uint8_t maskExpress; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t isMpls;
|
||||
uint8_t rsvd[5];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_RULE_SIZE];
|
||||
} MACSecRule_t;
|
||||
/* MACsec Map */
|
||||
static constexpr int MACSEC_SETTINGS_MAP_SIZE = 20;
|
||||
typedef union _MACSecMap
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index;
|
||||
uint64_t secTagSci; /*!< Identifies the SecTAG SCI for this Flow. */
|
||||
uint8_t secYIndex; /*!< index for entry in Egress secY Policy */
|
||||
uint8_t isControlPacket; /*!< Identifies all packets matching this index lookup as control packets. */
|
||||
uint8_t scIndex; /*!< Identifies the SC for this Flow. */
|
||||
uint8_t auxiliaryPlcy; /*!< Auxiliary policy bits. */
|
||||
uint8_t ruleId; /*!< Identifies the Rule for this Flow. */
|
||||
uint8_t rsvd[5];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_MAP_SIZE];
|
||||
} MACSecMap_t;
|
||||
/* MACsec SecY */
|
||||
/**
|
||||
* @brief Define the permit police for frames as defined in 802.1ae
|
||||
*
|
||||
*/
|
||||
static constexpr int MACSEC_SETTINGS_SECY_SIZE = 24;
|
||||
typedef union _MACSecSecY
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index; /*!< Identifies the SecY for this Flow. */
|
||||
uint8_t controlledPortEnabled; /*!< Enable (or disable) operation of the Controlled port associated with this SecY */
|
||||
uint8_t frameValidationType; /*!< see MACSEC_VALIDATEFRAME */
|
||||
uint8_t secTagIcvStripType; /*!< see MACSEC_STRIP_SECTAG_ICV */
|
||||
uint8_t cipher; /*!< Define the cipher suite to use for this SecY see MACSEC_CIPHER_SUITE */
|
||||
uint8_t confidentialOffset; /*!< Define the number of bytes that are unencrypted following the SecTag. */
|
||||
uint8_t icvIncludesDaSa; /*!< When set, the outer DA/SA bytes are included in the authentication GHASH calculation */
|
||||
uint8_t replayProtect; /*!< Enables Anti-Replay protection */
|
||||
uint32_t replayWindow; /*!< Unsigned value indicating the size of the anti-replay window. */
|
||||
uint8_t
|
||||
protectFrames; /*!< 0 = do not encrypt or authenticate this packet; 1 = always Authenticate frame and if SecTag.TCI.E = 1 encrypt the packet as well. */
|
||||
uint8_t
|
||||
secTagOffset; /*!< Define the offset in bytes from either the start of the packet or a matching Etype depending on SecTag_Insertion_Mode. */
|
||||
uint8_t secTagTci; /*!< Tag Control Information excluding the AN field which originates from the SA Policy table */
|
||||
uint16_t mtu; /*!< Specifies the outgoing MTU for this SecY */
|
||||
uint8_t rsvd[6];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SECY_SIZE];
|
||||
} MACSecSecY_t;
|
||||
/* MACsec SC */
|
||||
static constexpr int MACSEC_SETTINGS_SC_SIZE = 24;
|
||||
typedef union _MACSecSc
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index; /*!< SC index. */
|
||||
uint8_t secYIndex; /*!< SecY associated with this packet. */
|
||||
uint64_t sci; /*!< The Secure Channel Identifier. */
|
||||
uint8_t saIndex0; /*!< Define the 1st SA to use */
|
||||
uint8_t saIndex1; /*!< Define the 2nd SA to use */
|
||||
uint8_t saIndex0InUse; /*!< Specifies whether 1st SA is in use or not. */
|
||||
uint8_t saIndex1InUse; /*!< Specifies whether 2nd SA is in use or not. */
|
||||
uint8_t enableAutoRekey; /*!< If enabled, then once the pn_threshold is reached, auto rekey will happen. */
|
||||
uint8_t
|
||||
isActiveSa1; /*!< If set, then sa_index1 is the currently active SA index. If cleared, the sa_index0 is the currently active SA index). */
|
||||
uint8_t rsvd[7];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SC_SIZE];
|
||||
} MACSecSc_t;
|
||||
/* MACsec SA */
|
||||
static constexpr int MACSEC_SETTINGS_SA_SIZE = 80;
|
||||
typedef union _MACSecSa
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t index; /*!< SA index */
|
||||
uint8_t
|
||||
sak[32]; /*!< 256b SAK: Define the encryption key to be used to encrypte this packet. The lower 128 bits are used for 128-bit ciphers. */
|
||||
uint8_t hashKey[16]; /*!< 128b Hash Key: Key used for authentication. */
|
||||
uint8_t salt[12]; /*!< 96b Salt value: Salt value used in XPN ciphers. */
|
||||
uint32_t ssci; /*!< 32b SSCI value: Short Secure Channel Identifier, used in XPN ciphers. */
|
||||
uint8_t an; /*!< 2b SecTag Association Number (AN) */
|
||||
uint64_t nextPn; /*!< 64b next_pn value: Next packet number to insert into outgoing packet on a particular SA. */
|
||||
uint8_t rsvd[5];
|
||||
uint8_t enable;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SA_SIZE];
|
||||
} MACSecSa_t;
|
||||
/* MACsec Flags */
|
||||
static constexpr int 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 */
|
||||
typedef struct MACSEC_CONFIG_t
|
||||
{
|
||||
MACSecFlags_t flags;
|
||||
MACSecRule_t rule[MACsecConfig::NumRules];
|
||||
MACSecMap_t map[MACsecConfig::NumMaps];
|
||||
MACSecSecY_t secy[MACsecConfig::NumSecY];
|
||||
MACSecSc_t sc[MACsecConfig::NumSc];
|
||||
MACSecSa_t sa[MACsecConfig::NumSa];
|
||||
} MACSEC_CONFIG;
|
||||
typedef union _MACSecGlobalFlags
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t en : 1; // '1' = enable; '0' = disable
|
||||
uint32_t nvm : 1; // store macsec config in non-volatile memory
|
||||
uint32_t reserved : 30;
|
||||
};
|
||||
uint32_t flags_32b;
|
||||
} MACSecGlobalFlags_t;
|
||||
#define MACSEC_SETTINGS_SIZE (2040) // leave space for expansion and keep nicely aligned for flashing
|
||||
typedef union _MACSEC_SETTINGS
|
||||
{
|
||||
struct
|
||||
{
|
||||
MACSecGlobalFlags_t flags;
|
||||
MACSEC_CONFIG rx;
|
||||
MACSEC_CONFIG tx;
|
||||
};
|
||||
uint8_t byte[MACSEC_SETTINGS_SIZE];
|
||||
} MACSEC_SETTINGS;
|
||||
|
||||
#define MACSEC_SETTINGS_VERSION 1
|
||||
struct MACSEC_SETTINGS_W_HDR
|
||||
{
|
||||
uint16_t version;
|
||||
uint16_t len;
|
||||
uint32_t crc32;
|
||||
MACSEC_SETTINGS macsec;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
std::shared_ptr<MACsecMessage> MACsecMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report)
|
||||
{
|
||||
if (bytestream.empty() || (bytestream.size() < sizeof(MACSEC_SETTINGS_W_HDR)))
|
||||
{
|
||||
report(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MACSEC_SETTINGS_W_HDR* macsecArgs = (MACSEC_SETTINGS_W_HDR*)bytestream.data();
|
||||
if (macsecArgs->version != MACSEC_SETTINGS_VERSION)
|
||||
{
|
||||
report(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
if (macsecArgs->len != sizeof(MACSEC_SETTINGS))
|
||||
{
|
||||
report(APIEvent::Type::SettingsLengthError, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
const auto crcCalculted = crc32(0, (uint8_t*)&macsecArgs->macsec, macsecArgs->len);
|
||||
if (macsecArgs->crc32 != crcCalculted)
|
||||
{
|
||||
report(APIEvent::Type::SettingsChecksumError, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto msg = std::make_shared<MACsecMessage>();
|
||||
|
||||
const auto& copyConfig = [](const MACSEC_CONFIG& source, MACsecConfig& dest)
|
||||
{
|
||||
dest.flags.en = source.flags.en;
|
||||
for (int index = 0; index < MACsecConfig::NumRules; index++)
|
||||
{
|
||||
if(!source.rule[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.rule[index].___name__ = (decltype(dest.rule[index].___name__))source.rule[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.rule[index].___name__.data(), source.rule[index].___name__, dest.rule[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(keyMacDa);
|
||||
__COPY_ARR(maskMacDa);
|
||||
__COPY_ARR(keyMacSa);
|
||||
__COPY_ARR(maskMacSa);
|
||||
__COPY_ITEM(keyVlanTagOuter1.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter1.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter1.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter1.exp);
|
||||
__COPY_ITEM(keyVlanTagOuter2.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter2.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter2.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter2.exp);
|
||||
__COPY_ITEM(keyEthertype);
|
||||
__COPY_ITEM(maskEthertype);
|
||||
__COPY_ITEM(keyBonusData);
|
||||
__COPY_ITEM(maskBonusData);
|
||||
__COPY_ITEM(keyTagMatchBitmap);
|
||||
__COPY_ITEM(maskTagMatchBitmap);
|
||||
__COPY_ITEM(keyPacketType);
|
||||
__COPY_ITEM(maskPacketType);
|
||||
__COPY_ITEM(keyInnerVlanType);
|
||||
__COPY_ITEM(maskInnerVlanType);
|
||||
__COPY_ITEM(keyOuterVlanType);
|
||||
__COPY_ITEM(maskOuterVlanType);
|
||||
__COPY_ITEM(keyNumTags);
|
||||
__COPY_ITEM(maskNumTags);
|
||||
__COPY_ITEM(keyExpress);
|
||||
__COPY_ITEM(maskExpress);
|
||||
__COPY_ITEM(isMpls);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumMaps; index++)
|
||||
{
|
||||
if(!source.map[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.map[index].___name__ = source.map[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secTagSci);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(isControlPacket);
|
||||
__COPY_ITEM(scIndex);
|
||||
__COPY_ITEM(auxiliaryPlcy);
|
||||
__COPY_ITEM(ruleId);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSecY; index++)
|
||||
{
|
||||
if(!source.secy[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.secy[index].___name__ = (decltype(dest.secy[index].___name__))source.secy[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(controlledPortEnabled);
|
||||
__COPY_ITEM(frameValidationType);
|
||||
__COPY_ITEM(secTagIcvStripType);
|
||||
__COPY_ITEM(cipher);
|
||||
__COPY_ITEM(confidentialOffset);
|
||||
__COPY_ITEM(icvIncludesDaSa);
|
||||
__COPY_ITEM(replayProtect);
|
||||
__COPY_ITEM(replayWindow);
|
||||
__COPY_ITEM(protectFrames);
|
||||
__COPY_ITEM(secTagOffset);
|
||||
__COPY_ITEM(secTagTci);
|
||||
__COPY_ITEM(mtu);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSc; index++)
|
||||
{
|
||||
if(!source.sc[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sc[index].___name__ = source.sc[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(sci);
|
||||
__COPY_ITEM(saIndex0);
|
||||
__COPY_ITEM(saIndex1);
|
||||
__COPY_ITEM(saIndex0InUse);
|
||||
__COPY_ITEM(saIndex1InUse);
|
||||
__COPY_ITEM(enableAutoRekey);
|
||||
__COPY_ITEM(isActiveSa1);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSa; index++)
|
||||
{
|
||||
if(!source.sa[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sa[index].___name__ = source.sa[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.sa[index].___name__.data(), source.sa[index].___name__, dest.sa[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(sak);
|
||||
__COPY_ARR(hashKey);
|
||||
__COPY_ARR(salt);
|
||||
__COPY_ITEM(ssci);
|
||||
__COPY_ITEM(an);
|
||||
__COPY_ITEM(nextPn);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
};
|
||||
|
||||
msg->flags.en = macsecArgs->macsec.flags.en;
|
||||
copyConfig(macsecArgs->macsec.rx, msg->rx);
|
||||
copyConfig(macsecArgs->macsec.tx, msg->tx);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool MACsecMessage::EncodeFromMessage(std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) const
|
||||
{
|
||||
MACSEC_SETTINGS_W_HDR* macsecArgs;
|
||||
|
||||
bytestream.resize(sizeof(MACSEC_SETTINGS_W_HDR), 0);
|
||||
macsecArgs = (MACSEC_SETTINGS_W_HDR*)bytestream.data();
|
||||
|
||||
macsecArgs->version = MACSEC_SETTINGS_VERSION;
|
||||
macsecArgs->len = sizeof(MACSEC_SETTINGS_W_HDR);
|
||||
|
||||
const auto& copyConfig = [](const MACsecConfig& source, MACSEC_CONFIG& dest)
|
||||
{
|
||||
dest.flags.en = (uint8_t)source.flags.en;
|
||||
for (int index = 0; index < MACsecConfig::NumRules; index++)
|
||||
{
|
||||
if(!source.rule[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.rule[index].___name__ = (decltype(dest.rule[index].___name__))source.rule[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.rule[index].___name__, source.rule[index].___name__.data(), source.rule[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(keyMacDa);
|
||||
__COPY_ARR(maskMacDa);
|
||||
__COPY_ARR(keyMacSa);
|
||||
__COPY_ARR(maskMacSa);
|
||||
__COPY_ITEM(keyVlanTagOuter1.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter1.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter1.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter1.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter1.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter1.exp);
|
||||
__COPY_ITEM(keyVlanTagOuter2.vid);
|
||||
__COPY_ITEM(keyVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(keyMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(keyMplsOuter2.exp);
|
||||
__COPY_ITEM(maskVlanTagOuter2.vid);
|
||||
__COPY_ITEM(maskVlanTagOuter2.priCfi);
|
||||
__COPY_ITEM(maskMplsOuter2.mplsLabel);
|
||||
__COPY_ITEM(maskMplsOuter2.exp);
|
||||
__COPY_ITEM(keyEthertype);
|
||||
__COPY_ITEM(maskEthertype);
|
||||
__COPY_ITEM(keyBonusData);
|
||||
__COPY_ITEM(maskBonusData);
|
||||
__COPY_ITEM(keyTagMatchBitmap);
|
||||
__COPY_ITEM(maskTagMatchBitmap);
|
||||
__COPY_ITEM(keyPacketType);
|
||||
__COPY_ITEM(maskPacketType);
|
||||
__COPY_ITEM(keyInnerVlanType);
|
||||
__COPY_ITEM(maskInnerVlanType);
|
||||
__COPY_ITEM(keyOuterVlanType);
|
||||
__COPY_ITEM(maskOuterVlanType);
|
||||
__COPY_ITEM(keyNumTags);
|
||||
__COPY_ITEM(maskNumTags);
|
||||
__COPY_ITEM(keyExpress);
|
||||
__COPY_ITEM(maskExpress);
|
||||
__COPY_ITEM(isMpls);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumMaps; index++)
|
||||
{
|
||||
if(!source.map[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.map[index].___name__ = source.map[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secTagSci);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(isControlPacket);
|
||||
__COPY_ITEM(scIndex);
|
||||
__COPY_ITEM(auxiliaryPlcy);
|
||||
__COPY_ITEM(ruleId);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSecY; index++)
|
||||
{
|
||||
if(!source.secy[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.secy[index].___name__ = (decltype(dest.secy[index].___name__))source.secy[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(controlledPortEnabled);
|
||||
__COPY_ITEM(frameValidationType);
|
||||
__COPY_ITEM(secTagIcvStripType);
|
||||
__COPY_ITEM(cipher);
|
||||
__COPY_ITEM(confidentialOffset);
|
||||
__COPY_ITEM(icvIncludesDaSa);
|
||||
__COPY_ITEM(replayProtect);
|
||||
__COPY_ITEM(replayWindow);
|
||||
__COPY_ITEM(protectFrames);
|
||||
__COPY_ITEM(secTagOffset);
|
||||
__COPY_ITEM(secTagTci);
|
||||
__COPY_ITEM(mtu);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSc; index++)
|
||||
{
|
||||
if(!source.sc[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sc[index].___name__ = source.sc[index].___name__
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ITEM(secYIndex);
|
||||
__COPY_ITEM(sci);
|
||||
__COPY_ITEM(saIndex0);
|
||||
__COPY_ITEM(saIndex1);
|
||||
__COPY_ITEM(saIndex0InUse);
|
||||
__COPY_ITEM(saIndex1InUse);
|
||||
__COPY_ITEM(enableAutoRekey);
|
||||
__COPY_ITEM(isActiveSa1);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
|
||||
for (int index = 0; index < MACsecConfig::NumSa; index++)
|
||||
{
|
||||
if(!source.sa[index].enable) continue;
|
||||
#undef __COPY_ITEM
|
||||
#define __COPY_ITEM(___name__) dest.sa[index].___name__ = source.sa[index].___name__
|
||||
#undef __COPY_ARR
|
||||
#define __COPY_ARR(___name__) (void)memcpy(dest.sa[index].___name__, source.sa[index].___name__.data(), source.sa[index].___name__.size())
|
||||
__COPY_ITEM(index);
|
||||
__COPY_ARR(sak);
|
||||
__COPY_ARR(hashKey);
|
||||
__COPY_ARR(salt);
|
||||
__COPY_ITEM(ssci);
|
||||
__COPY_ITEM(an);
|
||||
__COPY_ITEM(nextPn);
|
||||
__COPY_ITEM(enable);
|
||||
}
|
||||
};
|
||||
macsecArgs->macsec.flags.en = this->flags.en;
|
||||
macsecArgs->macsec.flags.nvm = this->flags.nvm;
|
||||
|
||||
copyConfig(this->rx, macsecArgs->macsec.rx);
|
||||
copyConfig(this->tx, macsecArgs->macsec.tx);
|
||||
|
||||
macsecArgs->crc32 = crc32(0, (uint8_t*)&macsecArgs->macsec, sizeof(MACSEC_SETTINGS));
|
||||
|
||||
(void)report;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "icsneo/communication/message/neomessage.h"
|
||||
#include "icsneo/communication/message/canmessage.h"
|
||||
#include "icsneo/communication/message/ethernetmessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/linmessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
@@ -51,7 +51,7 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
||||
eth.status.incompleteFrame = ethmsg->frameTooShort;
|
||||
// TODO Fill in extra status bits
|
||||
//eth.status.xyz = ethmsg->preemptionEnabled;
|
||||
//eth.status.xyz = ethmsg->fcsAvailable;
|
||||
//eth.status.xyz = ethmsg->fcs;
|
||||
//eth.status.xyz = ethmsg->noPadding;
|
||||
break;
|
||||
}
|
||||
@@ -104,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<CANErrorCountMessage>(message);
|
||||
auto canerrormsg = std::static_pointer_cast<CANErrorMessage>(message);
|
||||
canerror.transmitErrorCount = canerrormsg->transmitErrorCount;
|
||||
canerror.receiveErrorCount = canerrormsg->receiveErrorCount;
|
||||
canerror.status.canBusOff = canerrormsg->busOff;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
@@ -53,16 +53,18 @@ 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();
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
// 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;
|
||||
|
||||
@@ -16,8 +16,8 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
||||
if(packet->Length < 4)
|
||||
return nullptr;
|
||||
|
||||
const size_t ethernetFrameSize = packet->Length - (sizeof(uint16_t) * 2);
|
||||
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + ethernetFrameSize;
|
||||
const size_t fcsSize = packet->header.FCS_AVAIL ? 4 : 0;
|
||||
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + packet->Length;
|
||||
const size_t bytestreamActualSize = bytestream.size();
|
||||
if(bytestreamActualSize < bytestreamExpectedSize)
|
||||
return nullptr;
|
||||
@@ -36,8 +36,6 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
||||
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)
|
||||
@@ -47,11 +45,14 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
||||
// Decoder will fix as it has information about the timestampResolution increments
|
||||
message.timestamp = packet->timestamp.TS;
|
||||
|
||||
// Network ID is also not set, this will be fixed in the Decoder as well
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
if(fcsSize) {
|
||||
uint32_t& fcs = message.fcs.emplace();
|
||||
std::copy(dataend, dataend + fcsSize, (uint8_t*)&fcs);
|
||||
}
|
||||
|
||||
return messagePtr;
|
||||
}
|
||||
|
||||
+115
-36
@@ -88,6 +88,10 @@ Device::~Device() {
|
||||
disableMessagePolling();
|
||||
if(isOpen())
|
||||
close();
|
||||
if(heartbeatThread.joinable()) {
|
||||
stopHeartbeatThread = true;
|
||||
heartbeatThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Device::getTimestampResolution() const {
|
||||
@@ -218,8 +222,7 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
if(block) // Extensions say no
|
||||
return false;
|
||||
|
||||
// Get component versions *after* the extension "onDeviceOpen" hooks (e.g. device reflashes)
|
||||
|
||||
// Get component versions again *after* the extension "onDeviceOpen" hooks (e.g. device reflashes)
|
||||
if(supportsComponentVersions()) {
|
||||
if(auto compVersions = com->getComponentVersionsSync())
|
||||
componentVersions = std::move(*compVersions);
|
||||
@@ -246,6 +249,12 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
handleInternalMessage(message);
|
||||
}));
|
||||
|
||||
// Clear the previous heartbeat thread, in case open() was called on this instance more than once
|
||||
if(heartbeatThread.joinable())
|
||||
heartbeatThread.join();
|
||||
|
||||
stopHeartbeatThread = false;
|
||||
|
||||
heartbeatThread = std::thread([this]() {
|
||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||
|
||||
@@ -271,12 +280,12 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
}
|
||||
|
||||
while(!stopHeartbeatThread) {
|
||||
// Wait for 110ms for a possible heartbeat
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(110));
|
||||
std::unique_lock<std::mutex> recvLk(receivedMessageMutex);
|
||||
if(receivedMessage) {
|
||||
// Wait for 110ms for a possible heartbeat
|
||||
if(heartbeatCV.wait_for(recvLk, std::chrono::milliseconds(110), [&]() { return receivedMessage; })) {
|
||||
receivedMessage = false;
|
||||
} else {
|
||||
} else if(!stopHeartbeatThread) { // Add this condition here in case the thread was stopped while waiting for the last message
|
||||
|
||||
// Some communication, such as the bootloader and extractor interfaces, must
|
||||
// redirect the input stream from the device as it will no longer be in the
|
||||
// packet format we expect here. As a result, status updates will not reach
|
||||
@@ -285,9 +294,8 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
// otherwise quiet stream. This lock makes sure suppressDisconnects() will
|
||||
// block until we've either gotten our status update or disconnected from
|
||||
// the device.
|
||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
||||
if(heartbeatSuppressed())
|
||||
continue;
|
||||
std::unique_lock<std::mutex> lk(heartbeatMutex);
|
||||
if(heartbeatSuppressed()) continue;
|
||||
|
||||
// No heartbeat received, request a status
|
||||
com->sendCommand(Command::RequestStatusUpdate);
|
||||
@@ -297,8 +305,8 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
||||
receivedMessage = false;
|
||||
} else {
|
||||
if(!stopHeartbeatThread && !isDisconnected()) {
|
||||
close();
|
||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||
com->driver->close();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -348,6 +356,15 @@ APIEvent::Type Device::attemptToBeginCommunication() {
|
||||
else
|
||||
versions = std::move(*maybeVersions);
|
||||
|
||||
|
||||
// Get component versions before the extension "onDeviceOpen" hooks so that we can properly check verisons
|
||||
if(supportsComponentVersions()) {
|
||||
if(auto compVersions = com->getComponentVersionsSync())
|
||||
componentVersions = std::move(*compVersions);
|
||||
else
|
||||
return getCommunicationNotEstablishedError();
|
||||
}
|
||||
|
||||
return APIEvent::Type::NoErrorFound;
|
||||
}
|
||||
|
||||
@@ -371,10 +388,6 @@ bool Device::close() {
|
||||
|
||||
internalHandlerCallbackID = 0;
|
||||
|
||||
if(heartbeatThread.joinable())
|
||||
heartbeatThread.join();
|
||||
stopHeartbeatThread = false;
|
||||
|
||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onDeviceClose(); return true; });
|
||||
return com->close();
|
||||
}
|
||||
@@ -806,12 +819,6 @@ std::shared_ptr<HardwareInfo> Device::getHardwareInfo(std::chrono::milliseconds
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!isOnline()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto filter = std::make_shared<MessageFilter>(Message::Type::HardwareInfo);
|
||||
|
||||
auto response = com->waitForMessageSync([this]() {
|
||||
@@ -1691,7 +1698,10 @@ void Device::stopScriptStatusThreadIfNecessary(std::unique_lock<std::mutex> lk)
|
||||
Lifetime Device::suppressDisconnects() {
|
||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
||||
heartbeatSuppressedByUser++;
|
||||
return Lifetime([this] { std::lock_guard<std::mutex> lk2(heartbeatMutex); heartbeatSuppressedByUser--; });
|
||||
return Lifetime([this] {
|
||||
std::lock_guard<std::mutex> lk2(heartbeatMutex);
|
||||
heartbeatSuppressedByUser--;
|
||||
});
|
||||
}
|
||||
|
||||
void Device::addExtension(std::shared_ptr<DeviceExtension>&& extension) {
|
||||
@@ -1721,15 +1731,6 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
||||
case Message::Type::RawMessage: {
|
||||
auto rawMessage = std::static_pointer_cast<RawMessage>(message);
|
||||
switch(rawMessage->network.getNetID()) {
|
||||
case Network::NetID::Device: {
|
||||
// Device is not guaranteed to be a CANMessage, it might be a RawMessage
|
||||
// if it couldn't be decoded to a CANMessage. We only care about the
|
||||
// CANMessage decoding right now.
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(canmsg)
|
||||
handleNeoVIMessage(std::move(canmsg));
|
||||
break;
|
||||
}
|
||||
case Network::NetID::DeviceStatus:
|
||||
// Device Status format is unique per device, so the devices need to decode it themselves
|
||||
handleDeviceStatus(rawMessage);
|
||||
@@ -1739,6 +1740,15 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Message::Type::Frame: {
|
||||
// Device is not guaranteed to be a CANMessage, it might be a RawMessage
|
||||
// if it couldn't be decoded to a CANMessage. We only care about the
|
||||
// CANMessage decoding right now.
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(canmsg)
|
||||
handleNeoVIMessage(std::move(canmsg));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
forEachExtension([&](const std::shared_ptr<DeviceExtension>& ext) {
|
||||
@@ -1951,7 +1961,7 @@ bool Device::setRTC(const std::chrono::time_point<std::chrono::system_clock>& ti
|
||||
}
|
||||
|
||||
auto m51msg = std::dynamic_pointer_cast<Main51Message>(generic);
|
||||
if(!m51msg || m51msg->data.size() != 1) {
|
||||
if(!m51msg || m51msg->data.empty() || m51msg->data.size() > 2) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
@@ -1984,11 +1994,6 @@ std::optional<size_t> Device::getGenericBinarySize(uint16_t binaryIndex) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(!isOnline()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> args = GenericBinaryStatusPacket::EncodeArguments(binaryIndex);
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
@@ -2051,6 +2056,40 @@ bool Device::readBinaryFile(std::ostream& stream, uint16_t binaryIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::writeBinaryFile(const std::vector<uint8_t>& in, uint16_t binaryIndex)
|
||||
{
|
||||
auto timeout = std::chrono::milliseconds(100);
|
||||
|
||||
auto size = in.size();
|
||||
|
||||
std::vector<uint8_t> arguments(sizeof(ExtendedDataMessage::ExtendedDataHeader) + ExtendedDataMessage::MaxExtendedDataBufferSize);
|
||||
ExtendedDataMessage::ExtendedDataHeader& parameters = *reinterpret_cast<ExtendedDataMessage::ExtendedDataHeader*>(arguments.data());
|
||||
|
||||
auto filter = std::make_shared<MessageFilter>(Network::NetID::ExtendedData);
|
||||
|
||||
for (size_t offset = 0; offset < size; offset += ExtendedDataMessage::MaxExtendedDataBufferSize)
|
||||
{
|
||||
parameters.subCommand = ExtendedDataSubCommand::GenericBinaryWrite;
|
||||
parameters.userValue = static_cast<uint32_t>(binaryIndex);
|
||||
parameters.offset = static_cast<uint32_t>(offset);
|
||||
parameters.length = static_cast<uint32_t>(std::min(ExtendedDataMessage::MaxExtendedDataBufferSize, size - offset));
|
||||
(void)memcpy(&arguments[sizeof(ExtendedDataMessage::ExtendedDataHeader)], &in[offset], parameters.length);
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this, arguments]() {
|
||||
return com->sendCommand(Command::ExtendedData, arguments);
|
||||
},
|
||||
filter,
|
||||
timeout
|
||||
);
|
||||
if (!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Device::subscribeLiveData(std::shared_ptr<LiveDataCommandMessage> message) {
|
||||
if(!supportsLiveData()) {
|
||||
report(APIEvent::Type::LiveDataNotSupported, APIEvent::Severity::Error);
|
||||
@@ -3335,3 +3374,43 @@ std::optional<TC10StatusMessage> Device::getTC10Status(Network::NetID network) {
|
||||
|
||||
return *typed;
|
||||
}
|
||||
|
||||
std::optional<GPTPStatus> Device::getGPTPStatus(std::chrono::milliseconds timeout) {
|
||||
if(!supportsGPTP()) {
|
||||
report(APIEvent::Type::GPTPNotSupported, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this](){
|
||||
return com->sendCommand(ExtendedCommand::GetGPTPStatus, {});
|
||||
},
|
||||
std::make_shared<MessageFilter>(Message::Type::GPTPStatus),
|
||||
timeout
|
||||
);
|
||||
|
||||
if(!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
auto retMsg = std::static_pointer_cast<GPTPStatus>(response);
|
||||
if(!retMsg) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return *retMsg;
|
||||
}
|
||||
|
||||
bool Device::writeMACsecConfig(const MACsecMessage& message, uint16_t binaryIndex)
|
||||
{
|
||||
std::vector<uint8_t> raw;
|
||||
|
||||
message.EncodeFromMessage(raw, report);
|
||||
|
||||
return writeBinaryFile(raw, binaryIndex);
|
||||
}
|
||||
|
||||
@@ -197,6 +197,10 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
makeIfSerialMatches<RADGalaxy>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY2_H_
|
||||
makeIfSerialMatches<RADGalaxy2>(dev, newFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_H_
|
||||
makeIfSerialMatches<RADMars>(dev, newFoundDevices);
|
||||
#endif
|
||||
@@ -352,6 +356,10 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
RADGalaxy::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY2_H_
|
||||
RADGalaxy2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_H_
|
||||
RADMars::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ subprocess.call('cd ..; doxygen docs/icsneoc/Doxyfile', shell=True)
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'libicsneo'
|
||||
copyright = '2024, Intrepid Control Systems, Inc.'
|
||||
copyright = '2024-2025, Intrepid Control Systems, Inc.'
|
||||
author = 'Intrepid Control Systems, Inc.'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
@@ -6,4 +6,5 @@ Python API
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
:imported-members:
|
||||
:special-members: __init__
|
||||
|
||||
@@ -50,3 +50,41 @@ Receive CAN frames on HSCAN
|
||||
|
||||
# rx for 10s
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
Monitor Ethernet Status
|
||||
=======================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import icsneopy
|
||||
import time
|
||||
|
||||
def main():
|
||||
devices = icsneopy.find_all_devices()
|
||||
if len(devices) == 0:
|
||||
print("error: no devices found")
|
||||
return False
|
||||
|
||||
device = devices[0]
|
||||
print(f"info: monitoring Ethernet status on {device}")
|
||||
|
||||
def on_message(message):
|
||||
print(f"info: network: {message.network}, state: {message.state}, speed: {message.speed}, duplex: {message.duplex}, mode: {message.mode}")
|
||||
|
||||
filter = icsneopy.MessageFilter(icsneopy.Message.Type.EthernetStatus)
|
||||
callback = icsneopy.MessageCallback(on_message, filter)
|
||||
device.add_message_callback(callback)
|
||||
|
||||
if not device.open():
|
||||
print("error: unable to open device")
|
||||
return False
|
||||
|
||||
if not device.go_online():
|
||||
print("error: unable to go online")
|
||||
return False
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
main()
|
||||
|
||||
+6
-1
@@ -1,9 +1,14 @@
|
||||
=========
|
||||
libicsneo
|
||||
=========
|
||||
|
||||
libicsneo is the `Intrepid Control Systems <https://intrepidcs.com/>`_ device
|
||||
communication library. The source code for libicsneo can be found on GitHub:
|
||||
`https://github.com/intrepidcs/libicsneo <https://github.com/intrepidcs/libicsneo>`_
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:caption: API Documentation
|
||||
:caption: Documentation
|
||||
|
||||
icsneocpp/index
|
||||
icsneopy/index
|
||||
|
||||
@@ -267,7 +267,7 @@ void printMessage(const std::shared_ptr<icsneo::Message>& message) {
|
||||
} // end of icsneo::Message::Type::Frame
|
||||
case icsneo::Message::Type::CANErrorCount: {
|
||||
// A message of type CANErrorCount is guaranteed to be a CANErrorCount, so we can static cast safely
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorCountMessage>(message);
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorMessage>(message);
|
||||
std::cout << "\t\t" << cec->network << " error counts changed, REC=" << cec->receiveErrorCount
|
||||
<< " TEC=" << cec->transmitErrorCount << " (" << (cec->busOff ? "" : "Not ") << "Bus Off)" << std::endl;
|
||||
break;
|
||||
|
||||
@@ -252,7 +252,7 @@ int main() {
|
||||
} // end of icsneo::Message::Type::Frame
|
||||
case icsneo::Message::Type::CANErrorCount: {
|
||||
// A message of type CANErrorCount is guaranteed to be a CANErrorCount, so we can static cast safely
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorCountMessage>(message);
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorMessage>(message);
|
||||
|
||||
// Print the error counts
|
||||
std::cout << "\t\t" << cec->network << " error counts changed, REC=" << std::to_string(cec->receiveErrorCount)
|
||||
|
||||
@@ -109,6 +109,7 @@ public:
|
||||
LINSettingsNotAvailable = 0x2053,
|
||||
ModeNotFound = 0x2054,
|
||||
AppErrorParsingFailed = 0x2055,
|
||||
GPTPNotSupported = 0x2056,
|
||||
|
||||
// Transport Events
|
||||
FailedToRead = 0x3000,
|
||||
|
||||
@@ -51,6 +51,7 @@ enum class ExtendedCommand : uint16_t {
|
||||
StartDHCPServer = 0x0016,
|
||||
StopDHCPServer = 0x0017,
|
||||
GetSupportedFeatures = 0x0018,
|
||||
GetGPTPStatus = 0x0019,
|
||||
GetComponentVersions = 0x001A,
|
||||
Reboot = 0x001C,
|
||||
SetRootFSEntryFlags = 0x0027,
|
||||
@@ -72,6 +73,7 @@ enum class ExtendedResponse : int32_t {
|
||||
|
||||
enum class ExtendedDataSubCommand : uint32_t {
|
||||
GenericBinaryRead = 13,
|
||||
GenericBinaryWrite = 14,
|
||||
};
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* crc32.h
|
||||
*
|
||||
* Created on: Jun 22, 2020
|
||||
* Author: BJones
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CRC32_H_
|
||||
#define CRC32_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* When any data/buffer is run through calCRC(), then the resulting CRC value
|
||||
* is appended to the end of the data/buffer and the data/buffer is rerun
|
||||
* through calCRC(), the result will be CRC32_IDENT
|
||||
*/
|
||||
#define CRC32_IDENT (0x2144DF1C) /**< CRC check value */
|
||||
|
||||
#define CRC32_ISVALID(crc) ((crc) == CRC32_IDENT)
|
||||
|
||||
uint32_t crc32(uint32_t crc, const unsigned char* buf, uint32_t len);
|
||||
uint32_t revcrc32(uint32_t crc, const unsigned char* buf, uint32_t len);
|
||||
|
||||
#endif // CRC32_H_
|
||||
@@ -1,25 +0,0 @@
|
||||
#ifndef __CANERRORCOUNTMESSAGE_H_
|
||||
#define __CANERRORCOUNTMESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class CANErrorCountMessage : public Message {
|
||||
public:
|
||||
CANErrorCountMessage(uint8_t tec, uint8_t rec, bool busOffFlag)
|
||||
: Message(Message::Type::CANErrorCount), transmitErrorCount(tec), receiveErrorCount(rec), busOff(busOffFlag){}
|
||||
|
||||
Network network;
|
||||
uint8_t transmitErrorCount;
|
||||
uint8_t receiveErrorCount;
|
||||
bool busOff;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef __CANERRORMESSAGE_H_
|
||||
#define __CANERRORMESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
enum class CANErrorCode : uint8_t
|
||||
{
|
||||
NoError = 0,
|
||||
StuffError = 1,
|
||||
FormError = 2,
|
||||
AckError = 3,
|
||||
Bit1Error = 4,
|
||||
Bit0Error = 5,
|
||||
CRCError = 6,
|
||||
NoChange = 7
|
||||
};
|
||||
class CANErrorMessage : public Message {
|
||||
public:
|
||||
CANErrorMessage() : Message(Type::CANError) {}
|
||||
Network network;
|
||||
uint8_t transmitErrorCount;
|
||||
uint8_t receiveErrorCount;
|
||||
bool busOff;
|
||||
bool errorPassive;
|
||||
bool errorWarn;
|
||||
CANErrorCode dataErrorCode;
|
||||
CANErrorCode errorCode;
|
||||
};
|
||||
|
||||
using CANErrorCountMessage = CANErrorMessage;
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -35,7 +35,7 @@ class EthernetMessage : public Frame {
|
||||
public:
|
||||
bool preemptionEnabled = false;
|
||||
uint8_t preemptionFlags = 0;
|
||||
bool fcsAvailable = false;
|
||||
std::optional<uint32_t> fcs;
|
||||
bool frameTooShort = false;
|
||||
bool noPadding = false;
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef __ETHERNETSTATUSMESSAGE_H__
|
||||
#define __ETHERNETSTATUSMESSAGE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class EthernetStatusMessage : public Message {
|
||||
public:
|
||||
enum class LinkSpeed {
|
||||
LinkSpeedAuto,
|
||||
LinkSpeed10,
|
||||
LinkSpeed100,
|
||||
LinkSpeed1000,
|
||||
LinkSpeed2500,
|
||||
LinkSpeed5000,
|
||||
LinkSpeed10000,
|
||||
};
|
||||
enum class LinkMode {
|
||||
LinkModeAuto,
|
||||
LinkModeMaster,
|
||||
LinkModeSlave,
|
||||
LinkModeInvalid,
|
||||
};
|
||||
EthernetStatusMessage(Network net, bool state, LinkSpeed speed, bool duplex, LinkMode mode) : Message(Type::EthernetStatus),
|
||||
network(net), state(state), speed(speed), duplex(duplex), mode(mode) {}
|
||||
Network network;
|
||||
bool state;
|
||||
LinkSpeed speed;
|
||||
bool duplex;
|
||||
LinkMode mode;
|
||||
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||
};
|
||||
|
||||
}; // namespace icsneo
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __ETHERNETSTATUSMESSAGE_H__
|
||||
@@ -0,0 +1,103 @@
|
||||
#ifndef __GPTPSTATUSMESSAGE_H_
|
||||
#define __GPTPSTATUSMESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class GPTPStatus : public Message {
|
||||
public:
|
||||
typedef uint64_t TimeInterval;
|
||||
typedef uint64_t ClockID;
|
||||
|
||||
struct Timestamp {
|
||||
uint64_t seconds;
|
||||
uint32_t nanoseconds;
|
||||
|
||||
double toSeconds() const {
|
||||
static constexpr double billion = 1e9;
|
||||
return (double)seconds + ((double)nanoseconds) / billion;
|
||||
}
|
||||
};
|
||||
|
||||
struct ScaledNanoSeconds {
|
||||
int16_t nanosecondsMSB; // The most significant bits
|
||||
int64_t nanosecondsLSB; // The least significant bits
|
||||
int16_t fractionalNanoseconds; // Fractional part
|
||||
};
|
||||
|
||||
struct PortID {
|
||||
ClockID clockIdentity;
|
||||
uint16_t portNumber;
|
||||
};
|
||||
struct ClockQuality {
|
||||
uint8_t clockClass;
|
||||
uint8_t clockAccuracy;
|
||||
uint16_t offsetScaledLogVariance;
|
||||
};
|
||||
|
||||
struct SystemID {
|
||||
uint8_t priority1;
|
||||
ClockQuality clockQuality;
|
||||
uint8_t priority2;
|
||||
ClockID clockID;
|
||||
};
|
||||
|
||||
struct PriorityVector {
|
||||
SystemID sysID;
|
||||
uint16_t stepsRemoved;
|
||||
PortID portID;
|
||||
uint16_t portNumber;
|
||||
};
|
||||
|
||||
struct ParentDS {
|
||||
PortID parentPortIdentity;
|
||||
int32_t cumulativeRateRatio;
|
||||
ClockID grandmasterIdentity;
|
||||
uint8_t gmClockQualityClockClass;
|
||||
uint8_t gmClockQualityClockAccuracy;
|
||||
uint16_t gmClockQualityOffsetScaledLogVariance;
|
||||
uint8_t gmPriority1;
|
||||
uint8_t gmPriority2;
|
||||
};
|
||||
|
||||
struct CurrentDS {
|
||||
uint16_t stepsRemoved;
|
||||
TimeInterval offsetFromMaster;
|
||||
ScaledNanoSeconds lastgmPhaseChange;
|
||||
double lastgmFreqChange;
|
||||
uint16_t gmTimeBaseIndicator;
|
||||
uint32_t gmChangeCount;
|
||||
uint32_t timeOfLastgmChangeEvent;
|
||||
uint32_t timeOfLastgmPhaseChangeEvent;
|
||||
uint32_t timeOfLastgmFreqChangeEvent;
|
||||
};
|
||||
|
||||
GPTPStatus() : Message(Message::Type::GPTPStatus) {}
|
||||
static std::shared_ptr<GPTPStatus> DecodeToMessage(std::vector<uint8_t>& bytes, const device_eventhandler_t& report);
|
||||
|
||||
Timestamp currentTime;
|
||||
PriorityVector gmPriority;
|
||||
int64_t msOffsetNs;
|
||||
uint8_t isSync;
|
||||
uint8_t linkStatus;
|
||||
int64_t linkDelayNS;
|
||||
uint8_t selectedRole;
|
||||
uint8_t asCapable;
|
||||
uint8_t isSyntonized;
|
||||
Timestamp lastRXSyncTS; // t2 in IEEE 1588-2019 Figure-16
|
||||
CurrentDS currentDS;
|
||||
ParentDS parentDS;
|
||||
|
||||
bool shortFormat = false; // Set to true if the above variables weren't set (some firmware versions do not contain all the above variables)
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,200 @@
|
||||
#ifndef __MACSECMESSAGE_H__
|
||||
#define __MACSECMESSAGE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
#include "icsneo/communication/packet.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <array>
|
||||
#include <cstring>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct MACsecVLANTag
|
||||
{
|
||||
uint16_t vid; /*!< 12 bits */
|
||||
uint8_t priCfi; /*!< PRI - 3 bits, CFI - 1bit */
|
||||
};
|
||||
|
||||
struct MACsecMPLSOuter
|
||||
{
|
||||
uint32_t mplsLabel; /*!< 20 bits */
|
||||
uint8_t exp; /*!< 3 bits */
|
||||
};
|
||||
|
||||
enum class MACsecPacketType : uint8_t
|
||||
{
|
||||
NoVLANOrMPLS = 0,
|
||||
SingleVLAN = 1,
|
||||
DualVLAN = 2,
|
||||
MPLS = 3,
|
||||
SingleVLANFollowedByMPLS = 4,
|
||||
DualVLANFollowedByMPLS = 5,
|
||||
Unsupported = 6,
|
||||
};
|
||||
|
||||
struct MACsecRule
|
||||
{
|
||||
uint8_t index;
|
||||
std::array<uint8_t, 6> keyMacDa; /*!< MAC DA field extracted from the packet */
|
||||
std::array<uint8_t, 6> maskMacDa; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
std::array<uint8_t, 6> keyMacSa; /*!< MAC SA field extracted from the packet */
|
||||
std::array<uint8_t, 6> maskMacSa; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t keyEthertype; /*!< First E-Type found in the packet that doesn't match one of the preconfigured custom tag. */
|
||||
uint16_t maskEthertype; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACsecVLANTag keyVlanTagOuter1; /*!< outermost/1st VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACsecMPLSOuter keyMplsOuter1;
|
||||
MACsecVLANTag maskVlanTagOuter1; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACsecMPLSOuter maskMplsOuter1;
|
||||
MACsecVLANTag keyVlanTagOuter2; /*!< 2nd outermost VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
|
||||
MACsecMPLSOuter keyMplsOuter2;
|
||||
MACsecVLANTag maskVlanTagOuter2; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACsecMPLSOuter maskMplsOuter2;
|
||||
uint16_t keyBonusData; /*!< 2 bytes of additional bonus data extracted from one of the custom tags. */
|
||||
uint16_t maskBonusData; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyTagMatchBitmap; /*!< 8 bits total. Maps 1 to 1 bitwise with the set of custom tags. (set bit[N]=1 if check Nth custom tag) */
|
||||
uint8_t maskTagMatchBitmap; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
MACsecPacketType keyPacketType; /*!< Encoded Packet Type, see MACSEC_PACKET_TYPE */
|
||||
uint8_t maskPacketType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t keyInnerVlanType; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the second outermost VLAN Tag. */
|
||||
uint16_t maskInnerVlanType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint16_t keyOuterVlanType; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the outermost VLAN Tag. */
|
||||
uint16_t maskOuterVlanType; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
uint8_t keyNumTags; /*!< 7 bits total. Number of VLAN/custom tags or MPLS lables detected. Ingress: before SecTag; Egress: total detected. Exclude MCS header tags. i.e. Bit 2: 2 tags/labels before SecTAG...Bit 6: 6 or more tags/labels before SecTAG. */
|
||||
uint8_t maskNumTags; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
bool keyExpress; /*!< 1 bits. Express packet. */
|
||||
uint8_t maskExpress; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
|
||||
bool isMpls;
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct MACsecMap
|
||||
{
|
||||
uint8_t index;
|
||||
uint64_t secTagSci; /*!< Identifies the SecTAG SCI for this Flow. */
|
||||
uint8_t secYIndex; /*!< index for entry in Egress secY Policy */
|
||||
bool isControlPacket; /*!< Identifies all packets matching this index lookup as control packets. */
|
||||
uint8_t scIndex; /*!< Identifies the SC for this Flow. */
|
||||
uint8_t auxiliaryPlcy; /*!< Auxiliary policy bits. */
|
||||
uint8_t ruleId; /*!< Identifies the Rule for this Flow. */
|
||||
bool enable;
|
||||
};
|
||||
|
||||
enum class MACsecValidateFrameType : uint8_t
|
||||
{
|
||||
Disabled = 0, /*!< Disable validation */
|
||||
Check = 1, /*!< Enable validation, do not discard invalid frames*/
|
||||
Strict = 2, /*!< Enable validation and discard invalid frames */
|
||||
NA = 3 /*!< No processing or accounting */
|
||||
};
|
||||
|
||||
enum class MACsecSecTagIcvStripType : uint8_t
|
||||
{
|
||||
StripBoth = 0, /*!< Strip both SecTag and ICV from packet */
|
||||
StripSecTagPreserveICV = 1,
|
||||
PreserveSecTagStripICV = 2, /*!< Preserve SecTag, Strip ICV */
|
||||
PreserveBoth = 3 /*!< Preserve both SecTag and ICV */
|
||||
};
|
||||
|
||||
enum class MACsecCipherSuiteType : uint8_t
|
||||
{
|
||||
GcmAes128 = 0,
|
||||
GcmAes256 = 1,
|
||||
GcmAes128Xpn = 2,
|
||||
GcmAes256Xpn = 3
|
||||
};
|
||||
|
||||
struct MACsecSecY
|
||||
{
|
||||
uint8_t index; /*!< Identifies the SecY for this Flow. */
|
||||
bool controlledPortEnabled; /*!< Enable (or disable) operation of the Controlled port associated with this SecY */
|
||||
MACsecValidateFrameType frameValidationType; /*!< see MACSEC_VALIDATEFRAME */
|
||||
MACsecSecTagIcvStripType secTagIcvStripType; /*!< see MACSEC_STRIP_SECTAG_ICV */
|
||||
MACsecCipherSuiteType cipher; /*!< Define the cipher suite to use for this SecY see MACSEC_CIPHER_SUITE */
|
||||
uint8_t confidentialOffset; /*!< Define the number of bytes that are unencrypted following the SecTag. */
|
||||
bool icvIncludesDaSa; /*!< When set, the outer DA/SA bytes are included in the authentication GHASH calculation */
|
||||
bool replayProtect; /*!< Enables Anti-Replay protection */
|
||||
uint32_t replayWindow; /*!< Unsigned value indicating the size of the anti-replay window. */
|
||||
bool protectFrames; /*!< 0 = do not encrypt or authenticate this packet; 1 = always Authenticate frame and if SecTag.TCI.E = 1 encrypt the packet as well. */
|
||||
uint8_t secTagOffset; /*!< Define the offset in bytes from either the start of the packet or a matching Etype depending on SecTag_Insertion_Mode. */
|
||||
uint8_t secTagTci; /*!< Tag Control Information excluding the AN field which originates from the SA Policy table */
|
||||
uint16_t mtu; /*!< Specifies the outgoing MTU for this SecY */
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct MACsecSc
|
||||
{
|
||||
uint8_t index; /*!< SC index. */
|
||||
uint8_t secYIndex; /*!< SecY associated with this packet. */
|
||||
uint64_t sci; /*!< The Secure Channel Identifier. */
|
||||
uint8_t saIndex0; /*!< Define the 1st SA to use */
|
||||
uint8_t saIndex1; /*!< Define the 2nd SA to use */
|
||||
bool saIndex0InUse; /*!< Specifies whether 1st SA is in use or not. */
|
||||
bool saIndex1InUse; /*!< Specifies whether 2nd SA is in use or not. */
|
||||
bool enableAutoRekey; /*!< If enabled, then once the pn_threshold is reached, auto rekey will happen. */
|
||||
bool isActiveSa1; /*!< If set, then sa_index1 is the currently active SA index. If cleared, the sa_index0 is the currently active SA index). */
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct MACsecSa
|
||||
{
|
||||
uint8_t index; /*!< SA index */
|
||||
std::array<uint8_t, 32> sak; /*!< 256b SAK: Define the encryption key to be used to encrypte this packet. The lower 128 bits are used for 128-bit ciphers. */
|
||||
std::array<uint8_t, 16> hashKey; /*!< 128b Hash Key: Key used for authentication. */
|
||||
std::array<uint8_t, 12> salt; /*!< 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. */
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct MACSecFlags
|
||||
{
|
||||
bool en; // '1' = enable; '0' = disable
|
||||
};
|
||||
|
||||
/* MACSec Settings for 1 port/phy */
|
||||
struct MACsecConfig
|
||||
{
|
||||
static constexpr int NumFlags = 1;
|
||||
static constexpr int NumRules = 2;
|
||||
static constexpr int NumMaps = 2;
|
||||
static constexpr int NumSecY = 2;
|
||||
static constexpr int NumSc = 2;
|
||||
static constexpr int NumSa = 4;
|
||||
|
||||
MACSecFlags flags;
|
||||
std::array<MACsecRule, NumRules> rule;
|
||||
std::array<MACsecMap, NumMaps> map;
|
||||
std::array<MACsecSecY, NumSecY> secy;
|
||||
std::array<MACsecSc, NumSc> sc;
|
||||
std::array<MACsecSa, NumSa> sa;
|
||||
};
|
||||
|
||||
struct MACSecGlobalFlags
|
||||
{
|
||||
bool en; // '1' = enable; '0' = disable
|
||||
bool nvm; // store macsec config in non-volatile memory
|
||||
};
|
||||
|
||||
class MACsecMessage : public Message
|
||||
{
|
||||
public:
|
||||
MACsecMessage(void) : Message(Message::Type::RawMessage) {}
|
||||
|
||||
MACSecGlobalFlags flags;
|
||||
MACsecConfig rx;
|
||||
MACsecConfig tx;
|
||||
|
||||
static std::shared_ptr<MACsecMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
||||
bool EncodeFromMessage(std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
Frame = 0,
|
||||
|
||||
CANErrorCount = 0x100,
|
||||
CANError = 0x100,
|
||||
|
||||
LINHeaderOnly = 0x200,
|
||||
LINBreak = 0x201,
|
||||
@@ -41,6 +42,8 @@ public:
|
||||
HardwareInfo = 0x8010,
|
||||
TC10Status = 0x8011,
|
||||
AppError = 0x8012,
|
||||
GPTPStatus = 0x8013,
|
||||
EthernetStatus = 0x8014,
|
||||
};
|
||||
|
||||
Message(Type t) : type(t) {}
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace icsneo {
|
||||
|
||||
typedef uint16_t icscm_bitfield;
|
||||
|
||||
#pragma pack(push,2)
|
||||
struct HardwareCANPacket {
|
||||
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||
static bool EncodeFromMessage(const CANMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
||||
@@ -50,6 +51,28 @@ struct HardwareCANPacket {
|
||||
uint64_t IsExtended : 1;
|
||||
} timestamp;
|
||||
};
|
||||
struct HardwareCANErrorPacket {
|
||||
uint8_t error_code;
|
||||
uint8_t brs_data_error_code;
|
||||
|
||||
uint16_t reserved;
|
||||
|
||||
uint16_t DLC : 4;
|
||||
uint16_t : 4;
|
||||
uint16_t ERROR_INDICATOR : 1;
|
||||
uint16_t : 7;
|
||||
|
||||
uint8_t flags;
|
||||
uint8_t REC;
|
||||
uint8_t TEC;
|
||||
|
||||
static bool GetErrorWarn(uint8_t flags) { return flags & 0b0000'0001; }
|
||||
static bool GetErrorPassive(uint8_t flags) { return flags & 0b0000'1000; }
|
||||
static bool GetBusOff(uint8_t flags) { return flags & 0b0010'0000; }
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
#pragma pack(push, 2)
|
||||
|
||||
typedef uint16_t icscm_bitfield;
|
||||
|
||||
struct HardwareEthernetPacket {
|
||||
@@ -42,6 +44,8 @@ struct HardwareEthernetPacket {
|
||||
uint16_t Length;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "icsneo/communication/message/extendeddatamessage.h"
|
||||
#include "icsneo/communication/message/livedatamessage.h"
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
#include "icsneo/communication/message/macsecmessage.h"
|
||||
#include "icsneo/communication/packet/genericbinarystatuspacket.h"
|
||||
#include "icsneo/communication/packet/livedatapacket.h"
|
||||
#include "icsneo/device/extensions/flexray/controller.h"
|
||||
@@ -50,6 +51,7 @@
|
||||
#include "icsneo/disk/vsa/vsa.h"
|
||||
#include "icsneo/disk/vsa/vsaparser.h"
|
||||
#include "icsneo/communication/message/versionmessage.h"
|
||||
#include "icsneo/communication/message/gptpstatusmessage.h"
|
||||
|
||||
|
||||
#define ICSNEO_FINDABLE_DEVICE_BASE(className, type) \
|
||||
@@ -623,6 +625,7 @@ public:
|
||||
|
||||
std::optional<size_t> getGenericBinarySize(uint16_t binaryIndex);
|
||||
bool readBinaryFile(std::ostream& stream, uint16_t binaryIndex);
|
||||
bool writeBinaryFile(const std::vector<uint8_t>& in, uint16_t binaryIndex);
|
||||
bool subscribeLiveData(std::shared_ptr<LiveDataCommandMessage> message);
|
||||
bool unsubscribeLiveData(const LiveDataHandle& handle);
|
||||
bool clearAllLiveData();
|
||||
@@ -727,12 +730,18 @@ public:
|
||||
virtual bool supportsComponentVersions() const { return false; }
|
||||
|
||||
virtual bool supportsTC10() const { return false; }
|
||||
|
||||
virtual bool supportsGPTP() const { return false; }
|
||||
|
||||
bool requestTC10Wake(Network::NetID network);
|
||||
|
||||
bool requestTC10Sleep(Network::NetID network);
|
||||
|
||||
std::optional<TC10StatusMessage> getTC10Status(Network::NetID network);
|
||||
std::optional<GPTPStatus> getGPTPStatus(std::chrono::milliseconds timeout = std::chrono::milliseconds(100));
|
||||
|
||||
/* MACsec support */
|
||||
virtual bool writeMACsecConfig(const MACsecMessage& message, uint16_t binaryIndex);
|
||||
|
||||
protected:
|
||||
bool online = false;
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
EtherBADGE = (0x00000016),
|
||||
RAD_A2B = (0x00000017),
|
||||
RADEpsilon = (0x00000018),
|
||||
RADGalaxy2 = (0x00000021),
|
||||
RADMoon3 = (0x00000023),
|
||||
RADComet = (0x00000024),
|
||||
FIRE3_FlexRay = (0x00000025),
|
||||
@@ -182,6 +183,8 @@ public:
|
||||
return "neoVI Flex";
|
||||
case RADGalaxy:
|
||||
return "RAD-Galaxy";
|
||||
case RADGalaxy2:
|
||||
return "RAD-Galaxy 2";
|
||||
case RADStar2:
|
||||
return "RAD-Star 2";
|
||||
case VividCAN:
|
||||
@@ -248,6 +251,7 @@ private:
|
||||
#define ICSNEO_DEVICETYPE_ETHERBADGE ((devicetype_t)0x00000016)
|
||||
#define ICSNEO_DEVICETYPE_RAD_A2B ((devicetype_t)0x00000017)
|
||||
#define ICSNEO_DEVICETYPE_RADEPSILON ((devicetype_t)0x00000018)
|
||||
#define ICSNEO_DEVICETYPE_RADGALAXY2 ((devicetype_t)0x00000021)
|
||||
#define ICSNEO_DEVICETYPE_RADMoon3 ((devicetype_t)0x00000023)
|
||||
#define ICSNEO_DEVICETYPE_RADCOMET ((devicetype_t)0x00000024)
|
||||
#define ICSNEO_DEVICETYPE_FIRE3FLEXRAY ((devicetype_t)0x00000025)
|
||||
|
||||
@@ -444,20 +444,21 @@ typedef struct LOGGER_SETTINGS_t
|
||||
#define RAD_GPTP_NUM_PORTS 1 // 1 because only supported as gPTP endpoint
|
||||
typedef struct RAD_GPTP_SETTINGS_t
|
||||
{
|
||||
uint32_t neighborPropDelayThresh;//ns
|
||||
uint32_t sys_phc_sync_interval;//ns
|
||||
int8_t logPDelayReqInterval;// log2ms
|
||||
int8_t logSyncInterval;// log2ms
|
||||
int8_t logAnnounceInterval;// log2ms
|
||||
uint32_t neighborPropDelayThresh; //ns
|
||||
uint32_t sys_phc_sync_interval; //ns
|
||||
int8_t logPDelayReqInterval; // log2ms
|
||||
int8_t logSyncInterval; // log2ms
|
||||
int8_t logAnnounceInterval; // log2ms
|
||||
uint8_t profile;
|
||||
uint8_t priority1;
|
||||
uint8_t clockclass;
|
||||
uint8_t clockaccuracy;
|
||||
uint8_t priority2;
|
||||
uint16_t offset_scaled_log_variance;
|
||||
uint8_t gPTPportRole[RAD_GPTP_NUM_PORTS];
|
||||
uint8_t portEnable[RAD_GPTP_NUM_PORTS];
|
||||
uint8_t rsvd[16];
|
||||
uint8_t gptpPortRole;
|
||||
uint8_t gptpEnabledPort;
|
||||
uint8_t enableClockSyntonization;
|
||||
uint8_t rsvd[15];
|
||||
} RAD_GPTP_SETTINGS;//36 Bytes with RAD_GPTP_NUM_PORTS = 1
|
||||
#define RAD_GPTP_SETTINGS_SIZE 36
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@ protected:
|
||||
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool supportsComponentVersions() const override { return true; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -79,6 +79,8 @@ protected:
|
||||
|
||||
bool supportsLiveData() const override { return true; }
|
||||
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
std::optional<MemoryAddress> getCoreminiStartAddressFlash() const override {
|
||||
return 33*1024*1024;
|
||||
}
|
||||
@@ -90,6 +92,7 @@ protected:
|
||||
bool supportsEraseMemory() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
}
|
||||
|
||||
bool supportsComponentVersions() const override { return true; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
NeoVIRED2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
}
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADA2B(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
@@ -77,6 +78,7 @@ protected:
|
||||
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
}
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
using Device::Device;
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
bool supportsTC10() const override { return true; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADComet3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
}
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADGalaxy(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#ifndef __RADGALAXY2_H_
|
||||
#define __RADGALAXY2_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/decoder.h"
|
||||
#include "icsneo/disk/extextractordiskreaddriver.h"
|
||||
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||
#include "icsneo/device/tree/radgalaxy2/radgalaxy2settings.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADGalaxy2 : public Device {
|
||||
public:
|
||||
// Serial numbers start with G2
|
||||
// Ethernet MAC allocation is 0x17, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(RADGalaxy2, DeviceType::RADGalaxy2, "G2");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::HSCAN,
|
||||
Network::NetID::MSCAN,
|
||||
Network::NetID::HSCAN2,
|
||||
Network::NetID::HSCAN3,
|
||||
Network::NetID::HSCAN4,
|
||||
Network::NetID::HSCAN5,
|
||||
Network::NetID::HSCAN6,
|
||||
Network::NetID::HSCAN7,
|
||||
|
||||
Network::NetID::LIN,
|
||||
Network::NetID::LIN2,
|
||||
|
||||
Network::NetID::Ethernet,
|
||||
Network::NetID::Ethernet2,
|
||||
Network::NetID::Ethernet3,
|
||||
|
||||
Network::NetID::OP_Ethernet1,
|
||||
Network::NetID::OP_Ethernet2,
|
||||
Network::NetID::OP_Ethernet3,
|
||||
Network::NetID::OP_Ethernet4,
|
||||
Network::NetID::OP_Ethernet5,
|
||||
Network::NetID::OP_Ethernet6,
|
||||
Network::NetID::OP_Ethernet7,
|
||||
Network::NetID::OP_Ethernet8,
|
||||
Network::NetID::OP_Ethernet9,
|
||||
Network::NetID::OP_Ethernet10,
|
||||
Network::NetID::OP_Ethernet11,
|
||||
Network::NetID::OP_Ethernet12,
|
||||
|
||||
Network::NetID::ISO9141,
|
||||
Network::NetID::ISO9141_2,
|
||||
|
||||
Network::NetID::MDIO1,
|
||||
Network::NetID::MDIO2,
|
||||
Network::NetID::MDIO3,
|
||||
Network::NetID::MDIO4,
|
||||
Network::NetID::MDIO5,
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
|
||||
bool supportsTC10() const override { return true; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADGalaxy2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADGalaxy2Settings, Disk::ExtExtractorDiskReadDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
Device::setupPacketizer(packetizer);
|
||||
packetizer.disableChecksum = true;
|
||||
packetizer.align16bit = false;
|
||||
}
|
||||
|
||||
void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportCANFD = true;
|
||||
encoder.supportEthPhy = true;
|
||||
}
|
||||
|
||||
void setupDecoder(Decoder& decoder) override {
|
||||
Device::setupDecoder(decoder);
|
||||
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||
}
|
||||
|
||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
for(auto& netid : GetSupportedNetworks())
|
||||
rxNetworks.emplace_back(netid);
|
||||
}
|
||||
|
||||
// The supported TX networks are the same as the supported RX networks for this device
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
void handleDeviceStatus(const std::shared_ptr<RawMessage>& message) override {
|
||||
if(message->data.size() < sizeof(radgalaxy2_status_t))
|
||||
return;
|
||||
std::lock_guard<std::mutex> lk(ioMutex);
|
||||
const radgalaxy2_status_t* status = reinterpret_cast<const radgalaxy2_status_t*>(message->data.data());
|
||||
ethActivationStatus = status->ethernetActivationLineEnabled;
|
||||
}
|
||||
|
||||
std::optional<MemoryAddress> getCoreminiStartAddressFlash() const override {
|
||||
return 512*4;
|
||||
}
|
||||
|
||||
std::optional<MemoryAddress> getCoreminiStartAddressSD() const override {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,192 @@
|
||||
#ifndef __RADGALAXY2SETTINGS_H_
|
||||
#define __RADGALAXY2SETTINGS_H_
|
||||
|
||||
#include "icsneo/device/idevicesettings.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 2)
|
||||
|
||||
typedef struct {
|
||||
uint32_t ecu_id;
|
||||
uint16_t perf_en;
|
||||
|
||||
/* CAN */
|
||||
CAN_SETTINGS can1;
|
||||
CANFD_SETTINGS canfd1;
|
||||
CAN_SETTINGS can2;
|
||||
CANFD_SETTINGS canfd2;
|
||||
CAN_SETTINGS can3;
|
||||
CANFD_SETTINGS canfd3;
|
||||
CAN_SETTINGS can4;
|
||||
CANFD_SETTINGS canfd4;
|
||||
CAN_SETTINGS can5;
|
||||
CANFD_SETTINGS canfd5;
|
||||
CAN_SETTINGS can6;
|
||||
CANFD_SETTINGS canfd6;
|
||||
CAN_SETTINGS can7;
|
||||
CANFD_SETTINGS canfd7;
|
||||
CAN_SETTINGS can8;
|
||||
CANFD_SETTINGS canfd8;
|
||||
|
||||
// SWCAN_SETTINGS swcan1; G2 does not have SWCAN.
|
||||
uint16_t network_enables;
|
||||
// SWCAN_SETTINGS swcan2; G2 does not have SWCAN.
|
||||
uint16_t network_enables_2;
|
||||
|
||||
uint32_t pwr_man_timeout;
|
||||
uint16_t pwr_man_enable;
|
||||
|
||||
uint16_t network_enabled_on_boot;
|
||||
|
||||
/* ISO15765-2 Transport Layer */
|
||||
uint16_t iso15765_separation_time_offset;
|
||||
|
||||
/* ISO9141 - Keyword */
|
||||
uint16_t iso_9141_kwp_enable_reserved;
|
||||
ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_1;
|
||||
uint16_t iso_parity_1;
|
||||
|
||||
uint16_t iso_msg_termination_1;
|
||||
|
||||
uint16_t idle_wakeup_network_enables_1;
|
||||
uint16_t idle_wakeup_network_enables_2;
|
||||
|
||||
/* reserved for T1 networks such as BR1, BR2, etc.. */
|
||||
uint16_t network_enables_3;
|
||||
uint16_t idle_wakeup_network_enables_3;
|
||||
|
||||
STextAPISettings text_api;
|
||||
|
||||
uint64_t termination_enables; // New feature unlike Galaxy.
|
||||
|
||||
TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings;
|
||||
struct
|
||||
{
|
||||
uint16_t hwComLatencyTestEn : 1;
|
||||
uint16_t reserved : 15;
|
||||
} flags;
|
||||
|
||||
LIN_SETTINGS lin1;
|
||||
|
||||
OP_ETH_GENERAL_SETTINGS opEthGen;
|
||||
OP_ETH_SETTINGS opEth1;
|
||||
OP_ETH_SETTINGS opEth2;
|
||||
OP_ETH_SETTINGS opEth3;
|
||||
OP_ETH_SETTINGS opEth4;
|
||||
OP_ETH_SETTINGS opEth5;
|
||||
OP_ETH_SETTINGS opEth6;
|
||||
OP_ETH_SETTINGS opEth7;
|
||||
OP_ETH_SETTINGS opEth8;
|
||||
OP_ETH_SETTINGS opEth9;
|
||||
OP_ETH_SETTINGS opEth10;
|
||||
OP_ETH_SETTINGS opEth11;
|
||||
OP_ETH_SETTINGS opEth12;
|
||||
OP_ETH_SETTINGS opEth13;
|
||||
OP_ETH_SETTINGS opEth14;
|
||||
OP_ETH_SETTINGS opEth15;
|
||||
OP_ETH_SETTINGS opEth16;
|
||||
|
||||
ETHERNET10G_SETTINGS ethernet10g;
|
||||
ETHERNET10G_SETTINGS ethernet10g_2;
|
||||
ETHERNET10G_SETTINGS ethernet10g_3;
|
||||
|
||||
uint16_t network_enables_4;
|
||||
RAD_REPORTING_SETTINGS reporting;
|
||||
RAD_GPTP_SETTINGS gPTP;
|
||||
|
||||
uint64_t network_enables_5;
|
||||
|
||||
LIN_SETTINGS lin2;
|
||||
} radgalaxy2_settings_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t unused[3];
|
||||
uint8_t ethernetActivationLineEnabled;
|
||||
} radgalaxy2_status_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class RADGalaxy2Settings : public IDeviceSettings {
|
||||
public:
|
||||
RADGalaxy2Settings(std::shared_ptr<Communication> com) : IDeviceSettings(com, sizeof(radgalaxy2_settings_t)) {}
|
||||
const CAN_SETTINGS* getCANSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radgalaxy2_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::HSCAN:
|
||||
return &(cfg->can1);
|
||||
case Network::NetID::MSCAN:
|
||||
return &(cfg->can2);
|
||||
case Network::NetID::HSCAN2:
|
||||
return &(cfg->can3);
|
||||
case Network::NetID::HSCAN3:
|
||||
return &(cfg->can4);
|
||||
case Network::NetID::HSCAN4:
|
||||
return &(cfg->can5);
|
||||
case Network::NetID::HSCAN5:
|
||||
return &(cfg->can6);
|
||||
case Network::NetID::HSCAN6:
|
||||
return &(cfg->can7);
|
||||
case Network::NetID::HSCAN7:
|
||||
return &(cfg->can8);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
const CANFD_SETTINGS* getCANFDSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radgalaxy2_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::HSCAN:
|
||||
return &(cfg->canfd1);
|
||||
case Network::NetID::MSCAN:
|
||||
return &(cfg->canfd2);
|
||||
case Network::NetID::HSCAN2:
|
||||
return &(cfg->canfd3);
|
||||
case Network::NetID::HSCAN3:
|
||||
return &(cfg->canfd4);
|
||||
case Network::NetID::HSCAN4:
|
||||
return &(cfg->canfd5);
|
||||
case Network::NetID::HSCAN5:
|
||||
return &(cfg->canfd6);
|
||||
case Network::NetID::HSCAN6:
|
||||
return &(cfg->canfd7);
|
||||
case Network::NetID::HSCAN7:
|
||||
return &(cfg->canfd8);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const LIN_SETTINGS* getLINSettingsFor(Network net) const override {
|
||||
auto cfg = getStructurePointer<radgalaxy2_settings_t>();
|
||||
if(cfg == nullptr)
|
||||
return nullptr;
|
||||
switch(net.getNetID()) {
|
||||
case Network::NetID::LIN:
|
||||
return &(cfg->lin1);
|
||||
case Network::NetID::LIN2:
|
||||
return &(cfg->lin2);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
@@ -22,10 +22,11 @@ public:
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
bool supportsTC10() const override { return true; }
|
||||
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADGigastar(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADGigastarSettings>(makeDriver);
|
||||
initialize<RADGigastarSettings, Disk::ExtExtractorDiskReadDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
|
||||
@@ -76,7 +76,8 @@ namespace icsneo
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
bool supportsTC10() const override { return true; }
|
||||
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADGigastar2(neodevice_t neodevice, const driver_factory_t &makeDriver) : Device(neodevice)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
ICSNEO_FINDABLE_DEVICE(RADMars, DeviceType::RADMars, "GL");
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
bool supportsGPTP() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADMars(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
|
||||
@@ -29,6 +29,8 @@ public:
|
||||
|
||||
bool supportsComponentVersions() const override { return true; }
|
||||
|
||||
bool supportsTC10() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADMoon3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADMoon3Settings>(makeDriver);
|
||||
|
||||
@@ -220,7 +220,7 @@ typedef unsigned __int64 uint64_t;
|
||||
#define NEODEVICE_RADEPSILON_EXPRESS (0x0000001d)
|
||||
#define NEODEVICE_RADPROXIMA (0x0000001e)
|
||||
#define NEODEVICE_NEW_DEVICE_58 (0x0000001f)
|
||||
#define NEODEVICE_NEW_DEVICE_59 (0x00000021)
|
||||
#define NEODEVICE_RAD_GALAXY_2 (0x00000021)
|
||||
#define NEODEVICE_RAD_BMS (0x00000022)
|
||||
#define NEODEVICE_RADMOON3 (0x00000023)
|
||||
#define NEODEVICE_RADCOMET (0x00000024)
|
||||
@@ -2999,6 +2999,100 @@ typedef struct _SRADGigastarSettings
|
||||
|
||||
#define SRADGigastarSettings_SIZE 710
|
||||
|
||||
typedef struct _SRADGalaxy2Settings
|
||||
{
|
||||
uint32_t ecu_id;
|
||||
uint16_t perf_en;
|
||||
|
||||
/* CAN */
|
||||
CAN_SETTINGS can1;
|
||||
CANFD_SETTINGS canfd1;
|
||||
CAN_SETTINGS can2;
|
||||
CANFD_SETTINGS canfd2;
|
||||
CAN_SETTINGS can3;
|
||||
CANFD_SETTINGS canfd3;
|
||||
CAN_SETTINGS can4;
|
||||
CANFD_SETTINGS canfd4;
|
||||
CAN_SETTINGS can5;
|
||||
CANFD_SETTINGS canfd5;
|
||||
CAN_SETTINGS can6;
|
||||
CANFD_SETTINGS canfd6;
|
||||
CAN_SETTINGS can7;
|
||||
CANFD_SETTINGS canfd7;
|
||||
CAN_SETTINGS can8;
|
||||
CANFD_SETTINGS canfd8;
|
||||
|
||||
// SWCAN_SETTINGS swcan1; G2 does not have SWCAN.
|
||||
uint16_t network_enables;
|
||||
// SWCAN_SETTINGS swcan2; G2 does not have SWCAN.
|
||||
uint16_t network_enables_2;
|
||||
|
||||
uint32_t pwr_man_timeout;
|
||||
uint16_t pwr_man_enable;
|
||||
|
||||
uint16_t network_enabled_on_boot;
|
||||
|
||||
/* ISO15765-2 Transport Layer */
|
||||
uint16_t iso15765_separation_time_offset;
|
||||
|
||||
/* ISO9141 - Keyword */
|
||||
uint16_t iso_9141_kwp_enable_reserved;
|
||||
ISO9141_KEYWORD2000_SETTINGS iso9141_kwp_settings_1;
|
||||
uint16_t iso_parity_1;
|
||||
|
||||
uint16_t iso_msg_termination_1;
|
||||
|
||||
uint16_t idle_wakeup_network_enables_1;
|
||||
uint16_t idle_wakeup_network_enables_2;
|
||||
|
||||
/* reserved for T1 networks such as BR1, BR2, etc.. */
|
||||
uint16_t network_enables_3;
|
||||
uint16_t idle_wakeup_network_enables_3;
|
||||
|
||||
STextAPISettings text_api;
|
||||
|
||||
uint64_t termination_enables; // New feature unlike Galaxy.
|
||||
|
||||
TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings;
|
||||
struct
|
||||
{
|
||||
uint16_t hwComLatencyTestEn : 1;
|
||||
uint16_t reserved : 15;
|
||||
} flags;
|
||||
|
||||
LIN_SETTINGS lin1;
|
||||
|
||||
OP_ETH_GENERAL_SETTINGS opEthGen;
|
||||
OP_ETH_SETTINGS opEth1;
|
||||
OP_ETH_SETTINGS opEth2;
|
||||
OP_ETH_SETTINGS opEth3;
|
||||
OP_ETH_SETTINGS opEth4;
|
||||
OP_ETH_SETTINGS opEth5;
|
||||
OP_ETH_SETTINGS opEth6;
|
||||
OP_ETH_SETTINGS opEth7;
|
||||
OP_ETH_SETTINGS opEth8;
|
||||
OP_ETH_SETTINGS opEth9;
|
||||
OP_ETH_SETTINGS opEth10;
|
||||
OP_ETH_SETTINGS opEth11;
|
||||
OP_ETH_SETTINGS opEth12;
|
||||
OP_ETH_SETTINGS opEth13;
|
||||
OP_ETH_SETTINGS opEth14;
|
||||
OP_ETH_SETTINGS opEth15;
|
||||
OP_ETH_SETTINGS opEth16;
|
||||
|
||||
ETHERNET10G_SETTINGS ethernet10g;
|
||||
ETHERNET10G_SETTINGS ethernet10g_2;
|
||||
ETHERNET10G_SETTINGS ethernet10g_3;
|
||||
|
||||
uint16_t network_enables_4;
|
||||
RAD_REPORTING_SETTINGS reporting;
|
||||
RAD_GPTP_SETTINGS gPTP;
|
||||
|
||||
uint64_t network_enables_5;
|
||||
LIN_SETTINGS lin2;
|
||||
} SRADGalaxy2Settings;
|
||||
#define SRADGalaxy2Settings_SIZE 840
|
||||
|
||||
typedef struct _SVividCANSettings
|
||||
{
|
||||
uint32_t ecu_id;
|
||||
@@ -5425,6 +5519,7 @@ CHECK_STRUCT_SIZE(SPendantSettings);
|
||||
CHECK_STRUCT_SIZE(SIEVBSettings);
|
||||
CHECK_STRUCT_SIZE(SEEVBSettings);
|
||||
CHECK_STRUCT_SIZE(SRADGalaxySettings);
|
||||
CHECK_STRUCT_SIZE(SRADGalaxy2Settings);
|
||||
CHECK_STRUCT_SIZE(SRADStar2Settings);
|
||||
CHECK_STRUCT_SIZE(SOBD2SimSettings)
|
||||
CHECK_STRUCT_SIZE(CmProbeSettings);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "icsneo/communication/message/ethernetmessage.h"
|
||||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
||||
#include "icsneo/communication/message/iso9141message.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/ethphymessage.h"
|
||||
#include "icsneo/communication/message/i2cmessage.h"
|
||||
#include "icsneo/communication/message/a2bmessage.h"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "icsneo/device/tree/radmoont1s/radmoont1s.h"
|
||||
#include "icsneo/device/tree/radepsilon/radepsilon.h"
|
||||
#include "icsneo/device/tree/radgalaxy/radgalaxy.h"
|
||||
#include "icsneo/device/tree/radgalaxy2/radgalaxy2.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastar.h"
|
||||
#include "icsneo/device/tree/radgigastar2/radgigastar2.h"
|
||||
#include "icsneo/device/tree/radjupiter/radjupiter.h"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "icsneo/device/tree/radmoont1s/radmoont1s.h"
|
||||
#include "icsneo/device/tree/radepsilon/radepsilon.h"
|
||||
#include "icsneo/device/tree/radgalaxy/radgalaxy.h"
|
||||
#include "icsneo/device/tree/radgalaxy2/radgalaxy2.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastar.h"
|
||||
#include "icsneo/device/tree/radgigastar2/radgigastar2.h"
|
||||
#include "icsneo/device/tree/radjupiter/radjupiter.h"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef __WINDOWS_STRINGS_H__
|
||||
#define __WINDOWS_STRINGS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
// Helper function to convert UTF-16 to UTF-8 strings (wide to standard)
|
||||
std::string convertWideString(const std::wstring& value);
|
||||
|
||||
// Helper function to convert UTF-8 to UTF-16 strings (standard to wide)
|
||||
std::wstring convertStringToWide(const std::string& value);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __WINDOWS_STRINGS_H__
|
||||
@@ -95,6 +95,8 @@ bool FTD3XX::close() {
|
||||
addEvent(ret, APIEvent::Severity::EventWarning);
|
||||
}
|
||||
|
||||
handle.reset();
|
||||
|
||||
setIsClosing(false);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -88,6 +88,21 @@ void TCP::Socket::poll(uint16_t event, uint32_t msTimeout) {
|
||||
}
|
||||
|
||||
void TCP::Find(std::vector<FoundDevice>& found) {
|
||||
static const auto tcpDisabled = []() -> bool {
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
const auto disabled = std::getenv("LIBICSNEO_DISABLE_TCP");
|
||||
return disabled ? std::stoi(disabled) : false;
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
};
|
||||
if(tcpDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
static const auto MDNS_PORT = htons((unsigned short)5353);
|
||||
static const auto MDNS_IP = htonl((((uint32_t)224U) << 24U) | ((uint32_t)251U));
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <winsock2.h>
|
||||
|
||||
#include "icsneo/platform/windows/pcap.h"
|
||||
#include "icsneo/platform/windows/strings.h"
|
||||
#include "icsneo/communication/network.h"
|
||||
#include "icsneo/communication/communication.h"
|
||||
#include "icsneo/communication/ethernetpacketizer.h"
|
||||
@@ -11,14 +12,12 @@
|
||||
#include <pcap.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
#include <codecvt>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
|
||||
std::vector<PCAP::NetworkInterface> PCAP::knownInterfaces;
|
||||
|
||||
@@ -80,8 +79,8 @@ void PCAP::Find(std::vector<FoundDevice>& found) {
|
||||
|
||||
memcpy(iface.macAddress, aa->PhysicalAddress, sizeof(iface.macAddress));
|
||||
iface.nameFromWin32API = aa->AdapterName;
|
||||
iface.descriptionFromWin32API = converter.to_bytes(aa->Description);
|
||||
iface.friendlyNameFromWin32API = converter.to_bytes(aa->FriendlyName);
|
||||
iface.descriptionFromWin32API = convertWideString(aa->Description);
|
||||
iface.friendlyNameFromWin32API = convertWideString(aa->FriendlyName);
|
||||
if(iface.descriptionFromWin32API.find("LAN9512/LAN9514") != std::string::npos) {
|
||||
// This is an Ethernet EVB device
|
||||
iface.fullName = "Intrepid Ethernet EVB ( " + iface.friendlyNameFromWin32API + " : " + iface.descriptionFromWin32API + " )";
|
||||
@@ -187,7 +186,7 @@ bool PCAP::IsHandleValid(neodevice_handle_t handle) {
|
||||
return (netifIndex < knownInterfaces.size());
|
||||
}
|
||||
|
||||
PCAP::PCAP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice), pcap(PCAPDLL::getInstance()), ethPacketizer(err) {
|
||||
PCAP::PCAP(const device_eventhandler_t& eventHandler, neodevice_t& forDevice) : Driver(eventHandler), pcap(PCAPDLL::getInstance()), device(forDevice), ethPacketizer(eventHandler) {
|
||||
if(IsHandleValid(device.handle)) {
|
||||
iface = knownInterfaces[(device.handle >> 24) & 0xFF];
|
||||
iface.fp = nullptr; // We're going to open our own connection to the interface. This should already be nullptr but just in case.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "icsneo/platform/windows/registry.h"
|
||||
#include "icsneo/platform/windows/strings.h"
|
||||
#include "icsneo/platform/windows.h"
|
||||
#include <codecvt>
|
||||
#include <vector>
|
||||
@@ -6,8 +7,6 @@
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
|
||||
class Key {
|
||||
public:
|
||||
Key(std::wstring path, bool readwrite = false);
|
||||
@@ -95,8 +94,8 @@ bool Registry::Get(std::wstring path, std::wstring key, std::wstring& value) {
|
||||
|
||||
bool Registry::Get(std::string path, std::string key, std::string& value) {
|
||||
std::wstring wvalue;
|
||||
bool ret = Get(converter.from_bytes(path), converter.from_bytes(key), wvalue);
|
||||
value = converter.to_bytes(wvalue);
|
||||
bool ret = Get(convertStringToWide(path), convertStringToWide(key), wvalue);
|
||||
value = convertWideString(wvalue);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -116,5 +115,5 @@ bool Registry::Get(std::wstring path, std::wstring key, uint32_t& value) {
|
||||
}
|
||||
|
||||
bool Registry::Get(std::string path, std::string key, uint32_t& value) {
|
||||
return Get(converter.from_bytes(path), converter.from_bytes(key), value);
|
||||
return Get(convertStringToWide(path), convertStringToWide(key), value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
|
||||
#include <icsneo/platform/windows/strings.h>
|
||||
|
||||
// Helper function to convert UTF-16 to UTF-8 strings (wide to standard)
|
||||
std::string icsneo::convertWideString(const std::wstring& value) {
|
||||
// Get the width of the string (character count)
|
||||
int width = WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)value.c_str(), -1, 0, 0, NULL, NULL);
|
||||
// Create the new string
|
||||
std::string new_string(width+1, '\0');
|
||||
// fill the new string with the converted characters
|
||||
WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)value.c_str(), -1, new_string.data(), width, NULL, NULL);
|
||||
return new_string;
|
||||
};
|
||||
|
||||
// Helper function to convert UTF-8 to UTF-16 strings (standard to wide)
|
||||
std::wstring icsneo::convertStringToWide(const std::string& value) {
|
||||
// Get the width of the string (character count)
|
||||
int width = MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, NULL, 0);
|
||||
// Create the new string
|
||||
std::wstring new_string(width+1, '\0');
|
||||
// fill the new string with the converted characters
|
||||
MultiByteToWideChar(CP_UTF8, 0, value.c_str(), -1, (LPWSTR)new_string.data(), width);
|
||||
return new_string;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "icsneo/platform/windows/ftdi.h"
|
||||
#include "icsneo/platform/windows/strings.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#include "icsneo/platform/registry.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
@@ -15,7 +16,6 @@
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
static const std::wstring DRIVER_SERVICES_REG_KEY = L"SYSTEM\\CurrentControlSet\\services\\";
|
||||
static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\";
|
||||
static constexpr unsigned int RETRY_TIMES = 5;
|
||||
@@ -95,7 +95,7 @@ void VCP::Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driver
|
||||
if(!device.productId)
|
||||
continue;
|
||||
|
||||
std::string serial = converter.to_bytes(oss.str());
|
||||
std::string serial = convertWideString(oss.str());
|
||||
// The serial number should not have a path slash in it. If it does, that means we don't have the real serial.
|
||||
if(serial.find_first_of('\\') != std::string::npos) {
|
||||
// The serial number was not in the first serenum key where we expected it.
|
||||
@@ -142,12 +142,12 @@ void VCP::Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driver
|
||||
// This is a device with characters in the serial number
|
||||
if(correctSerial.size() != 6)
|
||||
continue;
|
||||
serial = converter.to_bytes(correctSerial);
|
||||
serial = convertWideString(correctSerial);
|
||||
}
|
||||
else {
|
||||
std::wstringstream soss;
|
||||
soss << sn;
|
||||
serial = converter.to_bytes(soss.str());
|
||||
serial = convertWideString(soss.str());
|
||||
}
|
||||
|
||||
if(serial.find_first_of('\\') != std::string::npos)
|
||||
|
||||
+5
-1
@@ -1,5 +1,5 @@
|
||||
[build-system]
|
||||
requires = ["scikit-build-core", "pybind11", "setuptools>=64", "setuptools-scm>=8"]
|
||||
requires = ["scikit-build-core", "pybind11", "setuptools>=64", "setuptools-scm>=8", "mypy"]
|
||||
build-backend = "scikit_build_core.build"
|
||||
|
||||
[project]
|
||||
@@ -47,3 +47,7 @@ local_scheme = "no-local-version"
|
||||
[tool.scikit-build.cmake.define]
|
||||
LIBICSNEO_ENABLE_BINDINGS_PYTHON = true
|
||||
LIBICSNEO_ENABLE_TCP = true
|
||||
CMAKE_MSVC_RUNTIME_LIBRARY = "MultiThreaded"
|
||||
|
||||
[tool.cibuildwheel]
|
||||
skip = "pp*"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <icsneo/platform/windows/strings.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST(WindowsUtilTest, testConvertWideString) {
|
||||
#ifdef WIN32
|
||||
std::wstring wideString(L"Hello World!");
|
||||
auto normalString = icsneo::convertWideString(wideString);
|
||||
|
||||
ASSERT_STREQ(normalString.c_str(), "Hello World!");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(WindowsUtilTest, testConvertStringToWide) {
|
||||
#ifdef WIN32
|
||||
std::string normalString("Hello World!");
|
||||
auto wideString = icsneo::convertStringToWide(normalString);
|
||||
|
||||
ASSERT_STREQ(wideString.c_str(), L"Hello World!");
|
||||
#endif
|
||||
}
|
||||
+1
-1
@@ -55,7 +55,7 @@
|
||||
#include <io.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
#include "IP6_misc.h"
|
||||
#include "ip6_misc.h"
|
||||
#endif
|
||||
|
||||
#define caddr_t char*
|
||||
|
||||
Reference in New Issue
Block a user