mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-09-23 01:09:47 +02:00
Compare commits
15
Commits
icsneo_api
...
ea5f11268c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea5f11268c | ||
|
|
759cb2436d | ||
|
|
771d82826f | ||
|
|
b7330a2cea | ||
|
|
fb3778f91b | ||
|
|
a0c8cc62df | ||
|
|
77b3564677 | ||
|
|
051063e684 | ||
|
|
7c1cfde6a0 | ||
|
|
d4995fa2a9 | ||
|
|
fb5c4babce | ||
|
|
4ba1a1e1dd | ||
|
|
6b9a687ff9 | ||
|
|
02b5dafca9 | ||
|
|
f04cd16bee |
+2
-114
@@ -4,7 +4,6 @@ variables:
|
|||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- unit_test
|
- unit_test
|
||||||
- hardware_test
|
|
||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@@ -307,119 +306,6 @@ unit_test linux/fedora/39/amd64/clang:
|
|||||||
needs:
|
needs:
|
||||||
- build linux/fedora/39/amd64/clang
|
- 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
|
# Python Module
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@@ -522,6 +408,8 @@ push github:
|
|||||||
image: alpine:latest
|
image: alpine:latest
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||||
|
when: delayed
|
||||||
|
start_in: 10 minutes
|
||||||
dependencies:
|
dependencies:
|
||||||
- deploy python/pypi
|
- deploy python/pypi
|
||||||
needs:
|
needs:
|
||||||
|
|||||||
+5
-18
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
project(libicsneo VERSION 0.3.0)
|
project(libicsneo VERSION 0.3.0)
|
||||||
|
|
||||||
cmake_policy(SET CMP0074 NEW)
|
cmake_policy(SET CMP0074 NEW)
|
||||||
@@ -7,7 +7,6 @@ if(POLICY CMP0135)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(LIBICSNEO_BUILD_UNIT_TESTS "Build unit tests." OFF)
|
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_DOCS "Build documentation. Don't use in Visual Studio." OFF)
|
||||||
option(LIBICSNEO_BUILD_EXAMPLES "Build examples." ON)
|
option(LIBICSNEO_BUILD_EXAMPLES "Build examples." ON)
|
||||||
option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON)
|
option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON)
|
||||||
@@ -111,6 +110,7 @@ endif()
|
|||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(PLATFORM_SRC
|
set(PLATFORM_SRC
|
||||||
|
platform/windows/strings.cpp
|
||||||
platform/windows/registry.cpp
|
platform/windows/registry.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -248,6 +248,7 @@ set(SRC_FILES
|
|||||||
communication/message/tc10statusmessage.cpp
|
communication/message/tc10statusmessage.cpp
|
||||||
communication/message/gptpstatusmessage.cpp
|
communication/message/gptpstatusmessage.cpp
|
||||||
communication/message/ethernetstatusmessage.cpp
|
communication/message/ethernetstatusmessage.cpp
|
||||||
|
communication/message/macsecmessage.cpp
|
||||||
communication/packet/flexraypacket.cpp
|
communication/packet/flexraypacket.cpp
|
||||||
communication/packet/canpacket.cpp
|
communication/packet/canpacket.cpp
|
||||||
communication/packet/a2bpacket.cpp
|
communication/packet/a2bpacket.cpp
|
||||||
@@ -275,6 +276,7 @@ set(SRC_FILES
|
|||||||
communication/driver.cpp
|
communication/driver.cpp
|
||||||
communication/livedata.cpp
|
communication/livedata.cpp
|
||||||
communication/ringbuffer.cpp
|
communication/ringbuffer.cpp
|
||||||
|
communication/crc32.cpp
|
||||||
device/extensions/flexray/extension.cpp
|
device/extensions/flexray/extension.cpp
|
||||||
device/extensions/flexray/controller.cpp
|
device/extensions/flexray/controller.cpp
|
||||||
device/idevicesettings.cpp
|
device/idevicesettings.cpp
|
||||||
@@ -527,6 +529,7 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
|||||||
test/unit/livedataencoderdecodertest.cpp
|
test/unit/livedataencoderdecodertest.cpp
|
||||||
test/unit/ringbuffertest.cpp
|
test/unit/ringbuffertest.cpp
|
||||||
test/unit/apperrordecodertest.cpp
|
test/unit/apperrordecodertest.cpp
|
||||||
|
test/unit/windowsstrings.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
||||||
@@ -539,22 +542,6 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
|||||||
add_test(NAME libicsneo-unit-test-suite COMMAND libicsneo-unit-tests)
|
add_test(NAME libicsneo-unit-test-suite COMMAND libicsneo-unit-tests)
|
||||||
endif()
|
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_NAME ${PROJECT_NAME})
|
||||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||||
include(CPack)
|
include(CPack)
|
||||||
@@ -1,7 +1,18 @@
|
|||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
|
||||||
set(PYBIND11_FINDPYTHON ON)
|
set(PYBIND11_FINDPYTHON ON)
|
||||||
|
|
||||||
|
if(PYBIND11_ROOT)
|
||||||
find_package(pybind11 CONFIG REQUIRED)
|
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
|
pybind11_add_module(icsneopy
|
||||||
icsneopy/api/event.cpp
|
icsneopy/api/event.cpp
|
||||||
@@ -19,8 +30,11 @@ pybind11_add_module(icsneopy
|
|||||||
icsneopy/communication/message/mdiomessage.cpp
|
icsneopy/communication/message/mdiomessage.cpp
|
||||||
icsneopy/communication/message/gptpstatusmessage.cpp
|
icsneopy/communication/message/gptpstatusmessage.cpp
|
||||||
icsneopy/communication/message/ethernetstatusmessage.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/callback/messagecallback.cpp
|
||||||
icsneopy/communication/message/filter/messagefilter.cpp
|
icsneopy/communication/message/filter/messagefilter.cpp
|
||||||
|
icsneopy/disk/diskdriver.cpp
|
||||||
icsneopy/device/device.cpp
|
icsneopy/device/device.cpp
|
||||||
icsneopy/icsneocpp.cpp
|
icsneopy/icsneocpp.cpp
|
||||||
)
|
)
|
||||||
@@ -28,6 +42,10 @@ target_link_libraries(icsneopy PRIVATE icsneocpp)
|
|||||||
|
|
||||||
install(TARGETS icsneopy LIBRARY DESTINATION icsneopy)
|
install(TARGETS icsneopy LIBRARY DESTINATION icsneopy)
|
||||||
|
|
||||||
add_custom_command(TARGET icsneopy POST_BUILD COMMAND stubgen -m icsneopy -o .)
|
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 ${CMAKE_CURRENT_BINARY_DIR}/icsneopy.pyi __init__.py py.typed DESTINATION icsneopy)
|
install(FILES __init__.py DESTINATION icsneopy)
|
||||||
|
|||||||
@@ -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,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
|
||||||
|
|
||||||
@@ -5,42 +5,51 @@
|
|||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
void init_device(pybind11::module_& m) {
|
void init_device(pybind11::module_& m) {
|
||||||
pybind11::class_<Device, std::shared_ptr<Device>>(m, "Device")
|
pybind11::class_<Device, std::shared_ptr<Device>>(m, "Device")
|
||||||
.def("get_type", &Device::getType)
|
.def("__repr__", &Device::describe)
|
||||||
.def("get_serial", &Device::getSerial)
|
|
||||||
.def("get_serial_number", &Device::getSerialNumber)
|
|
||||||
.def("get_product_name", &Device::getProductName)
|
|
||||||
.def("open", [](Device& device) { return device.open(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("close", &Device::close, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("is_open", &Device::isOpen)
|
|
||||||
.def("go_online", &Device::goOnline, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("go_offline", &Device::goOffline, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("is_online", &Device::isOnline)
|
|
||||||
.def("enable_message_polling", &Device::enableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("disable_message_polling", &Device::disableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("is_message_polling_enabled", &Device::isMessagePollingEnabled)
|
|
||||||
.def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("get_current_message_count", &Device::getCurrentMessageCount)
|
|
||||||
.def("get_polling_message_limit", &Device::getPollingMessageLimit)
|
|
||||||
.def("set_polling_message_limit", &Device::setPollingMessageLimit)
|
|
||||||
.def("add_message_callback", &Device::addMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
.def("add_message_callback", &Device::addMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||||
.def("remove_message_callback", &Device::removeMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
.def("clear_script", &Device::clearScript, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||||
.def("transmit", pybind11::overload_cast<std::shared_ptr<Frame>>(&Device::transmit), 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("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_rx_networks", &Device::getSupportedRXNetworks, pybind11::return_value_policy::reference)
|
||||||
.def("get_supported_tx_networks", &Device::getSupportedTXNetworks, pybind11::return_value_policy::reference)
|
.def("get_supported_tx_networks", &Device::getSupportedTXNetworks, pybind11::return_value_policy::reference)
|
||||||
.def("get_rtc", &Device::getRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("describe", &Device::describe)
|
|
||||||
.def("is_online_supported", &Device::isOnlineSupported)
|
|
||||||
.def("supports_tc10", &Device::supportsTC10)
|
|
||||||
.def("request_tc10_wake", &Device::requestTC10Wake, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("request_tc10_sleep", &Device::requestTC10Sleep, pybind11::call_guard<pybind11::gil_scoped_release>())
|
|
||||||
.def("get_tc10_status", &Device::getTC10Status, pybind11::call_guard<pybind11::gil_scoped_release>())
|
.def("get_tc10_status", &Device::getTC10Status, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||||
.def("get_gptp_status", &Device::getGPTPStatus, pybind11::arg("timeout") = std::chrono::milliseconds(100), pybind11::call_guard<pybind11::gil_scoped_release>())
|
.def("get_type", &Device::getType)
|
||||||
.def("__repr__", &Device::describe);
|
.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("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
|
} // namespace icsneo
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -20,6 +20,9 @@ void init_tc10statusmessage(pybind11::module_&);
|
|||||||
void init_gptpstatusmessage(pybind11::module_&);
|
void init_gptpstatusmessage(pybind11::module_&);
|
||||||
void init_mdiomessage(pybind11::module_&);
|
void init_mdiomessage(pybind11::module_&);
|
||||||
void init_ethernetstatusmessage(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_device(pybind11::module_&);
|
||||||
void init_messagefilter(pybind11::module_&);
|
void init_messagefilter(pybind11::module_&);
|
||||||
void init_messagecallback(pybind11::module_&);
|
void init_messagecallback(pybind11::module_&);
|
||||||
@@ -45,8 +48,11 @@ PYBIND11_MODULE(icsneopy, m) {
|
|||||||
init_gptpstatusmessage(m);
|
init_gptpstatusmessage(m);
|
||||||
init_mdiomessage(m);
|
init_mdiomessage(m);
|
||||||
init_ethernetstatusmessage(m);
|
init_ethernetstatusmessage(m);
|
||||||
|
init_macsecmessage(m);
|
||||||
|
init_scriptstatusmessage(m);
|
||||||
init_messagefilter(m);
|
init_messagefilter(m);
|
||||||
init_messagecallback(m);
|
init_messagecallback(m);
|
||||||
|
init_diskdriver(m);
|
||||||
init_device(m);
|
init_device(m);
|
||||||
|
|
||||||
m.def("find_all_devices", &FindAllDevices);
|
m.def("find_all_devices", &FindAllDevices);
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_EXAMPLES=ON \
|
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
|
cmake --build build || exit 1
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ REM build
|
|||||||
cd build
|
cd build
|
||||||
set CFLAGS=/WX
|
set CFLAGS=/WX
|
||||||
set CXXFLAGS=/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%
|
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||||
cmake --build .
|
cmake --build .
|
||||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||||
|
|||||||
@@ -37,29 +37,28 @@ bool Communication::open() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Communication::spawnThreads() {
|
void Communication::spawnThreads() {
|
||||||
|
closing = false;
|
||||||
readTaskThread = std::thread(&Communication::readTask, this);
|
readTaskThread = std::thread(&Communication::readTask, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Communication::joinThreads() {
|
void Communication::joinThreads() {
|
||||||
closing = true;
|
|
||||||
|
|
||||||
if(pauseReadTask) {
|
if(pauseReadTask) {
|
||||||
resumeReads();
|
resumeReads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closing = true;
|
||||||
if(readTaskThread.joinable())
|
if(readTaskThread.joinable())
|
||||||
readTaskThread.join();
|
readTaskThread.join();
|
||||||
closing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Communication::close() {
|
bool Communication::close() {
|
||||||
joinThreads();
|
|
||||||
|
|
||||||
if(!isOpen() && !isDisconnected()) {
|
if(!isOpen() && !isDisconnected()) {
|
||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joinThreads();
|
||||||
|
|
||||||
return driver->close();
|
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;
|
||||||
|
}
|
||||||
@@ -265,6 +265,8 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||||||
case Command::GetMainVersion:
|
case Command::GetMainVersion:
|
||||||
case Command::GetSecondaryVersions:
|
case Command::GetSecondaryVersions:
|
||||||
case Command::NeoReadMemory:
|
case Command::NeoReadMemory:
|
||||||
|
case Command::ClearCoreMini:
|
||||||
|
case Command::LoadCoreMini:
|
||||||
// There is a firmware handling idiosyncrasy with these commands
|
// There is a firmware handling idiosyncrasy with these commands
|
||||||
// They must be encoded in the short format
|
// They must be encoded in the short format
|
||||||
m51msg->forceShortFormat = true;
|
m51msg->forceShortFormat = true;
|
||||||
|
|||||||
@@ -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
|
||||||
+64
-19
@@ -88,6 +88,10 @@ Device::~Device() {
|
|||||||
disableMessagePolling();
|
disableMessagePolling();
|
||||||
if(isOpen())
|
if(isOpen())
|
||||||
close();
|
close();
|
||||||
|
if(heartbeatThread.joinable()) {
|
||||||
|
stopHeartbeatThread = true;
|
||||||
|
heartbeatThread.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Device::getTimestampResolution() const {
|
uint16_t Device::getTimestampResolution() const {
|
||||||
@@ -245,6 +249,12 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
|||||||
handleInternalMessage(message);
|
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]() {
|
heartbeatThread = std::thread([this]() {
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||||
|
|
||||||
@@ -270,12 +280,12 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while(!stopHeartbeatThread) {
|
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);
|
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;
|
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
|
// 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
|
// 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
|
// packet format we expect here. As a result, status updates will not reach
|
||||||
@@ -284,9 +294,8 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
|||||||
// otherwise quiet stream. This lock makes sure suppressDisconnects() will
|
// otherwise quiet stream. This lock makes sure suppressDisconnects() will
|
||||||
// block until we've either gotten our status update or disconnected from
|
// block until we've either gotten our status update or disconnected from
|
||||||
// the device.
|
// the device.
|
||||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
std::unique_lock<std::mutex> lk(heartbeatMutex);
|
||||||
if(heartbeatSuppressed())
|
if(heartbeatSuppressed()) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
// No heartbeat received, request a status
|
// No heartbeat received, request a status
|
||||||
com->sendCommand(Command::RequestStatusUpdate);
|
com->sendCommand(Command::RequestStatusUpdate);
|
||||||
@@ -296,8 +305,8 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
|||||||
receivedMessage = false;
|
receivedMessage = false;
|
||||||
} else {
|
} else {
|
||||||
if(!stopHeartbeatThread && !isDisconnected()) {
|
if(!stopHeartbeatThread && !isDisconnected()) {
|
||||||
|
close();
|
||||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||||
com->driver->close();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -379,10 +388,6 @@ bool Device::close() {
|
|||||||
|
|
||||||
internalHandlerCallbackID = 0;
|
internalHandlerCallbackID = 0;
|
||||||
|
|
||||||
if(heartbeatThread.joinable())
|
|
||||||
heartbeatThread.join();
|
|
||||||
stopHeartbeatThread = false;
|
|
||||||
|
|
||||||
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onDeviceClose(); return true; });
|
forEachExtension([](const std::shared_ptr<DeviceExtension>& ext) { ext->onDeviceClose(); return true; });
|
||||||
return com->close();
|
return com->close();
|
||||||
}
|
}
|
||||||
@@ -814,7 +819,6 @@ std::shared_ptr<HardwareInfo> Device::getHardwareInfo(std::chrono::milliseconds
|
|||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto filter = std::make_shared<MessageFilter>(Message::Type::HardwareInfo);
|
auto filter = std::make_shared<MessageFilter>(Message::Type::HardwareInfo);
|
||||||
|
|
||||||
auto response = com->waitForMessageSync([this]() {
|
auto response = com->waitForMessageSync([this]() {
|
||||||
@@ -1694,7 +1698,10 @@ void Device::stopScriptStatusThreadIfNecessary(std::unique_lock<std::mutex> lk)
|
|||||||
Lifetime Device::suppressDisconnects() {
|
Lifetime Device::suppressDisconnects() {
|
||||||
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
std::lock_guard<std::mutex> lk(heartbeatMutex);
|
||||||
heartbeatSuppressedByUser++;
|
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) {
|
void Device::addExtension(std::shared_ptr<DeviceExtension>&& extension) {
|
||||||
@@ -1987,11 +1994,6 @@ std::optional<size_t> Device::getGenericBinarySize(uint16_t binaryIndex) {
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isOnline()) {
|
|
||||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> args = GenericBinaryStatusPacket::EncodeArguments(binaryIndex);
|
std::vector<uint8_t> args = GenericBinaryStatusPacket::EncodeArguments(binaryIndex);
|
||||||
|
|
||||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||||
@@ -2054,6 +2056,40 @@ bool Device::readBinaryFile(std::ostream& stream, uint16_t binaryIndex) {
|
|||||||
return true;
|
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) {
|
bool Device::subscribeLiveData(std::shared_ptr<LiveDataCommandMessage> message) {
|
||||||
if(!supportsLiveData()) {
|
if(!supportsLiveData()) {
|
||||||
report(APIEvent::Type::LiveDataNotSupported, APIEvent::Severity::Error);
|
report(APIEvent::Type::LiveDataNotSupported, APIEvent::Severity::Error);
|
||||||
@@ -3369,3 +3405,12 @@ std::optional<GPTPStatus> Device::getGPTPStatus(std::chrono::milliseconds timeou
|
|||||||
|
|
||||||
return *retMsg;
|
return *retMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Device::writeMACsecConfig(const MACsecMessage& message, uint16_t binaryIndex)
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> raw;
|
||||||
|
|
||||||
|
message.EncodeFromMessage(raw, report);
|
||||||
|
|
||||||
|
return writeBinaryFile(raw, binaryIndex);
|
||||||
|
}
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ enum class ExtendedResponse : int32_t {
|
|||||||
|
|
||||||
enum class ExtendedDataSubCommand : uint32_t {
|
enum class ExtendedDataSubCommand : uint32_t {
|
||||||
GenericBinaryRead = 13,
|
GenericBinaryRead = 13,
|
||||||
|
GenericBinaryWrite = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#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_
|
||||||
@@ -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
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "icsneo/communication/message/extendeddatamessage.h"
|
#include "icsneo/communication/message/extendeddatamessage.h"
|
||||||
#include "icsneo/communication/message/livedatamessage.h"
|
#include "icsneo/communication/message/livedatamessage.h"
|
||||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||||
|
#include "icsneo/communication/message/macsecmessage.h"
|
||||||
#include "icsneo/communication/packet/genericbinarystatuspacket.h"
|
#include "icsneo/communication/packet/genericbinarystatuspacket.h"
|
||||||
#include "icsneo/communication/packet/livedatapacket.h"
|
#include "icsneo/communication/packet/livedatapacket.h"
|
||||||
#include "icsneo/device/extensions/flexray/controller.h"
|
#include "icsneo/device/extensions/flexray/controller.h"
|
||||||
@@ -624,6 +625,7 @@ public:
|
|||||||
|
|
||||||
std::optional<size_t> getGenericBinarySize(uint16_t binaryIndex);
|
std::optional<size_t> getGenericBinarySize(uint16_t binaryIndex);
|
||||||
bool readBinaryFile(std::ostream& stream, 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 subscribeLiveData(std::shared_ptr<LiveDataCommandMessage> message);
|
||||||
bool unsubscribeLiveData(const LiveDataHandle& handle);
|
bool unsubscribeLiveData(const LiveDataHandle& handle);
|
||||||
bool clearAllLiveData();
|
bool clearAllLiveData();
|
||||||
@@ -738,6 +740,9 @@ public:
|
|||||||
std::optional<TC10StatusMessage> getTC10Status(Network::NetID network);
|
std::optional<TC10StatusMessage> getTC10Status(Network::NetID network);
|
||||||
std::optional<GPTPStatus> getGPTPStatus(std::chrono::milliseconds timeout = std::chrono::milliseconds(100));
|
std::optional<GPTPStatus> getGPTPStatus(std::chrono::milliseconds timeout = std::chrono::milliseconds(100));
|
||||||
|
|
||||||
|
/* MACsec support */
|
||||||
|
virtual bool writeMACsecConfig(const MACsecMessage& message, uint16_t binaryIndex);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool online = false;
|
bool online = false;
|
||||||
int messagePollingCallbackID = 0;
|
int messagePollingCallbackID = 0;
|
||||||
@@ -843,6 +848,13 @@ protected:
|
|||||||
|
|
||||||
neodevice_t& getWritableNeoDevice() { return data; }
|
neodevice_t& getWritableNeoDevice() { return data; }
|
||||||
|
|
||||||
|
enum class LEDState : uint8_t {
|
||||||
|
Offline = 0x04,
|
||||||
|
CoreMiniRunning = 0x08, // This should override "offline" if the CoreMini is running
|
||||||
|
Online = 0x10
|
||||||
|
};
|
||||||
|
LEDState ledState;
|
||||||
|
void updateLEDState();
|
||||||
private:
|
private:
|
||||||
neodevice_t data;
|
neodevice_t data;
|
||||||
std::shared_ptr<ResetStatusMessage> latestResetStatus;
|
std::shared_ptr<ResetStatusMessage> latestResetStatus;
|
||||||
@@ -871,14 +883,6 @@ private:
|
|||||||
|
|
||||||
APIEvent::Type getCommunicationNotEstablishedError();
|
APIEvent::Type getCommunicationNotEstablishedError();
|
||||||
|
|
||||||
enum class LEDState : uint8_t {
|
|
||||||
Offline = 0x04,
|
|
||||||
CoreMiniRunning = 0x08, // This should override "offline" if the CoreMini is running
|
|
||||||
Online = 0x10
|
|
||||||
};
|
|
||||||
LEDState ledState;
|
|
||||||
void updateLEDState();
|
|
||||||
|
|
||||||
size_t pollingMessageLimit = 20000;
|
size_t pollingMessageLimit = 20000;
|
||||||
moodycamel::BlockingConcurrentQueue<std::shared_ptr<Message>> pollingContainer;
|
moodycamel::BlockingConcurrentQueue<std::shared_ptr<Message>> pollingContainer;
|
||||||
void enforcePollingMessageLimit();
|
void enforcePollingMessageLimit();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
RADGigastar(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
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 {
|
void setupPacketizer(Packetizer& packetizer) override {
|
||||||
|
|||||||
@@ -48,24 +48,19 @@ public:
|
|||||||
return Device::getProductName();
|
return Device::getProductName();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RADMoon 2 does not go online, you can only set settings and
|
|
||||||
// view PHY information (when supported)
|
|
||||||
bool goOnline() override {
|
bool goOnline() override {
|
||||||
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
if(!com->sendCommand(Command::EnableNetworkCommunication, true))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
bool goOffline() override {
|
updateLEDState();
|
||||||
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
online = true;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getEthPhyRegControlSupported() const override { return true; }
|
bool getEthPhyRegControlSupported() const override { return true; }
|
||||||
|
|
||||||
virtual uint8_t getPhyAddrOrPort() const = 0;
|
virtual uint8_t getPhyAddrOrPort() const = 0;
|
||||||
|
|
||||||
bool isOnlineSupported() const override { return false; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using Device::Device;
|
using Device::Device;
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ typedef struct {
|
|||||||
uint16_t pc_com_mode;
|
uint16_t pc_com_mode;
|
||||||
TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings;
|
TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings;
|
||||||
uint16_t hwComLatencyTestEn;
|
uint16_t hwComLatencyTestEn;
|
||||||
|
|
||||||
|
RAD_GPTP_SETTINGS gPTP;
|
||||||
|
uint64_t network_enables_5;
|
||||||
|
|
||||||
} radmoon2_settings_t;
|
} radmoon2_settings_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public:
|
|||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::Ethernet,
|
Network::NetID::Ethernet,
|
||||||
Network::NetID::OP_Ethernet1,
|
Network::NetID::OP_Ethernet1,
|
||||||
|
Network::NetID::MDIO1
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
@@ -29,6 +30,8 @@ public:
|
|||||||
|
|
||||||
bool supportsComponentVersions() const override { return true; }
|
bool supportsComponentVersions() const override { return true; }
|
||||||
|
|
||||||
|
bool supportsTC10() const override { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RADMoon3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
RADMoon3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||||
initialize<RADMoon3Settings>(makeDriver);
|
initialize<RADMoon3Settings>(makeDriver);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ typedef struct {
|
|||||||
uint16_t enableLatencyTest : 1;
|
uint16_t enableLatencyTest : 1;
|
||||||
uint16_t reserved : 15;
|
uint16_t reserved : 15;
|
||||||
} flags; // 2
|
} flags; // 2
|
||||||
|
uint64_t network_enables_5;
|
||||||
} radmoon3_settings_t;
|
} radmoon3_settings_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|||||||
@@ -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__
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
|
||||||
#include "icsneo/platform/windows/pcap.h"
|
#include "icsneo/platform/windows/pcap.h"
|
||||||
|
#include "icsneo/platform/windows/strings.h"
|
||||||
#include "icsneo/communication/network.h"
|
#include "icsneo/communication/network.h"
|
||||||
#include "icsneo/communication/communication.h"
|
#include "icsneo/communication/communication.h"
|
||||||
#include "icsneo/communication/ethernetpacketizer.h"
|
#include "icsneo/communication/ethernetpacketizer.h"
|
||||||
@@ -11,14 +12,12 @@
|
|||||||
#include <pcap.h>
|
#include <pcap.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#pragma comment(lib, "IPHLPAPI.lib")
|
#pragma comment(lib, "IPHLPAPI.lib")
|
||||||
#include <codecvt>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
|
||||||
|
|
||||||
std::vector<PCAP::NetworkInterface> PCAP::knownInterfaces;
|
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));
|
memcpy(iface.macAddress, aa->PhysicalAddress, sizeof(iface.macAddress));
|
||||||
iface.nameFromWin32API = aa->AdapterName;
|
iface.nameFromWin32API = aa->AdapterName;
|
||||||
iface.descriptionFromWin32API = converter.to_bytes(aa->Description);
|
iface.descriptionFromWin32API = convertWideString(aa->Description);
|
||||||
iface.friendlyNameFromWin32API = converter.to_bytes(aa->FriendlyName);
|
iface.friendlyNameFromWin32API = convertWideString(aa->FriendlyName);
|
||||||
if(iface.descriptionFromWin32API.find("LAN9512/LAN9514") != std::string::npos) {
|
if(iface.descriptionFromWin32API.find("LAN9512/LAN9514") != std::string::npos) {
|
||||||
// This is an Ethernet EVB device
|
// This is an Ethernet EVB device
|
||||||
iface.fullName = "Intrepid Ethernet EVB ( " + iface.friendlyNameFromWin32API + " : " + iface.descriptionFromWin32API + " )";
|
iface.fullName = "Intrepid Ethernet EVB ( " + iface.friendlyNameFromWin32API + " : " + iface.descriptionFromWin32API + " )";
|
||||||
@@ -187,7 +186,7 @@ bool PCAP::IsHandleValid(neodevice_handle_t handle) {
|
|||||||
return (netifIndex < knownInterfaces.size());
|
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)) {
|
if(IsHandleValid(device.handle)) {
|
||||||
iface = knownInterfaces[(device.handle >> 24) & 0xFF];
|
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.
|
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/registry.h"
|
||||||
|
#include "icsneo/platform/windows/strings.h"
|
||||||
#include "icsneo/platform/windows.h"
|
#include "icsneo/platform/windows.h"
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -6,8 +7,6 @@
|
|||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
public:
|
public:
|
||||||
Key(std::wstring path, bool readwrite = false);
|
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) {
|
bool Registry::Get(std::string path, std::string key, std::string& value) {
|
||||||
std::wstring wvalue;
|
std::wstring wvalue;
|
||||||
bool ret = Get(converter.from_bytes(path), converter.from_bytes(key), wvalue);
|
bool ret = Get(convertStringToWide(path), convertStringToWide(key), wvalue);
|
||||||
value = converter.to_bytes(wvalue);
|
value = convertWideString(wvalue);
|
||||||
return ret;
|
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) {
|
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/ftdi.h"
|
||||||
|
#include "icsneo/platform/windows/strings.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#include "icsneo/platform/registry.h"
|
#include "icsneo/platform/registry.h"
|
||||||
#include "icsneo/device/founddevice.h"
|
#include "icsneo/device/founddevice.h"
|
||||||
@@ -15,7 +16,6 @@
|
|||||||
|
|
||||||
using namespace icsneo;
|
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 DRIVER_SERVICES_REG_KEY = L"SYSTEM\\CurrentControlSet\\services\\";
|
||||||
static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\";
|
static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\";
|
||||||
static constexpr unsigned int RETRY_TIMES = 5;
|
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)
|
if(!device.productId)
|
||||||
continue;
|
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.
|
// 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) {
|
if(serial.find_first_of('\\') != std::string::npos) {
|
||||||
// The serial number was not in the first serenum key where we expected it.
|
// 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
|
// This is a device with characters in the serial number
|
||||||
if(correctSerial.size() != 6)
|
if(correctSerial.size() != 6)
|
||||||
continue;
|
continue;
|
||||||
serial = converter.to_bytes(correctSerial);
|
serial = convertWideString(correctSerial);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::wstringstream soss;
|
std::wstringstream soss;
|
||||||
soss << sn;
|
soss << sn;
|
||||||
serial = converter.to_bytes(soss.str());
|
serial = convertWideString(soss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(serial.find_first_of('\\') != std::string::npos)
|
if(serial.find_first_of('\\') != std::string::npos)
|
||||||
|
|||||||
@@ -47,3 +47,7 @@ local_scheme = "no-local-version"
|
|||||||
[tool.scikit-build.cmake.define]
|
[tool.scikit-build.cmake.define]
|
||||||
LIBICSNEO_ENABLE_BINDINGS_PYTHON = true
|
LIBICSNEO_ENABLE_BINDINGS_PYTHON = true
|
||||||
LIBICSNEO_ENABLE_TCP = 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user